Skip to content

Commit

Permalink
Update the backend when an exam switches from proctored to timed
Browse files Browse the repository at this point in the history
  • Loading branch information
Dave St.Germain committed Jan 3, 2019
1 parent 0a8669a commit 6a60af4
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 4 deletions.
26 changes: 22 additions & 4 deletions edx_proctoring/signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,27 @@
from edx_proctoring.backends import get_backend_provider


@receiver(pre_save, sender=models.ProctoredExam)
def check_for_category_switch(sender, instance, **kwargs): # pylint: disable=unused-argument
"""
If the exam switches from proctored to timed, notify the backend
"""
if instance.id:
original = sender.objects.get(pk=instance.id)
if original.is_proctored and instance.is_proctored != original.is_proctored:
from edx_proctoring.serializers import ProctoredExamSerializer
exam = ProctoredExamSerializer(instance).data
exam['is_active'] = False
exam['is_proctored'] = True
# we have to pretend that the exam is still proctored
# or else we get_backend_provider will return None
backend = get_backend_provider(exam)
backend.on_exam_saved(exam)


@receiver(post_save, sender=models.ProctoredExamReviewPolicy)
@receiver(post_save, sender=models.ProctoredExam)
def _save_exam_on_backend(sender, instance, **kwargs): # pylint: disable=unused-argument
def save_exam_on_backend(sender, instance, **kwargs): # pylint: disable=unused-argument
"""
Save the exam to the backend provider when our model changes.
It also combines the review policy into the exam when saving to the backend
Expand Down Expand Up @@ -49,7 +67,7 @@ def on_review_policy_changed(sender, instance, signal, **kwargs): # pylint: dis
# Hook up the post_save signal to record creations in the ProctoredExamStudentAllowanceHistory table.
@receiver(pre_save, sender=models.ProctoredExamStudentAllowance)
@receiver(pre_delete, sender=models.ProctoredExamStudentAllowance)
def on_allowance_saved(sender, instance, signal, **kwargs): # pylint: disable=unused-argument
def on_allowance_changed(sender, instance, signal, **kwargs): # pylint: disable=unused-argument
"""
Archiving all changes made to the Student Allowance.
Will only archive on update/delete, and not on new entries created.
Expand All @@ -65,7 +83,7 @@ def on_allowance_saved(sender, instance, signal, **kwargs): # pylint: disable=u

@receiver(pre_save, sender=models.ProctoredExamStudentAttempt)
@receiver(pre_delete, sender=models.ProctoredExamStudentAttempt)
def on_attempt_updated(sender, instance, signal, **kwargs): # pylint: disable=unused-argument
def on_attempt_changed(sender, instance, signal, **kwargs): # pylint: disable=unused-argument
"""
Archive the exam attempt whenever the attempt status is about to be
modified. Make a new entry with the previous value of the status in the
Expand All @@ -91,7 +109,7 @@ def on_attempt_updated(sender, instance, signal, **kwargs): # pylint: disable=u
# Hook up the signals to record updates/deletions in the ProctoredExamStudentAllowanceHistory table.
@receiver(pre_save, sender=models.ProctoredExamSoftwareSecureReview)
@receiver(pre_delete, sender=models.ProctoredExamSoftwareSecureReview)
def on_review_saved(sender, instance, signal, **kwargs): # pylint: disable=unused-argument
def on_review_changed(sender, instance, signal, **kwargs): # pylint: disable=unused-argument
"""
Archiving all changes made to the Review.
Will only archive on update/delete, and not on new entries created.
Expand Down
10 changes: 10 additions & 0 deletions edx_proctoring/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,16 @@ def test_update_timed_exam(self):

self.assertEqual(update_timed_exam.hide_after_due, True)

def test_switch_from_proctored_to_timed(self):
"""
Test that switches an exam from proctored to timed.
The backend should be notified that the exam is inactive
"""
proctored_exam = get_exam_by_id(self.proctored_exam_id)
update_exam(self.proctored_exam_id, is_proctored=False)
backend = get_backend_provider(proctored_exam)
self.assertEqual(backend.last_exam['is_active'], False)

def test_update_non_existing_exam(self):
"""
test to update the non-existing proctored exam
Expand Down

0 comments on commit 6a60af4

Please sign in to comment.