Fix sequence navigation issues for CCX courses
MA-2258
This commit is contained in:
@@ -38,6 +38,11 @@ new_contract('XBlock', XBlock)
|
||||
LIBRARY_ROOT = 'library.xml'
|
||||
COURSE_ROOT = 'course.xml'
|
||||
|
||||
# List of names of computed fields on xmodules that are of type usage keys.
|
||||
# This list can be used to determine which fields need to be stripped of
|
||||
# extraneous usage key data when entering/exiting modulestores.
|
||||
XMODULE_FIELDS_WITH_USAGE_KEYS = ['location', 'parent']
|
||||
|
||||
|
||||
class ModuleStoreEnum(object):
|
||||
"""
|
||||
|
||||
@@ -17,8 +17,7 @@ from opaque_keys.edx.locator import LibraryLocator
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
from xmodule.assetstore import AssetMetadata
|
||||
|
||||
from . import ModuleStoreWriteBase
|
||||
from . import ModuleStoreEnum
|
||||
from . import ModuleStoreWriteBase, ModuleStoreEnum, XMODULE_FIELDS_WITH_USAGE_KEYS
|
||||
from .exceptions import ItemNotFoundError, DuplicateCourseError
|
||||
from .draft_and_published import ModuleStoreDraftAndPublished
|
||||
from .split_migrator import SplitMigrator
|
||||
@@ -67,8 +66,9 @@ def strip_key(func):
|
||||
retval = retval.version_agnostic()
|
||||
if rem_branch and hasattr(retval, 'for_branch'):
|
||||
retval = retval.for_branch(None)
|
||||
if hasattr(retval, 'location'):
|
||||
retval.location = strip_key_func(retval.location)
|
||||
for field_name in XMODULE_FIELDS_WITH_USAGE_KEYS:
|
||||
if hasattr(retval, field_name):
|
||||
setattr(retval, field_name, strip_key_func(getattr(retval, field_name)))
|
||||
return retval
|
||||
|
||||
# function for stripping both, collection of, and individual, values
|
||||
|
||||
@@ -127,6 +127,8 @@ class MongoKeyValueStore(InheritanceKeyValueStore):
|
||||
def set(self, key, value):
|
||||
if key.scope == Scope.children:
|
||||
self._children = value
|
||||
elif key.scope == Scope.parent:
|
||||
self._parent = value
|
||||
elif key.scope == Scope.settings:
|
||||
self._metadata[key.field_name] = value
|
||||
elif key.scope == Scope.content:
|
||||
|
||||
@@ -767,15 +767,15 @@ class TestMongoKeyValueStore(unittest.TestCase):
|
||||
def test_write(self):
|
||||
yield (self._check_write, KeyValueStore.Key(Scope.content, None, None, 'foo'), 'new_data')
|
||||
yield (self._check_write, KeyValueStore.Key(Scope.children, None, None, 'children'), [])
|
||||
yield (self._check_write, KeyValueStore.Key(Scope.children, None, None, 'parent'), None)
|
||||
yield (self._check_write, KeyValueStore.Key(Scope.settings, None, None, 'meta'), 'new_settings')
|
||||
# write Scope.parent raises InvalidScope, which is covered in test_write_invalid_scope
|
||||
|
||||
def test_write_non_dict_data(self):
|
||||
self.kvs = MongoKeyValueStore('xml_data', self.parent, self.children, self.metadata)
|
||||
self._check_write(KeyValueStore.Key(Scope.content, None, None, 'data'), 'new_data')
|
||||
|
||||
def test_write_invalid_scope(self):
|
||||
for scope in (Scope.preferences, Scope.user_info, Scope.user_state, Scope.parent):
|
||||
for scope in (Scope.preferences, Scope.user_info, Scope.user_state):
|
||||
with assert_raises(InvalidScopeError):
|
||||
self.kvs.set(KeyValueStore.Key(scope, None, None, 'foo'), 'new_value')
|
||||
|
||||
|
||||
Reference in New Issue
Block a user