Commit c10e11e9 by Douglas Hall

Merge pull request #261 from edx/release

Merging 0.12.5 release to master
parents 257f7329 174f651d
...@@ -1563,7 +1563,8 @@ def _get_practice_exam_view(exam, context, exam_id, user_id, course_id): ...@@ -1563,7 +1563,8 @@ def _get_practice_exam_view(exam, context, exam_id, user_id, course_id):
elif attempt_status == ProctoredExamStudentAttemptStatus.started: elif attempt_status == ProctoredExamStudentAttemptStatus.started:
# when we're taking the exam we should not override the view # when we're taking the exam we should not override the view
return None return None
elif attempt_status == ProctoredExamStudentAttemptStatus.created: elif attempt_status in [ProctoredExamStudentAttemptStatus.created,
ProctoredExamStudentAttemptStatus.download_software_clicked]:
provider = get_backend_provider() provider = get_backend_provider()
student_view_template = 'proctored_exam/instructions.html' student_view_template = 'proctored_exam/instructions.html'
context.update({ context.update({
......
...@@ -18,11 +18,11 @@ from rest_framework.negotiation import BaseContentNegotiation ...@@ -18,11 +18,11 @@ from rest_framework.negotiation import BaseContentNegotiation
from edx_proctoring.api import ( from edx_proctoring.api import (
get_exam_attempt_by_code, get_exam_attempt_by_code,
mark_exam_attempt_as_ready, mark_exam_attempt_as_ready,
update_exam_attempt) update_exam_attempt
)
from edx_proctoring.exceptions import ProctoredBaseException
from edx_proctoring.backends import get_backend_provider from edx_proctoring.backends import get_backend_provider
from edx_proctoring.exceptions import ProctoredBaseException
from edx_proctoring.models import ProctoredExamStudentAttemptStatus
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
...@@ -48,7 +48,8 @@ def start_exam_callback(request, attempt_code): # pylint: disable=unused-argume ...@@ -48,7 +48,8 @@ def start_exam_callback(request, attempt_code): # pylint: disable=unused-argume
status=404 status=404
) )
if attempt['status'] == "created": if attempt['status'] in [ProctoredExamStudentAttemptStatus.created,
ProctoredExamStudentAttemptStatus.download_software_clicked]:
mark_exam_attempt_as_ready(attempt['proctored_exam']['id'], attempt['user']['id']) mark_exam_attempt_as_ready(attempt['proctored_exam']['id'], attempt['user']['id'])
template = loader.get_template('proctored_exam/proctoring_launch_callback.html') template = loader.get_template('proctored_exam/proctoring_launch_callback.html')
......
...@@ -1625,12 +1625,16 @@ class ProctoredExamApiTests(LoggedInTestCase): ...@@ -1625,12 +1625,16 @@ class ProctoredExamApiTests(LoggedInTestCase):
) )
self.assertIn(self.practice_exam_submitted_msg, rendered_response) self.assertIn(self.practice_exam_submitted_msg, rendered_response)
def test_get_studentview_created_status_practiceexam(self): @ddt.data(
ProctoredExamStudentAttemptStatus.created,
ProctoredExamStudentAttemptStatus.download_software_clicked,
)
def test_get_studentview_created_status_practiceexam(self, status):
""" """
Test for get_student_view practice exam which has been created. Test for get_student_view practice exam which has been created.
""" """
exam_attempt = self._create_started_practice_exam_attempt() exam_attempt = self._create_started_practice_exam_attempt()
exam_attempt.status = ProctoredExamStudentAttemptStatus.created exam_attempt.status = status
exam_attempt.save() exam_attempt.save()
rendered_response = get_student_view( rendered_response = get_student_view(
......
...@@ -441,6 +441,56 @@ class TestStudentProctoredExamAttempt(LoggedInTestCase): ...@@ -441,6 +441,56 @@ class TestStudentProctoredExamAttempt(LoggedInTestCase):
return ProctoredExamStudentAttempt.objects.get_exam_attempt(proctored_exam.id, self.user.id) return ProctoredExamStudentAttempt.objects.get_exam_attempt(proctored_exam.id, self.user.id)
def _test_exam_attempt_creation(self):
"""
Create proctored exam and exam attempt and verify the status of the attempt is "created"
"""
# 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,
is_proctored=True
)
attempt_id = create_exam_attempt(proctored_exam.id, self.user.id)
attempt = get_exam_attempt_by_id(attempt_id)
self.assertEqual(attempt['status'], "created")
return attempt
def _test_repeated_start_exam_callbacks(self, attempt):
"""
Given an exam attempt, call the start exam callback twice to verify
that the status in not incorrectly reverted
"""
# hit callback and verify that exam status is 'ready to start'
attempt_id = attempt['id']
code = attempt['attempt_code']
self.client.get(
reverse('edx_proctoring.anonymous.proctoring_launch_callback.start_exam', kwargs={'attempt_code': code})
)
attempt = get_exam_attempt_by_id(attempt_id)
self.assertEqual(attempt['status'], "ready_to_start")
# update exam status to 'started'
exam_id = attempt['proctored_exam']['id']
user_id = attempt['user']['id']
update_attempt_status(exam_id, user_id, ProctoredExamStudentAttemptStatus.started)
attempt = get_exam_attempt_by_id(attempt_id)
self.assertEqual(attempt['status'], "started")
# hit callback again and verify that status is still 'started' and not 'ready to start'
self.client.get(
reverse('edx_proctoring.anonymous.proctoring_launch_callback.start_exam', kwargs={'attempt_code': code})
)
attempt = get_exam_attempt_by_id(attempt_id)
self.assertEqual(attempt['status'], "started")
self.assertFalse(attempt['status'] == "ready_to_start")
def test_start_exam_create(self): def test_start_exam_create(self):
""" """
Start an exam (create an exam attempt) Start an exam (create an exam attempt)
...@@ -515,46 +565,28 @@ class TestStudentProctoredExamAttempt(LoggedInTestCase): ...@@ -515,46 +565,28 @@ class TestStudentProctoredExamAttempt(LoggedInTestCase):
attempt = get_exam_attempt_by_id(old_attempt_id) attempt = get_exam_attempt_by_id(old_attempt_id)
self.assertIsNotNone(attempt['started_at']) self.assertIsNotNone(attempt['started_at'])
def test_start_exam_callback(self): def test_start_exam_callback_when_created(self):
""" """
Test that hitting software secure callback URL twice does not change the state Test that hitting software secure callback URL twice when the attempt state begins at
from 'started' back to 'ready to start' 'created' does not change the state from 'started' back to 'ready to start'
""" """
# Create an exam. attempt = self._test_exam_attempt_creation()
proctored_exam = ProctoredExam.objects.create( self._test_repeated_start_exam_callbacks(attempt)
course_id='a/b/c',
content_id='test_content',
exam_name='Test Exam',
external_id='123aXqe3',
time_limit_mins=90,
is_proctored=True
)
attempt_id = create_exam_attempt(proctored_exam.id, self.user.id)
attempt = get_exam_attempt_by_id(attempt_id)
self.assertEqual(attempt['status'], "created")
# hit callback and verify that exam status is 'ready to start' def test_start_exam_callback_when_download_software_clicked(self):
code = attempt['attempt_code'] """
self.client.get( Test that hitting software secure callback URL twice when the attempt state begins at
reverse('edx_proctoring.anonymous.proctoring_launch_callback.start_exam', kwargs={'attempt_code': code}) 'download_software_clicked' does not change the state from 'started' back to 'ready to start'
) """
attempt = get_exam_attempt_by_id(attempt_id) # Create an exam.
self.assertEqual(attempt['status'], "ready_to_start") attempt = self._test_exam_attempt_creation()
# update exam status to 'started' # Update attempt status to 'download_software_clicked'
exam_id = attempt['proctored_exam']['id'] exam_id = attempt['proctored_exam']['id']
user_id = attempt['user']['id'] user_id = attempt['user']['id']
update_attempt_status(exam_id, user_id, ProctoredExamStudentAttemptStatus.started) update_attempt_status(exam_id, user_id, ProctoredExamStudentAttemptStatus.download_software_clicked)
attempt = get_exam_attempt_by_id(attempt_id)
self.assertEqual(attempt['status'], "started")
# hit callback again and verify that status is still 'started' and not 'ready to start' self._test_repeated_start_exam_callbacks(attempt)
self.client.get(
reverse('edx_proctoring.anonymous.proctoring_launch_callback.start_exam', kwargs={'attempt_code': code})
)
attempt = get_exam_attempt_by_id(attempt_id)
self.assertEqual(attempt['status'], "started")
self.assertFalse(attempt['status'] == "ready_to_start")
def test_attempt_readback(self): def test_attempt_readback(self):
""" """
......
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