Commit 4333ba90 by chrisndodge

Merge pull request #14 from edx/muhhshoaib/PHX-47-proctoring-launch-screen

PHX-47 added the html for the proctored exam instruction template
parents 923f51b1 7e10f65d
......@@ -149,7 +149,8 @@ def get_exam_attempt(exam_id, user_id):
Return an existing exam attempt for the given student
"""
exam_attempt_obj = ProctoredExamStudentAttempt.get_exam_attempt(exam_id, user_id)
return exam_attempt_obj.__dict__ if exam_attempt_obj else None
serialized_attempt_obj = ProctoredExamStudentAttemptSerializer(exam_attempt_obj)
return serialized_attempt_obj.data if exam_attempt_obj else None
def create_exam_attempt(exam_id, user_id, external_id):
......@@ -303,6 +304,7 @@ def get_student_view(user_id, course_id, content_id, context):
student_view_template = 'proctoring/seq_proctored_exam_entrance.html'
else:
student_view_template = 'proctoring/seq_proctored_exam_instructions.html'
context.update({'exam_code': '@asDASD@E2313213SDASD213123423WEWA'})
else:
student_view_template = 'proctoring/seq_timed_exam_entrance.html'
elif has_finished_exam:
......
......@@ -46,14 +46,17 @@ class ProctoredExamStudentAttemptSerializer(serializers.ModelSerializer):
"""
Serializer for the ProctoredExamStudentAttempt Model.
"""
proctored_exam_id = serializers.IntegerField(source="proctored_exam_id")
class Meta:
"""
Meta Class
"""
model = ProctoredExamStudentAttempt
fields = (
"id", "created", "modified", "user_id", "started_at", "completed_at",
"external_id", "status"
"external_id", "status", "proctored_exam_id"
)
......
{% load i18n %}
<div class="sequence" data-exam-id="{{exam_id}}">
</div>
<div class="sequence proctored-exam entrance" data-exam-id="{{exam_id}}">
<h3>
{% blocktrans %}
......@@ -40,6 +38,14 @@
<i class="fa fa-arrow-circle-right start-timed-exam" data-ajax-url="{{enter_exam_endpoint}}" data-exam-id="{{exam_id}}" data-attempt-proctored=false></i>
</div>
</div>
<div class="footer-sequence">
<h4> {% trans "Why i am seeing these options?" %} </h4>
<p>
{% blocktrans %}
Text to be added here.
{% endblocktrans %}
</p>
</div>
{% include 'proctoring/seq_proctored_exam_footer.html' %}
<script type="text/javascript">
......
{% load i18n %}
<div class="footer-sequence">
<h4> {% trans "Why i am seeing these options?" %} </h4>
<p>
{% blocktrans %}
Text to be added here.
{% endblocktrans %}
</p>
</div>
<div class="faq-proctoring-exam">
<h4> {% trans "See Also" %} </h4>
<p>
......
{% load i18n %}
<div class="sequence" data-exam-id="{{exam_id}}">
How to launch the proctored exam content goes here
<div class="sequence proctored-exam instructions" data-exam-id="{{exam_id}}">
<h3>
{% blocktrans %}
Awaiting Proctoring Installation & Set Up
{% endblocktrans %}
</h3>
<p>
{% blocktrans %}
you have chosen to take {{display_name}} as a proctored exam. You should be redirected to a new window
with installation and setup instructions. You can also <a href="#">open the installation</a>
{% endblocktrans %}
</p>
<div class="proctored-exam-message">
<h3>
{% blocktrans %}
Here is your unique exam code. You'll be asked for it during the setup.
{% endblocktrans %}
</h3>
<h1> {{exam_code}}</h1>
<p>
{% blocktrans %}
Please do not share this code. It can only be used once and it tied to your edX Account.
{% endblocktrans %}
</p>
</div>
</div>
<div class="footer-sequence border-b-0 padding-b-0">
<span> {% trans "Note: Once you complete your installation and set up, your timed exam will begin." %} </span>
<p>
{% blocktrans %}
Please be prepared to start the exam and follow all the guidelines of an edX proctored exam.
{% endblocktrans %}
</p>
<p class="proctored-exam-option">
{% blocktrans %}
Don't want to take this as a proctored exam? <a href="#">Take this as an open exam instead.</a>
{% endblocktrans %}
</p>
</div>
{% include 'proctoring/seq_proctored_exam_footer.html' %}
{% load i18n %}
<div class="sequence timed-exam expired">
<div class="gated-sequence">
{% trans "You have run out of time!" %}
</div>
<div class="critical-time sequence proctored-exam entrance" data-exam-id="{{exam_id}}">
<h3>
{% blocktrans %}
You did not complete the exam in the allotted time
{% endblocktrans %}
</h3>
<p>
{% blocktrans %}
Since you did not submit your exam before the time allotted expired, your work cannot be
considered as an exam that is eligible for credit. Any work you've completed may still be counted for
partial credit towards your grade.
{% endblocktrans %}
</p>
<div class="proctored-exam-message">
<p>
{% blocktrans %}
Please see <a href="#">your progress in this course</a> for your general course credit worthiness.
{% endblocktrans %}
</p>
</div>
</div>
{% include 'proctoring/seq_timed_exam_footer.html' %}
\ No newline at end of file
<div class="footer-sequence border-b-0 padding-b-0">
<span> {% trans "Is there anything i can do to make up/replace this session ?" %} </span>
<p>
{% blocktrans %}
text goes here.
{% endblocktrans %}
</p>
</div>
{% include 'proctoring/seq_timed_exam_footer.html' %}
......@@ -20,7 +20,8 @@ from edx_proctoring.exceptions import (
ProctoredExamAlreadyExists,
ProctoredExamNotFoundException,
StudentExamAttemptAlreadyExistsException,
StudentExamAttemptDoesNotExistsException
StudentExamAttemptDoesNotExistsException,
StudentExamAttemptedAlreadyStarted
)
from edx_proctoring.models import (
ProctoredExam,
......@@ -64,7 +65,17 @@ class ProctoredExamApiTests(LoggedInTestCase):
time_limit_mins=self.default_time_limit
)
def _create_student_exam_attempt(self):
def _create_unstarted_exam_attempt(self):
"""
Creates the ProctoredExamStudentAttempt object.
"""
return ProctoredExamStudentAttempt.objects.create(
proctored_exam_id=self.proctored_exam_id,
user_id=self.user_id,
external_id=self.external_id
)
def _create_started_exam_attempt(self):
"""
Creates the ProctoredExamStudentAttempt object.
"""
......@@ -195,30 +206,54 @@ class ProctoredExamApiTests(LoggedInTestCase):
attempt_id = create_exam_attempt(self.proctored_exam_id, self.user_id, '')
self.assertGreater(attempt_id, 0)
def test_recreate_an_exam_attempt(self):
"""
Start an exam attempt that has already been created.
Raises StudentExamAttemptAlreadyExistsException
"""
proctored_exam_student_attempt = self._create_unstarted_exam_attempt()
with self.assertRaises(StudentExamAttemptAlreadyExistsException):
create_exam_attempt(proctored_exam_student_attempt.proctored_exam, self.user_id, self.external_id)
def test_get_exam_attempt(self):
"""
Test to get the already made exam attempt.
"""
self._create_student_exam_attempt()
self._create_unstarted_exam_attempt()
exam_attempt = get_exam_attempt(self.proctored_exam_id, self.user_id)
self.assertEqual(exam_attempt['proctored_exam_id'], self.proctored_exam_id)
self.assertEqual(exam_attempt['user_id'], self.user_id)
def test_restart_exam_attempt(self):
def test_start_uncreated_attempt(self):
"""
Start an exam attempt that has already been started.
Raises StudentExamAttemptAlreadyExistsException
Test to attempt starting an attempt which has not been created yet.
should raise an exception.
"""
proctored_exam_student_attempt = self._create_student_exam_attempt()
with self.assertRaises(StudentExamAttemptAlreadyExistsException):
create_exam_attempt(proctored_exam_student_attempt.proctored_exam, self.user_id, self.external_id)
with self.assertRaises(StudentExamAttemptDoesNotExistsException):
start_exam_attempt(self.proctored_exam_id, self.user_id)
def test_start_a_created_attempt(self):
"""
Test to attempt starting an attempt which has been created but not started.
"""
self._create_unstarted_exam_attempt()
start_exam_attempt(self.proctored_exam_id, self.user_id)
def test_restart_a_started_attempt(self):
"""
Test to attempt starting an attempt which has been created but not started.
"""
self._create_unstarted_exam_attempt()
start_exam_attempt(self.proctored_exam_id, self.user_id)
with self.assertRaises(StudentExamAttemptedAlreadyStarted):
start_exam_attempt(self.proctored_exam_id, self.user_id)
def test_stop_exam_attempt(self):
"""
Stop an exam attempt.
"""
proctored_exam_student_attempt = self._create_student_exam_attempt()
proctored_exam_student_attempt = self._create_unstarted_exam_attempt()
self.assertIsNone(proctored_exam_student_attempt.completed_at)
proctored_exam_attempt_id = stop_exam_attempt(
proctored_exam_student_attempt.proctored_exam, self.user_id
......@@ -237,7 +272,7 @@ class ProctoredExamApiTests(LoggedInTestCase):
Test to get the all the active
exams for the user.
"""
active_exam_attempt = self._create_student_exam_attempt()
active_exam_attempt = self._create_started_exam_attempt()
self.assertEqual(active_exam_attempt.is_active, True)
exam_id = create_exam(
course_id=self.course_id,
......
......@@ -486,6 +486,14 @@ class TestStudentProctoredExamAttempt(LoggedInTestCase):
)
self.assertEqual(response.status_code, 200)
ProctoredExamStudentAttempt.objects.filter(
proctored_exam_id=proctored_exam.id,
user_id=self.user.id,
external_id=proctored_exam.external_id,
).update(
started_at=datetime.now(pytz.UTC)
)
response = self.client.get(
reverse('edx_proctoring.proctored_exam.attempt')
)
......
......@@ -239,7 +239,7 @@ class StudentProctoredExamAttempt(AuthenticatedAPIView):
def post(self, request):
"""
HTTP POST handler. To create an exam.
HTTP POST handler. To create an exam attempt.
"""
start_immediately = request.DATA.get('start_clock', 'false').lower() == 'true'
exam_id = request.DATA.get('exam_id', None)
......
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