Commit 16dd840b by Chris Dodge

add different views depending if exam attempt is a sample attempt

parent db5d3fa1
...@@ -549,6 +549,7 @@ def get_student_view(user_id, course_id, content_id, ...@@ -549,6 +549,7 @@ def get_student_view(user_id, course_id, content_id,
is_proctored=is_proctored, is_proctored=is_proctored,
is_practice_exam=is_practice_exam is_practice_exam=is_practice_exam
) )
exam = get_exam_by_content_id(course_id, content_id)
attempt = get_exam_attempt(exam_id, user_id) attempt = get_exam_attempt(exam_id, user_id)
has_started_exam = attempt and attempt.get('started_at') has_started_exam = attempt and attempt.get('started_at')
...@@ -573,7 +574,10 @@ def get_student_view(user_id, course_id, content_id, ...@@ -573,7 +574,10 @@ def get_student_view(user_id, course_id, content_id,
if is_proctored: if is_proctored:
if not attempt: if not attempt:
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:
student_view_template = 'proctoring/seq_proctored_exam_entrance.html'
else: else:
provider = get_backend_provider() provider = get_backend_provider()
student_view_template = 'proctoring/seq_proctored_exam_instructions.html' student_view_template = 'proctoring/seq_proctored_exam_instructions.html'
...@@ -586,7 +590,10 @@ def get_student_view(user_id, course_id, content_id, ...@@ -586,7 +590,10 @@ def get_student_view(user_id, course_id, content_id,
elif attempt['status'] == ProctoredExamStudentAttemptStatus.timed_out: elif attempt['status'] == ProctoredExamStudentAttemptStatus.timed_out:
student_view_template = 'proctoring/seq_timed_exam_expired.html' student_view_template = 'proctoring/seq_timed_exam_expired.html'
elif attempt['status'] == ProctoredExamStudentAttemptStatus.submitted: elif attempt['status'] == ProctoredExamStudentAttemptStatus.submitted:
student_view_template = 'proctoring/seq_proctored_exam_submitted.html' if attempt['is_sample_attempt']:
student_view_template = 'proctoring/seq_proctored_practice_exam_submitted.html'
else:
student_view_template = 'proctoring/seq_proctored_exam_submitted.html'
elif attempt['status'] == ProctoredExamStudentAttemptStatus.verified: elif attempt['status'] == ProctoredExamStudentAttemptStatus.verified:
student_view_template = 'proctoring/seq_proctored_exam_verified.html' student_view_template = 'proctoring/seq_proctored_exam_verified.html'
elif attempt['status'] == ProctoredExamStudentAttemptStatus.rejected: elif attempt['status'] == ProctoredExamStudentAttemptStatus.rejected:
......
...@@ -131,7 +131,7 @@ class ProctoredExamStudentAttemptManager(models.Manager): ...@@ -131,7 +131,7 @@ class ProctoredExamStudentAttemptManager(models.Manager):
Q(user__username__contains=search_by) | Q(user__email__contains=search_by) Q(user__username__contains=search_by) | Q(user__email__contains=search_by)
) )
return self.filter(filtered_query) return self.filter(filtered_query).order_by('-created')
def get_active_student_attempts(self, user_id, course_id=None): def get_active_student_attempts(self, user_id, course_id=None):
""" """
......
{% load i18n %}
<div class="sequence proctored-exam entrance" data-exam-id="{{exam_id}}">
<h3>
{% blocktrans %}
Would you like to take {{ display_name }} as a practice proctored exam?
{% endblocktrans %}
</h3>
<p>
{% blocktrans %}
Since you're enrolled in this course as a verified student, you have the option practice taking a proctored exam. Online proctoring is one requirement towards being eligible for credit.
{% endblocktrans %}
</p>
<p>
{% blocktrans %}
This practice proctored exam is being provided to you so that you can learn more about proctoring. Also this
practice exam will give you a chance to test your computer system with the proctoring software without it
counting towards your grade.
{% endblocktrans %}
</p>
<p>
{% blocktrans %}
While it is not requireed to take this practice proctored exam, it is highly recommended.
{% endblocktrans %}
</p>
<div class="gated-sequence">
<span><i class="fa fa-lock"></i></span>
<a class="start-timed-exam" data-ajax-url="{{enter_exam_endpoint}}" data-exam-id="{{exam_id}}" data-attempt-proctored=true data-start-immediately=false>
{% trans "Yes, I want to take this practice exam with online proctoring" %}
</a>
<p>
{% blocktrans %}
You will be guided through installing {{platform_name}} approved online proctoring software and
performing various checks to set up your proctored exam session. Have your photo ID
ready for the photo ID verification step.<br />
Immediately after you complete the set up, you will begin your timed and proctored exam.<br />
Before you set up your proctoring session, you might want to <a href="#">read this</a>
to learn more about taking a proctored exam.<br />
{% endblocktrans %}
</p>
<i class="fa fa-arrow-circle-right start-timed-exam" data-ajax-url="{{enter_exam_endpoint}}" data-exam-id="{{exam_id}}" data-attempt-proctored=true data-start-immediately=false></i>
</div>
</div>
{% include 'proctoring/seq_proctored_exam_footer.html' %}
<script type="text/javascript">
$('.start-timed-exam').click(
function(event) {
var action_url = $(this).data('ajax-url');
var exam_id = $(this).data('exam-id');
var attempt_proctored = $(this).data('attempt-proctored');
var start_immediately = $(this).data('start-immediately');
if (typeof action_url === "undefined" ) {
return false;
}
$.post(
action_url,
{
"exam_id": exam_id,
"attempt_proctored": attempt_proctored,
"start_clock": start_immediately
},
function(data) {
// reload the page, because we've unlocked it
location.reload();
}
);
}
);
</script>
{% load i18n %}
<div class="sequence proctored-exam completed" data-exam-id="{{exam_id}}">
<h3>
{% blocktrans %}
You have submitted this practice proctored exam
{% endblocktrans %}
</h3>
<h4>
{% blocktrans %}
Your Practice Proctoring Session: <b> Completed </b>
{% endblocktrans %}
</h4>
<p>
{% blocktrans %}
As practice exams do not count towards a grade or credit eligibility
they are not reviewed. You have completed your practice exam and should continue
with the rest of your course
{% endblocktrans %}
</p>
</div>
...@@ -87,6 +87,8 @@ class ProctoredExamApiTests(LoggedInTestCase): ...@@ -87,6 +87,8 @@ class ProctoredExamApiTests(LoggedInTestCase):
self.proctored_exam_verified_msg = 'Your proctoring session was reviewed and passed all requirements' self.proctored_exam_verified_msg = 'Your proctoring session was reviewed and passed all requirements'
self.proctored_exam_rejected_msg = 'Your proctoring session was reviewed and did not pass requirements' self.proctored_exam_rejected_msg = 'Your proctoring session was reviewed and did not pass requirements'
self.timed_exam_completed_msg = 'This is the end of your timed exam' 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'
def _create_proctored_exam(self): def _create_proctored_exam(self):
""" """
...@@ -569,6 +571,20 @@ class ProctoredExamApiTests(LoggedInTestCase): ...@@ -569,6 +571,20 @@ class ProctoredExamApiTests(LoggedInTestCase):
self.assertIn('data-exam-id="%d"' % self.proctored_exam_id, rendered_response) self.assertIn('data-exam-id="%d"' % self.proctored_exam_id, rendered_response)
self.assertIn(self.start_an_exam_msg % self.exam_name, rendered_response) self.assertIn(self.start_an_exam_msg % self.exam_name, rendered_response)
# try practice exam variant
rendered_response = get_student_view(
user_id=self.user_id,
course_id=self.course_id,
content_id=self.content_id + 'foo',
context={
'is_proctored': True,
'display_name': self.exam_name,
'default_time_limit_mins': 90,
'is_practice_exam': True,
}
)
self.assertIn(self.start_a_practice_exam_msg % self.exam_name, rendered_response)
def test_get_honor_view_with_practice_exam(self): # pylint: disable=invalid-name def test_get_honor_view_with_practice_exam(self): # pylint: disable=invalid-name
""" """
Test for get_student_view prompting when the student is enrolled in non-verified Test for get_student_view prompting when the student is enrolled in non-verified
...@@ -706,6 +722,22 @@ class ProctoredExamApiTests(LoggedInTestCase): ...@@ -706,6 +722,22 @@ class ProctoredExamApiTests(LoggedInTestCase):
) )
self.assertIn(self.proctored_exam_submitted_msg, rendered_response) self.assertIn(self.proctored_exam_submitted_msg, rendered_response)
# test the variant if we are a sample attempt
exam_attempt.is_sample_attempt = True
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.practice_exam_submitted_msg, rendered_response)
def test_get_studentview_rejected_status(self): # pylint: disable=invalid-name def test_get_studentview_rejected_status(self): # pylint: disable=invalid-name
""" """
Test for get_student_view proctored exam which has been rejected. Test for get_student_view proctored exam which has been rejected.
......
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