Commit 7c268e57 by Hasnain

If practice exam's due date has passed then student can still attempt the exam

parent 0387d065
...@@ -463,7 +463,7 @@ def update_exam_attempt(attempt_id, **kwargs): ...@@ -463,7 +463,7 @@ def update_exam_attempt(attempt_id, **kwargs):
exam_attempt_obj.save() exam_attempt_obj.save()
def _has_due_date_passed(due_datetime): def has_due_date_passed(due_datetime):
""" """
return True if due date is lesser than current datetime, otherwise False return True if due date is lesser than current datetime, otherwise False
and if due_datetime is None then we don't have to consider the due date for return False and if due_datetime is None then we don't have to consider the due date for return False
...@@ -478,7 +478,7 @@ def _was_review_status_acknowledged(is_status_acknowledged, due_datetime): ...@@ -478,7 +478,7 @@ def _was_review_status_acknowledged(is_status_acknowledged, due_datetime):
""" """
return True if review status has been acknowledged and due date has been passed return True if review status has been acknowledged and due date has been passed
""" """
return is_status_acknowledged and _has_due_date_passed(due_datetime) return is_status_acknowledged and has_due_date_passed(due_datetime)
def _create_and_decline_attempt(exam_id, user_id): def _create_and_decline_attempt(exam_id, user_id):
...@@ -1418,7 +1418,7 @@ def _get_timed_exam_view(exam, context, exam_id, user_id, course_id): ...@@ -1418,7 +1418,7 @@ def _get_timed_exam_view(exam, context, exam_id, user_id, course_id):
attempt_status = attempt['status'] if attempt else None attempt_status = attempt['status'] if attempt else None
has_due_date = True if exam['due_date'] is not None else False has_due_date = True if exam['due_date'] is not None else False
if not attempt_status: if not attempt_status:
if _has_due_date_passed(exam['due_date']): if has_due_date_passed(exam['due_date']):
student_view_template = 'timed_exam/expired.html' student_view_template = 'timed_exam/expired.html'
else: else:
student_view_template = 'timed_exam/entrance.html' student_view_template = 'timed_exam/entrance.html'
...@@ -1430,7 +1430,7 @@ def _get_timed_exam_view(exam, context, exam_id, user_id, course_id): ...@@ -1430,7 +1430,7 @@ def _get_timed_exam_view(exam, context, exam_id, user_id, course_id):
elif attempt_status == ProctoredExamStudentAttemptStatus.submitted: elif attempt_status == ProctoredExamStudentAttemptStatus.submitted:
# check if the exam's due_date has passed then we return None # check if the exam's due_date has passed then we return None
# so that the user can see his exam answers in read only mode. # so that the user can see his exam answers in read only mode.
if _has_due_date_passed(exam['due_date']): if has_due_date_passed(exam['due_date']):
return None return None
student_view_template = 'timed_exam/submitted.html' student_view_template = 'timed_exam/submitted.html'
...@@ -1509,7 +1509,7 @@ def _calculate_allowed_mins(due_datetime, allowed_mins): ...@@ -1509,7 +1509,7 @@ def _calculate_allowed_mins(due_datetime, allowed_mins):
actual_allowed_mins = allowed_mins actual_allowed_mins = allowed_mins
if due_datetime: if due_datetime:
if _has_due_date_passed(due_datetime): if has_due_date_passed(due_datetime):
is_exam_past_due_date = True is_exam_past_due_date = True
elif current_datetime + timedelta(minutes=allowed_mins) > due_datetime: elif current_datetime + timedelta(minutes=allowed_mins) > due_datetime:
...@@ -1546,7 +1546,7 @@ def _get_proctored_exam_context(exam, attempt, course_id, is_practice_exam=False ...@@ -1546,7 +1546,7 @@ def _get_proctored_exam_context(exam, attempt, course_id, is_practice_exam=False
'progress_page_url': progress_page_url, 'progress_page_url': progress_page_url,
'is_sample_attempt': is_practice_exam, 'is_sample_attempt': is_practice_exam,
'has_due_date': has_due_date, 'has_due_date': has_due_date,
'has_due_date_passed': _has_due_date_passed(exam['due_date']), 'has_due_date_passed': has_due_date_passed(exam['due_date']),
'does_time_remain': _does_time_remain(attempt), 'does_time_remain': _does_time_remain(attempt),
'enter_exam_endpoint': reverse('edx_proctoring.proctored_exam.attempt.collection'), 'enter_exam_endpoint': reverse('edx_proctoring.proctored_exam.attempt.collection'),
'exam_started_poll_url': reverse( 'exam_started_poll_url': reverse(
...@@ -1666,7 +1666,7 @@ def _get_proctored_exam_view(exam, context, exam_id, user_id, course_id): ...@@ -1666,7 +1666,7 @@ def _get_proctored_exam_view(exam, context, exam_id, user_id, course_id):
}) })
# if exam due date has passed, then we can't take the exam # if exam due date has passed, then we can't take the exam
if _has_due_date_passed(exam['due_date']): if has_due_date_passed(exam['due_date']):
student_view_template = 'proctored_exam/expired.html' student_view_template = 'proctored_exam/expired.html'
elif not prerequisite_status['are_prerequisites_satisifed']: elif not prerequisite_status['are_prerequisites_satisifed']:
# do we have any declined prerequisites, if so, then we # do we have any declined prerequisites, if so, then we
......
...@@ -30,7 +30,8 @@ from edx_proctoring.api import ( ...@@ -30,7 +30,8 @@ from edx_proctoring.api import (
get_exam_attempt_by_id, get_exam_attempt_by_id,
remove_exam_attempt, remove_exam_attempt,
update_attempt_status, update_attempt_status,
update_exam_attempt update_exam_attempt,
has_due_date_passed,
) )
from edx_proctoring.exceptions import ( from edx_proctoring.exceptions import (
ProctoredBaseException, ProctoredBaseException,
...@@ -596,8 +597,13 @@ class StudentProctoredExamAttemptCollection(AuthenticatedAPIView): ...@@ -596,8 +597,13 @@ class StudentProctoredExamAttemptCollection(AuthenticatedAPIView):
attempt_proctored = request.data.get('attempt_proctored', 'false').lower() == 'true' attempt_proctored = request.data.get('attempt_proctored', 'false').lower() == 'true'
try: try:
exam = get_exam_by_id(exam_id) exam = get_exam_by_id(exam_id)
if exam['due_date'] and exam['due_date'] <= datetime.now(pytz.UTC):
raise ProctoredExamPermissionDenied('Attempted to access expired exam') # Bypassing the due date check for practice exam
# because student can attempt the practice after the due date
if not exam.get("is_practice_exam") and has_due_date_passed(exam.get('due_date')):
raise ProctoredExamPermissionDenied(
'Attempted to access expired exam with exam_id {exam_id}'.format(exam_id=exam_id)
)
exam_attempt_id = create_exam_attempt( exam_attempt_id = create_exam_attempt(
exam_id=exam_id, exam_id=exam_id,
......
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