Commit c3e7960a by Chris Dodge

when the client app polls, be sure to timeout when time expires

parent 1bb60c89
...@@ -279,6 +279,16 @@ def get_exam_attempt_by_id(attempt_id): ...@@ -279,6 +279,16 @@ def get_exam_attempt_by_id(attempt_id):
return _get_exam_attempt(exam_attempt_obj) return _get_exam_attempt(exam_attempt_obj)
def get_exam_attempt_by_code(attempt_code):
"""
Signals the beginning of an exam attempt when we only have
an attempt code
"""
exam_attempt_obj = ProctoredExamStudentAttempt.objects.get_exam_attempt_by_code(attempt_code)
return _get_exam_attempt(exam_attempt_obj)
def update_exam_attempt(attempt_id, **kwargs): def update_exam_attempt(attempt_id, **kwargs):
""" """
update exam_attempt update exam_attempt
...@@ -297,17 +307,6 @@ def update_exam_attempt(attempt_id, **kwargs): ...@@ -297,17 +307,6 @@ def update_exam_attempt(attempt_id, **kwargs):
exam_attempt_obj.save() exam_attempt_obj.save()
def get_exam_attempt_by_code(attempt_code):
"""
Signals the beginning of an exam attempt when we only have
an attempt code
"""
exam_attempt_obj = ProctoredExamStudentAttempt.objects.get_exam_attempt_by_code(attempt_code)
serialized_attempt_obj = ProctoredExamStudentAttemptSerializer(exam_attempt_obj)
return serialized_attempt_obj.data if exam_attempt_obj else None
def create_exam_attempt(exam_id, user_id, taking_as_proctored=False): def create_exam_attempt(exam_id, user_id, taking_as_proctored=False):
""" """
Creates an exam attempt for user_id against exam_id. There should only be Creates an exam attempt for user_id against exam_id. There should only be
......
...@@ -557,6 +557,68 @@ class TestStudentProctoredExamAttempt(LoggedInTestCase): ...@@ -557,6 +557,68 @@ class TestStudentProctoredExamAttempt(LoggedInTestCase):
response_data = json.loads(response.content) response_data = json.loads(response.content)
self.assertEqual(response_data['status'], 'error') self.assertEqual(response_data['status'], 'error')
def test_attempt_callback_timeout(self):
"""
Ensures that the polling from the client will cause the
server to transition to timed_out if the user runs out of time
"""
# Create an exam.
proctored_exam = ProctoredExam.objects.create(
course_id='a/b/c',
content_id='test_content',
exam_name='Test Exam',
external_id='123aXqe3',
time_limit_mins=90
)
attempt_data = {
'exam_id': proctored_exam.id,
'external_id': proctored_exam.external_id,
'start_clock': True,
}
response = self.client.post(
reverse('edx_proctoring.proctored_exam.attempt.collection'),
attempt_data
)
self.assertEqual(response.status_code, 200)
response_data = json.loads(response.content)
attempt_id = response_data['exam_attempt_id']
self.assertEqual(attempt_id, 1)
response = self.client.get(
reverse('edx_proctoring.proctored_exam.attempt', args=[attempt_id])
)
self.assertEqual(response.status_code, 200)
response_data = json.loads(response.content)
self.assertEqual(response_data['status'], 'started')
attempt_code = response_data['attempt_code']
# test the polling callback point
response = self.client.get(
reverse(
'edx_proctoring.anonymous.proctoring_poll_status',
args=[attempt_code]
)
)
self.assertEqual(response.status_code, 200)
response_data = json.loads(response.content)
self.assertEqual(response_data['status'], 'started')
# set time to be in future
reset_time = datetime.now(pytz.UTC) + timedelta(minutes=180)
with freeze_time(reset_time):
# Now the callback should transition us away from started
response = self.client.get(
reverse(
'edx_proctoring.anonymous.proctoring_poll_status',
args=[attempt_code]
)
)
self.assertEqual(response.status_code, 200)
response_data = json.loads(response.content)
self.assertEqual(response_data['status'], 'submitted')
def test_remove_attempt(self): def test_remove_attempt(self):
""" """
Confirms that an attempt can be removed Confirms that an attempt can be removed
......
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