Commit d1c9b6a2 by Afzal Wali

Added a test for create Exam REST API

parent bf15198d
......@@ -49,7 +49,7 @@ class ProctoredExam(TimeStampedModel):
"""
try:
proctored_exam = cls.objects.get(course_id=course_id, content_id=content_id)
except cls.DoesNotExist:
except cls.DoesNotExist: # pylint: disable=no-member
proctored_exam = None
return proctored_exam
......@@ -61,7 +61,7 @@ class ProctoredExam(TimeStampedModel):
"""
try:
proctored_exam = cls.objects.get(id=exam_id)
except cls.DoesNotExist:
except cls.DoesNotExist: # pylint: disable=no-member
proctored_exam = None
return proctored_exam
......@@ -119,7 +119,7 @@ class ProctoredExamStudentAttempt(TimeStampedModel):
"""
try:
exam_attempt_obj = cls.objects.get(proctored_exam_id=exam_id, user_id=user_id)
except cls.DoesNotExist:
except cls.DoesNotExist: # pylint: disable=no-member
exam_attempt_obj = None
return exam_attempt_obj
......@@ -182,7 +182,7 @@ class ProctoredExamStudentAllowance(TimeStampedModel):
"""
try:
student_allowance = cls.objects.get(proctored_exam_id=exam_id, user_id=user_id, key=key)
except cls.DoesNotExist:
except cls.DoesNotExist: # pylint: disable=no-member
student_allowance = None
return student_allowance
......@@ -202,7 +202,7 @@ class ProctoredExamStudentAllowance(TimeStampedModel):
student_allowance = cls.objects.get(proctored_exam_id=exam_id, user_id=user_id, key=key)
student_allowance.value = value
student_allowance.save()
except cls.DoesNotExist:
except cls.DoesNotExist: # pylint: disable=no-member
cls.objects.create(proctored_exam_id=exam_id, user_id=user_id, key=key, value=value)
......
"""Defines serializers used by the Proctoring API."""
from django.conf import settings
from rest_framework import serializers
from edx_proctoring.models import ProctoredExam, ProctoredExamStudentAttempt, ProctoredExamStudentAllowance
class StrictBooleanField(serializers.BooleanField):
"""
Boolean field serializer to cater for a bug in DRF BooleanField serializer
where required=True is ignored.
"""
def from_native(self, value):
if value in ('true', 't', 'True', '1'):
return True
if value in ('false', 'f', 'False', '0'):
return False
return None
class ProctoredExamSerializer(serializers.ModelSerializer):
"""
Serializer for the ProctoredExam Model.
"""
course_id = serializers.RegexField(settings.COURSE_ID_REGEX, required=True)
content_id = serializers.CharField(required=True)
external_id = serializers.CharField(required=True)
exam_name = serializers.CharField(required=True)
time_limit_mins = serializers.IntegerField(required=True)
is_active = StrictBooleanField(required=True)
is_proctored = StrictBooleanField(required=True)
class Meta:
"""
Meta Class
"""
model = ProctoredExam
fields = (
"course_id", "content_id", "external_id", "exam_name",
"time_limit_mins", "is_proctored", "is_active"
......
......@@ -3,6 +3,7 @@ All tests for the proctored_exams.py
"""
from django.test.client import Client
from django.core.urlresolvers import reverse, NoReverseMatch
from edx_proctoring.models import ProctoredExam
from .utils import (
LoggedInTestCase
......@@ -35,16 +36,85 @@ class ProctoredExamsApiTests(LoggedInTestCase):
response = self.client.get(reverse(urlpattern.name))
except NoReverseMatch:
# some of our URL mappings may require a argument substitution
response = self.client.get(reverse(urlpattern.name, args=[0]))
try:
response = self.client.get(reverse(urlpattern.name, args=[0]))
except NoReverseMatch:
# some require 2 args.
response = self.client.get(reverse(urlpattern.name, args=["0/0/0", 0]))
self.assertEqual(response.status_code, 403)
def test_get_proctored_exam_status(self):
class StudentProctoredExamAttempt(LoggedInTestCase):
"""
Tests for StudentProctoredExamAttempt
"""
def test_get_exam_attempt(self):
"""
Test Case for retrieving student proctored exam status.
Test Case for retrieving student proctored exam attempt status.
"""
response = self.client.get(
reverse('edx_proctoring.proctored_exam.attempt')
)
self.assertEqual(response.status_code, 200)
class ProctoredExamViewTests(LoggedInTestCase):
"""
Tests for the ProctoredExamView
"""
def test_create_exam(self):
"""
Test the POST method of the exam endpoint to create an exam.
"""
exam_data = {
'course_id': "a/b/c",
'exam_name': "midterm1",
'content_id': '123aXqe0',
'time_limit_mins': 90,
'external_id': '123',
'is_proctored': True,
'is_active': True
}
response = self.client.post(
reverse('edx_proctoring.proctored_exam.exam'),
exam_data
)
self.assertEqual(response.status_code, 200)
self.assertGreater(response.data['exam_id'], 0)
# Now lookup the exam by giving the exam_id returned and match the data.
response = self.client.get(
reverse('edx_proctoring.proctored_exam.exam_by_id', kwargs={'exam_id': response.data['exam_id']})
)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data['course_id'], exam_data['course_id'])
self.assertEqual(response.data['exam_name'], exam_data['exam_name'])
self.assertEqual(response.data['content_id'], exam_data['content_id'])
self.assertEqual(response.data['external_id'], exam_data['external_id'])
self.assertEqual(response.data['time_limit_mins'], exam_data['time_limit_mins'])
def test_get_exam_by_id(self):
"""
Tests the Get Exam by id endpoint
"""
# Create an exam.
proctored_exam = ProctoredExam.objects.create(
course_id='test_course',
content_id='test_content',
exam_name='Test Exam',
external_id='123aXqe3',
time_limit_mins=90
)
response = self.client.get(
reverse('edx_proctoring.proctored_exam.exam_by_id', kwargs={'exam_id': proctored_exam.id})
)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data['course_id'], proctored_exam.course_id)
self.assertEqual(response.data['exam_name'], proctored_exam.exam_name)
self.assertEqual(response.data['content_id'], proctored_exam.content_id)
self.assertEqual(response.data['external_id'], proctored_exam.external_id)
self.assertEqual(response.data['time_limit_mins'], proctored_exam.time_limit_mins)
......@@ -16,13 +16,13 @@ urlpatterns = patterns( # pylint: disable=invalid-name
url(
r'edx_proctoring/v1/proctored_exam/exam/exam_id/(?P<exam_id>\d+)$',
views.ProctoredExamView.as_view(),
name='edx_proctoring.proctored_exam.exam'
name='edx_proctoring.proctored_exam.exam_by_id'
),
url(
r'edx_proctoring/v1/proctored_exam/exam/course_id/{}/content_id/(?P<content_id>\d+)$'.format(
settings.COURSE_ID_PATTERN),
views.ProctoredExamView.as_view(),
name='edx_proctoring.proctored_exam.exam'
name='edx_proctoring.proctored_exam.exam_by_content_id'
),
url(
r'edx_proctoring/v1/proctored_exam/attempt$',
......
......@@ -101,7 +101,15 @@ class ProctoredExamView(AuthenticatedAPIView):
serializer = ProctoredExamSerializer(data=request.DATA)
if serializer.is_valid():
try:
exam_id = create_exam(**request.DATA)
exam_id = create_exam(
course_id=request.DATA.get('course_id', None),
content_id=request.DATA.get('content_id', None),
exam_name=request.DATA.get('exam_name', None),
time_limit_mins=request.DATA.get('time_limit_mins', None),
is_proctored=request.DATA.get('is_proctored', None),
external_id=request.DATA.get('external_id', None),
is_active=request.DATA.get('is_active', None)
)
return Response({'exam_id': exam_id})
except ProctoredExamAlreadyExists:
return Response(
......
......@@ -68,4 +68,5 @@ MIDDLEWARE_CLASSES = (
ROOT_URLCONF = 'edx_proctoring.urls'
COURSE_ID_PATTERN = r'(?P<course_id>[^/+]+(/|\+)[^/+]+(/|\+)[^/]+)'
COURSE_ID_REGEX = r'[^/+]+(/|\+)[^/+]+(/|\+)[^/]+'
COURSE_ID_PATTERN = r'(?P<course_id>%s)'%COURSE_ID_REGEX
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