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
089e1d69
Commit
089e1d69
authored
Nov 10, 2015
by
chrisndodge
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #228 from edx/cdodge/release-rebase3
Cdodge/release rebase3
parents
1d8b10f6
f4898f58
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
66 additions
and
32 deletions
+66
-32
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/templates/proctored_exam/confirm-decline.html
+4
-4
edx_proctoring/templates/proctored_exam/footer.html
+1
-1
edx_proctoring/templates/proctored_exam/ready_to_start.html
+1
-1
edx_proctoring/tests/test_models.py
+16
-1
No files found.
edx_proctoring/backends/software_secure.py
View file @
089e1d69
...
...
@@ -36,6 +36,9 @@ from edx_proctoring.serializers import (
log
=
logging
.
getLogger
(
__name__
)
SOFTWARE_SECURE_INVALID_CHARS
=
'[]<>#:|?/
\'
"*
\\
'
class
SoftwareSecureBackendProvider
(
ProctoringBackendProvider
):
"""
Implementation of the ProctoringBackendProvider for Software Secure's
...
...
@@ -372,6 +375,10 @@ class SoftwareSecureBackendProvider(ProctoringBackendProvider):
now
=
datetime
.
datetime
.
utcnow
()
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"
)
# 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
{
"examCode"
:
attempt_code
,
"organization"
:
self
.
organization
,
...
...
@@ -382,7 +389,7 @@ class SoftwareSecureBackendProvider(ProctoringBackendProvider):
"reviewerNotes"
:
reviewer_notes
,
"examPassword"
:
self
.
_encrypt_password
(
self
.
crypto_key
,
attempt_code
),
"examSponsor"
:
self
.
exam_sponsor
,
"examName"
:
exam
[
'exam_name'
]
,
"examName"
:
exam
_name
,
"ssiProduct"
:
'rp-now'
,
# need to pass in a URL to the LMS?
"examUrl"
:
callback_url
,
...
...
edx_proctoring/backends/tests/test_software_secure.py
View file @
089e1d69
...
...
@@ -41,9 +41,12 @@ from edx_proctoring.models import (
ProctoredExamStudentAttemptHistory
,
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.backends.software_secure
import
SOFTWARE_SECURE_INVALID_CHARS
@all_requests
...
...
@@ -216,14 +219,6 @@ class SoftwareSecureTests(TestCase):
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
):
"""
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):
# assert that we use the default that is defined in system configuration
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
with
HTTMock
(
mock_response_content
):
# patch the _get_payload method on the backend provider
# 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
)
for
illegal_char
in
SOFTWARE_SECURE_INVALID_CHARS
:
exam_id
=
create_exam
(
course_id
=
'foo/bar/baz'
,
content_id
=
'content with {}'
.
format
(
illegal_char
),
exam_name
=
'Sample Exam with {} character'
.
format
(
illegal_char
),
time_limit_mins
=
10
,
is_proctored
=
True
)
# make sure we recorded that there is no review policy
attempt
=
get_exam_attempt_by_id
(
attempt_id
)
self
.
assertIsNone
(
attempt
[
'review_policy_id'
])
with
HTTMock
(
mock_response_content
):
# patch the _get_payload method on the backend provider
# 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
):
"""
...
...
edx_proctoring/models.py
View file @
089e1d69
...
...
@@ -60,7 +60,7 @@ class ProctoredExam(TimeStampedModel):
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
,
exam_name
=
self
.
exam_name
,
active
=
'active'
if
self
.
is_active
else
'inactive'
,
...
...
edx_proctoring/templates/proctored_exam/confirm-decline.html
View file @
089e1d69
{% load i18n %}
<div
class=
"proctored-exam
-skip-confirm-wrapper
hidden"
>
<div
class=
"proctored-exam
skip-confirm-wrapper warning
hidden"
>
<div
class=
"proctored-exam-skip-confirm"
>
<div
class=
"msg-title"
>
{% blocktrans %}
...
...
@@ -12,10 +12,10 @@
{% endblocktrans %}
</div>
<div
class=
"proctored-exam-skip-actions"
>
<button
class=
"proctored-exam-skip-confirm-button btn btn-pl-primary btn-base"
data-ajax-url=
"{{enter_exam_endpoint}}"
data-exam-id=
"{{exam_id}}"
>
<button
class=
"
exam-action-button
proctored-exam-skip-confirm-button btn btn-pl-primary btn-base"
data-ajax-url=
"{{enter_exam_endpoint}}"
data-exam-id=
"{{exam_id}}"
>
{% trans "Continue Exam Without Proctoring" %}
</button>
<button
class=
"
proctored-exam-skip-cancel-button btn btn-default
btn-base"
>
<button
class=
"
exam-action-button proctored-exam-skip-cancel-button btn btn-secondary
btn-base"
>
{% trans "Go Back" %}
</button>
</div>
...
...
@@ -46,7 +46,7 @@
if
(
!
inProcess
)
{
enableClickEvent
(
$
(
this
));
$
(
".proctored-exam.entrance"
).
removeClass
(
'hidden'
);
$
(
".proctored-exam
-
skip-confirm-wrapper"
).
addClass
(
'hidden'
);
$
(
".proctored-exam
.
skip-confirm-wrapper"
).
addClass
(
'hidden'
);
}
else
{
return
false
;
}
...
...
edx_proctoring/templates/proctored_exam/footer.html
View file @
089e1d69
...
...
@@ -63,7 +63,7 @@
if
(
!
attempt_proctored
)
{
enableClickEvent
(
$
(
this
));
$
(
".proctored-exam.entrance"
).
addClass
(
'hidden'
);
$
(
".proctored-exam
-
skip-confirm-wrapper"
).
removeClass
(
'hidden'
);
$
(
".proctored-exam
.
skip-confirm-wrapper"
).
removeClass
(
'hidden'
);
}
else
{
var
action_url
=
$
(
this
).
data
(
'ajax-url'
);
var
exam_id
=
$
(
this
).
data
(
'exam-id'
);
...
...
edx_proctoring/templates/proctored_exam/ready_to_start.html
View file @
089e1d69
...
...
@@ -15,7 +15,7 @@
{% endblocktrans %}
</p>
<div>
<button
type=
"button"
class=
"proctored-enter-exam btn btn-pl-primary btn-base"
data-action=
"start"
data-exam-id=
"{{exam_id}}"
data-change-state-url=
"{{change_state_url}}"
>
<button
type=
"button"
class=
"
exam-action-button
proctored-enter-exam btn btn-pl-primary btn-base"
data-action=
"start"
data-exam-id=
"{{exam_id}}"
data-change-state-url=
"{{change_state_url}}"
>
{% blocktrans %}
Start my exam
{% endblocktrans %}
...
...
edx_proctoring/tests/test_models.py
View file @
089e1d69
# coding=utf-8
# pylint: disable=invalid-name
"""
All tests for the models.py
"""
# pylint: disable=invalid-name
from
edx_proctoring.models
import
(
ProctoredExam
,
ProctoredExamStudentAllowance
,
...
...
@@ -29,6 +30,20 @@ class ProctoredExamModelTests(LoggedInTestCase):
"""
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
"""
Test to Save and update the proctored Exam Student Allowance object.
...
...
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