Commit bed05040 by Chris Dodge

add the ready_to_start page

parent 5ad4465d
......@@ -718,25 +718,30 @@ def get_student_view(user_id, course_id, content_id,
expires_at = attempt['started_at'] + timedelta(minutes=attempt['allowed_time_limit_mins'])
does_time_remain = datetime.now(pytz.UTC) < expires_at
if not has_started_exam:
if attempt:
print '*** status = {}'.format(attempt['status'])
if not attempt:
# determine whether to show a timed exam only entrance screen
# or a screen regarding proctoring
if is_proctored:
if not attempt:
if exam['is_practice_exam']:
student_view_template = 'proctoring/seq_proctored_practice_exam_entrance.html'
else:
student_view_template = 'proctoring/seq_proctored_exam_entrance.html'
if exam['is_practice_exam']:
student_view_template = 'proctoring/seq_proctored_practice_exam_entrance.html'
else:
provider = get_backend_provider()
student_view_template = 'proctoring/seq_proctored_exam_instructions.html'
context.update({
'exam_code': attempt['attempt_code'],
'software_download_url': provider.get_software_download_url(),
})
student_view_template = 'proctoring/seq_proctored_exam_entrance.html'
else:
student_view_template = 'proctoring/seq_timed_exam_entrance.html'
elif attempt['status'] == ProctoredExamStudentAttemptStatus.created:
provider = get_backend_provider()
student_view_template = 'proctoring/seq_proctored_exam_instructions.html'
context.update({
'exam_code': attempt['attempt_code'],
'software_download_url': provider.get_software_download_url(),
})
elif attempt['status'] == ProctoredExamStudentAttemptStatus.ready_to_start:
student_view_template = 'proctoring/seq_proctored_exam_ready_to_start.html'
elif attempt['status'] == ProctoredExamStudentAttemptStatus.error:
student_view_template = 'proctoring/seq_proctored_exam_error.html'
elif attempt['status'] == ProctoredExamStudentAttemptStatus.timed_out:
......
......@@ -192,11 +192,13 @@
{% endblocktrans %}
</p>
</div>
<!--
<div class="footer">
<button>
{% blocktrans %} Go to my exam {% endblocktrans %}
</button>
</div>
-->
</div>
<script type="text/javascript">
......
......@@ -138,24 +138,9 @@
if (_waiting_for_proctored_interval != null) {
clearInterval(_waiting_for_proctored_interval)
}
// Let the student know exam is ready to start.
// This alert may or may not bring the browser window back to the
// foreground (depending on browser as well as user settings)
alert('{% trans "Your proctored exam has started, please click OK to enter into your exam." %}')
// after the user acknowledges the alert then we can start
// the exam and timer
$.ajax({
url: url,
type: 'PUT',
data: {
action: 'start'
},
success: function() {
// Reloading page will reflect the new state of the attempt
location.reload()
}
});
// we've state transitioned, so refresh the page
// to reflect the new state (which will expose the test)
location.reload();
}
});
}
......
{% load i18n %}
<div class="sequence proctored-exam instructions" data-exam-id="{{exam_id}}" data-exam-started-poll-url="{{exam_started_poll_url}}">
<h3>
{% blocktrans %}
Your Proctoring Installation and Set Up is Complete
{% endblocktrans %}
</h3>
<p>
{% blocktrans %}
Placeholder content. <strong>Please keep the proctoring software open and running while you complete your exam</strong>.
{% endblocktrans %}
</p>
<div class="proctored-exam-message">
<h3>
{% blocktrans %}
You May Begin Your Exam Now
{% endblocktrans %}
</h3>
<p>
{% blocktrans %}
Your proctored and timed exam is now ready. Once you start, <strong>you will have {{total_time}} to
complete the exam and cannot stop the timer</strong>. If you did not active complete the exam, at the
end of that period your exam will close and proctoring session will be reviewed.
{% endblocktrans %}
</p>
<div>
<button type="button" class="proctored-enter-exam" data-action="start" data-exam-id="{{exam_id}}" data-change-state-url="{{change_state_url}}">
{% blocktrans %}
I'm ready! Start my timed proctored exam
{% endblocktrans %}
</button>
</div>
</div>
</div>
{% include 'proctoring/seq_proctored_exam_footer.html' %}
<script type="text/javascript">
$('.proctored-enter-exam').click(
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')
// Update the state of the attempt
$.ajax({
url: action_url,
type: 'PUT',
data: {
action: action
},
success: function() {
// Reloading page will reflect the new state of the attempt
location.reload()
}
});
}
);
</script>
......@@ -101,6 +101,7 @@ class ProctoredExamApiTests(LoggedInTestCase):
self.timed_exam_completed_msg = 'This is the end of your timed exam'
self.start_a_practice_exam_msg = 'Would you like to take %s as a practice proctored exam?'
self.practice_exam_submitted_msg = 'You have submitted this practice proctored exam'
self.ready_to_start_msg = 'Your Proctoring Installation and Set Up is Complete'
set_runtime_service('credit', MockCreditService())
set_runtime_service('instructor', MockInstructorService())
......@@ -161,7 +162,8 @@ class ProctoredExamApiTests(LoggedInTestCase):
proctored_exam_id=self.proctored_exam_id if is_proctored else self.timed_exam,
user_id=self.user_id,
external_id=self.external_id,
allowed_time_limit_mins=10
allowed_time_limit_mins=10,
status='created'
)
def _create_started_exam_attempt(self, started_at=None, is_proctored=True):
......@@ -820,6 +822,27 @@ class ProctoredExamApiTests(LoggedInTestCase):
)
self.assertIsNone(rendered_response)
def test_get_studentview_ready(self):
"""
Assert that we get the right content
when the exam is ready to be started
"""
exam_attempt = self._create_started_exam_attempt()
exam_attempt.status = ProctoredExamStudentAttemptStatus.ready_to_start
exam_attempt.save()
rendered_response = get_student_view(
user_id=self.user_id,
course_id=self.course_id,
content_id=self.content_id,
context={
'is_proctored': True,
'display_name': self.exam_name,
'default_time_limit_mins': 90
}
)
self.assertIn(self.ready_to_start_msg, rendered_response)
def test_get_studentview_started_exam(self): # pylint: disable=invalid-name
"""
Test for get_student_view proctored exam which has started.
......@@ -869,7 +892,7 @@ class ProctoredExamApiTests(LoggedInTestCase):
Test for get_student_view proctored exam which has been submitted.
"""
exam_attempt = self._create_started_exam_attempt()
exam_attempt.status = "submitted"
exam_attempt.status = ProctoredExamStudentAttemptStatus.submitted
exam_attempt.save()
rendered_response = get_student_view(
......@@ -905,7 +928,7 @@ class ProctoredExamApiTests(LoggedInTestCase):
Test for get_student_view proctored exam which has been rejected.
"""
exam_attempt = self._create_started_exam_attempt()
exam_attempt.status = "rejected"
exam_attempt.status = ProctoredExamStudentAttemptStatus.rejected
exam_attempt.save()
rendered_response = get_student_view(
......@@ -925,7 +948,7 @@ class ProctoredExamApiTests(LoggedInTestCase):
Test for get_student_view proctored exam which has been verified.
"""
exam_attempt = self._create_started_exam_attempt()
exam_attempt.status = "verified"
exam_attempt.status = ProctoredExamStudentAttemptStatus.verified
exam_attempt.save()
rendered_response = get_student_view(
......
......@@ -14,34 +14,34 @@ class TestHumanizedTime(unittest.TestCase):
tests the humanized_time utility function against different values.
"""
human_time = humanized_time(0)
self.assertEqual(human_time, "0 Minutes")
self.assertEqual(human_time, "0 minutes")
human_time = humanized_time(1)
self.assertEqual(human_time, "1 Minute")
self.assertEqual(human_time, "1 minute")
human_time = humanized_time(10)
self.assertEqual(human_time, "10 Minutes")
self.assertEqual(human_time, "10 minutes")
human_time = humanized_time(60)
self.assertEqual(human_time, "1 Hour")
self.assertEqual(human_time, "1 hour")
human_time = humanized_time(61)
self.assertEqual(human_time, "1 Hour and 1 Minute")
self.assertEqual(human_time, "1 hour and 1 minute")
human_time = humanized_time(62)
self.assertEqual(human_time, "1 Hour and 2 Minutes")
self.assertEqual(human_time, "1 hour and 2 minutes")
human_time = humanized_time(120)
self.assertEqual(human_time, "2 Hours")
self.assertEqual(human_time, "2 hours")
human_time = humanized_time(121)
self.assertEqual(human_time, "2 Hours and 1 Minute")
self.assertEqual(human_time, "2 hours and 1 minute")
human_time = humanized_time(150)
self.assertEqual(human_time, "2 Hours and 30 Minutes")
self.assertEqual(human_time, "2 hours and 30 minutes")
human_time = humanized_time(180)
self.assertEqual(human_time, "3 Hours")
self.assertEqual(human_time, "3 hours")
human_time = humanized_time(-60)
self.assertEqual(human_time, "error")
......@@ -33,10 +33,10 @@ def humanized_time(time_in_minutes):
hours_present = False
template = ""
elif hours == 1:
template = _("{num_of_hours} Hour")
template = _("{num_of_hours} hour")
hours_present = True
elif hours >= 2:
template = _("{num_of_hours} Hours")
template = _("{num_of_hours} hours")
hours_present = True
else:
template = "error"
......@@ -44,17 +44,17 @@ def humanized_time(time_in_minutes):
if template != "error":
if minutes == 0:
if not hours_present:
template = _("{num_of_minutes} Minutes")
template = _("{num_of_minutes} minutes")
elif minutes == 1:
if hours_present:
template += _(" and {num_of_minutes} Minute")
template += _(" and {num_of_minutes} minute")
else:
template += _("{num_of_minutes} Minute")
template += _("{num_of_minutes} minute")
else:
if hours_present:
template += _(" and {num_of_minutes} Minutes")
template += _(" and {num_of_minutes} minutes")
else:
template += _("{num_of_minutes} Minutes")
template += _("{num_of_minutes} minutes")
human_time = template.format(num_of_hours=hours, num_of_minutes=minutes)
return human_time
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