Hide After Due setting for Timed Exams

TNL-4366
Changes in studio to allow the hide_after_due setting to be utilized.

Includes:
    -python changes to contentstore, where the data is stored.
    -refactoring of timed-examination-preference-editor.underscore, to add this
        setting and make the editor more accessible.
    -javascript changes to link the new setting to the correct data model.
    -sass updates to fix a11y issues on the editor modal.
    -addition of post-due visibility information to course outline in studio.
    -new tests: python, js, acceptance, and a11y
This commit is contained in:
Eric Fischer
2016-04-21 09:26:22 -04:00
parent ecfd953e80
commit ea77c3ec42
15 changed files with 480 additions and 337 deletions

View File

@@ -83,7 +83,8 @@ def register_special_exams(course_key):
due_date=timed_exam.due,
is_proctored=timed_exam.is_proctored_exam,
is_practice_exam=timed_exam.is_practice_exam,
is_active=True
is_active=True,
hide_after_due=timed_exam.hide_after_due,
)
msg = 'Updated timed exam {exam_id}'.format(exam_id=exam['id'])
log.info(msg)
@@ -97,7 +98,8 @@ def register_special_exams(course_key):
due_date=timed_exam.due,
is_proctored=timed_exam.is_proctored_exam,
is_practice_exam=timed_exam.is_practice_exam,
is_active=True
is_active=True,
hide_after_due=timed_exam.hide_after_due,
)
msg = 'Created new timed exam {exam_id}'.format(exam_id=exam_id)
log.info(msg)

View File

@@ -53,6 +53,10 @@ class TestProctoredExams(ModuleStoreTestCase):
exam_review_policy = get_review_policy_by_exam_id(exam['id'])
self.assertEqual(exam_review_policy['review_policy'], sequence.exam_review_rules)
if not exam['is_proctored'] and not exam['is_practice_exam']:
# the hide after due value only applies to timed exams
self.assertEqual(exam['hide_after_due'], sequence.hide_after_due)
self.assertEqual(exam['course_id'], unicode(self.course.id))
self.assertEqual(exam['content_id'], unicode(sequence.location))
self.assertEqual(exam['exam_name'], sequence.display_name)
@@ -62,13 +66,14 @@ class TestProctoredExams(ModuleStoreTestCase):
self.assertEqual(exam['is_active'], expected_active)
@ddt.data(
(True, 10, True, False, True, False),
(True, 10, False, False, True, False),
(True, 10, True, True, True, True),
(True, 10, True, False, True, False, False),
(True, 10, False, False, True, False, False),
(True, 10, False, False, True, False, True),
(True, 10, True, True, True, True, False),
)
@ddt.unpack
def test_publishing_exam(self, is_time_limited, default_time_limit_minutes,
is_proctored_exam, is_practice_exam, expected_active, republish):
def test_publishing_exam(self, is_time_limited, default_time_limit_minutes, is_proctored_exam,
is_practice_exam, expected_active, republish, hide_after_due):
"""
Happy path testing to see that when a course is published which contains
a proctored exam, it will also put an entry into the exam tables
@@ -85,7 +90,8 @@ class TestProctoredExams(ModuleStoreTestCase):
is_proctored_exam=is_proctored_exam,
is_practice_exam=is_practice_exam,
due=datetime.now(UTC) + timedelta(minutes=default_time_limit_minutes + 1),
exam_review_rules="allow_use_of_paper"
exam_review_rules="allow_use_of_paper",
hide_after_due=hide_after_due,
)
listen_for_course_publish(self, self.course.id)
@@ -117,7 +123,8 @@ class TestProctoredExams(ModuleStoreTestCase):
graded=True,
is_time_limited=True,
default_time_limit_minutes=10,
is_proctored_exam=True
is_proctored_exam=True,
hide_after_due=False,
)
listen_for_course_publish(self, self.course.id)
@@ -147,7 +154,8 @@ class TestProctoredExams(ModuleStoreTestCase):
graded=True,
is_time_limited=True,
default_time_limit_minutes=10,
is_proctored_exam=True
is_proctored_exam=True,
hide_after_due=False,
)
listen_for_course_publish(self, self.course.id)
@@ -182,7 +190,8 @@ class TestProctoredExams(ModuleStoreTestCase):
graded=True,
is_time_limited=True,
default_time_limit_minutes=10,
is_proctored_exam=True
is_proctored_exam=True,
hide_after_due=False,
)
listen_for_course_publish(self, self.course.id)
@@ -218,7 +227,8 @@ class TestProctoredExams(ModuleStoreTestCase):
is_time_limited=True,
default_time_limit_minutes=10,
is_proctored_exam=True,
exam_review_rules="allow_use_of_paper"
exam_review_rules="allow_use_of_paper",
hide_after_due=False,
)
listen_for_course_publish(self, self.course.id)

View File

@@ -935,7 +935,8 @@ def create_xblock_info(xblock, data=None, metadata=None, include_ancestor_info=F
"is_practice_exam": xblock.is_practice_exam,
"is_time_limited": xblock.is_time_limited,
"exam_review_rules": xblock.exam_review_rules,
"default_time_limit_minutes": xblock.default_time_limit_minutes
"default_time_limit_minutes": xblock.default_time_limit_minutes,
"hide_after_due": xblock.hide_after_due,
})
# Update with gating info