Commit 39c71d9f by Diana Huang Committed by GitHub

Merge pull request #334 from edx/diana/use-correct-completion-date

Use expire time for timeouts instead of now.
parents 9d5acea4 a3415c8b
...@@ -391,7 +391,8 @@ def _check_for_attempt_timeout(attempt): ...@@ -391,7 +391,8 @@ def _check_for_attempt_timeout(attempt):
update_attempt_status( update_attempt_status(
attempt['proctored_exam']['id'], attempt['proctored_exam']['id'],
attempt['user']['id'], attempt['user']['id'],
ProctoredExamStudentAttemptStatus.timed_out ProctoredExamStudentAttemptStatus.timed_out,
timeout_timestamp=expires_at
) )
attempt = get_exam_attempt_by_id(attempt['id']) attempt = get_exam_attempt_by_id(attempt['id'])
...@@ -715,7 +716,8 @@ def mark_exam_attempt_as_ready(exam_id, user_id): ...@@ -715,7 +716,8 @@ def mark_exam_attempt_as_ready(exam_id, user_id):
return update_attempt_status(exam_id, user_id, ProctoredExamStudentAttemptStatus.ready_to_start) return update_attempt_status(exam_id, user_id, ProctoredExamStudentAttemptStatus.ready_to_start)
def update_attempt_status(exam_id, user_id, to_status, raise_if_not_found=True, cascade_effects=True): def update_attempt_status(exam_id, user_id, to_status,
raise_if_not_found=True, cascade_effects=True, timeout_timestamp=None):
""" """
Internal helper to handle state transitions of attempt status Internal helper to handle state transitions of attempt status
""" """
...@@ -730,11 +732,11 @@ def update_attempt_status(exam_id, user_id, to_status, raise_if_not_found=True, ...@@ -730,11 +732,11 @@ def update_attempt_status(exam_id, user_id, to_status, raise_if_not_found=True,
# In some configuration we may treat timeouts the same # In some configuration we may treat timeouts the same
# as the user saying he/she wises to submit the exam # as the user saying he/she wises to submit the exam
alias_timeout = ( treat_timeout_as_submitted = (
to_status == ProctoredExamStudentAttemptStatus.timed_out and to_status == ProctoredExamStudentAttemptStatus.timed_out and
not settings.PROCTORING_SETTINGS.get('ALLOW_TIMED_OUT_STATE', False) not settings.PROCTORING_SETTINGS.get('ALLOW_TIMED_OUT_STATE', False)
) )
if alias_timeout: if treat_timeout_as_submitted:
to_status = ProctoredExamStudentAttemptStatus.submitted to_status = ProctoredExamStudentAttemptStatus.submitted
exam_attempt_obj = ProctoredExamStudentAttempt.objects.get_exam_attempt(exam_id, user_id) exam_attempt_obj = ProctoredExamStudentAttempt.objects.get_exam_attempt(exam_id, user_id)
...@@ -792,6 +794,8 @@ def update_attempt_status(exam_id, user_id, to_status, raise_if_not_found=True, ...@@ -792,6 +794,8 @@ def update_attempt_status(exam_id, user_id, to_status, raise_if_not_found=True,
) )
if add_start_time: if add_start_time:
exam_attempt_obj.started_at = datetime.now(pytz.UTC) exam_attempt_obj.started_at = datetime.now(pytz.UTC)
elif treat_timeout_as_submitted:
exam_attempt_obj.completed_at = timeout_timestamp
elif to_status == ProctoredExamStudentAttemptStatus.submitted: elif to_status == ProctoredExamStudentAttemptStatus.submitted:
# likewise, when we transition to submitted mark # likewise, when we transition to submitted mark
# when the exam has been completed # when the exam has been completed
......
...@@ -943,17 +943,19 @@ class ProctoredExamApiTests(ProctoredExamTestCase): ...@@ -943,17 +943,19 @@ class ProctoredExamApiTests(ProctoredExamTestCase):
to_status to_status
) )
def test_alias_timed_out(self): def test_time_out_as_submitted(self):
""" """
Verified that timed_out will automatically state transition Verified that timed_out will automatically state transition
to submitted to submitted
""" """
exam_attempt = self._create_started_exam_attempt() exam_attempt = self._create_started_exam_attempt()
random_timestamp = datetime.now(pytz.UTC) - timedelta(hours=4)
update_attempt_status( update_attempt_status(
exam_attempt.proctored_exam_id, exam_attempt.proctored_exam_id,
self.user.id, self.user.id,
ProctoredExamStudentAttemptStatus.timed_out ProctoredExamStudentAttemptStatus.timed_out,
timeout_timestamp=random_timestamp
) )
exam_attempt = get_exam_attempt_by_id(exam_attempt.id) exam_attempt = get_exam_attempt_by_id(exam_attempt.id)
...@@ -963,6 +965,37 @@ class ProctoredExamApiTests(ProctoredExamTestCase): ...@@ -963,6 +965,37 @@ class ProctoredExamApiTests(ProctoredExamTestCase):
ProctoredExamStudentAttemptStatus.submitted ProctoredExamStudentAttemptStatus.submitted
) )
self.assertEqual(
exam_attempt['completed_at'],
random_timestamp
)
@patch.dict('django.conf.settings.PROCTORING_SETTINGS', {'ALLOW_TIMED_OUT_STATE': True})
def test_timeout_not_submitted(self):
"""
Test that when the setting is disabled, the status remains timed_out
"""
exam_attempt = self._create_started_exam_attempt()
random_timestamp = datetime.now(pytz.UTC) - timedelta(hours=4)
update_attempt_status(
exam_attempt.proctored_exam_id,
self.user.id,
ProctoredExamStudentAttemptStatus.timed_out,
timeout_timestamp=random_timestamp
)
exam_attempt = get_exam_attempt_by_id(exam_attempt.id)
self.assertEqual(
exam_attempt['status'],
ProctoredExamStudentAttemptStatus.timed_out
)
self.assertNotEqual(
exam_attempt['completed_at'],
random_timestamp
)
def test_update_unexisting_attempt(self): def test_update_unexisting_attempt(self):
""" """
Tests updating an non-existing attempt Tests updating an non-existing attempt
......
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