Commit 5088ae30 by Adam Palay

when removing field from _field_data_cache when rebinding a module to a new…

when removing field from _field_data_cache when rebinding a module to a new user, also remove it from _dirty_fields (TNL-2640)
parent 213dc70d
......@@ -587,6 +587,12 @@ class XModuleMixin(XModuleFields, XBlock):
if field.scope.user == UserScope.ONE:
field._del_cached_value(self) # pylint: disable=protected-access
# not the most elegant way of doing this, but if we're removing
# a field from the module's field_data_cache, we should also
# remove it from its _dirty_fields
# pylint: disable=protected-access
if field in self._dirty_fields:
del self._dirty_fields[field]
# Set the new xmodule_runtime and field_data (which are user-specific)
self.xmodule_runtime = xmodule_runtime
......
......@@ -1360,23 +1360,44 @@ class TestRebindModule(TestSubmittingProblems):
super(TestRebindModule, self).setUp()
self.homework = self.add_graded_section_to_course('homework')
self.lti = ItemFactory.create(category='lti', parent=self.homework)
self.problem = ItemFactory.create(category='problem', parent=self.homework)
self.user = UserFactory.create()
self.anon_user = AnonymousUser()
def get_module_for_user(self, user):
def get_module_for_user(self, user, item=None):
"""Helper function to get useful module at self.location in self.course_id for user"""
mock_request = MagicMock()
mock_request.user = user
field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
self.course.id, user, self.course, depth=2)
if item is None:
item = self.lti
return render.get_module( # pylint: disable=protected-access
user,
mock_request,
self.lti.location,
item.location,
field_data_cache,
)._xmodule
def test_rebind_module_to_new_users(self):
module = self.get_module_for_user(self.user, self.problem)
# Bind the module to another student, which will remove "correct_map"
# from the module's _field_data_cache and _dirty_fields.
user2 = UserFactory.create()
module.descriptor.bind_for_student(module.system, user2.id)
# XBlock's save method assumes that if a field is in _dirty_fields,
# then it's also in _field_data_cache. If this assumption
# doesn't hold, then we get an error trying to bind this module
# to a third student, since we've removed "correct_map" from
# _field_data cache, but not _dirty_fields, when we bound
# this module to the second student. (TNL-2640)
user3 = UserFactory.create()
module.descriptor.bind_for_student(module.system, user3.id)
def test_rebind_noauth_module_to_user_not_anonymous(self):
"""
Tests that an exception is thrown when rebind_noauth_module_to_user is run from a
......
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