Skip to content
Snippets Groups Projects
Commit 760027bd authored by Calen Pennington's avatar Calen Pennington
Browse files

Normalize the representation of Scope.content data in MongoModulestore FieldData

Without this, the new 'items' field in the course_info xmodule caused
bizarre behavior. If you added the text 'items' to a course_info
section, then the LMS would throw a 500, because the field name isn't
'data', but the stored data is a string, leading to the check of
`key.field_name in self._data`, where key.field_name is the string 'items',
and self._data is the content string.
parent 73f75f23
No related merge requests found
......@@ -229,7 +229,7 @@ class AboutFields(object):
)
data = String(
help="Html contents to display for this module",
default="",
default=u"",
scope=Scope.content
)
......@@ -263,7 +263,7 @@ class StaticTabFields(object):
default="Empty",
)
data = String(
default=textwrap.dedent("""\
default=textwrap.dedent(u"""\
<p>This is where you can add additional pages to your courseware. Click the 'edit' button to begin editing.</p>
"""),
scope=Scope.content,
......@@ -300,7 +300,7 @@ class CourseInfoFields(object):
)
data = String(
help="Html contents to display for this module",
default="<ol></ol>",
default=u"<ol></ol>",
scope=Scope.content
)
......
......@@ -60,7 +60,10 @@ class MongoKeyValueStore(InheritanceKeyValueStore):
"""
def __init__(self, data, children, metadata):
super(MongoKeyValueStore, self).__init__()
self._data = data
if not isinstance(data, dict):
self._data = {'data': data}
else:
self._data = data
self._children = children
self._metadata = metadata
......@@ -72,10 +75,7 @@ class MongoKeyValueStore(InheritanceKeyValueStore):
elif key.scope == Scope.settings:
return self._metadata[key.field_name]
elif key.scope == Scope.content:
if key.field_name == 'data' and not isinstance(self._data, dict):
return self._data
else:
return self._data[key.field_name]
return self._data[key.field_name]
else:
raise InvalidScopeError(key)
......@@ -85,10 +85,7 @@ class MongoKeyValueStore(InheritanceKeyValueStore):
elif key.scope == Scope.settings:
self._metadata[key.field_name] = value
elif key.scope == Scope.content:
if key.field_name == 'data' and not isinstance(self._data, dict):
self._data = value
else:
self._data[key.field_name] = value
self._data[key.field_name] = value
else:
raise InvalidScopeError(key)
......@@ -99,9 +96,7 @@ class MongoKeyValueStore(InheritanceKeyValueStore):
if key.field_name in self._metadata:
del self._metadata[key.field_name]
elif key.scope == Scope.content:
if key.field_name == 'data' and not isinstance(self._data, dict):
self._data = None
else:
if key.field_name in self._data:
del self._data[key.field_name]
else:
raise InvalidScopeError(key)
......@@ -112,10 +107,7 @@ class MongoKeyValueStore(InheritanceKeyValueStore):
elif key.scope == Scope.settings:
return key.field_name in self._metadata
elif key.scope == Scope.content:
if key.field_name == 'data' and not isinstance(self._data, dict):
return True
else:
return key.field_name in self._data
return key.field_name in self._data
else:
return False
......@@ -640,6 +632,10 @@ class MongoModuleStore(ModuleStoreWriteBase):
# layer but added it here to enable quick conversion. I'll need to reconcile these.
if metadata is None:
metadata = {}
if definition_data is None:
definition_data = {}
if system is None:
services = {}
if self.i18n_service:
......@@ -658,11 +654,6 @@ class MongoModuleStore(ModuleStoreWriteBase):
services=services,
)
xblock_class = system.load_block_type(location.category)
if definition_data is None:
if hasattr(xblock_class, 'data') and xblock_class.data.default is not None:
definition_data = xblock_class.data.default
else:
definition_data = {}
dbmodel = self._create_new_field_data(location.category, location, definition_data, metadata)
xmodule = system.construct_xblock_from_class(
xblock_class,
......@@ -796,8 +787,6 @@ class MongoModuleStore(ModuleStoreWriteBase):
"""
try:
definition_data = xblock.get_explicitly_set_fields_by_scope()
if len(definition_data) == 1 and 'data' in definition_data:
definition_data = definition_data['data']
payload = {
'definition.data': definition_data,
'metadata': own_metadata(xblock),
......
......@@ -299,7 +299,7 @@ class TestMongoKeyValueStore(object):
assert_false(self.kvs.has(key))
def test_read_non_dict_data(self):
self.kvs._data = 'xml_data'
self.kvs = MongoKeyValueStore('xml_data', self.children, self.metadata)
assert_equals('xml_data', self.kvs.get(KeyValueStore.Key(Scope.content, None, None, 'data')))
def _check_write(self, key, value):
......@@ -312,7 +312,7 @@ class TestMongoKeyValueStore(object):
yield (self._check_write, KeyValueStore.Key(Scope.settings, None, None, 'meta'), 'new_settings')
def test_write_non_dict_data(self):
self.kvs._data = 'xml_data'
self.kvs = MongoKeyValueStore('xml_data', self.children, self.metadata)
self._check_write(KeyValueStore.Key(Scope.content, None, None, 'data'), 'new_data')
def test_write_invalid_scope(self):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment