Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
78370f36
Commit
78370f36
authored
Feb 02, 2016
by
Toby Lawrence
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #11400 from edx/PERF-258
Add the ability to exclude files from URL canonicalization.
parents
dffbc69a
e57d1a20
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
377 additions
and
112 deletions
+377
-112
common/djangoapps/static_replace/__init__.py
+3
-2
common/djangoapps/static_replace/migrations/0002_assetexcludedextensionsconfig.py
+27
-0
common/djangoapps/static_replace/models.py
+25
-0
common/djangoapps/static_replace/test/test_static_replace.py
+311
-104
common/lib/xmodule/xmodule/contentstore/content.py
+11
-6
No files found.
common/djangoapps/static_replace/__init__.py
View file @
78370f36
...
@@ -5,7 +5,7 @@ from django.contrib.staticfiles.storage import staticfiles_storage
...
@@ -5,7 +5,7 @@ from django.contrib.staticfiles.storage import staticfiles_storage
from
django.contrib.staticfiles
import
finders
from
django.contrib.staticfiles
import
finders
from
django.conf
import
settings
from
django.conf
import
settings
from
static_replace.models
import
AssetBaseUrlConfig
from
static_replace.models
import
AssetBaseUrlConfig
,
AssetExcludedExtensionsConfig
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore
import
ModuleStoreEnum
from
xmodule.modulestore
import
ModuleStoreEnum
from
xmodule.contentstore.content
import
StaticContent
from
xmodule.contentstore.content
import
StaticContent
...
@@ -182,7 +182,8 @@ def replace_static_urls(text, data_directory=None, course_id=None, static_asset_
...
@@ -182,7 +182,8 @@ def replace_static_urls(text, data_directory=None, course_id=None, static_asset_
# if not, then assume it's courseware specific content and then look in the
# if not, then assume it's courseware specific content and then look in the
# Mongo-backed database
# Mongo-backed database
base_url
=
AssetBaseUrlConfig
.
get_base_url
()
base_url
=
AssetBaseUrlConfig
.
get_base_url
()
url
=
StaticContent
.
get_canonicalized_asset_path
(
course_id
,
rest
,
base_url
)
excluded_exts
=
AssetExcludedExtensionsConfig
.
get_excluded_extensions
()
url
=
StaticContent
.
get_canonicalized_asset_path
(
course_id
,
rest
,
base_url
,
excluded_exts
)
if
AssetLocator
.
CANONICAL_NAMESPACE
in
url
:
if
AssetLocator
.
CANONICAL_NAMESPACE
in
url
:
url
=
url
.
replace
(
'block@'
,
'block/'
,
1
)
url
=
url
.
replace
(
'block@'
,
'block/'
,
1
)
...
...
common/djangoapps/static_replace/migrations/0002_assetexcludedextensionsconfig.py
0 → 100644
View file @
78370f36
# -*- coding: utf-8 -*-
from
__future__
import
unicode_literals
from
django.db
import
migrations
,
models
import
django.db.models.deletion
from
django.conf
import
settings
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
migrations
.
swappable_dependency
(
settings
.
AUTH_USER_MODEL
),
(
'static_replace'
,
'0001_initial'
),
]
operations
=
[
migrations
.
CreateModel
(
name
=
'AssetExcludedExtensionsConfig'
,
fields
=
[
(
'id'
,
models
.
AutoField
(
verbose_name
=
'ID'
,
serialize
=
False
,
auto_created
=
True
,
primary_key
=
True
)),
(
'change_date'
,
models
.
DateTimeField
(
auto_now_add
=
True
,
verbose_name
=
'Change date'
)),
(
'enabled'
,
models
.
BooleanField
(
default
=
False
,
verbose_name
=
'Enabled'
)),
(
'excluded_extensions'
,
models
.
TextField
(
default
=
b
'html'
,
help_text
=
b
'The file extensions to exclude from canonicalization. No leading period required. Values should be space separated i.e. "html svg css"'
)),
(
'changed_by'
,
models
.
ForeignKey
(
on_delete
=
django
.
db
.
models
.
deletion
.
PROTECT
,
editable
=
False
,
to
=
settings
.
AUTH_USER_MODEL
,
null
=
True
,
verbose_name
=
'Changed by'
)),
],
),
]
common/djangoapps/static_replace/models.py
View file @
78370f36
...
@@ -27,3 +27,28 @@ class AssetBaseUrlConfig(ConfigurationModel):
...
@@ -27,3 +27,28 @@ class AssetBaseUrlConfig(ConfigurationModel):
def
__unicode__
(
self
):
def
__unicode__
(
self
):
return
unicode
(
repr
(
self
))
return
unicode
(
repr
(
self
))
class
AssetExcludedExtensionsConfig
(
ConfigurationModel
):
"""Configuration for the the excluded file extensions when canonicalizing static asset paths."""
class
Meta
(
object
):
app_label
=
'static_replace'
excluded_extensions
=
TextField
(
default
=
'html'
,
help_text
=
'The file extensions to exclude from canonicalization. No leading period required. '
+
'Values should be space separated i.e. "html svg css"'
)
@classmethod
def
get_excluded_extensions
(
cls
):
"""Gets the excluded file extensions when canonicalizing static asset paths"""
add_period
=
lambda
x
:
'.'
+
x
return
map
(
add_period
,
cls
.
current
()
.
excluded_extensions
.
split
())
def
__repr__
(
self
):
return
'<AssetExcludedExtensionsConfig(extensions={})>'
.
format
(
self
.
get_excluded_extensions
()
.
split
())
def
__unicode__
(
self
):
return
unicode
(
repr
(
self
))
common/djangoapps/static_replace/test/test_static_replace.py
View file @
78370f36
...
@@ -98,11 +98,13 @@ def test_storage_url_not_exists(mock_storage):
...
@@ -98,11 +98,13 @@ def test_storage_url_not_exists(mock_storage):
@patch
(
'static_replace.StaticContent'
,
autospec
=
True
)
@patch
(
'static_replace.StaticContent'
,
autospec
=
True
)
@patch
(
'static_replace.modulestore'
,
autospec
=
True
)
@patch
(
'static_replace.modulestore'
,
autospec
=
True
)
@patch
(
'static_replace.AssetBaseUrlConfig.get_base_url'
)
@patch
(
'static_replace.AssetBaseUrlConfig.get_base_url'
)
def
test_mongo_filestore
(
mock_get_base_url
,
mock_modulestore
,
mock_static_content
):
@patch
(
'static_replace.AssetExcludedExtensionsConfig.get_excluded_extensions'
)
def
test_mongo_filestore
(
mock_get_excluded_extensions
,
mock_get_base_url
,
mock_modulestore
,
mock_static_content
):
mock_modulestore
.
return_value
=
Mock
(
MongoModuleStore
)
mock_modulestore
.
return_value
=
Mock
(
MongoModuleStore
)
mock_static_content
.
get_canonicalized_asset_path
.
return_value
=
"c4x://mock_url"
mock_static_content
.
get_canonicalized_asset_path
.
return_value
=
"c4x://mock_url"
mock_get_base_url
.
return_value
=
u''
mock_get_base_url
.
return_value
=
u''
mock_get_excluded_extensions
.
return_value
=
[
'foobar'
]
# No namespace => no change to path
# No namespace => no change to path
assert_equals
(
'"/static/data_dir/file.png"'
,
replace_static_urls
(
STATIC_SOURCE
,
DATA_DIRECTORY
))
assert_equals
(
'"/static/data_dir/file.png"'
,
replace_static_urls
(
STATIC_SOURCE
,
DATA_DIRECTORY
))
...
@@ -113,7 +115,7 @@ def test_mongo_filestore(mock_get_base_url, mock_modulestore, mock_static_conten
...
@@ -113,7 +115,7 @@ def test_mongo_filestore(mock_get_base_url, mock_modulestore, mock_static_conten
replace_static_urls
(
STATIC_SOURCE
,
DATA_DIRECTORY
,
course_id
=
COURSE_KEY
)
replace_static_urls
(
STATIC_SOURCE
,
DATA_DIRECTORY
,
course_id
=
COURSE_KEY
)
)
)
mock_static_content
.
get_canonicalized_asset_path
.
assert_called_once_with
(
COURSE_KEY
,
'file.png'
,
u''
)
mock_static_content
.
get_canonicalized_asset_path
.
assert_called_once_with
(
COURSE_KEY
,
'file.png'
,
u''
,
[
'foobar'
]
)
@patch
(
'static_replace.settings'
,
autospec
=
True
)
@patch
(
'static_replace.settings'
,
autospec
=
True
)
...
@@ -217,6 +219,13 @@ class CanonicalContentTest(SharedModuleStoreTestCase):
...
@@ -217,6 +219,13 @@ class CanonicalContentTest(SharedModuleStoreTestCase):
# Create an unlocked image with funky characters in the name.
# 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'
,
'weird {}_unlock.png'
)
cls
.
create_image
(
prefix
,
(
1
,
1
),
'black'
,
'special/weird {}_unlock.png'
)
# Create an HTML file to test extension exclusion, and create a control file.
cls
.
create_arbitrary_content
(
prefix
,
'{}_not_excluded.htm'
)
cls
.
create_arbitrary_content
(
prefix
,
'{}_excluded.html'
)
cls
.
create_arbitrary_content
(
prefix
,
'special/{}_not_excluded.htm'
)
cls
.
create_arbitrary_content
(
prefix
,
'special/{}_excluded.html'
)
@classmethod
@classmethod
def
create_image
(
cls
,
prefix
,
dimensions
,
color
,
name
,
locked
=
False
):
def
create_image
(
cls
,
prefix
,
dimensions
,
color
,
name
,
locked
=
False
):
...
@@ -244,86 +253,199 @@ class CanonicalContentTest(SharedModuleStoreTestCase):
...
@@ -244,86 +253,199 @@ class CanonicalContentTest(SharedModuleStoreTestCase):
return
new_content
return
new_content
@classmethod
def
create_arbitrary_content
(
cls
,
prefix
,
name
,
locked
=
False
):
"""
Creates an arbitrary piece of content with a fixed body, for when content doesn't matter.
Args:
prefix: the prefix to use e.g. split vs mongo
name: the name of the content; can be a format string
locked: whether or not the asset should be locked
Returns:
StaticContent: the StaticContent object for the created content
"""
new_buf
=
StringIO
(
'testingggggggggggg'
)
new_name
=
name
.
format
(
prefix
)
new_key
=
StaticContent
.
compute_location
(
cls
.
courses
[
prefix
]
.
id
,
new_name
)
new_content
=
StaticContent
(
new_key
,
new_name
,
'application/octet-stream'
,
new_buf
.
getvalue
(),
locked
=
locked
)
contentstore
()
.
save
(
new_content
)
return
new_content
@ddt.data
(
@ddt.data
(
# No leading slash.
# No leading slash.
(
u''
,
u'{prefix}_unlock.png'
,
u'/{asset_key}@{prefix}_unlock.png'
,
1
),
(
u''
,
u'{prfx}_unlock.png'
,
u'/{asset}@{prfx}_unlock.png'
,
1
),
(
u''
,
u'{prefix}_lock.png'
,
u'/{asset_key}@{prefix}_lock.png'
,
1
),
(
u''
,
u'{prfx}_lock.png'
,
u'/{asset}@{prfx}_lock.png'
,
1
),
(
u''
,
u'weird {prefix}_unlock.png'
,
u'/{asset_key}@weird_{prefix}_unlock.png'
,
1
),
(
u''
,
u'weird {prfx}_unlock.png'
,
u'/{asset}@weird_{prfx}_unlock.png'
,
1
),
(
u'dev'
,
u'{prefix}_unlock.png'
,
u'//dev/{asset_key}@{prefix}_unlock.png'
,
1
),
(
u''
,
u'{prfx}_excluded.html'
,
u'/{asset}@{prfx}_excluded.html'
,
1
),
(
u'dev'
,
u'{prefix}_lock.png'
,
u'/{asset_key}@{prefix}_lock.png'
,
1
),
(
u''
,
u'{prfx}_not_excluded.htm'
,
u'/{asset}@{prfx}_not_excluded.htm'
,
1
),
(
u'dev'
,
u'weird {prefix}_unlock.png'
,
u'//dev/{asset_key}@weird_{prefix}_unlock.png'
,
1
),
(
u'dev'
,
u'{prfx}_unlock.png'
,
u'//dev/{asset}@{prfx}_unlock.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'{prfx}_not_excluded.htm'
,
u'//dev/{asset}@{prfx}_not_excluded.htm'
,
1
),
# No leading slash with subdirectory. This ensures we properly substitute slashes.
# No leading slash with subdirectory. This ensures we properly substitute slashes.
(
u''
,
u'special/{prefix}_unlock.png'
,
u'/{asset_key}@special_{prefix}_unlock.png'
,
1
),
(
u''
,
u'special/{prfx}_unlock.png'
,
u'/{asset}@special_{prfx}_unlock.png'
,
1
),
(
u''
,
u'special/{prefix}_lock.png'
,
u'/{asset_key}@special_{prefix}_lock.png'
,
1
),
(
u''
,
u'special/{prfx}_lock.png'
,
u'/{asset}@special_{prfx}_lock.png'
,
1
),
(
u'dev'
,
u'special/{prefix}_unlock.png'
,
u'//dev/{asset_key}@special_{prefix}_unlock.png'
,
1
),
(
u''
,
u'special/weird {prfx}_unlock.png'
,
u'/{asset}@special_weird_{prfx}_unlock.png'
,
1
),
(
u'dev'
,
u'special/{prefix}_lock.png'
,
u'/{asset_key}@special_{prefix}_lock.png'
,
1
),
(
u''
,
u'special/{prfx}_excluded.html'
,
u'/{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}_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/{prfx}_not_excluded.htm'
,
u'//dev/{asset}@special_{prfx}_not_excluded.htm'
,
1
),
# Leading slash.
# Leading slash.
(
u''
,
u'/{prefix}_unlock.png'
,
u'/{asset_key}@{prefix}_unlock.png'
,
1
),
(
u''
,
u'/{prfx}_unlock.png'
,
u'/{asset}@{prfx}_unlock.png'
,
1
),
(
u''
,
u'/{prefix}_lock.png'
,
u'/{asset_key}@{prefix}_lock.png'
,
1
),
(
u''
,
u'/{prfx}_lock.png'
,
u'/{asset}@{prfx}_lock.png'
,
1
),
(
u'dev'
,
u'/{prefix}_unlock.png'
,
u'//dev/{asset_key}@{prefix}_unlock.png'
,
1
),
(
u''
,
u'/weird {prfx}_unlock.png'
,
u'/{asset}@weird_{prfx}_unlock.png'
,
1
),
(
u'dev'
,
u'/{prefix}_lock.png'
,
u'/{asset_key}@{prefix}_lock.png'
,
1
),
(
u''
,
u'/{prfx}_excluded.html'
,
u'/{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}_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'/{prfx}_not_excluded.htm'
,
u'//dev/{asset}@{prfx}_not_excluded.htm'
,
1
),
# Leading slash with subdirectory. This ensures we properly substitute slashes.
# Leading slash with subdirectory. This ensures we properly substitute slashes.
(
u''
,
u'/special/{prefix}_unlock.png'
,
u'/{asset_key}@special_{prefix}_unlock.png'
,
1
),
(
u''
,
u'/special/{prfx}_unlock.png'
,
u'/{asset}@special_{prfx}_unlock.png'
,
1
),
(
u''
,
u'/special/{prefix}_lock.png'
,
u'/{asset_key}@special_{prefix}_lock.png'
,
1
),
(
u''
,
u'/special/{prfx}_lock.png'
,
u'/{asset}@special_{prfx}_lock.png'
,
1
),
(
u'dev'
,
u'/special/{prefix}_unlock.png'
,
u'//dev/{asset_key}@special_{prefix}_unlock.png'
,
1
),
(
u''
,
u'/special/weird {prfx}_unlock.png'
,
u'/{asset}@special_weird_{prfx}_unlock.png'
,
1
),
(
u'dev'
,
u'/special/{prefix}_lock.png'
,
u'/{asset_key}@special_{prefix}_lock.png'
,
1
),
(
u''
,
u'/special/{prfx}_excluded.html'
,
u'/{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}_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/{prfx}_not_excluded.htm'
,
u'//dev/{asset}@special_{prfx}_not_excluded.htm'
,
1
),
# Static path.
# Static path.
(
u''
,
u'/static/{prefix}_unlock.png'
,
u'/{asset_key}@{prefix}_unlock.png'
,
1
),
(
u''
,
u'/static/{prfx}_unlock.png'
,
u'/{asset}@{prfx}_unlock.png'
,
1
),
(
u''
,
u'/static/{prefix}_lock.png'
,
u'/{asset_key}@{prefix}_lock.png'
,
1
),
(
u''
,
u'/static/{prfx}_lock.png'
,
u'/{asset}@{prfx}_lock.png'
,
1
),
(
u''
,
u'/static/weird {prefix}_unlock.png'
,
u'/{asset_key}@weird_{prefix}_unlock.png'
,
1
),
(
u''
,
u'/static/weird {prfx}_unlock.png'
,
u'/{asset}@weird_{prfx}_unlock.png'
,
1
),
(
u'dev'
,
u'/static/{prefix}_unlock.png'
,
u'//dev/{asset_key}@{prefix}_unlock.png'
,
1
),
(
u''
,
u'/static/{prfx}_excluded.html'
,
u'/{asset}@{prfx}_excluded.html'
,
1
),
(
u'dev'
,
u'/static/{prefix}_lock.png'
,
u'/{asset_key}@{prefix}_lock.png'
,
1
),
(
u''
,
u'/static/{prfx}_not_excluded.htm'
,
u'/{asset}@{prfx}_not_excluded.htm'
,
1
),
(
u'dev'
,
u'/static/weird {prefix}_unlock.png'
,
u'//dev/{asset_key}@weird_{prefix}_unlock.png'
,
1
),
(
u'dev'
,
u'/static/{prfx}_unlock.png'
,
u'//dev/{asset}@{prfx}_unlock.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/{prfx}_not_excluded.htm'
,
u'//dev/{asset}@{prfx}_not_excluded.htm'
,
1
),
# Static path with subdirectory. This ensures we properly substitute slashes.
# Static path with subdirectory. This ensures we properly substitute slashes.
(
u''
,
u'/static/special/{prefix}_unlock.png'
,
u'/{asset_key}@special_{prefix}_unlock.png'
,
1
),
(
u''
,
u'/static/special/{prfx}_unlock.png'
,
u'/{asset}@special_{prfx}_unlock.png'
,
1
),
(
u''
,
u'/static/special/{prefix}_lock.png'
,
u'/{asset_key}@special_{prefix}_lock.png'
,
1
),
(
u''
,
u'/static/special/{prfx}_lock.png'
,
u'/{asset}@special_{prfx}_lock.png'
,
1
),
(
u'dev'
,
u'/static/special/{prefix}_unlock.png'
,
u'//dev/{asset_key}@special_{prefix}_unlock.png'
,
1
),
(
u''
,
u'/static/special/weird {prfx}_unlock.png'
,
u'/{asset}@special_weird_{prfx}_unlock.png'
,
1
),
(
u'dev'
,
u'/static/special/{prefix}_lock.png'
,
u'/{asset_key}@special_{prefix}_lock.png'
,
1
),
(
u''
,
u'/static/special/{prfx}_excluded.html'
,
u'/{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}_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/{prfx}_not_excluded.htm'
,
u'//dev/{asset}@special_{prfx}_not_excluded.htm'
,
1
),
# Static path with query parameter.
# Static path with query parameter.
(
(
u''
,
u''
,
u'/static/{prefix}_unlock.png?foo=/static/{prefix}_lock.png'
,
u'/static/{prfx}_unlock.png?foo=/static/{prfx}_lock.png'
,
u'/{asset_key}@{prefix}_unlock.png?foo={encoded_asset_key}{prefix}_lock.png'
,
u'/{asset}@{prfx}_unlock.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'
,
2
2
),
),
(
(
u''
,
u''
,
u'/static/{prefix}_lock.png?foo=/static/{prefix}_unlock.png'
,
u'/static/{prfx}_excluded.html?foo=/static/{prfx}_excluded.html'
,
u'/{asset_key}@{prefix}_lock.png?foo={encoded_asset_key}{prefix}_unlock.png'
,
u'/{asset}@{prfx}_excluded.html?foo={encoded_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'
,
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'
,
2
),
(
u''
,
u'/static/{prfx}_not_excluded.htm?foo=/static/{prfx}_not_excluded.htm'
,
u'/{asset}@{prfx}_not_excluded.htm?foo={encoded_asset}{prfx}_not_excluded.htm'
,
2
),
(
u'dev'
,
u'/static/{prfx}_unlock.png?foo=/static/{prfx}_lock.png'
,
u'//dev/{asset}@{prfx}_unlock.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'
,
2
2
),
),
(
(
u'dev'
,
u'dev'
,
u'/static/{pr
efix}_unlock.png?foo=/static/{prefix}_lock.png
'
,
u'/static/{pr
fx}_excluded.html?foo=/static/{prfx}_excluded.html
'
,
u'/
/dev/{asset_key}@{prefix}_unlock.png?foo={encoded_asset_key}{prefix}_lock.png
'
,
u'/
{asset}@{prfx}_excluded.html?foo={encoded_asset}{prfx}_excluded.html
'
,
2
2
),
),
(
(
u'dev'
,
u'dev'
,
u'/static/{prefix}_lock.png?foo=/static/{prefix}_unlock.png'
,
u'/static/{prfx}_excluded.html?foo=/static/{prfx}_not_excluded.htm'
,
u'/{asset_key}@{prefix}_lock.png?foo={encoded_base_url}{encoded_asset_key}{prefix}_unlock.png'
,
u'/{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'
,
2
),
(
u'dev'
,
u'/static/{prfx}_not_excluded.htm?foo=/static/{prfx}_not_excluded.htm'
,
u'//dev/{asset}@{prfx}_not_excluded.htm?foo={encoded_base_url}{encoded_asset}{prfx}_not_excluded.htm'
,
2
2
),
),
# Already asset key.
# Already asset key.
(
u''
,
u'/{asset_key}@{prefix}_unlock.png'
,
u'/{asset_key}@{prefix}_unlock.png'
,
1
),
(
u''
,
u'/{asset}@{prfx}_unlock.png'
,
u'/{asset}@{prfx}_unlock.png'
,
1
),
(
u''
,
u'/{asset_key}@{prefix}_lock.png'
,
u'/{asset_key}@{prefix}_lock.png'
,
1
),
(
u''
,
u'/{asset}@{prfx}_lock.png'
,
u'/{asset}@{prfx}_lock.png'
,
1
),
(
u'dev'
,
u'/{asset_key}@{prefix}_unlock.png'
,
u'//dev/{asset_key}@{prefix}_unlock.png'
,
1
),
(
u''
,
u'/{asset}@weird_{prfx}_unlock.png'
,
u'/{asset}@weird_{prfx}_unlock.png'
,
1
),
(
u'dev'
,
u'/{asset_key}@{prefix}_lock.png'
,
u'/{asset_key}@{prefix}_lock.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
),
# Old, c4x-style path.
# Old, c4x-style path.
(
u''
,
u'/{c4x}/{prefix}_unlock.png'
,
u'/{c4x}/{prefix}_unlock.png'
,
1
),
(
u''
,
u'/{c4x}/{prfx}_unlock.png'
,
u'/{c4x}/{prfx}_unlock.png'
,
1
),
(
u''
,
u'/{c4x}/{prefix}_lock.png'
,
u'/{c4x}/{prefix}_lock.png'
,
1
),
(
u''
,
u'/{c4x}/{prfx}_lock.png'
,
u'/{c4x}/{prfx}_lock.png'
,
1
),
(
u''
,
u'/{c4x}/weird_{prefix}_lock.png'
,
u'/{c4x}/weird_{prefix}_lock.png'
,
1
),
(
u''
,
u'/{c4x}/weird_{prfx}_lock.png'
,
u'/{c4x}/weird_{prfx}_lock.png'
,
1
),
(
u'dev'
,
u'/{c4x}/{prefix}_unlock.png'
,
u'/{c4x}/{prefix}_unlock.png'
,
1
),
(
u''
,
u'/{c4x}/{prfx}_excluded.html'
,
u'/{c4x}/{prfx}_excluded.html'
,
1
),
(
u'dev'
,
u'/{c4x}/{prefix}_lock.png'
,
u'/{c4x}/{prefix}_lock.png'
,
1
),
(
u''
,
u'/{c4x}/{prfx}_not_excluded.htm'
,
u'/{c4x}/{prfx}_not_excluded.htm'
,
1
),
(
u'dev'
,
u'/{c4x}/weird_{prefix}_unlock.png'
,
u'/{c4x}/weird_{prefix}_unlock.png'
,
1
),
(
u'dev'
,
u'/{c4x}/{prfx}_unlock.png'
,
u'/{c4x}/{prfx}_unlock.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}/{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.
# Thumbnails.
(
u''
,
u'/{th_key}@{pr
efix}_unlock-{th_ext}'
,
u'/{th_key}@{prefi
x}_unlock-{th_ext}'
,
1
),
(
u''
,
u'/{th_key}@{pr
fx}_unlock-{th_ext}'
,
u'/{th_key}@{prf
x}_unlock-{th_ext}'
,
1
),
(
u''
,
u'/{th_key}@{pr
efix}_lock-{th_ext}'
,
u'/{th_key}@{prefi
x}_lock-{th_ext}'
,
1
),
(
u''
,
u'/{th_key}@{pr
fx}_lock-{th_ext}'
,
u'/{th_key}@{prf
x}_lock-{th_ext}'
,
1
),
(
u'dev'
,
u'/{th_key}@{pr
efix}_unlock-{th_ext}'
,
u'//dev/{th_key}@{prefi
x}_unlock-{th_ext}'
,
1
),
(
u'dev'
,
u'/{th_key}@{pr
fx}_unlock-{th_ext}'
,
u'//dev/{th_key}@{prf
x}_unlock-{th_ext}'
,
1
),
(
u'dev'
,
u'/{th_key}@{pr
efix}_lock-{th_ext}'
,
u'//dev/{th_key}@{prefi
x}_lock-{th_ext}'
,
1
),
(
u'dev'
,
u'/{th_key}@{pr
fx}_lock-{th_ext}'
,
u'//dev/{th_key}@{prf
x}_lock-{th_ext}'
,
1
),
)
)
@ddt.unpack
@ddt.unpack
def
test_canonical_asset_path_with_new_style_assets
(
self
,
base_url
,
start
,
expected
,
mongo_calls
):
def
test_canonical_asset_path_with_new_style_assets
(
self
,
base_url
,
start
,
expected
,
mongo_calls
):
exts
=
[
'.html'
,
'.tm'
]
prefix
=
'split'
prefix
=
'split'
encoded_base_url
=
quote_plus
(
'//'
+
base_url
)
encoded_base_url
=
quote_plus
(
'//'
+
base_url
)
c4x
=
'c4x/a/b/asset'
c4x
=
'c4x/a/b/asset'
...
@@ -333,116 +455,201 @@ class CanonicalContentTest(SharedModuleStoreTestCase):
...
@@ -333,116 +455,201 @@ class CanonicalContentTest(SharedModuleStoreTestCase):
th_ext
=
'png-16x16.jpg'
th_ext
=
'png-16x16.jpg'
start
=
start
.
format
(
start
=
start
.
format
(
pr
efi
x
=
prefix
,
pr
f
x
=
prefix
,
c4x
=
c4x
,
c4x
=
c4x
,
asset
_key
=
asset_key
,
asset
=
asset_key
,
encoded_base_url
=
encoded_base_url
,
encoded_base_url
=
encoded_base_url
,
encoded_asset
_key
=
encoded_asset_key
,
encoded_asset
=
encoded_asset_key
,
th_key
=
th_key
,
th_key
=
th_key
,
th_ext
=
th_ext
th_ext
=
th_ext
)
)
expected
=
expected
.
format
(
expected
=
expected
.
format
(
pr
efi
x
=
prefix
,
pr
f
x
=
prefix
,
c4x
=
c4x
,
c4x
=
c4x
,
asset
_key
=
asset_key
,
asset
=
asset_key
,
encoded_base_url
=
encoded_base_url
,
encoded_base_url
=
encoded_base_url
,
encoded_asset
_key
=
encoded_asset_key
,
encoded_asset
=
encoded_asset_key
,
th_key
=
th_key
,
th_key
=
th_key
,
th_ext
=
th_ext
th_ext
=
th_ext
)
)
with
check_mongo_calls
(
mongo_calls
):
with
check_mongo_calls
(
mongo_calls
):
asset_path
=
StaticContent
.
get_canonicalized_asset_path
(
self
.
courses
[
prefix
]
.
id
,
start
,
base_url
)
asset_path
=
StaticContent
.
get_canonicalized_asset_path
(
self
.
courses
[
prefix
]
.
id
,
start
,
base_url
,
exts
)
self
.
assertEqual
(
asset_path
,
expected
)
self
.
assertEqual
(
asset_path
,
expected
)
@ddt.data
(
@ddt.data
(
# No leading slash.
# No leading slash.
(
u''
,
u'{prefix}_unlock.png'
,
u'/{c4x}/{prefix}_unlock.png'
,
1
),
(
u''
,
u'{prfx}_unlock.png'
,
u'/{c4x}/{prfx}_unlock.png'
,
1
),
(
u''
,
u'{prefix}_lock.png'
,
u'/{c4x}/{prefix}_lock.png'
,
1
),
(
u''
,
u'{prfx}_lock.png'
,
u'/{c4x}/{prfx}_lock.png'
,
1
),
(
u''
,
u'weird {prefix}_unlock.png'
,
u'/{c4x}/weird_{prefix}_unlock.png'
,
1
),
(
u''
,
u'weird {prfx}_unlock.png'
,
u'/{c4x}/weird_{prfx}_unlock.png'
,
1
),
(
u'dev'
,
u'{prefix}_unlock.png'
,
u'//dev/{c4x}/{prefix}_unlock.png'
,
1
),
(
u''
,
u'{prfx}_excluded.html'
,
u'/{c4x}/{prfx}_excluded.html'
,
1
),
(
u'dev'
,
u'{prefix}_lock.png'
,
u'/{c4x}/{prefix}_lock.png'
,
1
),
(
u''
,
u'{prfx}_not_excluded.htm'
,
u'/{c4x}/{prfx}_not_excluded.htm'
,
1
),
(
u'dev'
,
u'weird {prefix}_unlock.png'
,
u'//dev/{c4x}/weird_{prefix}_unlock.png'
,
1
),
(
u'dev'
,
u'{prfx}_unlock.png'
,
u'//dev/{c4x}/{prfx}_unlock.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'{prfx}_not_excluded.htm'
,
u'//dev/{c4x}/{prfx}_not_excluded.htm'
,
1
),
# No leading slash with subdirectory. This ensures we probably substitute slashes.
# No leading slash with subdirectory. This ensures we probably substitute slashes.
(
u''
,
u'special/{prefix}_unlock.png'
,
u'/{c4x}/special_{prefix}_unlock.png'
,
1
),
(
u''
,
u'special/{prfx}_unlock.png'
,
u'/{c4x}/special_{prfx}_unlock.png'
,
1
),
(
u''
,
u'special/{prefix}_lock.png'
,
u'/{c4x}/special_{prefix}_lock.png'
,
1
),
(
u''
,
u'special/{prfx}_lock.png'
,
u'/{c4x}/special_{prfx}_lock.png'
,
1
),
(
u'dev'
,
u'special/{prefix}_unlock.png'
,
u'//dev/{c4x}/special_{prefix}_unlock.png'
,
1
),
(
u''
,
u'special/weird {prfx}_unlock.png'
,
u'/{c4x}/special_weird_{prfx}_unlock.png'
,
1
),
(
u'dev'
,
u'special/{prefix}_lock.png'
,
u'/{c4x}/special_{prefix}_lock.png'
,
1
),
(
u''
,
u'special/{prfx}_excluded.html'
,
u'/{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}_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/{prfx}_not_excluded.htm'
,
u'//dev/{c4x}/special_{prfx}_not_excluded.htm'
,
1
),
# Leading slash.
# Leading slash.
(
u''
,
u'/{prefix}_unlock.png'
,
u'/{c4x}/{prefix}_unlock.png'
,
1
),
(
u''
,
u'/{prfx}_unlock.png'
,
u'/{c4x}/{prfx}_unlock.png'
,
1
),
(
u''
,
u'/{prefix}_lock.png'
,
u'/{c4x}/{prefix}_lock.png'
,
1
),
(
u''
,
u'/{prfx}_lock.png'
,
u'/{c4x}/{prfx}_lock.png'
,
1
),
(
u'dev'
,
u'/{prefix}_unlock.png'
,
u'//dev/{c4x}/{prefix}_unlock.png'
,
1
),
(
u''
,
u'/weird {prfx}_unlock.png'
,
u'/{c4x}/weird_{prfx}_unlock.png'
,
1
),
(
u'dev'
,
u'/{prefix}_lock.png'
,
u'/{c4x}/{prefix}_lock.png'
,
1
),
(
u''
,
u'/{prfx}_excluded.html'
,
u'/{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}_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'/{prfx}_not_excluded.htm'
,
u'//dev/{c4x}/{prfx}_not_excluded.htm'
,
1
),
# Leading slash with subdirectory. This ensures we properly substitute slashes.
# Leading slash with subdirectory. This ensures we properly substitute slashes.
(
u''
,
u'/special/{prefix}_unlock.png'
,
u'/{c4x}/special_{prefix}_unlock.png'
,
1
),
(
u''
,
u'/special/{prfx}_unlock.png'
,
u'/{c4x}/special_{prfx}_unlock.png'
,
1
),
(
u''
,
u'/special/{prefix}_lock.png'
,
u'/{c4x}/special_{prefix}_lock.png'
,
1
),
(
u''
,
u'/special/{prfx}_lock.png'
,
u'/{c4x}/special_{prfx}_lock.png'
,
1
),
(
u'dev'
,
u'/special/{prefix}_unlock.png'
,
u'//dev/{c4x}/special_{prefix}_unlock.png'
,
1
),
(
u''
,
u'/special/weird {prfx}_unlock.png'
,
u'/{c4x}/special_weird_{prfx}_unlock.png'
,
1
),
(
u'dev'
,
u'/special/{prefix}_lock.png'
,
u'/{c4x}/special_{prefix}_lock.png'
,
1
),
(
u''
,
u'/special/{prfx}_excluded.html'
,
u'/{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}_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/{prfx}_not_excluded.htm'
,
u'//dev/{c4x}/special_{prfx}_not_excluded.htm'
,
1
),
# Static path.
# Static path.
(
u''
,
u'/static/{prefix}_unlock.png'
,
u'/{c4x}/{prefix}_unlock.png'
,
1
),
(
u''
,
u'/static/{prfx}_unlock.png'
,
u'/{c4x}/{prfx}_unlock.png'
,
1
),
(
u''
,
u'/static/{prefix}_lock.png'
,
u'/{c4x}/{prefix}_lock.png'
,
1
),
(
u''
,
u'/static/{prfx}_lock.png'
,
u'/{c4x}/{prfx}_lock.png'
,
1
),
(
u''
,
u'/static/weird {prefix}_unlock.png'
,
u'/{c4x}/weird_{prefix}_unlock.png'
,
1
),
(
u''
,
u'/static/weird {prfx}_unlock.png'
,
u'/{c4x}/weird_{prfx}_unlock.png'
,
1
),
(
u'dev'
,
u'/static/{prefix}_unlock.png'
,
u'//dev/{c4x}/{prefix}_unlock.png'
,
1
),
(
u''
,
u'/static/{prfx}_excluded.html'
,
u'/{c4x}/{prfx}_excluded.html'
,
1
),
(
u'dev'
,
u'/static/{prefix}_lock.png'
,
u'/{c4x}/{prefix}_lock.png'
,
1
),
(
u''
,
u'/static/{prfx}_not_excluded.htm'
,
u'/{c4x}/{prfx}_not_excluded.htm'
,
1
),
(
u'dev'
,
u'/static/weird {prefix}_unlock.png'
,
u'//dev/{c4x}/weird_{prefix}_unlock.png'
,
1
),
(
u'dev'
,
u'/static/{prfx}_unlock.png'
,
u'//dev/{c4x}/{prfx}_unlock.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/{prfx}_not_excluded.htm'
,
u'//dev/{c4x}/{prfx}_not_excluded.htm'
,
1
),
# Static path with subdirectory. This ensures we properly substitute slashes.
# Static path with subdirectory. This ensures we properly substitute slashes.
(
u''
,
u'/static/special/{prefix}_unlock.png'
,
u'/{c4x}/special_{prefix}_unlock.png'
,
1
),
(
u''
,
u'/static/special/{prfx}_unlock.png'
,
u'/{c4x}/special_{prfx}_unlock.png'
,
1
),
(
u''
,
u'/static/special/{prefix}_lock.png'
,
u'/{c4x}/special_{prefix}_lock.png'
,
1
),
(
u''
,
u'/static/special/{prfx}_lock.png'
,
u'/{c4x}/special_{prfx}_lock.png'
,
1
),
(
u'dev'
,
u'/static/special/{prefix}_unlock.png'
,
u'//dev/{c4x}/special_{prefix}_unlock.png'
,
1
),
(
u''
,
u'/static/special/weird {prfx}_unlock.png'
,
u'/{c4x}/special_weird_{prfx}_unlock.png'
,
1
),
(
u'dev'
,
u'/static/special/{prefix}_lock.png'
,
u'/{c4x}/special_{prefix}_lock.png'
,
1
),
(
u''
,
u'/static/special/{prfx}_excluded.html'
,
u'/{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}_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/{prfx}_not_excluded.htm'
,
u'//dev/{c4x}/special_{prfx}_not_excluded.htm'
,
1
),
# Static path with query parameter.
# Static path with query parameter.
(
(
u''
,
u''
,
u'/static/{prefix}_unlock.png?foo=/static/{prefix}_lock.png'
,
u'/static/{prfx}_unlock.png?foo=/static/{prfx}_lock.png'
,
u'/{c4x}/{prefix}_unlock.png?foo={encoded_c4x}{prefix}_lock.png'
,
u'/{c4x}/{prfx}_unlock.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'
,
2
),
(
u''
,
u'/static/{prfx}_excluded.html?foo=/static/{prfx}_excluded.html'
,
u'/{c4x}/{prfx}_excluded.html?foo={encoded_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'
,
2
2
),
),
(
(
u''
,
u''
,
u'/static/{prefix}_lock.png?foo=/static/{prefix}_unlock.png'
,
u'/static/{prfx}_not_excluded.htm?foo=/static/{prfx}_excluded.html'
,
u'/{c4x}/{prefix}_lock.png?foo={encoded_c4x}{prefix}_unlock.png'
,
u'/{c4x}/{prfx}_not_excluded.htm?foo={encoded_c4x}{prfx}_excluded.html'
,
2
),
(
u''
,
u'/static/{prfx}_not_excluded.htm?foo=/static/{prfx}_not_excluded.htm'
,
u'/{c4x}/{prfx}_not_excluded.htm?foo={encoded_c4x}{prfx}_not_excluded.htm'
,
2
),
(
u'dev'
,
u'/static/{prfx}_unlock.png?foo=/static/{prfx}_lock.png'
,
u'//dev/{c4x}/{prfx}_unlock.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'
,
2
),
(
u'dev'
,
u'/static/{prfx}_excluded.html?foo=/static/{prfx}_excluded.html'
,
u'/{c4x}/{prfx}_excluded.html?foo={encoded_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'
,
2
2
),
),
(
(
u'dev'
,
u'dev'
,
u'/static/{pr
efix}_unlock.png?foo=/static/{prefix}_lock.png
'
,
u'/static/{pr
fx}_not_excluded.htm?foo=/static/{prfx}_excluded.html
'
,
u'//dev/{c4x}/{pr
efix}_unlock.png?foo={encoded_c4x}{prefix}_lock.png
'
,
u'//dev/{c4x}/{pr
fx}_not_excluded.htm?foo={encoded_c4x}{prfx}_excluded.html
'
,
2
2
),
),
(
(
u'dev'
,
u'dev'
,
u'/static/{pr
efix}_lock.png?foo=/static/{prefix}_unlock.png
'
,
u'/static/{pr
fx}_not_excluded.htm?foo=/static/{prfx}_not_excluded.htm
'
,
u'/
{c4x}/{prefix}_lock.png?foo={encoded_base_url}{encoded_c4x}{prefix}_unlock.png
'
,
u'/
/dev/{c4x}/{prfx}_not_excluded.htm?foo={encoded_base_url}{encoded_c4x}{prfx}_not_excluded.htm
'
,
2
2
),
),
# Old, c4x-style path.
# Old, c4x-style path.
(
u''
,
u'/{c4x}/{prefix}_unlock.png'
,
u'/{c4x}/{prefix}_unlock.png'
,
1
),
(
u''
,
u'/{c4x}/{prfx}_unlock.png'
,
u'/{c4x}/{prfx}_unlock.png'
,
1
),
(
u''
,
u'/{c4x}/{prefix}_lock.png'
,
u'/{c4x}/{prefix}_lock.png'
,
1
),
(
u''
,
u'/{c4x}/{prfx}_lock.png'
,
u'/{c4x}/{prfx}_lock.png'
,
1
),
(
u''
,
u'/{c4x}/weird_{prefix}_unlock.png'
,
u'/{c4x}/weird_{prefix}_unlock.png'
,
1
),
(
u''
,
u'/{c4x}/weird_{prfx}_lock.png'
,
u'/{c4x}/weird_{prfx}_lock.png'
,
1
),
(
u'dev'
,
u'/{c4x}/{prefix}_unlock.png'
,
u'//dev/{c4x}/{prefix}_unlock.png'
,
1
),
(
u''
,
u'/{c4x}/{prfx}_excluded.html'
,
u'/{c4x}/{prfx}_excluded.html'
,
1
),
(
u'dev'
,
u'/{c4x}/{prefix}_lock.png'
,
u'/{c4x}/{prefix}_lock.png'
,
1
),
(
u''
,
u'/{c4x}/{prfx}_not_excluded.htm'
,
u'/{c4x}/{prfx}_not_excluded.htm'
,
1
),
(
u'dev'
,
u'/{c4x}/weird_{prefix}_unlock.png'
,
u'//dev/{c4x}/weird_{prefix}_unlock.png'
,
1
),
(
u'dev'
,
u'/{c4x}/{prfx}_unlock.png'
,
u'//dev/{c4x}/{prfx}_unlock.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}/{prfx}_not_excluded.htm'
,
u'//dev/{c4x}/{prfx}_not_excluded.htm'
,
1
),
)
)
@ddt.unpack
@ddt.unpack
def
test_canonical_asset_path_with_c4x_style_assets
(
self
,
base_url
,
start
,
expected
,
mongo_calls
):
def
test_canonical_asset_path_with_c4x_style_assets
(
self
,
base_url
,
start
,
expected
,
mongo_calls
):
exts
=
[
'.html'
,
'.tm'
]
prefix
=
'old'
prefix
=
'old'
c4x_block
=
'c4x/a/b/asset'
c4x_block
=
'c4x/a/b/asset'
encoded_c4x_block
=
quote_plus
(
'/'
+
c4x_block
+
'/'
)
encoded_c4x_block
=
quote_plus
(
'/'
+
c4x_block
+
'/'
)
encoded_base_url
=
quote_plus
(
'//'
+
base_url
)
encoded_base_url
=
quote_plus
(
'//'
+
base_url
)
start
=
start
.
format
(
start
=
start
.
format
(
pr
efi
x
=
prefix
,
pr
f
x
=
prefix
,
encoded_base_url
=
encoded_base_url
,
encoded_base_url
=
encoded_base_url
,
c4x
=
c4x_block
,
c4x
=
c4x_block
,
encoded_c4x
=
encoded_c4x_block
encoded_c4x
=
encoded_c4x_block
)
)
expected
=
expected
.
format
(
expected
=
expected
.
format
(
pr
efi
x
=
prefix
,
pr
f
x
=
prefix
,
encoded_base_url
=
encoded_base_url
,
encoded_base_url
=
encoded_base_url
,
c4x
=
c4x_block
,
c4x
=
c4x_block
,
encoded_c4x
=
encoded_c4x_block
encoded_c4x
=
encoded_c4x_block
)
)
with
check_mongo_calls
(
mongo_calls
):
with
check_mongo_calls
(
mongo_calls
):
asset_path
=
StaticContent
.
get_canonicalized_asset_path
(
self
.
courses
[
prefix
]
.
id
,
start
,
base_url
)
asset_path
=
StaticContent
.
get_canonicalized_asset_path
(
self
.
courses
[
prefix
]
.
id
,
start
,
base_url
,
exts
)
self
.
assertEqual
(
asset_path
,
expected
)
self
.
assertEqual
(
asset_path
,
expected
)
common/lib/xmodule/xmodule/contentstore/content.py
View file @
78370f36
...
@@ -168,7 +168,7 @@ class StaticContent(object):
...
@@ -168,7 +168,7 @@ class StaticContent(object):
return
StaticContent
.
compute_location
(
course_key
,
path
)
return
StaticContent
.
compute_location
(
course_key
,
path
)
@staticmethod
@staticmethod
def
get_canonicalized_asset_path
(
course_key
,
path
,
base_url
):
def
get_canonicalized_asset_path
(
course_key
,
path
,
base_url
,
excluded_exts
):
"""
"""
Returns a fully-qualified path to a piece of static content.
Returns a fully-qualified path to a piece of static content.
...
@@ -199,17 +199,22 @@ class StaticContent(object):
...
@@ -199,17 +199,22 @@ class StaticContent(object):
# If we can't find the item, just treat it as if it's locked.
# If we can't find the item, just treat it as if it's locked.
serve_from_cdn
=
False
serve_from_cdn
=
False
# See if this is an allowed file extension to serve. Some files aren't served through the
# CDN in order to avoid same-origin policy/CORS-related issues.
if
any
(
relative_path
.
lower
()
.
endswith
(
excluded_ext
.
lower
())
for
excluded_ext
in
excluded_exts
):
serve_from_cdn
=
False
# Update any query parameter values that have asset paths in them. This is for assets that
# Update any query parameter values that have asset paths in them. This is for assets that
# require their own after-the-fact values, like a Flash file that needs the path of a config
# require their own after-the-fact values, like a Flash file that needs the path of a config
# file passed to it e.g. /static/visualization.swf?configFile=/static/visualization.xml
# file passed to it e.g. /static/visualization.swf?configFile=/static/visualization.xml
query_params
=
parse_qsl
(
query_string
)
query_params
=
parse_qsl
(
query_string
)
updated_query_params
=
[]
updated_query_params
=
[]
for
query_name
,
query_val
ue
in
query_params
:
for
query_name
,
query_val
in
query_params
:
if
query_val
ue
.
startswith
(
"/static/"
):
if
query_val
.
startswith
(
"/static/"
):
new_
query_value
=
StaticContent
.
get_canonicalized_asset_path
(
course_key
,
query_value
,
base_url
)
new_
val
=
StaticContent
.
get_canonicalized_asset_path
(
course_key
,
query_val
,
base_url
,
excluded_exts
)
updated_query_params
.
append
((
query_name
,
new_
query_value
))
updated_query_params
.
append
((
query_name
,
new_
val
))
else
:
else
:
updated_query_params
.
append
((
query_name
,
query_val
ue
))
updated_query_params
.
append
((
query_name
,
query_val
))
serialized_asset_key
=
StaticContent
.
serialize_asset_key_with_slash
(
asset_key
)
serialized_asset_key
=
StaticContent
.
serialize_asset_key_with_slash
(
asset_key
)
base_url
=
base_url
if
serve_from_cdn
else
''
base_url
=
base_url
if
serve_from_cdn
else
''
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment