Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-proctoring
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenEdx
edx-proctoring
Commits
88c655c1
Commit
88c655c1
authored
Jun 26, 2015
by
Afzal Wali
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Some Quality fixes
parent
17f93b7d
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
62 additions
and
54 deletions
+62
-54
edx_proctoring/api.py
+3
-3
edx_proctoring/exceptions.py
+9
-6
edx_proctoring/serializers.py
+6
-0
edx_proctoring/tests/test_api.py
+10
-4
edx_proctoring/urls.py
+2
-1
edx_proctoring/views.py
+32
-40
No files found.
edx_proctoring/api.py
View file @
88c655c1
...
...
@@ -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
StudentExamAttempt
Already
ExistsException
raise
StudentExamAttempt
DoesNot
ExistsException
else
:
exam_attempt_obj
.
completed_at
=
datetime
.
now
(
pytz
.
UTC
)
exam_attempt_obj
.
save
()
...
...
edx_proctoring/exceptions.py
View file @
88c655c1
...
...
@@ -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.
"""
edx_proctoring/serializers.py
View file @
88c655c1
...
...
@@ -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"
,
...
...
edx_proctoring/tests/test_api.py
View file @
88c655c1
...
...
@@ -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
,
...
...
edx_proctoring/urls.py
View file @
88c655c1
...
...
@@ -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'
),
...
...
edx_proctoring/views.py
View file @
88c655c1
...
...
@@ -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
StudentExamAttemptAlreadyExists
Exception
:
return
Response
(
status
=
status
.
HTTP_400_BAD_REQUEST
,
data
=
{
"detail"
:
"E
xam
already started."
}
data
=
{
"detail"
:
"E
rror. 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
StudentExamAttemptDoesNotExists
Exception
:
return
Response
(
status
=
status
.
HTTP_400_BAD_REQUEST
,
data
=
{
"detail"
:
"E
xam N
ot in progress."
}
data
=
{
"detail"
:
"E
rror. Trying to stop an exam that is n
ot 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'
,
""
)
))
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment