Commit 51c79046 by Afzal Wali Committed by Muhammad Shoaib

Added the attempts history table.

parent 185e8304
......@@ -208,6 +208,68 @@ class ProctoredExamStudentAttempt(TimeStampedModel):
"""
self.delete()
class ProctoredExamStudentAttemptHistory(TimeStampedModel):
"""
This should be the same schema as ProctoredExamStudentAttempt
but will record (for audit history) all entries that have been updated.
"""
user = models.ForeignKey(User, db_index=True)
proctored_exam = models.ForeignKey(ProctoredExam, db_index=True)
# started/completed date times
started_at = models.DateTimeField(null=True)
completed_at = models.DateTimeField(null=True)
# this will be a unique string ID that the user
# will have to use when starting the proctored exam
attempt_code = models.CharField(max_length=255, null=True, db_index=True)
# This will be a integration specific ID - say to SoftwareSecure.
external_id = models.CharField(max_length=255, null=True, db_index=True)
# this is the time limit allowed to the student
allowed_time_limit_mins = models.IntegerField()
# what is the status of this attempt
status = models.CharField(max_length=64)
# if the user is attempting this as a proctored exam
# in case there is an option to opt-out
taking_as_proctored = models.BooleanField()
# Whether this attampt is considered a sample attempt, e.g. to try out
# the proctoring software
is_sample_attempt = models.BooleanField()
student_name = models.CharField(max_length=255)
@receiver(pre_delete, sender=ProctoredExamStudentAttempt)
def on_attempt_deleted(sender, instance, **kwargs): # pylint: disable=unused-argument
"""
Archive the exam attempt when the item is about to be deleted
Make a clone and populate in the History table
"""
archive_object = ProctoredExamStudentAttemptHistory(
user=instance.user,
proctored_exam=instance.proctored_exam,
started_at=instance.started_at,
completed_at=instance.completed_at,
attempt_code=instance.attempt_code,
external_id=instance.external_id,
allowed_time_limit_mins=instance.allowed_time_limit_mins,
status=instance.status,
taking_as_proctored=instance.taking_as_proctored,
is_sample_attempt=instance.is_sample_attempt,
student_name=instance.student_name
)
archive_object.save()
class QuerySetWithUpdateOverride(models.query.QuerySet):
"""
Custom QuerySet class to make an archive copy
......
......@@ -31,19 +31,23 @@
<% } %>
</td>
<td>
<% if (proctored_exam_attempt.completed_at){ %>
<% if (proctored_exam_attempt.completed_at){ %>
<%= proctored_exam_attempt.completed_at %> </td>
<% } else { %>
N/A
<% } %>
<td>
<% if (proctored_exam_attempt.status){ %>
<% if (proctored_exam_attempt.status){ %>
<%= proctored_exam_attempt.status %> </td>
<% } else { %>
N/A
<% } %>
<td>
<% if (proctored_exam_attempt.status){ %>
<button type="button" class="remove-attempt blue-button" data-attempt-id="<%= proctored_exam_attempt.id %>" ><%- gettext("Remove") %></button>
<% } else { %>
N/A
<% } %>
</td>
</tr>
<% }); %>
......
"""
All tests for the models.py
"""
from edx_proctoring.models import ProctoredExam, ProctoredExamStudentAllowance, ProctoredExamStudentAllowanceHistory
from edx_proctoring.models import ProctoredExam, ProctoredExamStudentAllowance, ProctoredExamStudentAllowanceHistory, \
ProctoredExamStudentAttempt, ProctoredExamStudentAttemptHistory
from .utils import (
LoggedInTestCase
......@@ -104,3 +105,39 @@ class ProctoredExamModelTests(LoggedInTestCase):
proctored_exam_student_history = ProctoredExamStudentAllowanceHistory.objects.filter(user_id=1)
self.assertEqual(len(proctored_exam_student_history), 1)
class ProctoredExamStudentAttemptTests(LoggedInTestCase):
"""
Tests for the ProctoredExamStudentAttempt Model
"""
def test_delete_proctored_exam_attempt(self): # pylint: disable=invalid-name
"""
"""
proctored_exam = ProctoredExam.objects.create(
course_id='test_course',
content_id='test_content',
exam_name='Test Exam',
external_id='123aXqe3',
time_limit_mins=90
)
attempt = ProctoredExamStudentAttempt.objects.create(
proctored_exam_id=proctored_exam.id,
user_id=1,
student_name="John. D",
allowed_time_limit_mins=10,
attempt_code="123456",
taking_as_proctored=True,
is_sample_attempt=True,
external_id=1
)
# No entry in the History table on creation of the Allowance entry.
attempt_history = ProctoredExamStudentAttemptHistory.objects.filter(user_id=1)
self.assertEqual(len(attempt_history), 0)
attempt.delete()
attempt_history = ProctoredExamStudentAttemptHistory.objects.filter(user_id=1)
self.assertEqual(len(attempt_history), 1)
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