Commit 700504c5 by Chris Rossi

Fix a bug in Individual Due Date Extensions (IDDE).

The IDDE implementation relied on a StudentModule being created for a
particular block in order to set the extended due date on that block.
Since StudentModules seem to be created on demand whenever data is
written to an attribute with Scope.user_state, it meant that if a
homework problem hadn't yet been touched by a student it was possible
that the due date extension wouldn't take effect for that problem, even
if the due date extension was successfully set for the parent unit.

This patch fixes this problem by creating new StudentModules as
necessary in order to make sure extended due dates propogate properly to
all problems in a unit.
parent d1891542
...@@ -199,11 +199,18 @@ class TestSetDueDateExtension(ModuleStoreTestCase): ...@@ -199,11 +199,18 @@ class TestSetDueDateExtension(ModuleStoreTestCase):
def test_set_due_date_extension(self): def test_set_due_date_extension(self):
extended = datetime.datetime(2013, 12, 25, 0, 0, tzinfo=utc) extended = datetime.datetime(2013, 12, 25, 0, 0, tzinfo=utc)
tools.set_due_date_extension(self.course, self.week1, self.user, tools.set_due_date_extension(self.course, self.week1, self.user, extended)
extended)
self.assertEqual(self.extended_due(self.week1), extended) self.assertEqual(self.extended_due(self.week1), extended)
self.assertEqual(self.extended_due(self.homework), extended) self.assertEqual(self.extended_due(self.homework), extended)
def test_set_due_date_extension_create_studentmodule(self):
extended = datetime.datetime(2013, 12, 25, 0, 0, tzinfo=utc)
user = UserFactory.create() # No student modules for this user
tools.set_due_date_extension(self.course, self.week1, user, extended)
extended_due = functools.partial(get_extended_due, self.course, student=user)
self.assertEqual(extended_due(self.week1), extended)
self.assertEqual(extended_due(self.homework), extended)
def test_reset_due_date_extension(self): def test_reset_due_date_extension(self):
tools.set_due_date_extension(self.course, self.week1, self.user, None) tools.set_due_date_extension(self.course, self.week1, self.user, None)
self.assertEqual(self.extended_due(self.week1), None) self.assertEqual(self.extended_due(self.week1), None)
......
...@@ -173,13 +173,30 @@ def set_due_date_extension(course, unit, student, due_date): ...@@ -173,13 +173,30 @@ def set_due_date_extension(course, unit, student, due_date):
course_id=course.id, course_id=course.id,
module_state_key=node.location module_state_key=node.location
) )
state = json.loads(student_module.state) state = json.loads(student_module.state)
state['extended_due'] = DATE_FIELD.to_json(due_date)
student_module.state = json.dumps(state)
student_module.save()
except StudentModule.DoesNotExist: except StudentModule.DoesNotExist:
pass # Normally, a StudentModule is created as a side effect of assigning
# a value to a property in an XModule or XBlock which has a scope
# of 'Scope.user_state'. Here, we want to alter user state but
# can't use the standard XModule/XBlock machinery to do so, because
# it fails to take into account that the state being altered might
# belong to a student other than the one currently logged in. As a
# result, in our work around, we need to detect whether the
# StudentModule has been created for the given student on the given
# unit and create it if it is missing, so we can use it to store
# the extended due date.
student_module = StudentModule.objects.create(
student_id=student.id,
course_id=course.id,
module_state_key=node.location,
module_type=node.category
)
state = {}
state['extended_due'] = DATE_FIELD.to_json(due_date)
student_module.state = json.dumps(state)
student_module.save()
for child in node.get_children(): for child in node.get_children():
set_due_date(child) set_due_date(child)
......
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