Commit bc7f5694 by chrisndodge

Merge pull request #232 from edx/PHX-213

PHX-213 / remove the "expire" status in exam attempt
parents ab676cbc ce852fcd
......@@ -375,21 +375,6 @@ def _create_and_decline_attempt(exam_id, user_id):
)
def _create_and_expire_attempt(exam_id, user_id):
"""
It will create the exam attempt and change the attempt's status to decline.
it will auto-decline further exams too
"""
create_exam_attempt(exam_id, user_id)
update_attempt_status(
exam_id,
user_id,
ProctoredExamStudentAttemptStatus.expired,
raise_if_not_found=False
)
def create_exam_attempt(exam_id, user_id, taking_as_proctored=False):
"""
Creates an exam attempt for user_id against exam_id. There should only be
......@@ -498,13 +483,6 @@ def create_exam_attempt(exam_id, user_id, taking_as_proctored=False):
review_policy_id=review_policy.id if review_policy else None,
)
if is_exam_past_due_date:
update_attempt_status(
exam_id,
user_id,
ProctoredExamStudentAttemptStatus.expired
)
log_msg = (
'Created exam attempt ({attempt_id}) for exam_id {exam_id} for '
'user_id {user_id} with taking as proctored = {taking_as_proctored} '
......@@ -1184,11 +1162,6 @@ STATUS_SUMMARY_MAP = {
'short_description': _('Failed Proctoring'),
'suggested_icon': 'fa-exclamation-triangle',
'in_completed_state': True
},
ProctoredExamStudentAttemptStatus.expired: {
'short_description': _('Exam Expired'),
'suggested_icon': 'fa-exclamation-triangle',
'in_completed_state': True
}
}
......@@ -1208,11 +1181,6 @@ PRACTICE_STATUS_SUMMARY_MAP = {
'short_description': _('Practice Exam Failed'),
'suggested_icon': 'fa-exclamation-triangle',
'in_completed_state': True
},
ProctoredExamStudentAttemptStatus.expired: {
'short_description': _('Exam Expired'),
'suggested_icon': 'fa-exclamation-triangle',
'in_completed_state': True
}
}
......@@ -1309,15 +1277,12 @@ def _get_timed_exam_view(exam, context, exam_id, user_id, course_id):
has_due_date = True if exam['due_date'] is not None else False
if not attempt_status:
if _has_due_date_passed(exam['due_date']):
_create_and_expire_attempt(exam_id, user_id)
student_view_template = 'proctored_exam/expired.html'
student_view_template = 'timed_exam/expired.html'
else:
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
elif attempt_status == ProctoredExamStudentAttemptStatus.expired:
student_view_template = 'proctored_exam/expired.html'
elif attempt_status == ProctoredExamStudentAttemptStatus.ready_to_submit:
student_view_template = 'timed_exam/ready_to_submit.html'
elif attempt_status == ProctoredExamStudentAttemptStatus.submitted:
......@@ -1450,15 +1415,12 @@ def _get_practice_exam_view(exam, context, exam_id, user_id, course_id):
if not attempt_status:
if _has_due_date_passed(exam['due_date']):
_create_and_expire_attempt(exam_id, user_id)
student_view_template = 'proctored_exam/expired.html'
else:
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 attempt_status == ProctoredExamStudentAttemptStatus.expired:
student_view_template = 'proctored_exam/expired.html'
elif attempt_status == ProctoredExamStudentAttemptStatus.created:
provider = get_backend_provider()
student_view_template = 'proctored_exam/instructions.html'
......@@ -1545,7 +1507,6 @@ 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 _has_due_date_passed(exam['due_date']):
_create_and_expire_attempt(exam_id, user_id)
student_view_template = 'proctored_exam/expired.html'
elif not prerequisite_status['are_prerequisites_satisifed']:
# do we have any declined prerequisites, if so, then we
......@@ -1580,8 +1541,6 @@ def _get_proctored_exam_view(exam, context, exam_id, user_id, course_id):
elif attempt_status == ProctoredExamStudentAttemptStatus.started:
# when we're taking the exam we should not override the view
return None
elif attempt_status == ProctoredExamStudentAttemptStatus.expired:
student_view_template = 'proctored_exam/expired.html'
elif attempt_status in [ProctoredExamStudentAttemptStatus.created,
ProctoredExamStudentAttemptStatus.download_software_clicked]:
provider = get_backend_provider()
......
......@@ -162,9 +162,6 @@ class ProctoredExamStudentAttemptStatus(object):
# the exam is believed to be in error
error = 'error'
# the exam has expired, i.e. past due date
expired = 'expired'
# status alias for sending email
status_alias_mapping = {
submitted: _('pending'),
......@@ -180,7 +177,7 @@ class ProctoredExamStudentAttemptStatus(object):
"""
return status in [
cls.declined, cls.timed_out, cls.submitted, cls.verified, cls.rejected,
cls.not_reviewed, cls.error, cls.expired
cls.not_reviewed, cls.error
]
@classmethod
......@@ -200,7 +197,7 @@ class ProctoredExamStudentAttemptStatus(object):
"""
return to_status in [
cls.verified, cls.rejected, cls.declined, cls.not_reviewed, cls.submitted,
cls.error, cls.expired
cls.error
]
@classmethod
......
{% load i18n %}
<div class="sequence proctored-exam completed" data-exam-id="{{exam_id}}">
<h3>
{% blocktrans %}
The due date for this exam has passed
{% endblocktrans %}
</h3>
<p>
{% blocktrans %}
Because the due date has passed, you are no longer able to take this exam.
{% endblocktrans %}
</p>
</div>
......@@ -518,25 +518,6 @@ class ProctoredExamApiTests(LoggedInTestCase):
minutes_before_past_due_date - 1 <= attempt['allowed_time_limit_mins'] <= minutes_before_past_due_date
)
def test_create_exam_attempt_with_past_due_datetime(self):
"""
Create the exam attempt with past due date
"""
due_date = datetime.now(pytz.UTC) + timedelta(days=1)
# exam is created with due datetime which has already passed
exam_id = self._create_exam_with_due_time(due_date=due_date)
# due_date is exactly after 24 hours, if student arrives after 2 days
# then he can not attempt the proctored exam
reset_time = due_date + timedelta(days=2)
with freeze_time(reset_time):
attempt_id = create_exam_attempt(exam_id, self.user_id)
attempt = get_exam_attempt_by_id(attempt_id)
self.assertEqual(attempt['status'], ProctoredExamStudentAttemptStatus.expired)
def test_create_an_exam_attempt(self):
"""
Create an unstarted exam attempt.
......@@ -681,7 +662,6 @@ class ProctoredExamApiTests(LoggedInTestCase):
(ProctoredExamStudentAttemptStatus.submitted, 'submitted'),
(ProctoredExamStudentAttemptStatus.declined, 'declined'),
(ProctoredExamStudentAttemptStatus.error, 'failed'),
(ProctoredExamStudentAttemptStatus.expired, 'failed'),
)
@ddt.unpack
def test_remove_exam_attempt_with_status(self, to_status, requirement_status):
......@@ -1764,12 +1744,6 @@ class ProctoredExamApiTests(LoggedInTestCase):
None
),
(
ProctoredExamStudentAttemptStatus.expired,
False,
None,
None
),
(
ProctoredExamStudentAttemptStatus.rejected,
True,
ProctoredExamStudentAttemptStatus.created,
......@@ -1866,9 +1840,7 @@ class ProctoredExamApiTests(LoggedInTestCase):
@ddt.data(
(ProctoredExamStudentAttemptStatus.declined, ProctoredExamStudentAttemptStatus.eligible),
(ProctoredExamStudentAttemptStatus.timed_out, ProctoredExamStudentAttemptStatus.created),
(ProctoredExamStudentAttemptStatus.expired, ProctoredExamStudentAttemptStatus.created),
(ProctoredExamStudentAttemptStatus.timed_out, ProctoredExamStudentAttemptStatus.download_software_clicked),
(ProctoredExamStudentAttemptStatus.expired, ProctoredExamStudentAttemptStatus.download_software_clicked),
(ProctoredExamStudentAttemptStatus.submitted, ProctoredExamStudentAttemptStatus.ready_to_start),
(ProctoredExamStudentAttemptStatus.verified, ProctoredExamStudentAttemptStatus.started),
(ProctoredExamStudentAttemptStatus.rejected, ProctoredExamStudentAttemptStatus.started),
......@@ -2071,14 +2043,6 @@ class ProctoredExamApiTests(LoggedInTestCase):
'suggested_icon': 'fa-exclamation-triangle',
'in_completed_state': True
}
),
(
ProctoredExamStudentAttemptStatus.expired, {
'status': ProctoredExamStudentAttemptStatus.expired,
'short_description': 'Exam Expired',
'suggested_icon': 'fa-exclamation-triangle',
'in_completed_state': True
}
)
)
@ddt.unpack
......@@ -2150,14 +2114,6 @@ class ProctoredExamApiTests(LoggedInTestCase):
'suggested_icon': 'fa-exclamation-triangle',
'in_completed_state': True
}
),
(
ProctoredExamStudentAttemptStatus.expired, {
'status': ProctoredExamStudentAttemptStatus.expired,
'short_description': 'Exam Expired',
'suggested_icon': 'fa-exclamation-triangle',
'in_completed_state': True
}
)
)
@ddt.unpack
......@@ -2335,8 +2291,7 @@ class ProctoredExamApiTests(LoggedInTestCase):
ProctoredExamStudentAttemptStatus.declined,
ProctoredExamStudentAttemptStatus.timed_out,
ProctoredExamStudentAttemptStatus.not_reviewed,
ProctoredExamStudentAttemptStatus.error,
ProctoredExamStudentAttemptStatus.expired
ProctoredExamStudentAttemptStatus.error
)
@patch.dict('settings.PROCTORING_SETTINGS', {'ALLOW_TIMED_OUT_STATE': True})
def test_not_send_email(self, status):
......
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