diff --git a/edx_proctoring/signals.py b/edx_proctoring/signals.py index 5d251df54ed..ebe9701d25a 100644 --- a/edx_proctoring/signals.py +++ b/edx_proctoring/signals.py @@ -5,7 +5,7 @@ from edx_proctoring import api from edx_proctoring import constants from edx_proctoring import models -from edx_proctoring.statuses import ProctoredExamStudentAttemptStatus +from edx_proctoring.statuses import ProctoredExamStudentAttemptStatus, SoftwareSecureReviewStatus from edx_proctoring.utils import emit_event, locate_attempt_by_attempt_code from edx_proctoring.backends import get_backend_provider @@ -141,6 +141,8 @@ def finish_review_workflow(sender, instance, signal, **kwargs): # pylint: disab # eligibility table if review.is_passing: attempt_status = ProctoredExamStudentAttemptStatus.verified + elif review.review_status == SoftwareSecureReviewStatus.not_reviewed: + attempt_status = ProctoredExamStudentAttemptStatus.error elif review.reviewed_by or not constants.REQUIRE_FAILURE_SECOND_REVIEWS: # reviews from the django admin have a reviewer set. They should be allowed to # reject an attempt diff --git a/edx_proctoring/tests/test_reviews.py b/edx_proctoring/tests/test_reviews.py index 51f62819b57..73598b2dcb3 100644 --- a/edx_proctoring/tests/test_reviews.py +++ b/edx_proctoring/tests/test_reviews.py @@ -369,6 +369,17 @@ def test_failure_submission_rejected(self): self.assertEqual(attempt['status'], expected_status) self.assertEqual(review.review_status, SoftwareSecureReviewStatus.suspicious) + def test_failure_not_reviewed(self): + """ + Tests that a review which comes back as "not reviewed" + transitions to an error state + """ + test_payload = self.get_review_payload(ReviewStatus.not_reviewed) + ProctoredExamReviewCallback().make_review(self.attempt, test_payload) + + attempt = get_exam_attempt_by_id(self.attempt_id) + self.assertEqual(attempt['status'], ProctoredExamStudentAttemptStatus.error) + def test_update_archived_attempt(self): """ Test calling the interface point with an attempt_code that was archived