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
98c6bf37
Commit
98c6bf37
authored
Aug 05, 2015
by
Chris Dodge
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
address some review feedback
parent
c57c8095
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
58 additions
and
7 deletions
+58
-7
edx_proctoring/api.py
+9
-0
edx_proctoring/callbacks.py
+1
-0
edx_proctoring/static/proctoring/js/views/proctored_exam_view.js
+2
-5
edx_proctoring/templates/proctoring/seq_proctored_exam_entrance.html
+11
-0
edx_proctoring/templates/proctoring/seq_proctored_exam_instructions.html
+12
-1
edx_proctoring/tests/test_api.py
+23
-1
No files found.
edx_proctoring/api.py
View file @
98c6bf37
...
@@ -418,6 +418,15 @@ def update_attempt_status(exam_id, user_id, to_status):
...
@@ -418,6 +418,15 @@ def update_attempt_status(exam_id, user_id, to_status):
Internal helper to handle state transitions of attempt status
Internal helper to handle state transitions of attempt status
"""
"""
# In some configuration we may treat timeouts the same
# as the user saying he/she wises to submit the exam
alias_timeout
=
(
to_status
==
ProctoredExamStudentAttemptStatus
.
timed_out
and
not
settings
.
PROCTORING_SETTINGS
.
get
(
'ALLOW_TIMED_OUT_STATE'
,
False
)
)
if
alias_timeout
:
to_status
=
ProctoredExamStudentAttemptStatus
.
ready_to_submit
exam_attempt_obj
=
ProctoredExamStudentAttempt
.
objects
.
get_exam_attempt
(
exam_id
,
user_id
)
exam_attempt_obj
=
ProctoredExamStudentAttempt
.
objects
.
get_exam_attempt
(
exam_id
,
user_id
)
if
exam_attempt_obj
is
None
:
if
exam_attempt_obj
is
None
:
raise
StudentExamAttemptDoesNotExistsException
(
'Error. Trying to look up an exam that does not exist.'
)
raise
StudentExamAttemptDoesNotExistsException
(
'Error. Trying to look up an exam that does not exist.'
)
...
...
edx_proctoring/callbacks.py
View file @
98c6bf37
...
@@ -39,6 +39,7 @@ def start_exam_callback(request, attempt_code): # pylint: disable=unused-argume
...
@@ -39,6 +39,7 @@ def start_exam_callback(request, attempt_code): # pylint: disable=unused-argume
IMPORTANT: This is an unauthenticated endpoint, so be VERY CAREFUL about extending
IMPORTANT: This is an unauthenticated endpoint, so be VERY CAREFUL about extending
this endpoint
this endpoint
"""
"""
attempt
=
get_exam_attempt_by_code
(
attempt_code
)
attempt
=
get_exam_attempt_by_code
(
attempt_code
)
if
not
attempt
:
if
not
attempt
:
return
HttpResponse
(
return
HttpResponse
(
...
...
edx_proctoring/static/proctoring/js/views/proctored_exam_view.js
View file @
98c6bf37
...
@@ -102,7 +102,6 @@ var edx = edx || {};
...
@@ -102,7 +102,6 @@ var edx = edx || {};
return
this
;
return
this
;
},
},
unloadMessage
:
function
()
{
unloadMessage
:
function
()
{
return
null
;
return
gettext
(
"As you are currently taking a proctored exam,
\
n"
+
return
gettext
(
"As you are currently taking a proctored exam,
\
n"
+
"you should not be navigation away from the exam.
\
n"
+
"you should not be navigation away from the exam.
\
n"
+
"This may be considered as a violation of the
\
n"
+
"This may be considered as a violation of the
\
n"
+
...
@@ -115,10 +114,8 @@ var edx = edx || {};
...
@@ -115,10 +114,8 @@ var edx = edx || {};
var
url
=
self
.
model
.
url
+
'/'
+
self
.
model
.
get
(
'attempt_id'
);
var
url
=
self
.
model
.
url
+
'/'
+
self
.
model
.
get
(
'attempt_id'
);
$
.
ajax
(
url
).
success
(
function
(
data
)
{
$
.
ajax
(
url
).
success
(
function
(
data
)
{
if
(
data
.
status
===
'error'
)
{
if
(
data
.
status
===
'error'
)
{
// Let the student know that his exam has failed due to an error.
// The proctoring session is in error state
// This alert may or may not bring the browser window back to the
// refresh the page to
// foreground (depending on browser as well as user settings)
alert
(
gettext
(
'Your exam has failed'
));
clearInterval
(
self
.
timerId
);
// stop the timer once the time finishes.
clearInterval
(
self
.
timerId
);
// stop the timer once the time finishes.
$
(
window
).
unbind
(
'beforeunload'
,
self
.
unloadMessage
);
$
(
window
).
unbind
(
'beforeunload'
,
self
.
unloadMessage
);
// refresh the page when the timer expired
// refresh the page when the timer expired
...
...
edx_proctoring/templates/proctoring/seq_proctored_exam_entrance.html
View file @
98c6bf37
...
@@ -53,6 +53,17 @@
...
@@ -53,6 +53,17 @@
var
exam_id
=
$
(
this
).
data
(
'exam-id'
);
var
exam_id
=
$
(
this
).
data
(
'exam-id'
);
var
attempt_proctored
=
$
(
this
).
data
(
'attempt-proctored'
);
var
attempt_proctored
=
$
(
this
).
data
(
'attempt-proctored'
);
var
start_immediately
=
$
(
this
).
data
(
'start-immediately'
);
var
start_immediately
=
$
(
this
).
data
(
'start-immediately'
);
if
(
!
attempt_proctored
)
{
var
msg
=
gettext
(
"Are you sure you want to take this exam without proctoring? "
+
"This will make you no longer eligible to earn credit for this course."
)
if
(
!
confirm
(
msg
))
{
return
;
}
}
if
(
typeof
action_url
===
"undefined"
)
{
if
(
typeof
action_url
===
"undefined"
)
{
return
false
;
return
false
;
}
}
...
...
edx_proctoring/templates/proctoring/seq_proctored_exam_instructions.html
View file @
98c6bf37
...
@@ -51,11 +51,22 @@
...
@@ -51,11 +51,22 @@
var
_waiting_for_proctored_interval
=
null
;
var
_waiting_for_proctored_interval
=
null
;
$
(
'.proctored-decline-exam'
).
click
(
$
(
'.proctored-decline-exam'
).
click
(
function
(
event
)
{
function
(
e
)
{
e
.
preventDefault
();
e
.
stopPropagation
();
var
action_url
=
$
(
this
).
data
(
'change-state-url'
);
var
action_url
=
$
(
this
).
data
(
'change-state-url'
);
var
exam_id
=
$
(
this
).
data
(
'exam-id'
);
var
exam_id
=
$
(
this
).
data
(
'exam-id'
);
var
action
=
$
(
this
).
data
(
'action'
)
var
action
=
$
(
this
).
data
(
'action'
)
var
msg
=
gettext
(
"Are you sure you want to take this exam without proctoring? "
+
"This will make you no longer eligible to earn credit for this course."
)
if
(
!
confirm
(
msg
))
{
return
;
}
// Update the state of the attempt
// Update the state of the attempt
$
.
ajax
({
$
.
ajax
({
url
:
action_url
,
url
:
action_url
,
...
...
edx_proctoring/tests/test_api.py
View file @
98c6bf37
...
@@ -839,6 +839,7 @@ class ProctoredExamApiTests(LoggedInTestCase):
...
@@ -839,6 +839,7 @@ class ProctoredExamApiTests(LoggedInTestCase):
)
)
self
.
assertIsNone
(
rendered_response
)
self
.
assertIsNone
(
rendered_response
)
@patch.dict
(
'django.conf.settings.PROCTORING_SETTINGS'
,
{
'ALLOW_TIMED_OUT_STATE'
:
True
})
def
test_get_studentview_timedout
(
self
):
def
test_get_studentview_timedout
(
self
):
"""
"""
Verifies that if we call get_studentview when the timer has expired
Verifies that if we call get_studentview when the timer has expired
...
@@ -959,6 +960,7 @@ class ProctoredExamApiTests(LoggedInTestCase):
...
@@ -959,6 +960,7 @@ class ProctoredExamApiTests(LoggedInTestCase):
)
)
self
.
assertIn
(
self
.
proctored_exam_completed_msg
,
rendered_response
)
self
.
assertIn
(
self
.
proctored_exam_completed_msg
,
rendered_response
)
@patch.dict
(
'django.conf.settings.PROCTORING_SETTINGS'
,
{
'ALLOW_TIMED_OUT_STATE'
:
True
})
def
test_get_studentview_expired
(
self
):
def
test_get_studentview_expired
(
self
):
"""
"""
Test for get_student_view proctored exam which has expired.
Test for get_student_view proctored exam which has expired.
...
@@ -1095,6 +1097,7 @@ class ProctoredExamApiTests(LoggedInTestCase):
...
@@ -1095,6 +1097,7 @@ class ProctoredExamApiTests(LoggedInTestCase):
(
ProctoredExamStudentAttemptStatus
.
error
,
ProctoredExamStudentAttemptStatus
.
started
),
(
ProctoredExamStudentAttemptStatus
.
error
,
ProctoredExamStudentAttemptStatus
.
started
),
)
)
@ddt.unpack
@ddt.unpack
@patch.dict
(
'django.conf.settings.PROCTORING_SETTINGS'
,
{
'ALLOW_TIMED_OUT_STATE'
:
True
})
def
test_illegal_status_transition
(
self
,
from_status
,
to_status
):
def
test_illegal_status_transition
(
self
,
from_status
,
to_status
):
"""
"""
Verify that we cannot reset backwards an attempt status
Verify that we cannot reset backwards an attempt status
...
@@ -1109,9 +1112,28 @@ class ProctoredExamApiTests(LoggedInTestCase):
...
@@ -1109,9 +1112,28 @@ class ProctoredExamApiTests(LoggedInTestCase):
)
)
with
self
.
assertRaises
(
ProctoredExamIllegalStatusTransition
):
with
self
.
assertRaises
(
ProctoredExamIllegalStatusTransition
):
print
'*** from = {} to {}'
.
format
(
from_status
,
to_status
)
update_attempt_status
(
update_attempt_status
(
exam_attempt
.
proctored_exam_id
,
exam_attempt
.
proctored_exam_id
,
self
.
user
.
id
,
self
.
user
.
id
,
to_status
to_status
)
)
def
test_alias_timed_out
(
self
):
"""
Verified that timed_out will automatically state transition
to ready_to_submit
"""
exam_attempt
=
self
.
_create_started_exam_attempt
()
update_attempt_status
(
exam_attempt
.
proctored_exam_id
,
self
.
user
.
id
,
ProctoredExamStudentAttemptStatus
.
timed_out
)
exam_attempt
=
get_exam_attempt_by_id
(
exam_attempt
.
id
)
self
.
assertEqual
(
exam_attempt
[
'status'
],
ProctoredExamStudentAttemptStatus
.
ready_to_submit
)
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