Commit 5ad4465d by chrisndodge

Merge pull request #61 from edx/cdodge/review-punchlist1

address some review feedback
parents c57c8095 e6cb0693
......@@ -418,6 +418,15 @@ def update_attempt_status(exam_id, user_id, to_status):
Internal helper to handle state transitions of attempt status
"""
# In some configuration we may treat timeouts the same
# as the user saying he/she wises to submit the exam
alias_timeout = (
to_status == ProctoredExamStudentAttemptStatus.timed_out and
not settings.PROCTORING_SETTINGS.get('ALLOW_TIMED_OUT_STATE', False)
)
if alias_timeout:
to_status = ProctoredExamStudentAttemptStatus.ready_to_submit
exam_attempt_obj = ProctoredExamStudentAttempt.objects.get_exam_attempt(exam_id, user_id)
if exam_attempt_obj is None:
raise StudentExamAttemptDoesNotExistsException('Error. Trying to look up an exam that does not exist.')
......
......@@ -39,6 +39,7 @@ def start_exam_callback(request, attempt_code): # pylint: disable=unused-argume
IMPORTANT: This is an unauthenticated endpoint, so be VERY CAREFUL about extending
this endpoint
"""
attempt = get_exam_attempt_by_code(attempt_code)
if not attempt:
return HttpResponse(
......
......@@ -102,7 +102,6 @@ var edx = edx || {};
return this;
},
unloadMessage: function () {
return null;
return gettext("As you are currently taking a proctored exam,\n" +
"you should not be navigation away from the exam.\n" +
"This may be considered as a violation of the \n" +
......@@ -115,10 +114,8 @@ var edx = edx || {};
var url = self.model.url + '/' + self.model.get('attempt_id');
$.ajax(url).success(function(data) {
if (data.status === 'error') {
// Let the student know that his exam has failed due to an error.
// This alert may or may not bring the browser window back to the
// foreground (depending on browser as well as user settings)
alert(gettext('Your exam has failed'));
// The proctoring session is in error state
// refresh the page to
clearInterval(self.timerId); // stop the timer once the time finishes.
$(window).unbind('beforeunload', self.unloadMessage);
// refresh the page when the timer expired
......
......@@ -53,6 +53,17 @@
var exam_id = $(this).data('exam-id');
var attempt_proctored = $(this).data('attempt-proctored');
var start_immediately = $(this).data('start-immediately');
if (!attempt_proctored) {
var msg = gettext(
"Are you sure you want to take this exam without proctoring? " +
"This will make you no longer eligible to earn credit for this course."
)
if (!confirm(msg)) {
return;
}
}
if (typeof action_url === "undefined" ) {
return false;
}
......
{% load i18n %}
<div class="sequence proctored-exam error">
<div class="gated-sequence">
{% trans "Your exam has been marked as failed due to an error." %}
</div>
<div class="failure sequence proctored-exam" data-exam-id="{{exam_id}}">
<h3>
{% blocktrans %}
Your proctoring session is in error
{% endblocktrans %}
</h3>
<h4>
{% blocktrans %}
Your Proctoring Session review: <b class="failure"> Failed </b>
{% endblocktrans %}
</h4>
<p>
{% blocktrans %}
It appears that your proctoring session has been shut down while you were taking this
exam. This invalidates your proctored exam and you will not be eligible for course
credit.
{% endblocktrans %}
</p>
<hr>
<p>
{% blocktrans %}
Please see <a href="{{progress_page_url}}">your progress in this course </a>
for your general course credit worthiness.
{% endblocktrans %}
</p>
</div>
<div class="footer-sequence border-b-0 padding-b-0">
<span> {% trans "Can I contest this review?" %} </span>
<p class="proctored-exam-option">
{% blocktrans %}
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor.
Aenean massa.
{% endblocktrans %}
</p>
<a href="#" class="contest-review">Contest this review</a>
<hr class="clearfix">
<span> {% trans "Is there anything I can do to make up/replace this session?" %} </span>
<p class="proctored-exam-option">
{% blocktrans %}
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor.
Aenean massa.
{% endblocktrans %}
</p>
<hr class="clearfix">
<span> {% trans "See Also" %} </span>
<p>
{% blocktrans %}
<a class="footer-link" href="#">
Frequently asked questions about proctoring and earning college credit.
</a>
{% endblocktrans %}
</p>
</div>
......@@ -51,11 +51,22 @@
var _waiting_for_proctored_interval = null;
$('.proctored-decline-exam').click(
function(event) {
function(e) {
e.preventDefault();
e.stopPropagation();
var action_url = $(this).data('change-state-url');
var exam_id = $(this).data('exam-id');
var action = $(this).data('action')
var msg = gettext(
"Are you sure you want to take this exam without proctoring? " +
"This will make you no longer eligible to earn credit for this course."
)
if (!confirm(msg)) {
return;
}
// Update the state of the attempt
$.ajax({
url: action_url,
......
......@@ -26,13 +26,4 @@
{% endblocktrans %}
</p>
</div>
<div class="footer-sequence border-b-0 padding-b-0">
<span> {% trans "See Also" %} </span>
<p>
{% blocktrans %}
<a class="footer-link" href="#">
Frequently asked questions about proctoring and earning college credit.
</a>
{% endblocktrans %}
</p>
</div>
{% include 'proctoring/seq_proctored_exam_footer.html' %}
......@@ -26,13 +26,4 @@
{% endblocktrans %}
</p>
</div>
<div class="footer-sequence border-b-0 padding-b-0">
<span> {% trans "See Also" %} </span>
<p>
{% blocktrans %}
<a class="footer-link" href="#">
Frequently asked questions about proctoring and earning college credit.
</a>
{% endblocktrans %}
</p>
</div>
{% include 'proctoring/seq_proctored_exam_footer.html' %}
......@@ -92,7 +92,7 @@ class ProctoredExamApiTests(LoggedInTestCase):
self.start_an_exam_msg = 'Would you like to take %s as a proctored exam?'
self.timed_exam_msg = '%s is a Timed Exam'
self.exam_time_expired_msg = 'You did not complete the exam in the allotted time'
self.exam_time_error_msg = 'Your exam has been marked as failed due to an error.'
self.exam_time_error_msg = 'Your proctoring session is in error'
self.chose_proctored_exam_msg = 'You have chosen to take %s as a proctored exam'
self.proctored_exam_completed_msg = 'This is the end of your proctored exam'
self.proctored_exam_submitted_msg = 'You have submitted this proctored exam for review'
......@@ -839,6 +839,7 @@ class ProctoredExamApiTests(LoggedInTestCase):
)
self.assertIsNone(rendered_response)
@patch.dict('django.conf.settings.PROCTORING_SETTINGS', {'ALLOW_TIMED_OUT_STATE': True})
def test_get_studentview_timedout(self):
"""
Verifies that if we call get_studentview when the timer has expired
......@@ -959,6 +960,7 @@ class ProctoredExamApiTests(LoggedInTestCase):
)
self.assertIn(self.proctored_exam_completed_msg, rendered_response)
@patch.dict('django.conf.settings.PROCTORING_SETTINGS', {'ALLOW_TIMED_OUT_STATE': True})
def test_get_studentview_expired(self):
"""
Test for get_student_view proctored exam which has expired.
......@@ -1095,6 +1097,7 @@ class ProctoredExamApiTests(LoggedInTestCase):
(ProctoredExamStudentAttemptStatus.error, ProctoredExamStudentAttemptStatus.started),
)
@ddt.unpack
@patch.dict('django.conf.settings.PROCTORING_SETTINGS', {'ALLOW_TIMED_OUT_STATE': True})
def test_illegal_status_transition(self, from_status, to_status):
"""
Verify that we cannot reset backwards an attempt status
......@@ -1109,9 +1112,28 @@ class ProctoredExamApiTests(LoggedInTestCase):
)
with self.assertRaises(ProctoredExamIllegalStatusTransition):
print '*** from = {} to {}'.format(from_status, to_status)
update_attempt_status(
exam_attempt.proctored_exam_id,
self.user.id,
to_status
)
def test_alias_timed_out(self):
"""
Verified that timed_out will automatically state transition
to ready_to_submit
"""
exam_attempt = self._create_started_exam_attempt()
update_attempt_status(
exam_attempt.proctored_exam_id,
self.user.id,
ProctoredExamStudentAttemptStatus.timed_out
)
exam_attempt = get_exam_attempt_by_id(exam_attempt.id)
self.assertEqual(
exam_attempt['status'],
ProctoredExamStudentAttemptStatus.ready_to_submit
)
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