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
534b32c7
Commit
534b32c7
authored
Oct 20, 2015
by
vkaracic
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Xblock utilities tests
Tests for xblock_utils.py functions.
parent
64d20bb6
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
218 additions
and
5 deletions
+218
-5
openedx/core/lib/tests/test_xblock_utils.py
+205
-0
openedx/core/lib/xblock_utils.py
+13
-5
No files found.
openedx/core/lib/tests/test_xblock_utils.py
0 → 100644
View file @
534b32c7
"""
Tests for xblock_utils.py
"""
from
__future__
import
unicode_literals
,
absolute_import
import
ddt
import
uuid
from
django.test.client
import
RequestFactory
from
courseware.models
import
StudentModule
# pylint: disable=import-error
from
lms.djangoapps.lms_xblock.runtime
import
quote_slashes
from
xblock.fragment
import
Fragment
from
xmodule.modulestore
import
ModuleStoreEnum
from
xmodule.modulestore.tests.django_utils
import
SharedModuleStoreTestCase
from
xmodule.modulestore.tests.factories
import
CourseFactory
from
openedx.core.lib.xblock_utils
import
(
wrap_fragment
,
request_token
,
wrap_xblock
,
replace_jump_to_id_urls
,
replace_course_urls
,
replace_static_urls
,
grade_histogram
,
sanitize_html_id
)
@ddt.ddt
class
TestXblockUtils
(
SharedModuleStoreTestCase
):
"""
Tests for xblock utility functions.
"""
@classmethod
def
setUpClass
(
cls
):
super
(
TestXblockUtils
,
cls
)
.
setUpClass
()
cls
.
course_mongo
=
CourseFactory
.
create
(
default_store
=
ModuleStoreEnum
.
Type
.
mongo
,
org
=
'TestX'
,
number
=
'TS01'
,
run
=
'2015'
)
cls
.
course_split
=
CourseFactory
.
create
(
default_store
=
ModuleStoreEnum
.
Type
.
split
,
org
=
'TestX'
,
number
=
'TS02'
,
run
=
'2015'
)
def
setUp
(
self
):
super
(
TestXblockUtils
,
self
)
.
setUp
()
def
create_fragment
(
self
,
content
=
None
):
"""
Create a fragment.
"""
fragment
=
Fragment
(
content
)
fragment
.
add_css
(
'body {background-color:red;}'
)
fragment
.
add_javascript
(
'alert("Hi!");'
)
return
fragment
def
test_wrap_fragment
(
self
):
"""
Verify that wrap_fragment adds new content.
"""
new_content
=
'<p>New Content<p>'
fragment
=
self
.
create_fragment
()
wrapped_fragment
=
wrap_fragment
(
fragment
,
new_content
)
self
.
assertEqual
(
'<p>New Content<p>'
,
wrapped_fragment
.
content
)
self
.
assertEqual
(
'body {background-color:red;}'
,
wrapped_fragment
.
resources
[
0
]
.
data
)
self
.
assertEqual
(
'alert("Hi!");'
,
wrapped_fragment
.
resources
[
1
]
.
data
)
def
test_request_token
(
self
):
"""
Verify that a proper token is returned.
"""
request_with_token
=
RequestFactory
()
.
get
(
'/'
)
request_with_token
.
_xblock_token
=
'123'
# pylint: disable=protected-access
token
=
request_token
(
request_with_token
)
self
.
assertEqual
(
token
,
'123'
)
request_without_token
=
RequestFactory
()
.
get
(
'/'
)
token
=
request_token
(
request_without_token
)
# Test to see if the token is an uuid1 hex value
test_uuid
=
uuid
.
UUID
(
token
,
version
=
1
)
self
.
assertEqual
(
token
,
test_uuid
.
hex
)
@ddt.data
(
(
'course_mongo'
,
'data-usage-id="i4x:;_;_TestX;_TS01;_course;_2015"'
),
(
'course_split'
,
'data-usage-id="block-v1:TestX+TS02+2015+type@course+block@course"'
)
)
@ddt.unpack
def
test_wrap_xblock
(
self
,
course_id
,
data_usage_id
):
"""
Verify that new content is added and the resources are the same.
"""
fragment
=
self
.
create_fragment
(
u"<h1>Test!</h1>"
)
course
=
getattr
(
self
,
course_id
)
test_wrap_output
=
wrap_xblock
(
runtime_class
=
'TestRuntime'
,
block
=
course
,
view
=
'baseview'
,
frag
=
fragment
,
context
=
None
,
usage_id_serializer
=
lambda
usage_id
:
quote_slashes
(
unicode
(
usage_id
)),
request_token
=
uuid
.
uuid1
()
.
get_hex
()
)
self
.
assertIsInstance
(
test_wrap_output
,
Fragment
)
self
.
assertIn
(
'xblock-baseview'
,
test_wrap_output
.
content
)
self
.
assertIn
(
'data-runtime-class="TestRuntime"'
,
test_wrap_output
.
content
)
self
.
assertIn
(
data_usage_id
,
test_wrap_output
.
content
)
self
.
assertIn
(
'<h1>Test!</h1>'
,
test_wrap_output
.
content
)
self
.
assertEqual
(
test_wrap_output
.
resources
[
0
]
.
data
,
u'body {background-color:red;}'
)
self
.
assertEqual
(
test_wrap_output
.
resources
[
1
]
.
data
,
'alert("Hi!");'
)
@ddt.data
(
'course_mongo'
,
'course_split'
)
def
test_replace_jump_to_id_urls
(
self
,
course_id
):
"""
Verify that the jump-to URL has been replaced.
"""
course
=
getattr
(
self
,
course_id
)
test_replace
=
replace_jump_to_id_urls
(
course_id
=
course
.
id
,
jump_to_id_base_url
=
'/base_url/'
,
block
=
course
,
view
=
'baseview'
,
frag
=
Fragment
(
'<a href="/jump_to_id/id">'
),
context
=
None
)
self
.
assertIsInstance
(
test_replace
,
Fragment
)
self
.
assertEqual
(
test_replace
.
content
,
'<a href="/base_url/id">'
)
@ddt.data
(
(
'course_mongo'
,
'<a href="/courses/TestX/TS01/2015/id">'
),
(
'course_split'
,
'<a href="/courses/course-v1:TestX+TS02+2015/id">'
)
)
@ddt.unpack
def
test_replace_course_urls
(
self
,
course_id
,
anchor_tag
):
"""
Verify that the course URL has been replaced.
"""
course
=
getattr
(
self
,
course_id
)
test_replace
=
replace_course_urls
(
course_id
=
course
.
id
,
block
=
course
,
view
=
'baseview'
,
frag
=
Fragment
(
'<a href="/course/id">'
),
context
=
None
)
self
.
assertIsInstance
(
test_replace
,
Fragment
)
self
.
assertEqual
(
test_replace
.
content
,
anchor_tag
)
@ddt.data
(
(
'course_mongo'
,
'<a href="/c4x/TestX/TS01/asset/id">'
),
(
'course_split'
,
'<a href="/asset-v1:TestX+TS02+2015+type@asset+block/id">'
)
)
@ddt.unpack
def
test_replace_static_urls
(
self
,
course_id
,
anchor_tag
):
"""
Verify that the static URL has been replaced.
"""
course
=
getattr
(
self
,
course_id
)
test_replace
=
replace_static_urls
(
data_dir
=
None
,
course_id
=
course
.
id
,
block
=
course
,
view
=
'baseview'
,
frag
=
Fragment
(
'<a href="/static/id">'
),
context
=
None
)
self
.
assertIsInstance
(
test_replace
,
Fragment
)
self
.
assertEqual
(
test_replace
.
content
,
anchor_tag
)
@ddt.data
(
'course_mongo'
,
'course_split'
)
def
test_grade_histogram
(
self
,
course_id
):
"""
Verify that a histogram has been created.
"""
course
=
getattr
(
self
,
course_id
)
usage_key
=
course
.
id
.
make_usage_key
(
'problem'
,
'first_problem'
)
StudentModule
.
objects
.
create
(
student_id
=
1
,
grade
=
100
,
module_state_key
=
usage_key
)
StudentModule
.
objects
.
create
(
student_id
=
2
,
grade
=
50
,
module_state_key
=
usage_key
)
grades
=
grade_histogram
(
usage_key
)
self
.
assertEqual
(
grades
[
0
],
(
50.0
,
1
))
self
.
assertEqual
(
grades
[
1
],
(
100.0
,
1
))
def
test_sanitize_html_id
(
self
):
"""
Verify that colons and dashes are replaced.
"""
dirty_string
=
'I:have-un:allowed_characters'
clean_string
=
sanitize_html_id
(
dirty_string
)
self
.
assertEqual
(
clean_string
,
'I_have_un_allowed_characters'
)
openedx/core/lib/xblock_utils.py
View file @
534b32c7
...
@@ -5,9 +5,10 @@ Functions that can are used to modify XBlock fragments for use in the LMS and St
...
@@ -5,9 +5,10 @@ Functions that can are used to modify XBlock fragments for use in the LMS and St
import
datetime
import
datetime
import
json
import
json
import
logging
import
logging
import
markupsafe
import
re
import
static_replace
import
static_replace
import
uuid
import
uuid
import
markupsafe
from
lxml
import
html
,
etree
from
lxml
import
html
,
etree
from
contracts
import
contract
from
contracts
import
contract
...
@@ -145,7 +146,7 @@ def wrap_xblock(
...
@@ -145,7 +146,7 @@ def wrap_xblock(
def
replace_jump_to_id_urls
(
course_id
,
jump_to_id_base_url
,
block
,
view
,
frag
,
context
):
# pylint: disable=unused-argument
def
replace_jump_to_id_urls
(
course_id
,
jump_to_id_base_url
,
block
,
view
,
frag
,
context
):
# pylint: disable=unused-argument
"""
"""
This will replace a link between courseware in the format
This will replace a link between courseware in the format
/jump_to/<id> with a URL for a page that will correctly redirect
/jump_to
_id
/<id> with a URL for a page that will correctly redirect
This is similar to replace_course_urls, but much more flexible and
This is similar to replace_course_urls, but much more flexible and
durable for Studio authored courses. See more comments in static_replace.replace_jump_to_urls
durable for Studio authored courses. See more comments in static_replace.replace_jump_to_urls
...
@@ -156,7 +157,7 @@ def replace_jump_to_id_urls(course_id, jump_to_id_base_url, block, view, frag, c
...
@@ -156,7 +157,7 @@ def replace_jump_to_id_urls(course_id, jump_to_id_base_url, block, view, frag, c
the end of this URL at re-write time
the end of this URL at re-write time
output: a new :class:`~xblock.fragment.Fragment` that modifies `frag` with
output: a new :class:`~xblock.fragment.Fragment` that modifies `frag` with
content that has been update with /jump_to links replaced
content that has been update with /jump_to
_id
links replaced
"""
"""
return
wrap_fragment
(
frag
,
static_replace
.
replace_jump_to_id_urls
(
frag
.
content
,
course_id
,
jump_to_id_base_url
))
return
wrap_fragment
(
frag
,
static_replace
.
replace_jump_to_id_urls
(
frag
.
content
,
course_id
,
jump_to_id_base_url
))
...
@@ -211,6 +212,14 @@ def grade_histogram(module_id):
...
@@ -211,6 +212,14 @@ def grade_histogram(module_id):
return
grades
return
grades
def
sanitize_html_id
(
html_id
):
"""
Template uses element_id in js function names, so can't allow dashes and colons.
"""
sanitized_html_id
=
re
.
sub
(
r'[:-]'
,
'_'
,
html_id
)
return
sanitized_html_id
@contract
(
user
=
User
,
has_instructor_access
=
bool
,
block
=
XBlock
,
view
=
basestring
,
frag
=
Fragment
,
context
=
"dict|None"
)
@contract
(
user
=
User
,
has_instructor_access
=
bool
,
block
=
XBlock
,
view
=
basestring
,
frag
=
Fragment
,
context
=
"dict|None"
)
def
add_staff_markup
(
user
,
has_instructor_access
,
disable_staff_debug_info
,
block
,
view
,
frag
,
context
):
# pylint: disable=unused-argument
def
add_staff_markup
(
user
,
has_instructor_access
,
disable_staff_debug_info
,
block
,
view
,
frag
,
context
):
# pylint: disable=unused-argument
"""
"""
...
@@ -299,8 +308,7 @@ def add_staff_markup(user, has_instructor_access, disable_staff_debug_info, bloc
...
@@ -299,8 +308,7 @@ def add_staff_markup(user, has_instructor_access, disable_staff_debug_info, bloc
'source_file'
:
source_file
,
'source_file'
:
source_file
,
'source_url'
:
'
%
s/
%
s/tree/master/
%
s'
%
(
giturl
,
data_dir
,
source_file
),
'source_url'
:
'
%
s/
%
s/tree/master/
%
s'
%
(
giturl
,
data_dir
,
source_file
),
'category'
:
str
(
block
.
__class__
.
__name__
),
'category'
:
str
(
block
.
__class__
.
__name__
),
# Template uses element_id in js function names, so can't allow dashes
'element_id'
:
sanitize_html_id
(
block
.
location
.
html_id
()),
'element_id'
:
block
.
location
.
html_id
()
.
replace
(
'-'
,
'_'
),
'edit_link'
:
edit_link
,
'edit_link'
:
edit_link
,
'user'
:
user
,
'user'
:
user
,
'xqa_server'
:
settings
.
FEATURES
.
get
(
'XQA_SERVER'
,
"http://your_xqa_server.com"
),
'xqa_server'
:
settings
.
FEATURES
.
get
(
'XQA_SERVER'
,
"http://your_xqa_server.com"
),
...
...
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