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
c426c114
Commit
c426c114
authored
Oct 06, 2015
by
Chris Dodge
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
archive any change to the attempt status
parent
a89c119c
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
95 additions
and
4 deletions
+95
-4
edx_proctoring/backends/tests/test_software_secure.py
+3
-1
edx_proctoring/migrations/0013_auto__add_field_proctoredexamstudentattempthistory_last_poll_timestamp.py
+0
-0
edx_proctoring/models.py
+44
-3
edx_proctoring/tests/test_models.py
+48
-0
No files found.
edx_proctoring/backends/tests/test_software_secure.py
View file @
c426c114
...
@@ -803,7 +803,9 @@ class SoftwareSecureTests(TestCase):
...
@@ -803,7 +803,9 @@ class SoftwareSecureTests(TestCase):
# look at the attempt again, since it moved into Archived state
# look at the attempt again, since it moved into Archived state
# then it should still remain unchanged
# then it should still remain unchanged
archived_attempt
=
ProctoredExamStudentAttemptHistory
.
objects
.
get
(
attempt_code
=
attempt
[
'attempt_code'
])
archived_attempt
=
ProctoredExamStudentAttemptHistory
.
objects
.
filter
(
attempt_code
=
attempt
[
'attempt_code'
]
)
.
latest
(
'created'
)
self
.
assertEqual
(
archived_attempt
.
status
,
attempt
[
'status'
])
self
.
assertEqual
(
archived_attempt
.
status
,
attempt
[
'status'
])
...
...
edx_proctoring/migrations/0013_auto__add_field_proctoredexamstudentattempthistory_last_poll_timestamp.py
0 → 100644
View file @
c426c114
This diff is collapsed.
Click to expand it.
edx_proctoring/models.py
View file @
c426c114
...
@@ -525,6 +525,9 @@ class ProctoredExamStudentAttemptHistory(TimeStampedModel):
...
@@ -525,6 +525,9 @@ class ProctoredExamStudentAttemptHistory(TimeStampedModel):
# this ID might point to a record that is in the History table
# this ID might point to a record that is in the History table
review_policy_id
=
models
.
IntegerField
(
null
=
True
)
review_policy_id
=
models
.
IntegerField
(
null
=
True
)
last_poll_timestamp
=
models
.
DateTimeField
(
null
=
True
)
last_poll_ipaddr
=
models
.
CharField
(
max_length
=
32
,
null
=
True
)
@classmethod
@classmethod
def
get_exam_attempt_by_code
(
cls
,
attempt_code
):
def
get_exam_attempt_by_code
(
cls
,
attempt_code
):
"""
"""
...
@@ -537,9 +540,10 @@ class ProctoredExamStudentAttemptHistory(TimeStampedModel):
...
@@ -537,9 +540,10 @@ class ProctoredExamStudentAttemptHistory(TimeStampedModel):
# there are any
# there are any
exam_attempt_obj
=
None
exam_attempt_obj
=
None
items
=
cls
.
objects
.
filter
(
attempt_code
=
attempt_code
)
.
order_by
(
"-created"
)
try
:
if
items
:
exam_attempt_obj
=
cls
.
objects
.
filter
(
attempt_code
=
attempt_code
)
.
latest
(
"created"
)
exam_attempt_obj
=
items
[
0
]
except
cls
.
DoesNotExist
:
# pylint: disable=no-member
pass
return
exam_attempt_obj
return
exam_attempt_obj
...
@@ -570,10 +574,47 @@ def on_attempt_deleted(sender, instance, **kwargs): # pylint: disable=unused-ar
...
@@ -570,10 +574,47 @@ def on_attempt_deleted(sender, instance, **kwargs): # pylint: disable=unused-ar
is_sample_attempt
=
instance
.
is_sample_attempt
,
is_sample_attempt
=
instance
.
is_sample_attempt
,
student_name
=
instance
.
student_name
,
student_name
=
instance
.
student_name
,
review_policy_id
=
instance
.
review_policy_id
,
review_policy_id
=
instance
.
review_policy_id
,
last_poll_timestamp
=
instance
.
last_poll_timestamp
,
last_poll_ipaddr
=
instance
.
last_poll_ipaddr
,
)
)
archive_object
.
save
()
archive_object
.
save
()
@receiver
(
pre_save
,
sender
=
ProctoredExamStudentAttempt
)
def
on_attempt_updated
(
sender
,
instance
,
**
kwargs
):
# pylint: disable=unused-argument
"""
Archive the exam attempt when the item is about to be deleted
Make a clone and populate in the History table
"""
if
instance
.
id
:
# on an update case, get the original
# and see if the status has changed, if so, then we need
# to archive it
original
=
ProctoredExamStudentAttempt
.
objects
.
get
(
id
=
instance
.
id
)
if
original
.
status
!=
instance
.
status
:
archive_object
=
ProctoredExamStudentAttemptHistory
(
user
=
original
.
user
,
attempt_id
=
original
.
id
,
proctored_exam
=
original
.
proctored_exam
,
started_at
=
original
.
started_at
,
completed_at
=
original
.
completed_at
,
attempt_code
=
original
.
attempt_code
,
external_id
=
original
.
external_id
,
allowed_time_limit_mins
=
original
.
allowed_time_limit_mins
,
status
=
original
.
status
,
taking_as_proctored
=
original
.
taking_as_proctored
,
is_sample_attempt
=
original
.
is_sample_attempt
,
student_name
=
original
.
student_name
,
review_policy_id
=
original
.
review_policy_id
,
last_poll_timestamp
=
original
.
last_poll_timestamp
,
last_poll_ipaddr
=
original
.
last_poll_ipaddr
,
)
archive_object
.
save
()
class
QuerySetWithUpdateOverride
(
models
.
query
.
QuerySet
):
class
QuerySetWithUpdateOverride
(
models
.
query
.
QuerySet
):
"""
"""
Custom QuerySet class to make an archive copy
Custom QuerySet class to make an archive copy
...
...
edx_proctoring/tests/test_models.py
View file @
c426c114
"""
"""
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
,
...
@@ -9,6 +10,7 @@ from edx_proctoring.models import (
...
@@ -9,6 +10,7 @@ from edx_proctoring.models import (
ProctoredExamStudentAttemptHistory
,
ProctoredExamStudentAttemptHistory
,
ProctoredExamReviewPolicy
,
ProctoredExamReviewPolicy
,
ProctoredExamReviewPolicyHistory
,
ProctoredExamReviewPolicyHistory
,
ProctoredExamStudentAttemptStatus
,
)
)
from
.utils
import
(
from
.utils
import
(
...
@@ -174,6 +176,52 @@ class ProctoredExamStudentAttemptTests(LoggedInTestCase):
...
@@ -174,6 +176,52 @@ class ProctoredExamStudentAttemptTests(LoggedInTestCase):
deleted_item
=
ProctoredExamStudentAttemptHistory
.
get_exam_attempt_by_code
(
"123456"
)
deleted_item
=
ProctoredExamStudentAttemptHistory
.
get_exam_attempt_by_code
(
"123456"
)
self
.
assertEqual
(
deleted_item
.
student_name
,
"John. D Updated"
)
self
.
assertEqual
(
deleted_item
.
student_name
,
"John. D Updated"
)
def
test_update_proctored_exam_attempt
(
self
):
"""
Deleting the proctored exam attempt creates an entry in the history table.
"""
proctored_exam
=
ProctoredExam
.
objects
.
create
(
course_id
=
'test_course'
,
content_id
=
'test_content'
,
exam_name
=
'Test Exam'
,
external_id
=
'123aXqe3'
,
time_limit_mins
=
90
)
attempt
=
ProctoredExamStudentAttempt
.
objects
.
create
(
proctored_exam_id
=
proctored_exam
.
id
,
user_id
=
1
,
status
=
ProctoredExamStudentAttemptStatus
.
created
,
student_name
=
"John. D"
,
allowed_time_limit_mins
=
10
,
attempt_code
=
"123456"
,
taking_as_proctored
=
True
,
is_sample_attempt
=
True
,
external_id
=
1
)
# No entry in the History table on creation of the Allowance entry.
attempt_history
=
ProctoredExamStudentAttemptHistory
.
objects
.
filter
(
user_id
=
1
)
self
.
assertEqual
(
len
(
attempt_history
),
0
)
# re-saving, but not changing status should not make an archive copy
attempt
.
student_name
=
'John. D Updated'
attempt
.
save
()
attempt_history
=
ProctoredExamStudentAttemptHistory
.
objects
.
filter
(
user_id
=
1
)
self
.
assertEqual
(
len
(
attempt_history
),
0
)
# change status...
attempt
.
status
=
ProctoredExamStudentAttemptStatus
.
started
attempt
.
save
()
attempt_history
=
ProctoredExamStudentAttemptHistory
.
objects
.
filter
(
user_id
=
1
)
self
.
assertEqual
(
len
(
attempt_history
),
1
)
# make sure we can ready it back with helper class method
updated_item
=
ProctoredExamStudentAttemptHistory
.
get_exam_attempt_by_code
(
"123456"
)
self
.
assertEqual
(
updated_item
.
student_name
,
"John. D Updated"
)
self
.
assertEqual
(
updated_item
.
status
,
ProctoredExamStudentAttemptStatus
.
created
)
def
test_get_exam_attempts
(
self
):
def
test_get_exam_attempts
(
self
):
"""
"""
Test to get all the exam attempts for a course
Test to get all the exam attempts for a course
...
...
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