Commit 88c655c1 by Afzal Wali

Some Quality fixes

parent 17f93b7d
......@@ -9,8 +9,8 @@ API which is in the views.py file, per edX coding standards
import pytz
from datetime import datetime
from edx_proctoring.exceptions import (
ProctoredExamAlreadyExists, ProctoredExamNotFoundException, StudentExamAttemptAlreadyExistsException
)
ProctoredExamAlreadyExists, ProctoredExamNotFoundException, StudentExamAttemptAlreadyExistsException,
StudentExamAttemptDoesNotExistsException)
from edx_proctoring.models import (
ProctoredExam, ProctoredExamStudentAllowance, ProctoredExamStudentAttempt
)
......@@ -150,7 +150,7 @@ def stop_exam_attempt(exam_id, user_id):
"""
exam_attempt_obj = ProctoredExamStudentAttempt.get_student_exam_attempt(exam_id, user_id)
if exam_attempt_obj is None:
raise StudentExamAttemptAlreadyExistsException
raise StudentExamAttemptDoesNotExistsException
else:
exam_attempt_obj.completed_at = datetime.now(pytz.UTC)
exam_attempt_obj.save()
......
......@@ -5,20 +5,23 @@ Specialized exceptions for the Notification subsystem
class ProctoredExamAlreadyExists(Exception):
"""
Generic exception when a look up fails. Since we are abstracting away the backends
we need to catch any native exceptions and re-throw as a generic exception
Raised when trying to create an Exam that already exists.
"""
class ProctoredExamNotFoundException(Exception):
"""
Generic exception when a look up fails. Since we are abstracting away the backends
we need to catch any native exceptions and re-throw as a generic exception
Raised when a look up fails.
"""
class StudentExamAttemptAlreadyExistsException(Exception):
"""
Generic exception when a look up fails. Since we are abstracting away the backends
we need to catch any native exceptions and re-throw as a generic exception
Raised when trying to start an exam when an Exam Attempt already exists.
"""
class StudentExamAttemptDoesNotExistsException(Exception):
"""
Raised when trying to stop an exam attempt where the Exam Attempt doesn't exist.
"""
......@@ -4,7 +4,13 @@ from edx_proctoring.models import ProctoredExam
class ProctoredExamSerializer(serializers.ModelSerializer):
"""
Serializer for the ProctoredExam Model.
"""
class Meta:
"""
Meta Class
"""
model = ProctoredExam
fields = (
"course_id", "content_id", "external_id", "exam_name",
......
......@@ -3,12 +3,11 @@ All tests for the models.py
"""
from datetime import datetime
import pytz
from edx_proctoring.api import create_exam, update_exam, get_exam_by_id, get_exam_by_content_id, add_allowance_for_user, \
remove_allowance_for_user, start_exam_attempt, stop_exam_attempt
from edx_proctoring.api import create_exam, update_exam, get_exam_by_id, get_exam_by_content_id, \
add_allowance_for_user, remove_allowance_for_user, start_exam_attempt, stop_exam_attempt
from edx_proctoring.exceptions import ProctoredExamAlreadyExists, ProctoredExamNotFoundException, \
StudentExamAttemptAlreadyExistsException
from edx_proctoring.models import ProctoredExam, ProctoredExamStudentAllowance, ProctoredExamStudentAllowanceHistory, \
ProctoredExamStudentAttempt
from edx_proctoring.models import ProctoredExam, ProctoredExamStudentAllowance, ProctoredExamStudentAttempt
from .utils import (
LoggedInTestCase
......@@ -35,6 +34,9 @@ class ProctoredExamApiTests(LoggedInTestCase):
self.external_id = 'test_external_id'
def _create_proctored_exam(self):
"""
Calls the api's create_exam to create an exam object.
"""
return create_exam(
course_id=self.course_id,
content_id=self.content_id,
......@@ -43,6 +45,10 @@ class ProctoredExamApiTests(LoggedInTestCase):
)
def _create_student_exam_attempt_entry(self):
"""
Creates the ProctoredExamStudentAttempt object.
"""
proctored_exam_id = self._create_proctored_exam()
return ProctoredExamStudentAttempt.objects.create(
proctored_exam_id=proctored_exam_id,
......
......@@ -19,7 +19,8 @@ urlpatterns = patterns( # pylint: disable=invalid-name
name='edx_proctoring.proctored_exam.exam'
),
url(
r'edx_proctoring/v1/proctored_exam/exam/course_id/{}/content_id/(?P<content_id>\d+)$'.format(settings.COURSE_ID_PATTERN),
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'
),
......
......@@ -7,7 +7,8 @@ from rest_framework import status
from rest_framework.response import Response
from edx_proctoring.api import create_exam, update_exam, get_exam_by_id, get_exam_by_content_id, start_exam_attempt, \
stop_exam_attempt, add_allowance_for_user, remove_allowance_for_user, get_active_exams_for_user
from edx_proctoring.exceptions import ProctoredExamNotFoundException, ProctoredExamAlreadyExists
from edx_proctoring.exceptions import ProctoredExamNotFoundException, ProctoredExamAlreadyExists, \
StudentExamAttemptAlreadyExistsException, StudentExamAttemptDoesNotExistsException
from edx_proctoring.serializers import ProctoredExamSerializer
from .utils import AuthenticatedAPIView
......@@ -115,13 +116,13 @@ class ProctoredExamView(AuthenticatedAPIView):
is_active=request.DATA.get('is_active', False),
)
return Response({'exam_id': exam_id})
except:
except ProctoredExamNotFoundException:
return Response(
status=status.HTTP_400_BAD_REQUEST,
data={"detail": "The exam_id does not exist."}
)
def get(self, request, exam_id=None, course_id=None, content_id=None):
def get(self, request, exam_id=None, course_id=None, content_id=None): # pylint: disable=unused-argument
"""
HTTP GET handler.
Scenarios:
......@@ -198,10 +199,10 @@ class StudentProctoredExamAttempt(AuthenticatedAPIView):
)
return Response({'exam_attempt_id': exam_attempt_id})
except Exception:
except StudentExamAttemptAlreadyExistsException:
return Response(
status=status.HTTP_400_BAD_REQUEST,
data={"detail": "Exam already started."}
data={"detail": "Error. Trying to start an exam that has already started."}
)
def put(self, request):
......@@ -215,66 +216,57 @@ class StudentProctoredExamAttempt(AuthenticatedAPIView):
)
return Response({"exam_attempt_id": exam_attempt_id})
except Exception:
except StudentExamAttemptDoesNotExistsException:
return Response(
status=status.HTTP_400_BAD_REQUEST,
data={"detail": "Exam Not in progress."}
data={"detail": "Error. Trying to stop an exam that is not in progress."}
)
class ExamAllowanceView(AuthenticatedAPIView):
"""
Endpoint for the ExamAlloawnce
/edx_proctoring/v1/proctored_exam/allowance
Supports:
HTTP PUT: Creates or Updates the allowance for a user.
HTTP DELETE: Removed an allowance for a user.
"""
def put(self, request):
"""
HTTP GET handler. Adds or updates Allowance
"""
try:
return Response(add_allowance_for_user(
exam_id=request.DATA.get('exam_id', ""),
user_id=request.DATA.get('user_id', ""),
key=request.DATA.get('key', ""),
value=request.DATA.get('value', "")
))
except:
return Response(
status=status.HTTP_400_BAD_REQUEST,
data={"detail": "Could not add Allowance."}
)
return Response(add_allowance_for_user(
exam_id=request.DATA.get('exam_id', ""),
user_id=request.DATA.get('user_id', ""),
key=request.DATA.get('key', ""),
value=request.DATA.get('value', "")
))
def delete(self, request):
"""
HTTP DELETE handler. Removes Allowance.
"""
try:
return Response(remove_allowance_for_user(
exam_id=request.DATA.get('exam_id', ""),
user_id=request.DATA.get('user_id', ""),
key=request.DATA.get('key', "")
))
except:
return Response(
status=status.HTTP_400_BAD_REQUEST,
data={"detail": "Could not remove Allowance."}
)
return Response(remove_allowance_for_user(
exam_id=request.DATA.get('exam_id', ""),
user_id=request.DATA.get('user_id', ""),
key=request.DATA.get('key', "")
))
class ActiveExamsForUserView(AuthenticatedAPIView):
"""
Endpoint for the Active Exams for a user.
/edx_proctoring/v1/proctored_exam/active_exams_for_user
Supports:
HTTP GET: returns a list of active exams for the user
"""
def get(self, request):
"""
returns the get_active_exams_for_user
"""
try:
return Response(get_active_exams_for_user(
user_id=request.DATA.get('user_id', ""),
course_id=request.DATA.get('course_id', "")
))
except:
return Response(
status=status.HTTP_400_BAD_REQUEST,
data={"detail": "Error."}
)
return Response(get_active_exams_for_user(
user_id=request.DATA.get('user_id', ""),
course_id=request.DATA.get('course_id', "")
))
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