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
edx
edx-proctoring
Commits
07ff5790
Commit
07ff5790
authored
Nov 06, 2015
by
Chris Dodge
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Substitute all illegal characters when registering exams with SoftwareSecure
parent
f8d04bb6
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
64 additions
and
26 deletions
+64
-26
edx_proctoring/backends/software_secure.py
+8
-1
edx_proctoring/backends/tests/test_software_secure.py
+35
-23
edx_proctoring/models.py
+1
-1
edx_proctoring/tests/test_models.py
+16
-1
setup.py
+4
-0
No files found.
edx_proctoring/backends/software_secure.py
View file @
07ff5790
...
@@ -36,6 +36,9 @@ from edx_proctoring.serializers import (
...
@@ -36,6 +36,9 @@ from edx_proctoring.serializers import (
log
=
logging
.
getLogger
(
__name__
)
log
=
logging
.
getLogger
(
__name__
)
SOFTWARE_SECURE_INVALID_CHARS
=
'[]<>#:|?/
\'
"*
\\
'
class
SoftwareSecureBackendProvider
(
ProctoringBackendProvider
):
class
SoftwareSecureBackendProvider
(
ProctoringBackendProvider
):
"""
"""
Implementation of the ProctoringBackendProvider for Software Secure's
Implementation of the ProctoringBackendProvider for Software Secure's
...
@@ -372,6 +375,10 @@ class SoftwareSecureBackendProvider(ProctoringBackendProvider):
...
@@ -372,6 +375,10 @@ class SoftwareSecureBackendProvider(ProctoringBackendProvider):
now
=
datetime
.
datetime
.
utcnow
()
now
=
datetime
.
datetime
.
utcnow
()
start_time_str
=
now
.
strftime
(
"
%
a,
%
d
%
b
%
Y
%
H:
%
M:
%
S GMT"
)
start_time_str
=
now
.
strftime
(
"
%
a,
%
d
%
b
%
Y
%
H:
%
M:
%
S GMT"
)
end_time_str
=
(
now
+
datetime
.
timedelta
(
minutes
=
time_limit_mins
))
.
strftime
(
"
%
a,
%
d
%
b
%
Y
%
H:
%
M:
%
S GMT"
)
end_time_str
=
(
now
+
datetime
.
timedelta
(
minutes
=
time_limit_mins
))
.
strftime
(
"
%
a,
%
d
%
b
%
Y
%
H:
%
M:
%
S GMT"
)
# remove all illegal characters from the exam name
exam_name
=
exam
[
'exam_name'
]
for
character
in
SOFTWARE_SECURE_INVALID_CHARS
:
exam_name
=
exam_name
.
replace
(
character
,
'_'
)
return
{
return
{
"examCode"
:
attempt_code
,
"examCode"
:
attempt_code
,
"organization"
:
self
.
organization
,
"organization"
:
self
.
organization
,
...
@@ -382,7 +389,7 @@ class SoftwareSecureBackendProvider(ProctoringBackendProvider):
...
@@ -382,7 +389,7 @@ class SoftwareSecureBackendProvider(ProctoringBackendProvider):
"reviewerNotes"
:
reviewer_notes
,
"reviewerNotes"
:
reviewer_notes
,
"examPassword"
:
self
.
_encrypt_password
(
self
.
crypto_key
,
attempt_code
),
"examPassword"
:
self
.
_encrypt_password
(
self
.
crypto_key
,
attempt_code
),
"examSponsor"
:
self
.
exam_sponsor
,
"examSponsor"
:
self
.
exam_sponsor
,
"examName"
:
exam
[
'exam_name'
]
,
"examName"
:
exam
_name
,
"ssiProduct"
:
'rp-now'
,
"ssiProduct"
:
'rp-now'
,
# need to pass in a URL to the LMS?
# need to pass in a URL to the LMS?
"examUrl"
:
callback_url
,
"examUrl"
:
callback_url
,
...
...
edx_proctoring/backends/tests/test_software_secure.py
View file @
07ff5790
...
@@ -41,9 +41,12 @@ from edx_proctoring.models import (
...
@@ -41,9 +41,12 @@ from edx_proctoring.models import (
ProctoredExamStudentAttemptHistory
,
ProctoredExamStudentAttemptHistory
,
ProctoredExamStudentAllowance
ProctoredExamStudentAllowance
)
)
from
edx_proctoring.backends.tests.test_review_payload
import
TEST_REVIEW_PAYLOAD
from
edx_proctoring.backends.tests.test_review_payload
import
(
TEST_REVIEW_PAYLOAD
)
from
edx_proctoring.tests.test_services
import
MockCreditService
from
edx_proctoring.tests.test_services
import
MockCreditService
from
edx_proctoring.backends.software_secure
import
SOFTWARE_SECURE_INVALID_CHARS
@all_requests
@all_requests
...
@@ -216,14 +219,6 @@ class SoftwareSecureTests(TestCase):
...
@@ -216,14 +219,6 @@ class SoftwareSecureTests(TestCase):
Create an unstarted proctoring attempt with no review policy associated with it.
Create an unstarted proctoring attempt with no review policy associated with it.
"""
"""
exam_id
=
create_exam
(
course_id
=
'foo/bar/baz'
,
content_id
=
'content'
,
exam_name
=
'Sample Exam'
,
time_limit_mins
=
10
,
is_proctored
=
True
)
def
assert_get_payload_mock_no_policy
(
exam
,
context
):
def
assert_get_payload_mock_no_policy
(
exam
,
context
):
"""
"""
Add a mock shim so we can assert that the _get_payload has been called with the right
Add a mock shim so we can assert that the _get_payload has been called with the right
...
@@ -236,23 +231,40 @@ class SoftwareSecureTests(TestCase):
...
@@ -236,23 +231,40 @@ class SoftwareSecureTests(TestCase):
# assert that we use the default that is defined in system configuration
# assert that we use the default that is defined in system configuration
self
.
assertEqual
(
result
[
'reviewerNotes'
],
constants
.
DEFAULT_SOFTWARE_SECURE_REVIEW_POLICY
)
self
.
assertEqual
(
result
[
'reviewerNotes'
],
constants
.
DEFAULT_SOFTWARE_SECURE_REVIEW_POLICY
)
# the check that if a colon was passed in for the exam name, then the colon was changed to
# a dash. This is because SoftwareSecure cannot handle a colon in the exam name
for
illegal_char
in
SOFTWARE_SECURE_INVALID_CHARS
:
if
illegal_char
in
exam
[
'exam_name'
]:
self
.
assertNotIn
(
illegal_char
,
result
[
'examName'
])
self
.
assertIn
(
'_'
,
result
[
'examName'
])
return
result
return
result
with
HTTMock
(
mock_response_content
):
for
illegal_char
in
SOFTWARE_SECURE_INVALID_CHARS
:
# patch the _get_payload method on the backend provider
exam_id
=
create_exam
(
# so that we can assert that we are called with the review policy
course_id
=
'foo/bar/baz'
,
# undefined and that we use the system default
content_id
=
'content with {}'
.
format
(
illegal_char
),
with
patch
.
object
(
get_backend_provider
(),
'_get_payload'
,
assert_get_payload_mock_no_policy
):
# pylint: disable=protected-access
exam_name
=
'Sample Exam with {} character'
.
format
(
illegal_char
),
attempt_id
=
create_exam_attempt
(
time_limit_mins
=
10
,
exam_id
,
is_proctored
=
True
self
.
user
.
id
,
)
taking_as_proctored
=
True
)
self
.
assertGreater
(
attempt_id
,
0
)
# make sure we recorded that there is no review policy
with
HTTMock
(
mock_response_content
):
attempt
=
get_exam_attempt_by_id
(
attempt_id
)
# patch the _get_payload method on the backend provider
self
.
assertIsNone
(
attempt
[
'review_policy_id'
])
# so that we can assert that we are called with the review policy
# undefined and that we use the system default
with
patch
.
object
(
get_backend_provider
(),
'_get_payload'
,
assert_get_payload_mock_no_policy
):
# pylint: disable=protected-access
attempt_id
=
create_exam_attempt
(
exam_id
,
self
.
user
.
id
,
taking_as_proctored
=
True
)
self
.
assertGreater
(
attempt_id
,
0
)
# make sure we recorded that there is no review policy
attempt
=
get_exam_attempt_by_id
(
attempt_id
)
self
.
assertIsNone
(
attempt
[
'review_policy_id'
])
def
test_single_name_attempt
(
self
):
def
test_single_name_attempt
(
self
):
"""
"""
...
...
edx_proctoring/models.py
View file @
07ff5790
...
@@ -60,7 +60,7 @@ class ProctoredExam(TimeStampedModel):
...
@@ -60,7 +60,7 @@ class ProctoredExam(TimeStampedModel):
How to serialize myself as a string
How to serialize myself as a string
"""
"""
return
"{course_id}: {exam_name} ({active})"
.
format
(
return
u
"{course_id}: {exam_name} ({active})"
.
format
(
course_id
=
self
.
course_id
,
course_id
=
self
.
course_id
,
exam_name
=
self
.
exam_name
,
exam_name
=
self
.
exam_name
,
active
=
'active'
if
self
.
is_active
else
'inactive'
,
active
=
'active'
if
self
.
is_active
else
'inactive'
,
...
...
edx_proctoring/tests/test_models.py
View file @
07ff5790
# coding=utf-8
# pylint: disable=invalid-name
"""
"""
All tests for the models.py
All tests for the models.py
"""
"""
# pylint: disable=invalid-name
from
edx_proctoring.models
import
(
from
edx_proctoring.models
import
(
ProctoredExam
,
ProctoredExam
,
ProctoredExamStudentAllowance
,
ProctoredExamStudentAllowance
,
...
@@ -29,6 +30,20 @@ class ProctoredExamModelTests(LoggedInTestCase):
...
@@ -29,6 +30,20 @@ class ProctoredExamModelTests(LoggedInTestCase):
"""
"""
super
(
ProctoredExamModelTests
,
self
)
.
setUp
()
super
(
ProctoredExamModelTests
,
self
)
.
setUp
()
def
test_unicode
(
self
):
"""
Make sure we support Unicode characters
"""
proctored_exam
=
ProctoredExam
.
objects
.
create
(
course_id
=
'test_course'
,
content_id
=
'test_content'
,
exam_name
=
u'अआईउऊऋऌ अआईउऊऋऌ'
,
external_id
=
'123aXqe3'
,
time_limit_mins
=
90
)
output
=
unicode
(
proctored_exam
)
self
.
assertEquals
(
output
,
u"test_course: अआईउऊऋऌ अआईउऊऋऌ (inactive)"
)
def
test_save_proctored_exam_student_allowance_history
(
self
):
# pylint: disable=invalid-name
def
test_save_proctored_exam_student_allowance_history
(
self
):
# pylint: disable=invalid-name
"""
"""
Test to Save and update the proctored Exam Student Allowance object.
Test to Save and update the proctored Exam Student Allowance object.
...
...
setup.py
View file @
07ff5790
...
@@ -34,7 +34,11 @@ def load_requirements(*requirements_paths):
...
@@ -34,7 +34,11 @@ def load_requirements(*requirements_paths):
setup
(
setup
(
name
=
'edx-proctoring'
,
name
=
'edx-proctoring'
,
<<<<<<<
HEAD
version
=
'0.11.0'
,
version
=
'0.11.0'
,
=======
version
=
'0.10.19'
,
>>>>>>>
Substitute
all
illegal
characters
when
registering
exams
with
SoftwareSecure
description
=
'Proctoring subsystem for Open edX'
,
description
=
'Proctoring subsystem for Open edX'
,
long_description
=
open
(
'README.md'
)
.
read
(),
long_description
=
open
(
'README.md'
)
.
read
(),
author
=
'edX'
,
author
=
'edX'
,
...
...
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