From a19cc377e6b8d15a5e04418c7ece7a806c77c311 Mon Sep 17 00:00:00 2001 From: Matt Hughes Date: Tue, 22 Jan 2019 09:40:14 -0500 Subject: [PATCH] Revert "block starting session while one session is 'started' status" This reverts commit c8a09cef836436647d829f23d76c32d7270003a9. --- edx_proctoring/api.py | 203 +++++++----------- .../other_exam_in_progress.html | 15 -- edx_proctoring/tests/test_student_view.py | 53 ----- 3 files changed, 77 insertions(+), 194 deletions(-) delete mode 100644 edx_proctoring/templates/proctored_exam/other_exam_in_progress.html diff --git a/edx_proctoring/api.py b/edx_proctoring/api.py index 1dcb4bd62c1..5a2382737a6 100644 --- a/edx_proctoring/api.py +++ b/edx_proctoring/api.py @@ -1246,8 +1246,8 @@ def get_last_exam_completion_date(course_id, username): def get_active_exams_for_user(user_id, course_id=None): """ This method will return a list of active exams for the user, - i.e. started_at != None and completed_at == None. There will only - be one. + i.e. started_at != None and completed_at == None. Theoretically there + could be more than one, but in practice it will be one active exam. If course_id is set, then attempts only for an exam in that course_id should be returned. @@ -1610,12 +1610,7 @@ def _get_timed_exam_view(exam, context, exam_id, user_id, course_id): if has_due_date_passed(exam['due_date']): student_view_template = 'timed_exam/expired.html' else: - is_other_exam, other_exam_url = _get_running_exam_info(user_id, exam_id) - if is_other_exam: - context.update({'exam_url': other_exam_url}) - student_view_template = 'proctored_exam/other_exam_in_progress.html' - else: - student_view_template = 'timed_exam/entrance.html' + student_view_template = 'timed_exam/entrance.html' elif attempt_status == ProctoredExamStudentAttemptStatus.started: # when we're taking the exam we should not override the view return None @@ -1777,28 +1772,16 @@ def _get_practice_exam_view(exam, context, exam_id, user_id, course_id): attempt_status = attempt['status'] if attempt else None - if attempt_status == ProctoredExamStudentAttemptStatus.started: + if not attempt_status: + student_view_template = 'practice_exam/entrance.html' + elif attempt_status == ProctoredExamStudentAttemptStatus.started: # when we're taking the exam we should not override the view return None - elif not attempt_status or attempt_status in [ - ProctoredExamStudentAttemptStatus.created, - ProctoredExamStudentAttemptStatus.download_software_clicked, - ProctoredExamStudentAttemptStatus.ready_to_start, - ]: - is_other_exam, other_exam_url = _get_running_exam_info(user_id, exam_id) - if is_other_exam: - context.update({'exam_url': other_exam_url}) - student_view_template = 'proctored_exam/other_exam_in_progress.html' - elif not attempt_status: - student_view_template = 'practice_exam/entrance.html' - elif attempt_status in [ - ProctoredExamStudentAttemptStatus.created, - ProctoredExamStudentAttemptStatus.download_software_clicked, - ]: - student_view_template = 'proctored_exam/instructions.html' - else: - # note: then the status must be ready_to_start - student_view_template = 'proctored_exam/ready_to_start.html' + elif attempt_status in [ProctoredExamStudentAttemptStatus.created, + ProctoredExamStudentAttemptStatus.download_software_clicked]: + student_view_template = 'proctored_exam/instructions.html' + elif attempt_status == ProctoredExamStudentAttemptStatus.ready_to_start: + student_view_template = 'proctored_exam/ready_to_start.html' elif attempt_status == ProctoredExamStudentAttemptStatus.error: student_view_template = 'practice_exam/error.html' elif attempt_status == ProctoredExamStudentAttemptStatus.submitted: @@ -1842,90 +1825,79 @@ def _get_proctored_exam_view(exam, context, exam_id, user_id, course_id): if attempt_status == ProctoredExamStudentAttemptStatus.declined: return None - if attempt_status == ProctoredExamStudentAttemptStatus.started: - # when we're taking the exam we should not override the view - return None - elif not attempt_status or attempt_status in [ - ProctoredExamStudentAttemptStatus.created, - ProctoredExamStudentAttemptStatus.download_software_clicked, - ProctoredExamStudentAttemptStatus.ready_to_start, - ]: - is_other_exam, other_exam_url = _get_running_exam_info(user_id, exam_id) - if is_other_exam: - context.update({'exam_url': other_exam_url}) - student_view_template = 'proctored_exam/other_exam_in_progress.html' - elif not attempt_status: - # student has not started an attempt - # so, show them: - # 1) If there are failed prerequisites then block user and say why - # 2) If there are pending prerequisites then block user and allow them to remediate them - # 3) If there are declined prerequisites, then we auto-decline proctoring since user - # explicitly declined their interest in credit - # 4) Otherwise - all prerequisites are satisfied - then give user - # option to take exam as proctored - - # get information about prerequisites - - credit_requirement_status = ( - credit_state.get('credit_requirement_status') - if credit_state else [] - ) + if not attempt_status: + # student has not started an attempt + # so, show them: + # 1) If there are failed prerequisites then block user and say why + # 2) If there are pending prerequisites then block user and allow them to remediate them + # 3) If there are declined prerequisites, then we auto-decline proctoring since user + # explicitly declined their interest in credit + # 4) Otherwise - all prerequisites are satisfied - then give user + # option to take exam as proctored + + # get information about prerequisites + + credit_requirement_status = ( + credit_state.get('credit_requirement_status') + if credit_state else [] + ) - prerequisite_status = _are_prerequirements_satisfied( - credit_requirement_status, - evaluate_for_requirement_name=exam['content_id'], - filter_out_namespaces=['grade'] - ) + prerequisite_status = _are_prerequirements_satisfied( + credit_requirement_status, + evaluate_for_requirement_name=exam['content_id'], + filter_out_namespaces=['grade'] + ) - # add any prerequisite information, if applicable - context.update({ - 'prerequisite_status': prerequisite_status - }) + # add any prerequisite information, if applicable + context.update({ + 'prerequisite_status': prerequisite_status + }) + + # if exam due date has passed, then we can't take the exam + if has_due_date_passed(exam['due_date']): + student_view_template = 'proctored_exam/expired.html' + elif not prerequisite_status['are_prerequisites_satisifed']: + # do we have any declined prerequisites, if so, then we + # will auto-decline this proctored exam + if prerequisite_status['declined_prerequisites']: + # user hasn't a record of attempt, create one now + # so we can mark it as declined + _create_and_decline_attempt(exam_id, user_id) + return None - # if exam due date has passed, then we can't take the exam - if has_due_date_passed(exam['due_date']): - student_view_template = 'proctored_exam/expired.html' - elif not prerequisite_status['are_prerequisites_satisifed']: - # do we have any declined prerequisites, if so, then we - # will auto-decline this proctored exam - if prerequisite_status['declined_prerequisites']: - # user hasn't a record of attempt, create one now - # so we can mark it as declined - _create_and_decline_attempt(exam_id, user_id) - return None - - # do we have failed prerequisites? That takes priority in terms of - # messaging - if prerequisite_status['failed_prerequisites']: - # Let's resolve the URLs to jump to this prequisite - prerequisite_status['failed_prerequisites'] = _resolve_prerequisite_links( - exam, - prerequisite_status['failed_prerequisites'] - ) - student_view_template = 'proctored_exam/failed-prerequisites.html' - else: - # Let's resolve the URLs to jump to this prequisite - prerequisite_status['pending_prerequisites'] = _resolve_prerequisite_links( - exam, - prerequisite_status['pending_prerequisites'] - ) - student_view_template = 'proctored_exam/pending-prerequisites.html' + # do we have failed prerequisites? That takes priority in terms of + # messaging + if prerequisite_status['failed_prerequisites']: + # Let's resolve the URLs to jump to this prequisite + prerequisite_status['failed_prerequisites'] = _resolve_prerequisite_links( + exam, + prerequisite_status['failed_prerequisites'] + ) + student_view_template = 'proctored_exam/failed-prerequisites.html' else: - student_view_template = 'proctored_exam/entrance.html' - # emit an event that the user was presented with the option - # to start timed exam - emit_event(exam, 'option-presented') - elif context.get('verification_status') is not APPROVED_STATUS: + # Let's resolve the URLs to jump to this prequisite + prerequisite_status['pending_prerequisites'] = _resolve_prerequisite_links( + exam, + prerequisite_status['pending_prerequisites'] + ) + student_view_template = 'proctored_exam/pending-prerequisites.html' + else: + student_view_template = 'proctored_exam/entrance.html' + # emit an event that the user was presented with the option + # to start timed exam + emit_event(exam, 'option-presented') + elif attempt_status == ProctoredExamStudentAttemptStatus.started: + # when we're taking the exam we should not override the view + return None + elif attempt_status in [ProctoredExamStudentAttemptStatus.created, + ProctoredExamStudentAttemptStatus.download_software_clicked]: + if context.get('verification_status') is not APPROVED_STATUS: # if the user has not id verified yet, show them the page that requires them to do so student_view_template = 'proctored_exam/id_verification.html' - elif attempt_status in [ - ProctoredExamStudentAttemptStatus.created, - ProctoredExamStudentAttemptStatus.download_software_clicked, - ]: - student_view_template = 'proctored_exam/instructions.html' else: - # note: then the status must be ready_to_start - student_view_template = 'proctored_exam/ready_to_start.html' + student_view_template = 'proctored_exam/instructions.html' + elif attempt_status == ProctoredExamStudentAttemptStatus.ready_to_start: + student_view_template = 'proctored_exam/ready_to_start.html' elif attempt_status == ProctoredExamStudentAttemptStatus.error: student_view_template = 'proctored_exam/error.html' elif attempt_status == ProctoredExamStudentAttemptStatus.timed_out: @@ -2033,27 +2005,6 @@ def get_student_view(user_id, course_id, content_id, return None -def _get_running_exam_info(user_id, currently_visited_exam_id): - """ - Check whether there are any other currently active exams besides - that currently being viewed - """ - active_exam_attempts = get_active_exams_for_user(user_id) - if active_exam_attempts: - active_exam = active_exam_attempts[0]['exam'] - is_other_exam_running = active_exam['id'] != currently_visited_exam_id - try: - # resolve the LMS url, note we can't assume we're running in - # a same process as the LMS - other_exam_url = reverse('jump_to', args=[active_exam['course_id'], active_exam['content_id']]) - except NoReverseMatch: - log.exception("Can't find exam url for course %s", active_exam['course_id']) - other_exam_url = '' - else: - is_other_exam_running, other_exam_url = False, '' - return is_other_exam_running, other_exam_url - - def get_exam_violation_report(course_id, include_practice_exams=False): """ Returns proctored exam attempts for the course id, including review details. diff --git a/edx_proctoring/templates/proctored_exam/other_exam_in_progress.html b/edx_proctoring/templates/proctored_exam/other_exam_in_progress.html deleted file mode 100644 index 665f3334448..00000000000 --- a/edx_proctoring/templates/proctored_exam/other_exam_in_progress.html +++ /dev/null @@ -1,15 +0,0 @@ -{% load i18n %} -
-

- {% blocktrans %} - Complete in-progress exam - {% endblocktrans %} -

- -

- {% blocktrans %} - You must complete your currently in-progress exam before you can attempt this one. - {% endblocktrans %} -

-
-{% include 'proctored_exam/footer.html' %} diff --git a/edx_proctoring/tests/test_student_view.py b/edx_proctoring/tests/test_student_view.py index f59d1c3f9a8..ab0b43d9ea0 100644 --- a/edx_proctoring/tests/test_student_view.py +++ b/edx_proctoring/tests/test_student_view.py @@ -64,7 +64,6 @@ def setUp(self): self.practice_exam_submitted_msg = 'You have submitted this practice proctored exam' self.take_exam_without_proctoring_msg = 'Take this exam without proctoring' self.ready_to_start_msg = 'Important' - self.complete_other_exam_first_msg = 'Complete in-progress exam' self.footer_msg = 'About Proctored Exams' self.timed_footer_msg = 'Can I request additional time to complete my exam?' @@ -132,18 +131,6 @@ def render_practice_exam(self, context_overrides=None): context_overrides=exam_context_overrides ) - def render_timed_exam(self): - """ - Renders a test timed exam - """ - exam_context_overrides = { - 'is_proctored': False - } - return self._render_exam( - self.timed_exam_id, - context_overrides=exam_context_overrides - ) - def test_get_student_view(self): """ Test for get_student_view prompting the user to take the exam @@ -470,46 +457,6 @@ def test_declined_attempt(self): rendered_response = self.render_proctored_exam() self.assertIsNone(rendered_response) - def test_get_studentview_exam_in_progress(self): - """ - Assert that we get the right content when another exam was - started first - """ - self._create_started_exam_attempt() - self.content_id = self.content_id + '_new' - self.proctored_exam_id = self._create_proctored_exam() - unstarted_attempt = self._create_unstarted_exam_attempt() - - unstarted_attempt.status = ProctoredExamStudentAttemptStatus.created - unstarted_attempt.save() - - rendered_response = self.render_proctored_exam() - self.assertIn(self.complete_other_exam_first_msg, rendered_response) - - def test_get_studentview_exam_in_progress_timed(self): - """ - Assert that we get the right content when another exam was - started first for timed and practice exams - """ - self._create_started_exam_attempt() - - rendered_response = self.render_timed_exam() - self.assertIn(self.complete_other_exam_first_msg, rendered_response) - - def test_get_studentview_exam_in_progress_practice(self): - """ - Assert that we get the right content when another exam was - started first for timed and practice exams - """ - self._create_started_exam_attempt() - unstarted_attempt = self._create_unstarted_exam_attempt(is_practice=True) - - unstarted_attempt.status = ProctoredExamStudentAttemptStatus.created - unstarted_attempt.save() - - rendered_response = self.render_practice_exam() - self.assertIn(self.complete_other_exam_first_msg, rendered_response) - def test_get_studentview_ready(self): """ Assert that we get the right content