Commit 449fcc1f by chrisndodge

Merge pull request #41 from edx/cdodge/make-ssiRecordLocator-compare-case-insensitive

treat the ssiExamLocator as potentially case insensitive, since I've …
parents 76e8bd48 2cfccdf6
...@@ -152,7 +152,10 @@ class SoftwareSecureBackendProvider(ProctoringBackendProvider): ...@@ -152,7 +152,10 @@ class SoftwareSecureBackendProvider(ProctoringBackendProvider):
raise StudentExamAttemptDoesNotExistsException(err_msg) raise StudentExamAttemptDoesNotExistsException(err_msg)
# then make sure we have the right external_id # then make sure we have the right external_id
if attempt_obj.external_id != external_id: # note that SoftwareSecure might send a case insensitive
# ssiRecordLocator than what it returned when we registered the
# exam
if attempt_obj.external_id.lower() != external_id.lower():
err_msg = ( err_msg = (
'Found attempt_code {attempt_code}, but the recorded external_id did not ' 'Found attempt_code {attempt_code}, but the recorded external_id did not '
'match the ssiRecordLocator that had been recorded previously. Has {existing} ' 'match the ssiRecordLocator that had been recorded previously. Has {existing} '
......
...@@ -18,6 +18,8 @@ from edx_proctoring.api import ( ...@@ -18,6 +18,8 @@ from edx_proctoring.api import (
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
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
...@@ -77,7 +79,15 @@ class ExamReviewCallback(APIView): ...@@ -77,7 +79,15 @@ class ExamReviewCallback(APIView):
provider = get_backend_provider() provider = get_backend_provider()
# call down into the underlying provider code # call down into the underlying provider code
provider.on_review_callback(request.DATA) try:
provider.on_review_callback(request.DATA)
except ProctoredBaseException, ex:
return Response(
data={
'reason': unicode(ex)
},
status=400
)
return Response( return Response(
data='OK', data='OK',
......
...@@ -1004,6 +1004,80 @@ class TestStudentProctoredExamAttempt(LoggedInTestCase): ...@@ -1004,6 +1004,80 @@ class TestStudentProctoredExamAttempt(LoggedInTestCase):
) )
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
def test_review_caseinsensitive(self):
"""
Simulates a callback from the proctoring service with the
review data
"""
exam_id = create_exam(
course_id='foo/bar/baz',
content_id='content',
exam_name='Sample Exam',
time_limit_mins=10,
is_proctored=True
)
# be sure to use the mocked out SoftwareSecure handlers
with HTTMock(mock_response_content):
attempt_id = create_exam_attempt(
exam_id,
self.user.id,
taking_as_proctored=True
)
attempt = get_exam_attempt_by_id(attempt_id)
self.assertIsNotNone(attempt['external_id'])
test_payload = Template(TEST_REVIEW_PAYLOAD).substitute(
attempt_code=attempt['attempt_code'],
external_id=attempt['external_id'].upper()
)
response = self.client.post(
reverse('edx_proctoring.anonymous.proctoring_review_callback'),
data=test_payload,
content_type='application/json'
)
self.assertEqual(response.status_code, 200)
def test_review_mismatch(self):
"""
Simulates a callback from the proctoring service with the
review data but the external_ids don't match
"""
exam_id = create_exam(
course_id='foo/bar/baz',
content_id='content',
exam_name='Sample Exam',
time_limit_mins=10,
is_proctored=True
)
# be sure to use the mocked out SoftwareSecure handlers
with HTTMock(mock_response_content):
attempt_id = create_exam_attempt(
exam_id,
self.user.id,
taking_as_proctored=True
)
attempt = get_exam_attempt_by_id(attempt_id)
self.assertIsNotNone(attempt['external_id'])
test_payload = Template(TEST_REVIEW_PAYLOAD).substitute(
attempt_code=attempt['attempt_code'],
external_id='mismatch'
)
response = self.client.post(
reverse('edx_proctoring.anonymous.proctoring_review_callback'),
data=test_payload,
content_type='application/json'
)
self.assertEqual(response.status_code, 400)
def test_review_callback_get(self): def test_review_callback_get(self):
""" """
We don't support any http METHOD other than GET We don't support any http METHOD other than GET
......
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