Commit e06b956f by chrisndodge

Merge pull request #229 from edx/muhhshoaib/PHX-161-set-review-policy-helper-methods

PHX-161 added the new helper methods to create/update review policy for proctored exams
parents e3de2426 b4d47eb1
......@@ -26,6 +26,8 @@ from edx_proctoring.exceptions import (
ProctoredExamIllegalStatusTransition,
ProctoredExamPermissionDenied,
ProctoredExamNotActiveException,
ProctoredExamReviewPolicyNotFoundException,
ProctoredExamReviewPolicyAlreadyExists
)
from edx_proctoring.models import (
ProctoredExam,
......@@ -38,6 +40,7 @@ from edx_proctoring.serializers import (
ProctoredExamSerializer,
ProctoredExamStudentAttemptSerializer,
ProctoredExamStudentAllowanceSerializer,
ProctoredExamReviewPolicySerializer
)
from edx_proctoring.utils import (
humanized_time,
......@@ -96,6 +99,106 @@ def create_exam(course_id, content_id, exam_name, time_limit_mins, due_date=None
return proctored_exam.id
def create_exam_review_policy(exam_id, set_by_user_id, review_policy):
"""
Creates a new exam_review_policy entity, if the review_policy
for exam_id does not already exist. If it exists, then raise exception.
Returns: id (PK)
"""
exam_review_policy = ProctoredExamReviewPolicy.get_review_policy_for_exam(exam_id)
if exam_review_policy is not None:
raise ProctoredExamReviewPolicyAlreadyExists
exam_review_policy = ProctoredExamReviewPolicy.objects.create(
proctored_exam_id=exam_id,
set_by_user_id=set_by_user_id,
review_policy=review_policy
)
log_msg = (
u'Created ProctoredExamReviewPolicy ({review_policy}) with parameters: exam_id={exam_id}, '
u'set_by_user_id={set_by_user_id}'.format(
exam_id=exam_id,
review_policy=review_policy,
set_by_user_id=set_by_user_id
)
)
log.info(log_msg)
return exam_review_policy.id
def update_review_policy(exam_id, set_by_user_id, review_policy):
"""
Given a exam id, update/remove the existing record, otherwise raise exception if not found.
Returns: review_policy_id
"""
log_msg = (
u'Updating exam review policy with exam_id {exam_id}'
u'set_by_user_id={set_by_user_id}, review_policy={review_policy}'
.format(
exam_id=exam_id, set_by_user_id=set_by_user_id, review_policy=review_policy,
)
)
log.info(log_msg)
exam_review_policy = ProctoredExamReviewPolicy.get_review_policy_for_exam(exam_id)
if exam_review_policy is None:
raise ProctoredExamReviewPolicyNotFoundException
if review_policy:
exam_review_policy.set_by_user_id = set_by_user_id
exam_review_policy.review_policy = review_policy
exam_review_policy.save()
msg = 'Updated exam review policy with {exam_id}'.format(exam_id=exam_id)
log.info(msg)
else:
exam_review_policy.delete()
msg = 'removed exam review policy with {exam_id}'.format(exam_id=exam_id)
log.info(msg)
def remove_review_policy(exam_id):
"""
Given a exam id, remove the existing record, otherwise raise exception if not found.
"""
log_msg = (
u'removing exam review policy with exam_id {exam_id}'
.format(exam_id=exam_id)
)
log.info(log_msg)
exam_review_policy = ProctoredExamReviewPolicy.get_review_policy_for_exam(exam_id)
if exam_review_policy is None:
raise ProctoredExamReviewPolicyNotFoundException
exam_review_policy.delete()
def get_review_policy_by_exam_id(exam_id):
"""
Looks up exam by the Primary Key. Raises exception if not found.
Returns dictionary version of the Django ORM object
e.g.
{
"id": 1
"proctored_exam": "{object}",
"set_by_user": "{object}",
"exam_review_rules": "review rules value"
"created": "datetime",
"modified": "datetime"
}
"""
exam_review_policy = ProctoredExamReviewPolicy.get_review_policy_for_exam(exam_id)
if exam_review_policy is None:
raise ProctoredExamReviewPolicyNotFoundException
return ProctoredExamReviewPolicySerializer(exam_review_policy).data
def update_exam(exam_id, exam_name=None, time_limit_mins=None, due_date=constants.MINIMUM_TIME,
is_proctored=None, is_practice_exam=None, external_id=None, is_active=None):
"""
......
......@@ -21,6 +21,18 @@ class ProctoredExamNotFoundException(ProctoredBaseException):
"""
class ProctoredExamReviewPolicyNotFoundException(ProctoredBaseException):
"""
Raised when a look up fails.
"""
class ProctoredExamReviewPolicyAlreadyExists(ProctoredBaseException):
"""
Raised when trying to create an ProctoredExamReviewPolicy that already exists.
"""
class ProctoredExamNotActiveException(ProctoredBaseException):
"""
Raised when a look up fails.
......
......@@ -2,7 +2,12 @@
from rest_framework import serializers
from rest_framework.fields import DateTimeField
from django.contrib.auth.models import User
from edx_proctoring.models import ProctoredExam, ProctoredExamStudentAttempt, ProctoredExamStudentAllowance
from edx_proctoring.models import (
ProctoredExam,
ProctoredExamStudentAttempt,
ProctoredExamStudentAllowance,
ProctoredExamReviewPolicy
)
class ProctoredExamSerializer(serializers.ModelSerializer):
......@@ -95,3 +100,20 @@ class ProctoredExamStudentAllowanceSerializer(serializers.ModelSerializer):
fields = (
"id", "created", "modified", "user", "key", "value", "proctored_exam"
)
class ProctoredExamReviewPolicySerializer(serializers.ModelSerializer):
"""
Serializer for the ProctoredExamStudentAllowance Model.
"""
proctored_exam = ProctoredExamSerializer()
set_by_user = UserSerializer()
class Meta:
"""
Meta Class
"""
model = ProctoredExamReviewPolicy
fields = (
"id", "created", "modified", "set_by_user", "proctored_exam", "review_policy"
)
......@@ -39,6 +39,10 @@ from edx_proctoring.api import (
_check_for_attempt_timeout,
_get_ordered_prerequisites,
_are_prerequirements_satisfied,
create_exam_review_policy,
get_review_policy_by_exam_id,
update_review_policy,
remove_review_policy,
)
from edx_proctoring.exceptions import (
ProctoredExamAlreadyExists,
......@@ -49,7 +53,9 @@ from edx_proctoring.exceptions import (
UserNotFoundException,
ProctoredExamIllegalStatusTransition,
ProctoredExamPermissionDenied,
AllowanceValueNotAllowedException
AllowanceValueNotAllowedException,
ProctoredExamReviewPolicyAlreadyExists,
ProctoredExamReviewPolicyNotFoundException
)
from edx_proctoring.models import (
ProctoredExam,
......@@ -417,6 +423,143 @@ class ProctoredExamApiTests(LoggedInTestCase):
exams = get_all_exams_for_course(self.course_id, False)
self.assertEqual(len(exams), 4)
def test_create_exam_review_policy(self):
"""
Test to create a new exam review policy for
proctored exam and tests that it stores in the
db correctly
"""
proctored_exam = get_exam_by_id(self.proctored_exam_id)
create_exam_review_policy(
exam_id=proctored_exam['id'],
set_by_user_id=self.user_id,
review_policy=u'allow use of paper'
)
# now get the exam review policy for the proctored exam
exam_review_policy = get_review_policy_by_exam_id(proctored_exam['id'])
self.assertEqual(exam_review_policy['proctored_exam']['id'], proctored_exam['id'])
self.assertEqual(exam_review_policy['set_by_user']['id'], self.user_id)
self.assertEqual(exam_review_policy['review_policy'], u'allow use of paper')
def test_update_exam_review_policy(self):
"""
Test to update existing exam review policy for
proctored exam and tests that it stores in the
db correctly and set the exam review policy to ''
will remove the entry from the database.
"""
proctored_exam = get_exam_by_id(self.proctored_exam_id)
create_exam_review_policy(
exam_id=proctored_exam['id'],
set_by_user_id=self.user_id,
review_policy=u'allow use of paper'
)
# now update the exam review policy for the proctored exam
update_review_policy(
exam_id=proctored_exam['id'],
set_by_user_id=self.user_id,
review_policy=u'allow use of calculator'
)
# now get the updated exam review policy for the proctored exam
exam_review_policy = get_review_policy_by_exam_id(proctored_exam['id'])
self.assertEqual(exam_review_policy['proctored_exam']['id'], proctored_exam['id'])
self.assertEqual(exam_review_policy['set_by_user']['id'], self.user_id)
self.assertEqual(exam_review_policy['review_policy'], u'allow use of calculator')
# now update the exam review policy for the proctored exam
# with review_policy value to "". This will delete the exam
# review policy object from the database.
update_review_policy(
exam_id=proctored_exam['id'],
set_by_user_id=self.user_id,
review_policy=u''
)
with self.assertRaises(ProctoredExamReviewPolicyNotFoundException):
get_review_policy_by_exam_id(proctored_exam['id'])
def test_remove_existing_exam_review_policy(self):
"""
Test to remove existing exam review policy for
proctored exam
"""
proctored_exam = get_exam_by_id(self.proctored_exam_id)
create_exam_review_policy(
exam_id=proctored_exam['id'],
set_by_user_id=self.user_id,
review_policy=u'allow use of paper'
)
# now remove the exam review policy for the proctored exam
remove_review_policy(
exam_id=proctored_exam['id']
)
# now get the exam review policy for the proctored exam
# which will raise the exception because the exam review
# policy has been removed.
with self.assertRaises(ProctoredExamReviewPolicyNotFoundException):
get_review_policy_by_exam_id(proctored_exam['id'])
def test_remove_non_existing_exam_review_policy(self):
"""
Test to remove non existing exam review policy for
proctored exam which will raise exception
"""
proctored_exam = get_exam_by_id(self.proctored_exam_id)
# now try to remove the non-existing exam review policy
# for the proctored exam which will raise exception
with self.assertRaises(ProctoredExamReviewPolicyNotFoundException):
remove_review_policy(
exam_id=proctored_exam['id']
)
def test_update_non_existing_exam_review_policy(self):
"""
Test to update non existing exam review policy for
proctored exam and it will raises exception
"""
# update the non existing exam review policy for the proctored exam
with self.assertRaises(ProctoredExamReviewPolicyNotFoundException):
update_review_policy(
exam_id=self.practice_exam_id,
set_by_user_id=10,
review_policy=u'allow use of calculator'
)
def test_create_exam_review_policy_with_same_exam_id(self):
"""
Test to create a same exam review policy will raise exception
"""
proctored_exam = get_exam_by_id(self.proctored_exam_id)
create_exam_review_policy(
exam_id=proctored_exam['id'],
set_by_user_id=self.user_id,
review_policy=u'allow use of paper'
)
# create the same review policy again will raise exception
with self.assertRaises(ProctoredExamReviewPolicyAlreadyExists):
create_exam_review_policy(
exam_id=proctored_exam['id'],
set_by_user_id=self.user_id,
review_policy=u'allow use of paper'
)
def test_get_non_existing_review_policy_raises_exception(self):
"""
Test to get the non-existing review policy raises exception
"""
with self.assertRaises(ProctoredExamReviewPolicyNotFoundException):
# now get the exam review policy for the proctored exam
get_review_policy_by_exam_id(self.practice_exam_id)
def test_get_timed_exam(self):
"""
test to get the exam by the exam_id and
......
......@@ -34,7 +34,7 @@ def load_requirements(*requirements_paths):
setup(
name='edx-proctoring',
version='0.11.2',
version='0.11.8',
description='Proctoring subsystem for Open edX',
long_description=open('README.md').read(),
author='edX',
......
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