From 5325ae73f551490d65e5a13901e1f86f379b9bb7 Mon Sep 17 00:00:00 2001 From: Alie Langston Date: Wed, 2 Oct 2024 14:50:05 -0400 Subject: [PATCH] fix: handle case where backend provider no longer exists for timed exams --- CHANGELOG.rst | 5 ++++- edx_proctoring/__init__.py | 2 +- edx_proctoring/api.py | 22 ++++++++++++++++++++-- edx_proctoring/handlers.py | 19 ++++++++++--------- edx_proctoring/tests/test_handlers.py | 2 +- package.json | 2 +- 6 files changed, 37 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 63e991f0bd..a71c474ffe 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -13,6 +13,9 @@ Change Log Unreleased ~~~~~~~~~~ +* fix timed exam bug for provider that no longer exists +* fix timed exam reset bug for provider that no longer exists +* fix instructor dashboard view for provider that no longer exists [4.17.0] ~~~~~~~~~~~~~~~~~~~~~ @@ -20,7 +23,7 @@ Unreleased [4.16.1] - 2023-08-8 ~~~~~~~~~~~~~~~~~~~~~ -* Updated django-simple-history package to 3.3.0 +* Updated django-simple-history package to 3.3.0 * Created no-op migrations needed for new django-simple-history package version [4.16.0] - 2023-06-22 diff --git a/edx_proctoring/__init__.py b/edx_proctoring/__init__.py index f34458f811..f5cb65ad4b 100644 --- a/edx_proctoring/__init__.py +++ b/edx_proctoring/__init__.py @@ -3,4 +3,4 @@ """ # Be sure to update the version number in edx_proctoring/package.json -__version__ = '4.18.1' +__version__ = '4.18.2' diff --git a/edx_proctoring/api.py b/edx_proctoring/api.py index 135e0874e0..507b19fb3a 100644 --- a/edx_proctoring/api.py +++ b/edx_proctoring/api.py @@ -2943,7 +2943,16 @@ def get_student_view(user_id, course_id, content_id, is_proctored_exam = exam['is_proctored'] and not exam['is_practice_exam'] is_timed_exam = not exam['is_proctored'] and not exam['is_practice_exam'] +<<<<<<< HEAD +<<<<<<< HEAD exam_backend = get_backend_provider(name=exam['backend']) +======= + # exam_backend = get_backend_provider(name=exam['backend']) + exam_backend = get_backend_provider(exam=exam) +>>>>>>> 3591678b69 (fix: handle case where backend provider no longer exists for timed exams) +======= + exam_backend = get_backend_provider(exam=exam) +>>>>>>> d2511db8eb (fix: allow timed exams for providers that are no longer valid) sub_view_func = None if is_timed_exam: @@ -3019,8 +3028,17 @@ def is_backend_dashboard_available(course_id): active_only=True ) for exam in exams: - if get_backend_provider(name=exam.backend).has_dashboard: - return True + try: + if get_backend_provider(name=exam.backend).has_dashboard: + return True + except NotImplementedError: + log.exception( + 'No proctoring backend configured for backend=%(backend)s', + { + 'backend': exam.backend, + } + ) + return False diff --git a/edx_proctoring/handlers.py b/edx_proctoring/handlers.py index a9dbdc7fc3..413171a588 100644 --- a/edx_proctoring/handlers.py +++ b/edx_proctoring/handlers.py @@ -127,15 +127,16 @@ def on_attempt_changed(sender, instance, signal, **kwargs): else: # remove the attempt on the backend # timed exams have no backend - backend = get_backend_provider(name=instance.proctored_exam.backend) - if backend: - result = backend.remove_exam_attempt(instance.proctored_exam.external_id, instance.external_id) - if not result: - log.error( - 'Failed to remove attempt_id=%s from backend=%s', - instance.id, - instance.proctored_exam.backend, - ) + if instance.proctored_exam.is_proctored: + backend = get_backend_provider(name=instance.proctored_exam.backend) + if backend: + result = backend.remove_exam_attempt(instance.proctored_exam.external_id, instance.external_id) + if not result: + log.error( + 'Failed to remove attempt_id=%s from backend=%s', + instance.id, + instance.proctored_exam.backend, + ) @receiver(post_delete, sender=models.ProctoredExamStudentAttempt) diff --git a/edx_proctoring/tests/test_handlers.py b/edx_proctoring/tests/test_handlers.py index 70d91458b3..62cf04dbc2 100644 --- a/edx_proctoring/tests/test_handlers.py +++ b/edx_proctoring/tests/test_handlers.py @@ -27,7 +27,7 @@ def setUp(self): self.proctored_exam = ProctoredExam.objects.create( course_id='x/y/z', content_id=self.content_id, exam_name=self.exam_name, time_limit_mins=self.default_time_limit, external_id=self.external_id, - backend=self.backend_name + backend=self.backend_name, is_proctored=True, ) self.attempt = ProctoredExamStudentAttempt.objects.create( proctored_exam=self.proctored_exam, user=self.user, attempt_code='12345', diff --git a/package.json b/package.json index 255bd3e632..56b2bade77 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@edx/edx-proctoring", "//": "Note that the version format is slightly different than that of the Python version when using prereleases.", - "version": "4.18.1", + "version": "4.18.2", "main": "edx_proctoring/static/index.js", "scripts": { "test": "gulp test"