Merge pull request #387 from edx/fix/cdodge/unescape-quote-strings
[STUD-406] Fix/cdodge/unescape quote strings
This commit is contained in:
@@ -137,7 +137,6 @@ class EditableMetadataFieldsTest(unittest.TestCase):
|
||||
type='Float', options={'min': 0, 'step': .3}
|
||||
)
|
||||
|
||||
|
||||
# Start of helper methods
|
||||
def get_xml_editable_fields(self, model_data):
|
||||
system = get_test_system()
|
||||
@@ -179,19 +178,19 @@ class TestSerialize(unittest.TestCase):
|
||||
def test_serialize(self):
|
||||
assert_equals('null', serialize_field(None))
|
||||
assert_equals('-2', serialize_field(-2))
|
||||
assert_equals('"2"', serialize_field('2'))
|
||||
assert_equals('2', serialize_field('2'))
|
||||
assert_equals('-3.41', serialize_field(-3.41))
|
||||
assert_equals('"2.589"', serialize_field('2.589'))
|
||||
assert_equals('2.589', serialize_field('2.589'))
|
||||
assert_equals('false', serialize_field(False))
|
||||
assert_equals('"false"', serialize_field('false'))
|
||||
assert_equals('"fAlse"', serialize_field('fAlse'))
|
||||
assert_equals('"hat box"', serialize_field('hat box'))
|
||||
assert_equals('{"bar": "hat", "frog": "green"}', serialize_field({'bar': 'hat', 'frog' : 'green'}))
|
||||
assert_equals('false', serialize_field('false'))
|
||||
assert_equals('fAlse', serialize_field('fAlse'))
|
||||
assert_equals('hat box', serialize_field('hat box'))
|
||||
assert_equals('{"bar": "hat", "frog": "green"}', serialize_field({'bar': 'hat', 'frog': 'green'}))
|
||||
assert_equals('[3.5, 5.6]', serialize_field([3.5, 5.6]))
|
||||
assert_equals('["foo", "bar"]', serialize_field(['foo', 'bar']))
|
||||
assert_equals('"2012-12-31T23:59:59Z"', serialize_field("2012-12-31T23:59:59Z"))
|
||||
assert_equals('"1 day 12 hours 59 minutes 59 seconds"',
|
||||
serialize_field("1 day 12 hours 59 minutes 59 seconds"))
|
||||
assert_equals('2012-12-31T23:59:59Z', serialize_field("2012-12-31T23:59:59Z"))
|
||||
assert_equals('1 day 12 hours 59 minutes 59 seconds',
|
||||
serialize_field("1 day 12 hours 59 minutes 59 seconds"))
|
||||
|
||||
|
||||
class TestDeserialize(unittest.TestCase):
|
||||
@@ -201,7 +200,6 @@ class TestDeserialize(unittest.TestCase):
|
||||
"""
|
||||
assert_equals(expected, deserialize_field(self.test_field(), arg))
|
||||
|
||||
|
||||
def assertDeserializeNonString(self):
|
||||
"""
|
||||
Asserts input value is returned for None or something that is not a string.
|
||||
|
||||
@@ -81,10 +81,14 @@ class AttrMap(_AttrMapBase):
|
||||
|
||||
def serialize_field(value):
|
||||
"""
|
||||
Return a string version of the value (where value is the JSON-formatted, internally stored value).
|
||||
Return a string version of the value (where value is the JSON-formatted, internally stored value).
|
||||
|
||||
If the value is a string, then we simply return what was passed in.
|
||||
Otherwise, we return json.dumps on the input value.
|
||||
"""
|
||||
if isinstance(value, basestring):
|
||||
return value
|
||||
|
||||
By default, this is the result of calling json.dumps on the input value.
|
||||
"""
|
||||
return json.dumps(value, cls=EdxJSONEncoder)
|
||||
|
||||
|
||||
@@ -126,7 +130,7 @@ class XmlDescriptor(XModuleDescriptor):
|
||||
"""
|
||||
|
||||
xml_attributes = Dict(help="Map of unhandled xml attributes, used only for storage between import and export",
|
||||
default={}, scope=Scope.settings)
|
||||
default={}, scope=Scope.settings)
|
||||
|
||||
# Extension to append to filename paths
|
||||
filename_extension = 'xml'
|
||||
@@ -141,23 +145,23 @@ class XmlDescriptor(XModuleDescriptor):
|
||||
# understand? And if we do, is this the place?
|
||||
# Related: What's the right behavior for clean_metadata?
|
||||
metadata_attributes = ('format', 'graceperiod', 'showanswer', 'rerandomize',
|
||||
'start', 'due', 'graded', 'display_name', 'url_name', 'hide_from_toc',
|
||||
'ispublic', # if True, then course is listed for all users; see
|
||||
'xqa_key', # for xqaa server access
|
||||
'giturl', # url of git server for origin of file
|
||||
# information about testcenter exams is a dict (of dicts), not a string,
|
||||
# so it cannot be easily exportable as a course element's attribute.
|
||||
'testcenter_info',
|
||||
# VS[compat] Remove once unused.
|
||||
'name', 'slug')
|
||||
'start', 'due', 'graded', 'display_name', 'url_name', 'hide_from_toc',
|
||||
'ispublic', # if True, then course is listed for all users; see
|
||||
'xqa_key', # for xqaa server access
|
||||
'giturl', # url of git server for origin of file
|
||||
# information about testcenter exams is a dict (of dicts), not a string,
|
||||
# so it cannot be easily exportable as a course element's attribute.
|
||||
'testcenter_info',
|
||||
# VS[compat] Remove once unused.
|
||||
'name', 'slug')
|
||||
|
||||
metadata_to_strip = ('data_dir',
|
||||
'tabs', 'grading_policy', 'published_by', 'published_date',
|
||||
'discussion_blackouts', 'testcenter_info',
|
||||
# VS[compat] -- remove the below attrs once everything is in the CMS
|
||||
'course', 'org', 'url_name', 'filename',
|
||||
# Used for storing xml attributes between import and export, for roundtrips
|
||||
'xml_attributes')
|
||||
'tabs', 'grading_policy', 'published_by', 'published_date',
|
||||
'discussion_blackouts', 'testcenter_info',
|
||||
# VS[compat] -- remove the below attrs once everything is in the CMS
|
||||
'course', 'org', 'url_name', 'filename',
|
||||
# Used for storing xml attributes between import and export, for roundtrips
|
||||
'xml_attributes')
|
||||
|
||||
metadata_to_export_to_policy = ('discussion_topics')
|
||||
|
||||
@@ -166,7 +170,7 @@ class XmlDescriptor(XModuleDescriptor):
|
||||
for field in set(cls.fields + cls.lms.fields):
|
||||
if field.name == attr:
|
||||
from_xml = lambda val: deserialize_field(field, val)
|
||||
to_xml = lambda val : serialize_field(val)
|
||||
to_xml = lambda val: serialize_field(val)
|
||||
return AttrMap(from_xml, to_xml)
|
||||
|
||||
return AttrMap()
|
||||
@@ -254,7 +258,7 @@ class XmlDescriptor(XModuleDescriptor):
|
||||
definition, children = cls.definition_from_xml(definition_xml, system)
|
||||
if definition_metadata:
|
||||
definition['definition_metadata'] = definition_metadata
|
||||
definition['filename'] = [ filepath, filename ]
|
||||
definition['filename'] = [filepath, filename]
|
||||
|
||||
return definition, children
|
||||
|
||||
@@ -280,7 +284,6 @@ class XmlDescriptor(XModuleDescriptor):
|
||||
metadata[attr] = attr_map.from_xml(val)
|
||||
return metadata
|
||||
|
||||
|
||||
@classmethod
|
||||
def apply_policy(cls, metadata, policy):
|
||||
"""
|
||||
@@ -374,7 +377,6 @@ class XmlDescriptor(XModuleDescriptor):
|
||||
"""
|
||||
return True
|
||||
|
||||
|
||||
def export_to_xml(self, resource_fs):
|
||||
"""
|
||||
Returns an xml string representing this module, and all modules
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<course name="A Simple Course" org="edX" course="simple" graceperiod="1 day 5 hours 59 minutes 59 seconds" slug="2012_Fall">
|
||||
<chapter name="Overview">
|
||||
<video name="Welcome" youtube_id_0_75=""izygArpw-Qo"" youtube_id_1_0=""p2Q6BrNhdh8"" youtube_id_1_25=""1EeWXzPdhSA"" youtube_id_1_5=""rABDYkeK0x8""/>
|
||||
<video name="Welcome" youtube_id_0_75="izygArpw-Qo" youtube_id_1_0="p2Q6BrNhdh8" youtube_id_1_25="1EeWXzPdhSA" youtube_id_1_5="rABDYkeK0x8"/>
|
||||
<videosequence format="Lecture Sequence" name="A simple sequence">
|
||||
<html name="toylab" filename="toylab"/>
|
||||
<video name="S0V1: Video Resources" youtube_id_0_75=""EuzkdzfR0i8"" youtube_id_1_0=""1bK-WdDi6Qw"" youtube_id_1_25=""0v1VzoDVUTM"" youtube_id_1_5=""Bxk_-ZJb240""/>
|
||||
<video name="S0V1: Video Resources" youtube_id_0_75="EuzkdzfR0i8" youtube_id_1_0="1bK-WdDi6Qw" youtube_id_1_25="0v1VzoDVUTM" youtube_id_1_5="Bxk_-ZJb240"/>
|
||||
</videosequence>
|
||||
<section name="Lecture 2">
|
||||
<sequential>
|
||||
<video youtube_id_1_0=""TBvX7HzxexQ""/>
|
||||
<video youtube_id_1_0="TBvX7HzxexQ"/>
|
||||
<problem name="L1 Problem 1" points="1" type="lecture" showanswer="attempted" filename="L1_Problem_1" rerandomize="never"/>
|
||||
</sequential>
|
||||
</section>
|
||||
@@ -18,7 +18,7 @@
|
||||
<problem type="lecture" showanswer="attempted" rerandomize="true" display_name="A simple coding problem" name="Simple coding problem" filename="ps01-simple" url_name="ps01-simple"/>
|
||||
</sequential>
|
||||
</section>
|
||||
<video name="Lost Video" youtube_id_1_0=""TBvX7HzxexQ""/>
|
||||
<video name="Lost Video" youtube_id_1_0="TBvX7HzxexQ"/>
|
||||
<sequential format="Lecture Sequence" url_name='test_sequence'>
|
||||
<vertical url_name='test_vertical'>
|
||||
<html url_name='test_html'>
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
<chapter url_name="Overview">
|
||||
<videosequence url_name="Toy_Videos">
|
||||
<html url_name="toylab"/>
|
||||
<video url_name="Video_Resources" youtube_id_1_0=""1bK-WdDi6Qw""/>
|
||||
<video url_name="Video_Resources" youtube_id_1_0="1bK-WdDi6Qw"/>
|
||||
</videosequence>
|
||||
<video url_name="Welcome" youtube_id_1_0=""p2Q6BrNhdh8""/>
|
||||
<video url_name="Welcome" youtube_id_1_0="p2Q6BrNhdh8"/>
|
||||
</chapter>
|
||||
<chapter url_name="Ch2">
|
||||
<html url_name="test_html">
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
<chapter url_name="Overview">
|
||||
<videosequence url_name="Toy_Videos">
|
||||
<html url_name="toylab"/>
|
||||
<video url_name="Video_Resources" youtube_id_1_0=""1bK-WdDi6Qw""/>
|
||||
<video url_name="Video_Resources" youtube_id_1_0="1bK-WdDi6Qw"/>
|
||||
</videosequence>
|
||||
<video url_name="Welcome" youtube_id_1_0=""p2Q6BrNhdh8""/>
|
||||
<video url_name="Welcome" youtube_id_1_0="p2Q6BrNhdh8"/>
|
||||
</chapter>
|
||||
<chapter url_name="Ch2">
|
||||
<html url_name="test_html">
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<chapter>
|
||||
<video url_name="toyvideo" youtube_id_1_0=""OEoXaMPEzfM""/>
|
||||
<video url_name="toyvideo" youtube_id_1_0="OEoXaMPEzfM"/>
|
||||
</chapter>
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
<chapter url_name="Overview">
|
||||
<videosequence url_name="Toy_Videos">
|
||||
<html url_name="secret:toylab"/>
|
||||
<video url_name="Video_Resources" youtube_id_1_0=""1bK-WdDi6Qw""/>
|
||||
<video url_name="Video_Resources" youtube_id_1_0="1bK-WdDi6Qw"/>
|
||||
</videosequence>
|
||||
<video url_name="Welcome" youtube_id_1_0=""p2Q6BrNhdh8""/>
|
||||
<video url_name="video_123456789012" youtube_id_1_0=""p2Q6BrNhdh8""/>
|
||||
<video url_name="video_4f66f493ac8f" youtube_id_1_0=""p2Q6BrNhdh8""/>
|
||||
<video url_name="Welcome" youtube_id_1_0="p2Q6BrNhdh8"/>
|
||||
<video url_name="video_123456789012" youtube_id_1_0="p2Q6BrNhdh8"/>
|
||||
<video url_name="video_4f66f493ac8f" youtube_id_1_0="p2Q6BrNhdh8"/>
|
||||
</chapter>
|
||||
<chapter url_name="secret:magic"/>
|
||||
<chapter url_name="poll_test"/>
|
||||
|
||||
@@ -1 +1 @@
|
||||
<video youtube_id_1_0=""1bK-WdDi6Qw"" display_name="Video Resources"/>
|
||||
<video youtube_id_1_0="1bK-WdDi6Qw" display_name="Video Resources"/>
|
||||
|
||||
Reference in New Issue
Block a user