Revert "Revert "[PERF-325] Add versioned course asset URLs when canonicalizing asset paths.""

This reverts commit 9967b6fd58.
This commit is contained in:
Toby Lawrence
2016-06-23 13:27:15 -04:00
parent 11fa2f3711
commit bb29ad5f30
9 changed files with 406 additions and 189 deletions

View File

@@ -1,12 +1,13 @@
# -*- coding: utf-8 -*-
"""Tests for static_replace"""
from urllib import quote_plus
import ddt
import re
from django.utils.http import urlquote, urlencode
from urlparse import urlparse, urlunparse, parse_qsl
from PIL import Image
from cStringIO import StringIO
from nose.tools import assert_equals, assert_true, assert_false # pylint: disable=no-name-in-module
from static_replace import (
replace_static_urls,
@@ -16,7 +17,6 @@ from static_replace import (
make_static_urls_absolute
)
from mock import patch, Mock
from opaque_keys.edx.locations import SlashSeparatedCourseKey
from xmodule.contentstore.content import StaticContent
from xmodule.contentstore.django import contentstore
@@ -25,12 +25,29 @@ from xmodule.modulestore.mongo import MongoModuleStore
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory, check_mongo_calls
from xmodule.modulestore.xml import XMLModuleStore
from xmodule.modulestore.exceptions import ItemNotFoundError
from xmodule.exceptions import NotFoundError
from xmodule.assetstore.assetmgr import AssetManager
DATA_DIRECTORY = 'data_dir'
COURSE_KEY = SlashSeparatedCourseKey('org', 'course', 'run')
STATIC_SOURCE = '"/static/file.png"'
def encode_unicode_characters_in_url(url):
"""
Encodes all Unicode characters to their percent-encoding representation
in both the path portion and query parameter portion of the given URL.
"""
scheme, netloc, path, params, query, fragment = urlparse(url)
query_params = parse_qsl(query)
updated_query_params = []
for query_name, query_val in query_params:
updated_query_params.append((query_name, urlquote(query_val)))
return urlunparse((scheme, netloc, urlquote(path, '/:+@'), params, urlencode(query_params), fragment))
def test_multi_replace():
course_source = '"/course/file.png"'
@@ -202,7 +219,7 @@ class CanonicalContentTest(SharedModuleStoreTestCase):
cls.courses[prefix] = CourseFactory.create(org='a', course='b', run=prefix)
# Create an unlocked image.
unlock_content = cls.create_image(prefix, (32, 32), 'blue', '{}_unlock.png')
unlock_content = cls.create_image(prefix, (32, 32), 'blue', u'{}_ünlöck.png')
# Create a locked image.
lock_content = cls.create_image(prefix, (32, 32), 'green', '{}_lock.png', locked=True)
@@ -212,14 +229,14 @@ class CanonicalContentTest(SharedModuleStoreTestCase):
contentstore().generate_thumbnail(lock_content, dimensions=(16, 16))
# Create an unlocked image in a subdirectory.
cls.create_image(prefix, (1, 1), 'red', 'special/{}_unlock.png')
cls.create_image(prefix, (1, 1), 'red', u'special/{}_ünlöck.png')
# Create a locked image in a subdirectory.
cls.create_image(prefix, (1, 1), 'yellow', 'special/{}_lock.png', locked=True)
# Create an unlocked image with funky characters in the name.
cls.create_image(prefix, (1, 1), 'black', 'weird {}_unlock.png')
cls.create_image(prefix, (1, 1), 'black', 'special/weird {}_unlock.png')
cls.create_image(prefix, (1, 1), 'black', u'weird {}_ünlöck.png')
cls.create_image(prefix, (1, 1), 'black', u'special/weird {}_ünlöck.png')
# Create an HTML file to test extension exclusion, and create a control file.
cls.create_arbitrary_content(prefix, '{}_not_excluded.htm')
@@ -227,6 +244,24 @@ class CanonicalContentTest(SharedModuleStoreTestCase):
cls.create_arbitrary_content(prefix, 'special/{}_not_excluded.htm')
cls.create_arbitrary_content(prefix, 'special/{}_excluded.html')
@classmethod
def get_content_digest_for_asset_path(cls, prefix, path):
"""
Takes an unprocessed asset path, parses it just enough to try and find the
asset it refers to, and returns the content digest of that asset if it exists.
"""
# Parse the path as if it was potentially a relative URL with query parameters,
# or an absolute URL, etc. Only keep the path because that's all we need.
_, _, relative_path, _, _, _ = urlparse(path)
asset_key = StaticContent.get_asset_key_from_path(cls.courses[prefix].id, relative_path)
try:
content = AssetManager.find(asset_key, as_stream=True)
return content.content_digest
except (ItemNotFoundError, NotFoundError):
return None
@classmethod
def create_image(cls, prefix, dimensions, color, name, locked=False):
"""
@@ -277,100 +312,100 @@ class CanonicalContentTest(SharedModuleStoreTestCase):
@ddt.data(
# No leading slash.
(u'', u'{prfx}_unlock.png', u'/{asset}@{prfx}_unlock.png', 1),
(u'', u'{prfx}_ünlöck.png', u'/{asset}@{prfx}_ünlöck.png', 1),
(u'', u'{prfx}_lock.png', u'/{asset}@{prfx}_lock.png', 1),
(u'', u'weird {prfx}_unlock.png', u'/{asset}@weird_{prfx}_unlock.png', 1),
(u'', u'{prfx}_excluded.html', u'/{asset}@{prfx}_excluded.html', 1),
(u'', u'weird {prfx}_ünlöck.png', u'/{asset}@weird_{prfx}_ünlöck.png', 1),
(u'', u'{prfx}_excluded.html', u'/{base_asset}@{prfx}_excluded.html', 1),
(u'', u'{prfx}_not_excluded.htm', u'/{asset}@{prfx}_not_excluded.htm', 1),
(u'dev', u'{prfx}_unlock.png', u'//dev/{asset}@{prfx}_unlock.png', 1),
(u'dev', u'{prfx}_ünlöck.png', u'//dev/{asset}@{prfx}_ünlöck.png', 1),
(u'dev', u'{prfx}_lock.png', u'/{asset}@{prfx}_lock.png', 1),
(u'dev', u'weird {prfx}_unlock.png', u'//dev/{asset}@weird_{prfx}_unlock.png', 1),
(u'dev', u'{prfx}_excluded.html', u'/{asset}@{prfx}_excluded.html', 1),
(u'dev', u'weird {prfx}_ünlöck.png', u'//dev/{asset}@weird_{prfx}_ünlöck.png', 1),
(u'dev', u'{prfx}_excluded.html', u'/{base_asset}@{prfx}_excluded.html', 1),
(u'dev', u'{prfx}_not_excluded.htm', u'//dev/{asset}@{prfx}_not_excluded.htm', 1),
# No leading slash with subdirectory. This ensures we properly substitute slashes.
(u'', u'special/{prfx}_unlock.png', u'/{asset}@special_{prfx}_unlock.png', 1),
(u'', u'special/{prfx}_ünlöck.png', u'/{asset}@special_{prfx}_ünlöck.png', 1),
(u'', u'special/{prfx}_lock.png', u'/{asset}@special_{prfx}_lock.png', 1),
(u'', u'special/weird {prfx}_unlock.png', u'/{asset}@special_weird_{prfx}_unlock.png', 1),
(u'', u'special/{prfx}_excluded.html', u'/{asset}@special_{prfx}_excluded.html', 1),
(u'', u'special/weird {prfx}_ünlöck.png', u'/{asset}@special_weird_{prfx}_ünlöck.png', 1),
(u'', u'special/{prfx}_excluded.html', u'/{base_asset}@special_{prfx}_excluded.html', 1),
(u'', u'special/{prfx}_not_excluded.htm', u'/{asset}@special_{prfx}_not_excluded.htm', 1),
(u'dev', u'special/{prfx}_unlock.png', u'//dev/{asset}@special_{prfx}_unlock.png', 1),
(u'dev', u'special/{prfx}_ünlöck.png', u'//dev/{asset}@special_{prfx}_ünlöck.png', 1),
(u'dev', u'special/{prfx}_lock.png', u'/{asset}@special_{prfx}_lock.png', 1),
(u'dev', u'special/weird {prfx}_unlock.png', u'//dev/{asset}@special_weird_{prfx}_unlock.png', 1),
(u'dev', u'special/{prfx}_excluded.html', u'/{asset}@special_{prfx}_excluded.html', 1),
(u'dev', u'special/weird {prfx}_ünlöck.png', u'//dev/{asset}@special_weird_{prfx}_ünlöck.png', 1),
(u'dev', u'special/{prfx}_excluded.html', u'/{base_asset}@special_{prfx}_excluded.html', 1),
(u'dev', u'special/{prfx}_not_excluded.htm', u'//dev/{asset}@special_{prfx}_not_excluded.htm', 1),
# Leading slash.
(u'', u'/{prfx}_unlock.png', u'/{asset}@{prfx}_unlock.png', 1),
(u'', u'/{prfx}_ünlöck.png', u'/{asset}@{prfx}_ünlöck.png', 1),
(u'', u'/{prfx}_lock.png', u'/{asset}@{prfx}_lock.png', 1),
(u'', u'/weird {prfx}_unlock.png', u'/{asset}@weird_{prfx}_unlock.png', 1),
(u'', u'/{prfx}_excluded.html', u'/{asset}@{prfx}_excluded.html', 1),
(u'', u'/weird {prfx}_ünlöck.png', u'/{asset}@weird_{prfx}_ünlöck.png', 1),
(u'', u'/{prfx}_excluded.html', u'/{base_asset}@{prfx}_excluded.html', 1),
(u'', u'/{prfx}_not_excluded.htm', u'/{asset}@{prfx}_not_excluded.htm', 1),
(u'dev', u'/{prfx}_unlock.png', u'//dev/{asset}@{prfx}_unlock.png', 1),
(u'dev', u'/{prfx}_ünlöck.png', u'//dev/{asset}@{prfx}_ünlöck.png', 1),
(u'dev', u'/{prfx}_lock.png', u'/{asset}@{prfx}_lock.png', 1),
(u'dev', u'/weird {prfx}_unlock.png', u'//dev/{asset}@weird_{prfx}_unlock.png', 1),
(u'dev', u'/{prfx}_excluded.html', u'/{asset}@{prfx}_excluded.html', 1),
(u'dev', u'/weird {prfx}_ünlöck.png', u'//dev/{asset}@weird_{prfx}_ünlöck.png', 1),
(u'dev', u'/{prfx}_excluded.html', u'/{base_asset}@{prfx}_excluded.html', 1),
(u'dev', u'/{prfx}_not_excluded.htm', u'//dev/{asset}@{prfx}_not_excluded.htm', 1),
# Leading slash with subdirectory. This ensures we properly substitute slashes.
(u'', u'/special/{prfx}_unlock.png', u'/{asset}@special_{prfx}_unlock.png', 1),
(u'', u'/special/{prfx}_ünlöck.png', u'/{asset}@special_{prfx}_ünlöck.png', 1),
(u'', u'/special/{prfx}_lock.png', u'/{asset}@special_{prfx}_lock.png', 1),
(u'', u'/special/weird {prfx}_unlock.png', u'/{asset}@special_weird_{prfx}_unlock.png', 1),
(u'', u'/special/{prfx}_excluded.html', u'/{asset}@special_{prfx}_excluded.html', 1),
(u'', u'/special/weird {prfx}_ünlöck.png', u'/{asset}@special_weird_{prfx}_ünlöck.png', 1),
(u'', u'/special/{prfx}_excluded.html', u'/{base_asset}@special_{prfx}_excluded.html', 1),
(u'', u'/special/{prfx}_not_excluded.htm', u'/{asset}@special_{prfx}_not_excluded.htm', 1),
(u'dev', u'/special/{prfx}_unlock.png', u'//dev/{asset}@special_{prfx}_unlock.png', 1),
(u'dev', u'/special/{prfx}_ünlöck.png', u'//dev/{asset}@special_{prfx}_ünlöck.png', 1),
(u'dev', u'/special/{prfx}_lock.png', u'/{asset}@special_{prfx}_lock.png', 1),
(u'dev', u'/special/weird {prfx}_unlock.png', u'//dev/{asset}@special_weird_{prfx}_unlock.png', 1),
(u'dev', u'/special/{prfx}_excluded.html', u'/{asset}@special_{prfx}_excluded.html', 1),
(u'dev', u'/special/weird {prfx}_ünlöck.png', u'//dev/{asset}@special_weird_{prfx}_ünlöck.png', 1),
(u'dev', u'/special/{prfx}_excluded.html', u'/{base_asset}@special_{prfx}_excluded.html', 1),
(u'dev', u'/special/{prfx}_not_excluded.htm', u'//dev/{asset}@special_{prfx}_not_excluded.htm', 1),
# Static path.
(u'', u'/static/{prfx}_unlock.png', u'/{asset}@{prfx}_unlock.png', 1),
(u'', u'/static/{prfx}_ünlöck.png', u'/{asset}@{prfx}_ünlöck.png', 1),
(u'', u'/static/{prfx}_lock.png', u'/{asset}@{prfx}_lock.png', 1),
(u'', u'/static/weird {prfx}_unlock.png', u'/{asset}@weird_{prfx}_unlock.png', 1),
(u'', u'/static/{prfx}_excluded.html', u'/{asset}@{prfx}_excluded.html', 1),
(u'', u'/static/weird {prfx}_ünlöck.png', u'/{asset}@weird_{prfx}_ünlöck.png', 1),
(u'', u'/static/{prfx}_excluded.html', u'/{base_asset}@{prfx}_excluded.html', 1),
(u'', u'/static/{prfx}_not_excluded.htm', u'/{asset}@{prfx}_not_excluded.htm', 1),
(u'dev', u'/static/{prfx}_unlock.png', u'//dev/{asset}@{prfx}_unlock.png', 1),
(u'dev', u'/static/{prfx}_ünlöck.png', u'//dev/{asset}@{prfx}_ünlöck.png', 1),
(u'dev', u'/static/{prfx}_lock.png', u'/{asset}@{prfx}_lock.png', 1),
(u'dev', u'/static/weird {prfx}_unlock.png', u'//dev/{asset}@weird_{prfx}_unlock.png', 1),
(u'dev', u'/static/{prfx}_excluded.html', u'/{asset}@{prfx}_excluded.html', 1),
(u'dev', u'/static/weird {prfx}_ünlöck.png', u'//dev/{asset}@weird_{prfx}_ünlöck.png', 1),
(u'dev', u'/static/{prfx}_excluded.html', u'/{base_asset}@{prfx}_excluded.html', 1),
(u'dev', u'/static/{prfx}_not_excluded.htm', u'//dev/{asset}@{prfx}_not_excluded.htm', 1),
# Static path with subdirectory. This ensures we properly substitute slashes.
(u'', u'/static/special/{prfx}_unlock.png', u'/{asset}@special_{prfx}_unlock.png', 1),
(u'', u'/static/special/{prfx}_ünlöck.png', u'/{asset}@special_{prfx}_ünlöck.png', 1),
(u'', u'/static/special/{prfx}_lock.png', u'/{asset}@special_{prfx}_lock.png', 1),
(u'', u'/static/special/weird {prfx}_unlock.png', u'/{asset}@special_weird_{prfx}_unlock.png', 1),
(u'', u'/static/special/{prfx}_excluded.html', u'/{asset}@special_{prfx}_excluded.html', 1),
(u'', u'/static/special/weird {prfx}_ünlöck.png', u'/{asset}@special_weird_{prfx}_ünlöck.png', 1),
(u'', u'/static/special/{prfx}_excluded.html', u'/{base_asset}@special_{prfx}_excluded.html', 1),
(u'', u'/static/special/{prfx}_not_excluded.htm', u'/{asset}@special_{prfx}_not_excluded.htm', 1),
(u'dev', u'/static/special/{prfx}_unlock.png', u'//dev/{asset}@special_{prfx}_unlock.png', 1),
(u'dev', u'/static/special/{prfx}_ünlöck.png', u'//dev/{asset}@special_{prfx}_ünlöck.png', 1),
(u'dev', u'/static/special/{prfx}_lock.png', u'/{asset}@special_{prfx}_lock.png', 1),
(u'dev', u'/static/special/weird {prfx}_unlock.png', u'//dev/{asset}@special_weird_{prfx}_unlock.png', 1),
(u'dev', u'/static/special/{prfx}_excluded.html', u'/{asset}@special_{prfx}_excluded.html', 1),
(u'dev', u'/static/special/weird {prfx}_ünlöck.png', u'//dev/{asset}@special_weird_{prfx}_ünlöck.png', 1),
(u'dev', u'/static/special/{prfx}_excluded.html', u'/{base_asset}@special_{prfx}_excluded.html', 1),
(u'dev', u'/static/special/{prfx}_not_excluded.htm', u'//dev/{asset}@special_{prfx}_not_excluded.htm', 1),
# Static path with query parameter.
(
u'',
u'/static/{prfx}_unlock.png?foo=/static/{prfx}_lock.png',
u'/{asset}@{prfx}_unlock.png?foo={encoded_asset}{prfx}_lock.png',
u'/static/{prfx}_ünlöck.png?foo=/static/{prfx}_lock.png',
u'/{asset}@{prfx}_ünlöck.png?foo={encoded_asset}{prfx}_lock.png',
2
),
(
u'',
u'/static/{prfx}_lock.png?foo=/static/{prfx}_unlock.png',
u'/{asset}@{prfx}_lock.png?foo={encoded_asset}{prfx}_unlock.png',
u'/static/{prfx}_lock.png?foo=/static/{prfx}_ünlöck.png',
u'/{asset}@{prfx}_lock.png?foo={encoded_asset}{prfx}_ünlöck.png',
2
),
(
u'',
u'/static/{prfx}_excluded.html?foo=/static/{prfx}_excluded.html',
u'/{asset}@{prfx}_excluded.html?foo={encoded_asset}{prfx}_excluded.html',
u'/{base_asset}@{prfx}_excluded.html?foo={encoded_base_asset}{prfx}_excluded.html',
2
),
(
u'',
u'/static/{prfx}_excluded.html?foo=/static/{prfx}_not_excluded.htm',
u'/{asset}@{prfx}_excluded.html?foo={encoded_asset}{prfx}_not_excluded.htm',
u'/{base_asset}@{prfx}_excluded.html?foo={encoded_asset}{prfx}_not_excluded.htm',
2
),
(
u'',
u'/static/{prfx}_not_excluded.htm?foo=/static/{prfx}_excluded.html',
u'/{asset}@{prfx}_not_excluded.htm?foo={encoded_asset}{prfx}_excluded.html',
u'/{asset}@{prfx}_not_excluded.htm?foo={encoded_base_asset}{prfx}_excluded.html',
2
),
(
@@ -381,32 +416,32 @@ class CanonicalContentTest(SharedModuleStoreTestCase):
),
(
u'dev',
u'/static/{prfx}_unlock.png?foo=/static/{prfx}_lock.png',
u'//dev/{asset}@{prfx}_unlock.png?foo={encoded_asset}{prfx}_lock.png',
u'/static/{prfx}_ünlöck.png?foo=/static/{prfx}_lock.png',
u'//dev/{asset}@{prfx}_ünlöck.png?foo={encoded_asset}{prfx}_lock.png',
2
),
(
u'dev',
u'/static/{prfx}_lock.png?foo=/static/{prfx}_unlock.png',
u'/{asset}@{prfx}_lock.png?foo={encoded_base_url}{encoded_asset}{prfx}_unlock.png',
u'/static/{prfx}_lock.png?foo=/static/{prfx}_ünlöck.png',
u'/{asset}@{prfx}_lock.png?foo={encoded_base_url}{encoded_asset}{prfx}_ünlöck.png',
2
),
(
u'dev',
u'/static/{prfx}_excluded.html?foo=/static/{prfx}_excluded.html',
u'/{asset}@{prfx}_excluded.html?foo={encoded_asset}{prfx}_excluded.html',
u'/{base_asset}@{prfx}_excluded.html?foo={encoded_base_asset}{prfx}_excluded.html',
2
),
(
u'dev',
u'/static/{prfx}_excluded.html?foo=/static/{prfx}_not_excluded.htm',
u'/{asset}@{prfx}_excluded.html?foo={encoded_base_url}{encoded_asset}{prfx}_not_excluded.htm',
u'/{base_asset}@{prfx}_excluded.html?foo={encoded_base_url}{encoded_asset}{prfx}_not_excluded.htm',
2
),
(
u'dev',
u'/static/{prfx}_not_excluded.htm?foo=/static/{prfx}_excluded.html',
u'//dev/{asset}@{prfx}_not_excluded.htm?foo={encoded_asset}{prfx}_excluded.html',
u'//dev/{asset}@{prfx}_not_excluded.htm?foo={encoded_base_asset}{prfx}_excluded.html',
2
),
(
@@ -416,163 +451,189 @@ class CanonicalContentTest(SharedModuleStoreTestCase):
2
),
# Already asset key.
(u'', u'/{asset}@{prfx}_unlock.png', u'/{asset}@{prfx}_unlock.png', 1),
(u'', u'/{asset}@{prfx}_lock.png', u'/{asset}@{prfx}_lock.png', 1),
(u'', u'/{asset}@weird_{prfx}_unlock.png', u'/{asset}@weird_{prfx}_unlock.png', 1),
(u'', u'/{asset}@{prfx}_excluded.html', u'/{asset}@{prfx}_excluded.html', 1),
(u'', u'/{asset}@{prfx}_not_excluded.htm', u'/{asset}@{prfx}_not_excluded.htm', 1),
(u'dev', u'/{asset}@{prfx}_unlock.png', u'//dev/{asset}@{prfx}_unlock.png', 1),
(u'dev', u'/{asset}@{prfx}_lock.png', u'/{asset}@{prfx}_lock.png', 1),
(u'dev', u'/{asset}@weird_{prfx}_unlock.png', u'//dev/{asset}@weird_{prfx}_unlock.png', 1),
(u'dev', u'/{asset}@{prfx}_excluded.html', u'/{asset}@{prfx}_excluded.html', 1),
(u'dev', u'/{asset}@{prfx}_not_excluded.htm', u'//dev/{asset}@{prfx}_not_excluded.htm', 1),
(u'', u'/{base_asset}@{prfx}_ünlöck.png', u'/{asset}@{prfx}_ünlöck.png', 1),
(u'', u'/{base_asset}@{prfx}_lock.png', u'/{asset}@{prfx}_lock.png', 1),
(u'', u'/{base_asset}@weird_{prfx}_ünlöck.png', u'/{asset}@weird_{prfx}_ünlöck.png', 1),
(u'', u'/{base_asset}@{prfx}_excluded.html', u'/{base_asset}@{prfx}_excluded.html', 1),
(u'', u'/{base_asset}@{prfx}_not_excluded.htm', u'/{asset}@{prfx}_not_excluded.htm', 1),
(u'dev', u'/{base_asset}@{prfx}_ünlöck.png', u'//dev/{asset}@{prfx}_ünlöck.png', 1),
(u'dev', u'/{base_asset}@{prfx}_lock.png', u'/{asset}@{prfx}_lock.png', 1),
(u'dev', u'/{base_asset}@weird_{prfx}_ünlöck.png', u'//dev/{asset}@weird_{prfx}_ünlöck.png', 1),
(u'dev', u'/{base_asset}@{prfx}_excluded.html', u'/{base_asset}@{prfx}_excluded.html', 1),
(u'dev', u'/{base_asset}@{prfx}_not_excluded.htm', u'//dev/{asset}@{prfx}_not_excluded.htm', 1),
# Old, c4x-style path.
(u'', u'/{c4x}/{prfx}_unlock.png', u'/{c4x}/{prfx}_unlock.png', 1),
(u'', u'/{c4x}/{prfx}_ünlöck.png', u'/{c4x}/{prfx}_ünlöck.png', 1),
(u'', u'/{c4x}/{prfx}_lock.png', u'/{c4x}/{prfx}_lock.png', 1),
(u'', u'/{c4x}/weird_{prfx}_lock.png', u'/{c4x}/weird_{prfx}_lock.png', 1),
(u'', u'/{c4x}/{prfx}_excluded.html', u'/{c4x}/{prfx}_excluded.html', 1),
(u'', u'/{c4x}/{prfx}_not_excluded.htm', u'/{c4x}/{prfx}_not_excluded.htm', 1),
(u'dev', u'/{c4x}/{prfx}_unlock.png', u'/{c4x}/{prfx}_unlock.png', 1),
(u'dev', u'/{c4x}/{prfx}_ünlöck.png', u'/{c4x}/{prfx}_ünlöck.png', 1),
(u'dev', u'/{c4x}/{prfx}_lock.png', u'/{c4x}/{prfx}_lock.png', 1),
(u'dev', u'/{c4x}/weird_{prfx}_unlock.png', u'/{c4x}/weird_{prfx}_unlock.png', 1),
(u'dev', u'/{c4x}/weird_{prfx}_ünlöck.png', u'/{c4x}/weird_{prfx}_ünlöck.png', 1),
(u'dev', u'/{c4x}/{prfx}_excluded.html', u'/{c4x}/{prfx}_excluded.html', 1),
(u'dev', u'/{c4x}/{prfx}_not_excluded.htm', u'/{c4x}/{prfx}_not_excluded.htm', 1),
# Thumbnails.
(u'', u'/{th_key}@{prfx}_unlock-{th_ext}', u'/{th_key}@{prfx}_unlock-{th_ext}', 1),
(u'', u'/{th_key}@{prfx}_lock-{th_ext}', u'/{th_key}@{prfx}_lock-{th_ext}', 1),
(u'dev', u'/{th_key}@{prfx}_unlock-{th_ext}', u'//dev/{th_key}@{prfx}_unlock-{th_ext}', 1),
(u'dev', u'/{th_key}@{prfx}_lock-{th_ext}', u'//dev/{th_key}@{prfx}_lock-{th_ext}', 1),
(u'', u'/{base_th_key}@{prfx}_ünlöck-{th_ext}', u'/{th_key}@{prfx}_ünlöck-{th_ext}', 1),
(u'', u'/{base_th_key}@{prfx}_lock-{th_ext}', u'/{th_key}@{prfx}_lock-{th_ext}', 1),
(u'dev', u'/{base_th_key}@{prfx}_ünlöck-{th_ext}', u'//dev/{th_key}@{prfx}_ünlöck-{th_ext}', 1),
(u'dev', u'/{base_th_key}@{prfx}_lock-{th_ext}', u'//dev/{th_key}@{prfx}_lock-{th_ext}', 1),
)
@ddt.unpack
def test_canonical_asset_path_with_new_style_assets(self, base_url, start, expected, mongo_calls):
exts = ['.html', '.tm']
prefix = 'split'
encoded_base_url = quote_plus('//' + base_url)
c4x = 'c4x/a/b/asset'
asset_key = 'asset-v1:a+b+{}+type@asset+block'.format(prefix)
encoded_asset_key = quote_plus('/asset-v1:a+b+{}+type@asset+block@'.format(prefix))
th_key = 'asset-v1:a+b+{}+type@thumbnail+block'.format(prefix)
th_ext = 'png-16x16.jpg'
prefix = u'split'
encoded_base_url = urlquote(u'//' + base_url)
c4x = u'c4x/a/b/asset'
base_asset_key = u'asset-v1:a+b+{}+type@asset+block'.format(prefix)
adjusted_asset_key = base_asset_key
encoded_asset_key = urlquote(u'/asset-v1:a+b+{}+type@asset+block@'.format(prefix))
encoded_base_asset_key = encoded_asset_key
base_th_key = u'asset-v1:a+b+{}+type@thumbnail+block'.format(prefix)
adjusted_th_key = base_th_key
th_ext = u'png-16x16.jpg'
start = start.format(
prfx=prefix,
c4x=c4x,
asset=asset_key,
base_asset=base_asset_key,
asset=adjusted_asset_key,
encoded_base_url=encoded_base_url,
encoded_asset=encoded_asset_key,
th_key=th_key,
base_th_key=base_th_key,
th_key=adjusted_th_key,
th_ext=th_ext
)
# Adjust for content digest. This gets dicey quickly and we have to order our steps:
# - replace format markets because they have curly braces
# - encode Unicode characters to percent-encoded
# - finally shove back in our regex patterns
digest = CanonicalContentTest.get_content_digest_for_asset_path(prefix, start)
if digest:
adjusted_asset_key = u'assets/courseware/MARK/asset-v1:a+b+{}+type@asset+block'.format(prefix)
adjusted_th_key = u'assets/courseware/MARK/asset-v1:a+b+{}+type@thumbnail+block'.format(prefix)
encoded_asset_key = u'/assets/courseware/MARK/asset-v1:a+b+{}+type@asset+block@'.format(prefix)
encoded_asset_key = urlquote(encoded_asset_key)
expected = expected.format(
prfx=prefix,
c4x=c4x,
asset=asset_key,
base_asset=base_asset_key,
asset=adjusted_asset_key,
encoded_base_url=encoded_base_url,
encoded_asset=encoded_asset_key,
th_key=th_key,
th_ext=th_ext
base_th_key=base_th_key,
th_key=adjusted_th_key,
th_ext=th_ext,
encoded_base_asset=encoded_base_asset_key,
)
expected = encode_unicode_characters_in_url(expected)
expected = expected.replace('MARK', '[a-f0-9]{32}')
expected = expected.replace('+', r'\+').replace('?', r'\?')
with check_mongo_calls(mongo_calls):
asset_path = StaticContent.get_canonicalized_asset_path(self.courses[prefix].id, start, base_url, exts)
self.assertEqual(asset_path, expected)
print expected
print asset_path
self.assertIsNotNone(re.match(expected, asset_path))
@ddt.data(
# No leading slash.
(u'', u'{prfx}_unlock.png', u'/{c4x}/{prfx}_unlock.png', 1),
(u'', u'{prfx}_ünlöck.png', u'/{c4x}/{prfx}_ünlöck.png', 1),
(u'', u'{prfx}_lock.png', u'/{c4x}/{prfx}_lock.png', 1),
(u'', u'weird {prfx}_unlock.png', u'/{c4x}/weird_{prfx}_unlock.png', 1),
(u'', u'{prfx}_excluded.html', u'/{c4x}/{prfx}_excluded.html', 1),
(u'', u'weird {prfx}_ünlöck.png', u'/{c4x}/weird_{prfx}_ünlöck.png', 1),
(u'', u'{prfx}_excluded.html', u'/{base_c4x}/{prfx}_excluded.html', 1),
(u'', u'{prfx}_not_excluded.htm', u'/{c4x}/{prfx}_not_excluded.htm', 1),
(u'dev', u'{prfx}_unlock.png', u'//dev/{c4x}/{prfx}_unlock.png', 1),
(u'dev', u'{prfx}_ünlöck.png', u'//dev/{c4x}/{prfx}_ünlöck.png', 1),
(u'dev', u'{prfx}_lock.png', u'/{c4x}/{prfx}_lock.png', 1),
(u'dev', u'weird {prfx}_unlock.png', u'//dev/{c4x}/weird_{prfx}_unlock.png', 1),
(u'dev', u'{prfx}_excluded.html', u'/{c4x}/{prfx}_excluded.html', 1),
(u'dev', u'weird {prfx}_ünlöck.png', u'//dev/{c4x}/weird_{prfx}_ünlöck.png', 1),
(u'dev', u'{prfx}_excluded.html', u'/{base_c4x}/{prfx}_excluded.html', 1),
(u'dev', u'{prfx}_not_excluded.htm', u'//dev/{c4x}/{prfx}_not_excluded.htm', 1),
# No leading slash with subdirectory. This ensures we probably substitute slashes.
(u'', u'special/{prfx}_unlock.png', u'/{c4x}/special_{prfx}_unlock.png', 1),
(u'', u'special/{prfx}_ünlöck.png', u'/{c4x}/special_{prfx}_ünlöck.png', 1),
(u'', u'special/{prfx}_lock.png', u'/{c4x}/special_{prfx}_lock.png', 1),
(u'', u'special/weird {prfx}_unlock.png', u'/{c4x}/special_weird_{prfx}_unlock.png', 1),
(u'', u'special/{prfx}_excluded.html', u'/{c4x}/special_{prfx}_excluded.html', 1),
(u'', u'special/weird {prfx}_ünlöck.png', u'/{c4x}/special_weird_{prfx}_ünlöck.png', 1),
(u'', u'special/{prfx}_excluded.html', u'/{base_c4x}/special_{prfx}_excluded.html', 1),
(u'', u'special/{prfx}_not_excluded.htm', u'/{c4x}/special_{prfx}_not_excluded.htm', 1),
(u'dev', u'special/{prfx}_unlock.png', u'//dev/{c4x}/special_{prfx}_unlock.png', 1),
(u'dev', u'special/{prfx}_ünlöck.png', u'//dev/{c4x}/special_{prfx}_ünlöck.png', 1),
(u'dev', u'special/{prfx}_lock.png', u'/{c4x}/special_{prfx}_lock.png', 1),
(u'dev', u'special/weird {prfx}_unlock.png', u'//dev/{c4x}/special_weird_{prfx}_unlock.png', 1),
(u'dev', u'special/{prfx}_excluded.html', u'/{c4x}/special_{prfx}_excluded.html', 1),
(u'dev', u'special/weird {prfx}_ünlöck.png', u'//dev/{c4x}/special_weird_{prfx}_ünlöck.png', 1),
(u'dev', u'special/{prfx}_excluded.html', u'/{base_c4x}/special_{prfx}_excluded.html', 1),
(u'dev', u'special/{prfx}_not_excluded.htm', u'//dev/{c4x}/special_{prfx}_not_excluded.htm', 1),
# Leading slash.
(u'', u'/{prfx}_unlock.png', u'/{c4x}/{prfx}_unlock.png', 1),
(u'', u'/{prfx}_ünlöck.png', u'/{c4x}/{prfx}_ünlöck.png', 1),
(u'', u'/{prfx}_lock.png', u'/{c4x}/{prfx}_lock.png', 1),
(u'', u'/weird {prfx}_unlock.png', u'/{c4x}/weird_{prfx}_unlock.png', 1),
(u'', u'/{prfx}_excluded.html', u'/{c4x}/{prfx}_excluded.html', 1),
(u'', u'/weird {prfx}_ünlöck.png', u'/{c4x}/weird_{prfx}_ünlöck.png', 1),
(u'', u'/{prfx}_excluded.html', u'/{base_c4x}/{prfx}_excluded.html', 1),
(u'', u'/{prfx}_not_excluded.htm', u'/{c4x}/{prfx}_not_excluded.htm', 1),
(u'dev', u'/{prfx}_unlock.png', u'//dev/{c4x}/{prfx}_unlock.png', 1),
(u'dev', u'/{prfx}_ünlöck.png', u'//dev/{c4x}/{prfx}_ünlöck.png', 1),
(u'dev', u'/{prfx}_lock.png', u'/{c4x}/{prfx}_lock.png', 1),
(u'dev', u'/weird {prfx}_unlock.png', u'//dev/{c4x}/weird_{prfx}_unlock.png', 1),
(u'dev', u'/{prfx}_excluded.html', u'/{c4x}/{prfx}_excluded.html', 1),
(u'dev', u'/weird {prfx}_ünlöck.png', u'//dev/{c4x}/weird_{prfx}_ünlöck.png', 1),
(u'dev', u'/{prfx}_excluded.html', u'/{base_c4x}/{prfx}_excluded.html', 1),
(u'dev', u'/{prfx}_not_excluded.htm', u'//dev/{c4x}/{prfx}_not_excluded.htm', 1),
# Leading slash with subdirectory. This ensures we properly substitute slashes.
(u'', u'/special/{prfx}_unlock.png', u'/{c4x}/special_{prfx}_unlock.png', 1),
(u'', u'/special/{prfx}_ünlöck.png', u'/{c4x}/special_{prfx}_ünlöck.png', 1),
(u'', u'/special/{prfx}_lock.png', u'/{c4x}/special_{prfx}_lock.png', 1),
(u'', u'/special/weird {prfx}_unlock.png', u'/{c4x}/special_weird_{prfx}_unlock.png', 1),
(u'', u'/special/{prfx}_excluded.html', u'/{c4x}/special_{prfx}_excluded.html', 1),
(u'', u'/special/weird {prfx}_ünlöck.png', u'/{c4x}/special_weird_{prfx}_ünlöck.png', 1),
(u'', u'/special/{prfx}_excluded.html', u'/{base_c4x}/special_{prfx}_excluded.html', 1),
(u'', u'/special/{prfx}_not_excluded.htm', u'/{c4x}/special_{prfx}_not_excluded.htm', 1),
(u'dev', u'/special/{prfx}_unlock.png', u'//dev/{c4x}/special_{prfx}_unlock.png', 1),
(u'dev', u'/special/{prfx}_ünlöck.png', u'//dev/{c4x}/special_{prfx}_ünlöck.png', 1),
(u'dev', u'/special/{prfx}_lock.png', u'/{c4x}/special_{prfx}_lock.png', 1),
(u'dev', u'/special/weird {prfx}_unlock.png', u'//dev/{c4x}/special_weird_{prfx}_unlock.png', 1),
(u'dev', u'/special/{prfx}_excluded.html', u'/{c4x}/special_{prfx}_excluded.html', 1),
(u'dev', u'/special/weird {prfx}_ünlöck.png', u'//dev/{c4x}/special_weird_{prfx}_ünlöck.png', 1),
(u'dev', u'/special/{prfx}_excluded.html', u'/{base_c4x}/special_{prfx}_excluded.html', 1),
(u'dev', u'/special/{prfx}_not_excluded.htm', u'//dev/{c4x}/special_{prfx}_not_excluded.htm', 1),
# Static path.
(u'', u'/static/{prfx}_unlock.png', u'/{c4x}/{prfx}_unlock.png', 1),
(u'', u'/static/{prfx}_ünlöck.png', u'/{c4x}/{prfx}_ünlöck.png', 1),
(u'', u'/static/{prfx}_lock.png', u'/{c4x}/{prfx}_lock.png', 1),
(u'', u'/static/weird {prfx}_unlock.png', u'/{c4x}/weird_{prfx}_unlock.png', 1),
(u'', u'/static/{prfx}_excluded.html', u'/{c4x}/{prfx}_excluded.html', 1),
(u'', u'/static/weird {prfx}_ünlöck.png', u'/{c4x}/weird_{prfx}_ünlöck.png', 1),
(u'', u'/static/{prfx}_excluded.html', u'/{base_c4x}/{prfx}_excluded.html', 1),
(u'', u'/static/{prfx}_not_excluded.htm', u'/{c4x}/{prfx}_not_excluded.htm', 1),
(u'dev', u'/static/{prfx}_unlock.png', u'//dev/{c4x}/{prfx}_unlock.png', 1),
(u'dev', u'/static/{prfx}_ünlöck.png', u'//dev/{c4x}/{prfx}_ünlöck.png', 1),
(u'dev', u'/static/{prfx}_lock.png', u'/{c4x}/{prfx}_lock.png', 1),
(u'dev', u'/static/weird {prfx}_unlock.png', u'//dev/{c4x}/weird_{prfx}_unlock.png', 1),
(u'dev', u'/static/{prfx}_excluded.html', u'/{c4x}/{prfx}_excluded.html', 1),
(u'dev', u'/static/weird {prfx}_ünlöck.png', u'//dev/{c4x}/weird_{prfx}_ünlöck.png', 1),
(u'dev', u'/static/{prfx}_excluded.html', u'/{base_c4x}/{prfx}_excluded.html', 1),
(u'dev', u'/static/{prfx}_not_excluded.htm', u'//dev/{c4x}/{prfx}_not_excluded.htm', 1),
# Static path with subdirectory. This ensures we properly substitute slashes.
(u'', u'/static/special/{prfx}_unlock.png', u'/{c4x}/special_{prfx}_unlock.png', 1),
(u'', u'/static/special/{prfx}_ünlöck.png', u'/{c4x}/special_{prfx}_ünlöck.png', 1),
(u'', u'/static/special/{prfx}_lock.png', u'/{c4x}/special_{prfx}_lock.png', 1),
(u'', u'/static/special/weird {prfx}_unlock.png', u'/{c4x}/special_weird_{prfx}_unlock.png', 1),
(u'', u'/static/special/{prfx}_excluded.html', u'/{c4x}/special_{prfx}_excluded.html', 1),
(u'', u'/static/special/weird {prfx}_ünlöck.png', u'/{c4x}/special_weird_{prfx}_ünlöck.png', 1),
(u'', u'/static/special/{prfx}_excluded.html', u'/{base_c4x}/special_{prfx}_excluded.html', 1),
(u'', u'/static/special/{prfx}_not_excluded.htm', u'/{c4x}/special_{prfx}_not_excluded.htm', 1),
(u'dev', u'/static/special/{prfx}_unlock.png', u'//dev/{c4x}/special_{prfx}_unlock.png', 1),
(u'dev', u'/static/special/{prfx}_ünlöck.png', u'//dev/{c4x}/special_{prfx}_ünlöck.png', 1),
(u'dev', u'/static/special/{prfx}_lock.png', u'/{c4x}/special_{prfx}_lock.png', 1),
(u'dev', u'/static/special/weird {prfx}_unlock.png', u'//dev/{c4x}/special_weird_{prfx}_unlock.png', 1),
(u'dev', u'/static/special/{prfx}_excluded.html', u'/{c4x}/special_{prfx}_excluded.html', 1),
(u'dev', u'/static/special/weird {prfx}_ünlöck.png', u'//dev/{c4x}/special_weird_{prfx}_ünlöck.png', 1),
(u'dev', u'/static/special/{prfx}_excluded.html', u'/{base_c4x}/special_{prfx}_excluded.html', 1),
(u'dev', u'/static/special/{prfx}_not_excluded.htm', u'//dev/{c4x}/special_{prfx}_not_excluded.htm', 1),
# Static path with query parameter.
(
u'',
u'/static/{prfx}_unlock.png?foo=/static/{prfx}_lock.png',
u'/{c4x}/{prfx}_unlock.png?foo={encoded_c4x}{prfx}_lock.png',
u'/static/{prfx}_ünlöck.png?foo=/static/{prfx}_lock.png',
u'/{c4x}/{prfx}_ünlöck.png?foo={encoded_c4x}{prfx}_lock.png',
2
),
(
u'',
u'/static/{prfx}_lock.png?foo=/static/{prfx}_unlock.png',
u'/{c4x}/{prfx}_lock.png?foo={encoded_c4x}{prfx}_unlock.png',
u'/static/{prfx}_lock.png?foo=/static/{prfx}_ünlöck.png',
u'/{c4x}/{prfx}_lock.png?foo={encoded_c4x}{prfx}_ünlöck.png',
2
),
(
u'',
u'/static/{prfx}_excluded.html?foo=/static/{prfx}_excluded.html',
u'/{c4x}/{prfx}_excluded.html?foo={encoded_c4x}{prfx}_excluded.html',
u'/{base_c4x}/{prfx}_excluded.html?foo={encoded_base_c4x}{prfx}_excluded.html',
2
),
(
u'',
u'/static/{prfx}_excluded.html?foo=/static/{prfx}_not_excluded.htm',
u'/{c4x}/{prfx}_excluded.html?foo={encoded_c4x}{prfx}_not_excluded.htm',
u'/{base_c4x}/{prfx}_excluded.html?foo={encoded_c4x}{prfx}_not_excluded.htm',
2
),
(
u'',
u'/static/{prfx}_not_excluded.htm?foo=/static/{prfx}_excluded.html',
u'/{c4x}/{prfx}_not_excluded.htm?foo={encoded_c4x}{prfx}_excluded.html',
u'/{c4x}/{prfx}_not_excluded.htm?foo={encoded_base_c4x}{prfx}_excluded.html',
2
),
(
@@ -583,32 +644,32 @@ class CanonicalContentTest(SharedModuleStoreTestCase):
),
(
u'dev',
u'/static/{prfx}_unlock.png?foo=/static/{prfx}_lock.png',
u'//dev/{c4x}/{prfx}_unlock.png?foo={encoded_c4x}{prfx}_lock.png',
u'/static/{prfx}_ünlöck.png?foo=/static/{prfx}_lock.png',
u'//dev/{c4x}/{prfx}_ünlöck.png?foo={encoded_c4x}{prfx}_lock.png',
2
),
(
u'dev',
u'/static/{prfx}_lock.png?foo=/static/{prfx}_unlock.png',
u'/{c4x}/{prfx}_lock.png?foo={encoded_base_url}{encoded_c4x}{prfx}_unlock.png',
u'/static/{prfx}_lock.png?foo=/static/{prfx}_ünlöck.png',
u'/{c4x}/{prfx}_lock.png?foo={encoded_base_url}{encoded_c4x}{prfx}_ünlöck.png',
2
),
(
u'dev',
u'/static/{prfx}_excluded.html?foo=/static/{prfx}_excluded.html',
u'/{c4x}/{prfx}_excluded.html?foo={encoded_c4x}{prfx}_excluded.html',
u'/{base_c4x}/{prfx}_excluded.html?foo={encoded_base_c4x}{prfx}_excluded.html',
2
),
(
u'dev',
u'/static/{prfx}_excluded.html?foo=/static/{prfx}_not_excluded.htm',
u'/{c4x}/{prfx}_excluded.html?foo={encoded_base_url}{encoded_c4x}{prfx}_not_excluded.htm',
u'/{base_c4x}/{prfx}_excluded.html?foo={encoded_base_url}{encoded_c4x}{prfx}_not_excluded.htm',
2
),
(
u'dev',
u'/static/{prfx}_not_excluded.htm?foo=/static/{prfx}_excluded.html',
u'//dev/{c4x}/{prfx}_not_excluded.htm?foo={encoded_c4x}{prfx}_excluded.html',
u'//dev/{c4x}/{prfx}_not_excluded.htm?foo={encoded_base_c4x}{prfx}_excluded.html',
2
),
(
@@ -618,38 +679,58 @@ class CanonicalContentTest(SharedModuleStoreTestCase):
2
),
# Old, c4x-style path.
(u'', u'/{c4x}/{prfx}_unlock.png', u'/{c4x}/{prfx}_unlock.png', 1),
(u'', u'/{c4x}/{prfx}_ünlöck.png', u'/{c4x}/{prfx}_ünlöck.png', 1),
(u'', u'/{c4x}/{prfx}_lock.png', u'/{c4x}/{prfx}_lock.png', 1),
(u'', u'/{c4x}/weird_{prfx}_lock.png', u'/{c4x}/weird_{prfx}_lock.png', 1),
(u'', u'/{c4x}/{prfx}_excluded.html', u'/{c4x}/{prfx}_excluded.html', 1),
(u'', u'/{c4x}/{prfx}_excluded.html', u'/{base_c4x}/{prfx}_excluded.html', 1),
(u'', u'/{c4x}/{prfx}_not_excluded.htm', u'/{c4x}/{prfx}_not_excluded.htm', 1),
(u'dev', u'/{c4x}/{prfx}_unlock.png', u'//dev/{c4x}/{prfx}_unlock.png', 1),
(u'dev', u'/{c4x}/{prfx}_ünlöck.png', u'//dev/{c4x}/{prfx}_ünlöck.png', 1),
(u'dev', u'/{c4x}/{prfx}_lock.png', u'/{c4x}/{prfx}_lock.png', 1),
(u'dev', u'/{c4x}/weird_{prfx}_unlock.png', u'//dev/{c4x}/weird_{prfx}_unlock.png', 1),
(u'dev', u'/{c4x}/{prfx}_excluded.html', u'/{c4x}/{prfx}_excluded.html', 1),
(u'dev', u'/{c4x}/weird_{prfx}_ünlöck.png', u'//dev/{c4x}/weird_{prfx}_ünlöck.png', 1),
(u'dev', u'/{c4x}/{prfx}_excluded.html', u'/{base_c4x}/{prfx}_excluded.html', 1),
(u'dev', u'/{c4x}/{prfx}_not_excluded.htm', u'//dev/{c4x}/{prfx}_not_excluded.htm', 1),
)
@ddt.unpack
def test_canonical_asset_path_with_c4x_style_assets(self, base_url, start, expected, mongo_calls):
exts = ['.html', '.tm']
prefix = 'old'
c4x_block = 'c4x/a/b/asset'
encoded_c4x_block = quote_plus('/' + c4x_block + '/')
encoded_base_url = quote_plus('//' + base_url)
base_c4x_block = 'c4x/a/b/asset'
adjusted_c4x_block = base_c4x_block
encoded_c4x_block = urlquote('/' + base_c4x_block + '/')
encoded_base_url = urlquote('//' + base_url)
encoded_base_c4x_block = encoded_c4x_block
start = start.format(
prfx=prefix,
encoded_base_url=encoded_base_url,
c4x=c4x_block,
encoded_c4x=encoded_c4x_block
)
expected = expected.format(
prfx=prefix,
encoded_base_url=encoded_base_url,
c4x=c4x_block,
c4x=base_c4x_block,
encoded_c4x=encoded_c4x_block
)
# Adjust for content digest. This gets dicey quickly and we have to order our steps:
# - replace format markets because they have curly braces
# - encode Unicode characters to percent-encoded
# - finally shove back in our regex patterns
digest = CanonicalContentTest.get_content_digest_for_asset_path(prefix, start)
if digest:
adjusted_c4x_block = 'assets/courseware/MARK/c4x/a/b/asset'
encoded_c4x_block = urlquote('/' + adjusted_c4x_block + '/')
expected = expected.format(
prfx=prefix,
encoded_base_url=encoded_base_url,
base_c4x=base_c4x_block,
c4x=adjusted_c4x_block,
encoded_c4x=encoded_c4x_block,
encoded_base_c4x=encoded_base_c4x_block,
)
expected = encode_unicode_characters_in_url(expected)
expected = expected.replace('MARK', '[a-f0-9]{32}')
expected = expected.replace('+', r'\+').replace('?', r'\?')
with check_mongo_calls(mongo_calls):
asset_path = StaticContent.get_canonicalized_asset_path(self.courses[prefix].id, start, base_url, exts)
self.assertEqual(asset_path, expected)
print expected
print asset_path
self.assertIsNotNone(re.match(expected, asset_path))