Commit 760027bd by Calen Pennington

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
......@@ -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):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment