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
29eca85f
Commit
29eca85f
authored
Jun 25, 2015
by
Afzal Wali
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Some integration fixes. Fixed the failing tests.
parent
38bcaeb7
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
39 additions
and
35 deletions
+39
-35
edx_proctoring/models.py
+5
-5
edx_proctoring/tests/test_api.py
+25
-19
edx_proctoring/tests/test_views.py
+1
-1
edx_proctoring/views.py
+8
-10
No files found.
edx_proctoring/models.py
View file @
29eca85f
...
@@ -96,7 +96,7 @@ class ProctoredExamStudentAttempt(TimeStampedModel):
...
@@ -96,7 +96,7 @@ class ProctoredExamStudentAttempt(TimeStampedModel):
"""
"""
if
cls
.
get_student_exam_attempt
(
exam_id
,
user_id
)
is
None
:
if
cls
.
get_student_exam_attempt
(
exam_id
,
user_id
)
is
None
:
return
cls
.
objects
.
create
(
return
cls
.
objects
.
create
(
proctored_exam
=
exam_id
,
proctored_exam
_id
=
exam_id
,
user_id
=
user_id
,
user_id
=
user_id
,
external_id
=
external_id
,
external_id
=
external_id
,
started_at
=
datetime
.
now
(
pytz
.
UTC
)
started_at
=
datetime
.
now
(
pytz
.
UTC
)
...
@@ -111,7 +111,7 @@ class ProctoredExamStudentAttempt(TimeStampedModel):
...
@@ -111,7 +111,7 @@ class ProctoredExamStudentAttempt(TimeStampedModel):
else Returns None.
else Returns None.
"""
"""
try
:
try
:
exam_attempt_obj
=
cls
.
objects
.
get
(
proctored_exam
=
exam_id
,
user_id
=
user_id
)
exam_attempt_obj
=
cls
.
objects
.
get
(
proctored_exam
_id
=
exam_id
,
user_id
=
user_id
)
except
cls
.
DoesNotExist
:
except
cls
.
DoesNotExist
:
exam_attempt_obj
=
None
exam_attempt_obj
=
None
return
exam_attempt_obj
return
exam_attempt_obj
...
@@ -161,7 +161,7 @@ class ProctoredExamStudentAllowance(TimeStampedModel):
...
@@ -161,7 +161,7 @@ class ProctoredExamStudentAllowance(TimeStampedModel):
Returns an allowance for a user within a given exam
Returns an allowance for a user within a given exam
"""
"""
try
:
try
:
student_allowance
=
cls
.
objects
.
get
(
proctored_exam
=
exam_id
,
user_id
=
user_id
,
key
=
key
)
student_allowance
=
cls
.
objects
.
get
(
proctored_exam
_id
=
exam_id
,
user_id
=
user_id
,
key
=
key
)
except
cls
.
DoesNotExist
:
except
cls
.
DoesNotExist
:
student_allowance
=
None
student_allowance
=
None
return
student_allowance
return
student_allowance
...
@@ -172,11 +172,11 @@ class ProctoredExamStudentAllowance(TimeStampedModel):
...
@@ -172,11 +172,11 @@ class ProctoredExamStudentAllowance(TimeStampedModel):
Add or (Update) an allowance for a user within a given exam
Add or (Update) an allowance for a user within a given exam
"""
"""
try
:
try
:
student_allowance
=
cls
.
objects
.
get
(
proctored_exam
=
exam_id
,
user_id
=
user_id
,
key
=
key
)
student_allowance
=
cls
.
objects
.
get
(
proctored_exam
_id
=
exam_id
,
user_id
=
user_id
,
key
=
key
)
student_allowance
.
value
=
value
student_allowance
.
value
=
value
student_allowance
.
save
()
student_allowance
.
save
()
except
cls
.
DoesNotExist
:
except
cls
.
DoesNotExist
:
cls
.
objects
.
create
(
proctored_exam
=
exam_id
,
user_id
=
user_id
,
key
=
key
,
value
=
value
)
cls
.
objects
.
create
(
proctored_exam
_id
=
exam_id
,
user_id
=
user_id
,
key
=
key
,
value
=
value
)
class
ProctoredExamStudentAllowanceHistory
(
TimeStampedModel
):
class
ProctoredExamStudentAllowanceHistory
(
TimeStampedModel
):
...
...
edx_proctoring/tests/test_api.py
View file @
29eca85f
...
@@ -43,18 +43,18 @@ class ProctoredExamApiTests(LoggedInTestCase):
...
@@ -43,18 +43,18 @@ class ProctoredExamApiTests(LoggedInTestCase):
)
)
def
_create_student_exam_attempt_entry
(
self
):
def
_create_student_exam_attempt_entry
(
self
):
proctored_exam
=
self
.
_create_proctored_exam
()
proctored_exam
_id
=
self
.
_create_proctored_exam
()
return
ProctoredExamStudentAttempt
.
objects
.
create
(
return
ProctoredExamStudentAttempt
.
objects
.
create
(
proctored_exam
=
proctored_exam
,
proctored_exam
_id
=
proctored_exam_id
,
user_id
=
self
.
user_id
,
user_id
=
self
.
user_id
,
external_id
=
self
.
external_id
,
external_id
=
self
.
external_id
,
started_at
=
datetime
.
now
(
pytz
.
UTC
)
started_at
=
datetime
.
now
(
pytz
.
UTC
)
)
)
def
_add_allowance_for_user
(
self
):
def
_add_allowance_for_user
(
self
):
proctored_exam
=
self
.
_create_proctored_exam
()
proctored_exam
_id
=
self
.
_create_proctored_exam
()
return
ProctoredExamStudentAllowance
.
objects
.
create
(
return
ProctoredExamStudentAllowance
.
objects
.
create
(
proctored_exam
=
proctored_exam
,
user_id
=
self
.
user_id
,
key
=
self
.
key
,
value
=
self
.
value
proctored_exam
_id
=
proctored_exam_id
,
user_id
=
self
.
user_id
,
key
=
self
.
key
,
value
=
self
.
value
)
)
def
test_create_exam
(
self
):
def
test_create_exam
(
self
):
...
@@ -85,14 +85,18 @@ class ProctoredExamApiTests(LoggedInTestCase):
...
@@ -85,14 +85,18 @@ class ProctoredExamApiTests(LoggedInTestCase):
"""
"""
test update the existing proctored exam
test update the existing proctored exam
"""
"""
proctored_exam
=
self
.
_create_proctored_exam
()
proctored_exam
_id
=
self
.
_create_proctored_exam
()
update
_proctored_exam
=
update_exam
(
update
d_proctored_exam_id
=
update_exam
(
proctored_exam
.
id
,
exam_name
=
'Updated Exam Name'
,
time_limit_mins
=
30
,
proctored_exam
_
id
,
exam_name
=
'Updated Exam Name'
,
time_limit_mins
=
30
,
is_proctored
=
True
,
external_id
=
'external_id'
,
is_active
=
True
is_proctored
=
True
,
external_id
=
'external_id'
,
is_active
=
True
)
)
# only those fields were updated, whose
# only those fields were updated, whose
# values are passed.
# values are passed.
self
.
assertEqual
(
proctored_exam_id
,
updated_proctored_exam_id
)
update_proctored_exam
=
ProctoredExam
.
objects
.
get
(
id
=
updated_proctored_exam_id
)
self
.
assertEqual
(
update_proctored_exam
.
exam_name
,
'Updated Exam Name'
)
self
.
assertEqual
(
update_proctored_exam
.
exam_name
,
'Updated Exam Name'
)
self
.
assertEqual
(
update_proctored_exam
.
time_limit_mins
,
30
)
self
.
assertEqual
(
update_proctored_exam
.
time_limit_mins
,
30
)
self
.
assertEqual
(
update_proctored_exam
.
course_id
,
'test_course'
)
self
.
assertEqual
(
update_proctored_exam
.
course_id
,
'test_course'
)
...
@@ -111,8 +115,8 @@ class ProctoredExamApiTests(LoggedInTestCase):
...
@@ -111,8 +115,8 @@ class ProctoredExamApiTests(LoggedInTestCase):
test to get the exam by the exam_id and
test to get the exam by the exam_id and
then compare their values.
then compare their values.
"""
"""
proctored_exam
=
self
.
_create_proctored_exam
()
proctored_exam
_id
=
self
.
_create_proctored_exam
()
proctored_exam
=
get_exam_by_id
(
proctored_exam
.
id
)
proctored_exam
=
get_exam_by_id
(
proctored_exam
_
id
)
self
.
assertEqual
(
proctored_exam
[
'course_id'
],
self
.
course_id
)
self
.
assertEqual
(
proctored_exam
[
'course_id'
],
self
.
course_id
)
self
.
assertEqual
(
proctored_exam
[
'content_id'
],
self
.
content_id
)
self
.
assertEqual
(
proctored_exam
[
'content_id'
],
self
.
content_id
)
self
.
assertEqual
(
proctored_exam
[
'exam_name'
],
self
.
exam_name
)
self
.
assertEqual
(
proctored_exam
[
'exam_name'
],
self
.
exam_name
)
...
@@ -135,17 +139,17 @@ class ProctoredExamApiTests(LoggedInTestCase):
...
@@ -135,17 +139,17 @@ class ProctoredExamApiTests(LoggedInTestCase):
get_exam_by_content_id
(
'teasd'
,
'tewasda'
)
get_exam_by_content_id
(
'teasd'
,
'tewasda'
)
def
test_add_allowance_for_user
(
self
):
def
test_add_allowance_for_user
(
self
):
proctored_exam
=
self
.
_create_proctored_exam
()
proctored_exam
_id
=
self
.
_create_proctored_exam
()
add_allowance_for_user
(
proctored_exam
,
self
.
user_id
,
self
.
key
,
self
.
value
)
add_allowance_for_user
(
proctored_exam
_id
,
self
.
user_id
,
self
.
key
,
self
.
value
)
student_allowance
=
ProctoredExamStudentAllowance
.
get_allowance_for_user
(
student_allowance
=
ProctoredExamStudentAllowance
.
get_allowance_for_user
(
proctored_exam
.
id
,
self
.
user_id
,
self
.
key
proctored_exam
_
id
,
self
.
user_id
,
self
.
key
)
)
self
.
assertIsNotNone
(
student_allowance
)
self
.
assertIsNotNone
(
student_allowance
)
def
test_allowance_for_user_already_exists
(
self
):
def
test_allowance_for_user_already_exists
(
self
):
student_allowance
=
self
.
_add_allowance_for_user
()
student_allowance
=
self
.
_add_allowance_for_user
()
add_allowance_for_user
(
student_allowance
.
proctored_exam
,
self
.
user_id
,
self
.
key
,
'new_value'
)
add_allowance_for_user
(
student_allowance
.
proctored_exam
.
id
,
self
.
user_id
,
self
.
key
,
'new_value'
)
student_allowance
=
ProctoredExamStudentAllowance
.
get_allowance_for_user
(
student_allowance
=
ProctoredExamStudentAllowance
.
get_allowance_for_user
(
student_allowance
.
proctored_exam
.
id
,
self
.
user_id
,
self
.
key
student_allowance
.
proctored_exam
.
id
,
self
.
user_id
,
self
.
key
...
@@ -154,10 +158,10 @@ class ProctoredExamApiTests(LoggedInTestCase):
...
@@ -154,10 +158,10 @@ class ProctoredExamApiTests(LoggedInTestCase):
self
.
assertEqual
(
student_allowance
.
value
,
'new_value'
)
self
.
assertEqual
(
student_allowance
.
value
,
'new_value'
)
def
test_get_allowance_for_user_does_not_exist
(
self
):
def
test_get_allowance_for_user_does_not_exist
(
self
):
proctored_exam
=
self
.
_create_proctored_exam
()
proctored_exam
_id
=
self
.
_create_proctored_exam
()
student_allowance
=
ProctoredExamStudentAllowance
.
get_allowance_for_user
(
student_allowance
=
ProctoredExamStudentAllowance
.
get_allowance_for_user
(
proctored_exam
.
id
,
self
.
user_id
,
self
.
key
proctored_exam
_
id
,
self
.
user_id
,
self
.
key
)
)
self
.
assertIsNone
(
student_allowance
)
self
.
assertIsNone
(
student_allowance
)
...
@@ -168,8 +172,8 @@ class ProctoredExamApiTests(LoggedInTestCase):
...
@@ -168,8 +172,8 @@ class ProctoredExamApiTests(LoggedInTestCase):
self
.
assertEqual
(
len
(
ProctoredExamStudentAllowance
.
objects
.
filter
()),
0
)
self
.
assertEqual
(
len
(
ProctoredExamStudentAllowance
.
objects
.
filter
()),
0
)
def
test_student_exam_attempt_entry_already_exists
(
self
):
def
test_student_exam_attempt_entry_already_exists
(
self
):
proctored_exam
=
self
.
_create_proctored_exam
()
proctored_exam
_id
=
self
.
_create_proctored_exam
()
start_exam_attempt
(
proctored_exam
,
self
.
user_id
,
self
.
external_id
)
start_exam_attempt
(
proctored_exam
_id
,
self
.
user_id
,
self
.
external_id
)
self
.
assertIsNotNone
(
start_exam_attempt
)
self
.
assertIsNotNone
(
start_exam_attempt
)
def
test_create_student_exam_attempt_entry
(
self
):
def
test_create_student_exam_attempt_entry
(
self
):
...
@@ -180,8 +184,10 @@ class ProctoredExamApiTests(LoggedInTestCase):
...
@@ -180,8 +184,10 @@ class ProctoredExamApiTests(LoggedInTestCase):
def
test_stop_exam_attempt
(
self
):
def
test_stop_exam_attempt
(
self
):
proctored_exam_student_attempt
=
self
.
_create_student_exam_attempt_entry
()
proctored_exam_student_attempt
=
self
.
_create_student_exam_attempt_entry
()
self
.
assertIsNone
(
proctored_exam_student_attempt
.
completed_at
)
self
.
assertIsNone
(
proctored_exam_student_attempt
.
completed_at
)
proctored_exam_student_attempt
=
stop_exam_attempt
(
proctored_exam_student_attempt
.
proctored_exam
,
self
.
user_id
)
proctored_exam_student_attempt_id
=
stop_exam_attempt
(
self
.
assertIsNotNone
(
proctored_exam_student_attempt
.
completed_at
)
proctored_exam_student_attempt
.
proctored_exam
,
self
.
user_id
)
self
.
assertEqual
(
proctored_exam_student_attempt
.
id
,
proctored_exam_student_attempt_id
)
def
test_stop_invalid_exam_attempt_raises_exception
(
self
):
def
test_stop_invalid_exam_attempt_raises_exception
(
self
):
proctored_exam
=
self
.
_create_proctored_exam
()
proctored_exam
=
self
.
_create_proctored_exam
()
...
...
edx_proctoring/tests/test_views.py
View file @
29eca85f
...
@@ -45,6 +45,6 @@ class ProctoredExamsApiTests(LoggedInTestCase):
...
@@ -45,6 +45,6 @@ class ProctoredExamsApiTests(LoggedInTestCase):
"""
"""
response
=
self
.
client
.
get
(
response
=
self
.
client
.
get
(
reverse
(
'edx_proctoring.proctored_exam.
status
'
)
reverse
(
'edx_proctoring.proctored_exam.
attempt
'
)
)
)
self
.
assertEqual
(
response
.
status_code
,
200
)
self
.
assertEqual
(
response
.
status_code
,
200
)
edx_proctoring/views.py
View file @
29eca85f
...
@@ -4,7 +4,6 @@ Proctored Exams HTTP-based API endpoints
...
@@ -4,7 +4,6 @@ Proctored Exams HTTP-based API endpoints
import
logging
import
logging
from
django.db
import
IntegrityError
from
django.db
import
IntegrityError
from
django.db.models
import
Model
from
rest_framework
import
status
from
rest_framework
import
status
from
rest_framework.response
import
Response
from
rest_framework.response
import
Response
...
@@ -90,9 +89,9 @@ class ProctoredExamView(AuthenticatedAPIView):
...
@@ -90,9 +89,9 @@ class ProctoredExamView(AuthenticatedAPIView):
content_id
=
request
.
DATA
.
get
(
'content_id'
,
""
),
content_id
=
request
.
DATA
.
get
(
'content_id'
,
""
),
exam_name
=
request
.
DATA
.
get
(
'exam_name'
,
""
),
exam_name
=
request
.
DATA
.
get
(
'exam_name'
,
""
),
time_limit_mins
=
request
.
DATA
.
get
(
'time_limit_mins'
,
""
),
time_limit_mins
=
request
.
DATA
.
get
(
'time_limit_mins'
,
""
),
is_proctored
=
True
if
request
.
DATA
.
get
(
'is_proctored'
,
"False"
)
.
lower
()
==
'true'
else
False
,
is_proctored
=
True
if
request
.
DATA
.
get
(
'is_proctored'
,
"False"
)
.
lower
()
==
'true'
else
False
,
external_id
=
request
.
DATA
.
get
(
'external_id'
,
""
),
external_id
=
request
.
DATA
.
get
(
'external_id'
,
""
),
is_active
=
True
if
request
.
DATA
.
get
(
'is_active'
,
""
)
.
lower
()
==
'true'
else
False
,
is_active
=
True
if
request
.
DATA
.
get
(
'is_active'
,
""
)
.
lower
()
==
'true'
else
False
,
)
)
return
Response
({
'exam_id'
:
exam_id
})
return
Response
({
'exam_id'
:
exam_id
})
except
IntegrityError
:
except
IntegrityError
:
...
@@ -111,12 +110,12 @@ class ProctoredExamView(AuthenticatedAPIView):
...
@@ -111,12 +110,12 @@ class ProctoredExamView(AuthenticatedAPIView):
exam_id
=
request
.
DATA
.
get
(
'exam_id'
,
""
),
exam_id
=
request
.
DATA
.
get
(
'exam_id'
,
""
),
exam_name
=
request
.
DATA
.
get
(
'exam_name'
,
""
),
exam_name
=
request
.
DATA
.
get
(
'exam_name'
,
""
),
time_limit_mins
=
request
.
DATA
.
get
(
'time_limit_mins'
,
""
),
time_limit_mins
=
request
.
DATA
.
get
(
'time_limit_mins'
,
""
),
is_proctored
=
True
if
request
.
DATA
.
get
(
'is_proctored'
,
"False"
)
.
lower
()
==
'true'
else
False
,
is_proctored
=
True
if
request
.
DATA
.
get
(
'is_proctored'
,
"False"
)
.
lower
()
==
'true'
else
False
,
external_id
=
request
.
DATA
.
get
(
'external_id'
,
""
),
external_id
=
request
.
DATA
.
get
(
'external_id'
,
""
),
is_active
=
True
if
request
.
DATA
.
get
(
'is_active'
,
""
)
.
lower
()
==
'true'
else
False
,
is_active
=
True
if
request
.
DATA
.
get
(
'is_active'
,
""
)
.
lower
()
==
'true'
else
False
,
)
)
return
Response
({
'exam_id'
:
exam_id
})
return
Response
({
'exam_id'
:
exam_id
})
except
Model
.
DoesNotExist
:
except
:
return
Response
(
return
Response
(
status
=
status
.
HTTP_400_BAD_REQUEST
,
status
=
status
.
HTTP_400_BAD_REQUEST
,
data
=
{
"detail"
:
"The exam_id does not exist."
}
data
=
{
"detail"
:
"The exam_id does not exist."
}
...
@@ -141,7 +140,7 @@ class ProctoredExamView(AuthenticatedAPIView):
...
@@ -141,7 +140,7 @@ class ProctoredExamView(AuthenticatedAPIView):
data
=
get_exam_by_id
(
exam_id
),
data
=
get_exam_by_id
(
exam_id
),
status
=
status
.
HTTP_200_OK
status
=
status
.
HTTP_200_OK
)
)
except
Model
.
DoesNotExist
:
except
Exception
:
return
Response
(
return
Response
(
status
=
status
.
HTTP_400_BAD_REQUEST
,
status
=
status
.
HTTP_400_BAD_REQUEST
,
data
=
{
"detail"
:
"The exam_id does not exist."
}
data
=
{
"detail"
:
"The exam_id does not exist."
}
...
@@ -152,7 +151,7 @@ class ProctoredExamView(AuthenticatedAPIView):
...
@@ -152,7 +151,7 @@ class ProctoredExamView(AuthenticatedAPIView):
data
=
get_exam_by_content_id
(
course_id
,
content_id
),
data
=
get_exam_by_content_id
(
course_id
,
content_id
),
status
=
status
.
HTTP_200_OK
status
=
status
.
HTTP_200_OK
)
)
except
Model
.
DoesNotExist
:
except
Exception
:
return
Response
(
return
Response
(
status
=
status
.
HTTP_400_BAD_REQUEST
,
status
=
status
.
HTTP_400_BAD_REQUEST
,
data
=
{
"detail"
:
"The exam with course_id, content_id does not exist."
}
data
=
{
"detail"
:
"The exam with course_id, content_id does not exist."
}
...
@@ -209,7 +208,6 @@ class StudentProctoredExamAttempt(AuthenticatedAPIView):
...
@@ -209,7 +208,6 @@ class StudentProctoredExamAttempt(AuthenticatedAPIView):
data
=
{
"detail"
:
"Exam already started."
}
data
=
{
"detail"
:
"Exam already started."
}
)
)
def
put
(
self
,
request
):
def
put
(
self
,
request
):
"""
"""
HTTP POST handler. To stop an exam.
HTTP POST handler. To stop an exam.
...
@@ -249,7 +247,6 @@ class ExamAllowanceView(AuthenticatedAPIView):
...
@@ -249,7 +247,6 @@ class ExamAllowanceView(AuthenticatedAPIView):
data
=
{
"detail"
:
"Could not add Allowance."
}
data
=
{
"detail"
:
"Could not add Allowance."
}
)
)
def
delete
(
self
,
request
):
def
delete
(
self
,
request
):
"""
"""
HTTP DELETE handler. Removes Allowance.
HTTP DELETE handler. Removes Allowance.
...
@@ -266,6 +263,7 @@ class ExamAllowanceView(AuthenticatedAPIView):
...
@@ -266,6 +263,7 @@ class ExamAllowanceView(AuthenticatedAPIView):
data
=
{
"detail"
:
"Could not remove Allowance."
}
data
=
{
"detail"
:
"Could not remove Allowance."
}
)
)
class
ActiveExamsForUserView
(
AuthenticatedAPIView
):
class
ActiveExamsForUserView
(
AuthenticatedAPIView
):
"""
"""
...
...
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