Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
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-platform
Commits
412f1205
Commit
412f1205
authored
Jun 25, 2015
by
Jonathan Piacenti
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Make resetting of attempts and student state on blocks recursive.
parent
754eb9af
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
158 additions
and
13 deletions
+158
-13
lms/djangoapps/instructor/enrollment.py
+19
-0
lms/djangoapps/instructor/tests/test_api.py
+0
-1
lms/djangoapps/instructor/tests/test_enrollment.py
+139
-12
No files found.
lms/djangoapps/instructor/enrollment.py
View file @
412f1205
...
@@ -5,6 +5,7 @@ Does not include any access control, be sure to check access before calling.
...
@@ -5,6 +5,7 @@ Does not include any access control, be sure to check access before calling.
"""
"""
import
json
import
json
import
logging
from
django.contrib.auth.models
import
User
from
django.contrib.auth.models
import
User
from
django.conf
import
settings
from
django.conf
import
settings
from
django.core.urlresolvers
import
reverse
from
django.core.urlresolvers
import
reverse
...
@@ -21,6 +22,11 @@ from student.models import anonymous_id_for_user
...
@@ -21,6 +22,11 @@ from student.models import anonymous_id_for_user
from
openedx.core.djangoapps.user_api.models
import
UserPreference
from
openedx.core.djangoapps.user_api.models
import
UserPreference
from
microsite_configuration
import
microsite
from
microsite_configuration
import
microsite
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore.exceptions
import
ItemNotFoundError
log
=
logging
.
getLogger
(
__name__
)
class
EmailEnrollmentState
(
object
):
class
EmailEnrollmentState
(
object
):
...
@@ -203,6 +209,19 @@ def reset_student_attempts(course_id, student, module_state_key, delete_module=F
...
@@ -203,6 +209,19 @@ def reset_student_attempts(course_id, student, module_state_key, delete_module=F
submissions.SubmissionError: unexpected error occurred while resetting the score in the submissions API.
submissions.SubmissionError: unexpected error occurred while resetting the score in the submissions API.
"""
"""
try
:
# A block may have children. Clear state on children first.
block
=
modulestore
()
.
get_item
(
module_state_key
)
if
block
.
has_children
:
for
child
in
block
.
children
:
try
:
reset_student_attempts
(
course_id
,
student
,
child
,
delete_module
=
delete_module
)
except
StudentModule
.
DoesNotExist
:
# If a particular child doesn't have any state, no big deal, as long as the parent does.
pass
except
ItemNotFoundError
:
log
.
warning
(
"Could not find
%
s in modulestore when attempting to reset attempts."
,
module_state_key
)
# Reset the student's score in the submissions API
# Reset the student's score in the submissions API
# Currently this is used only by open assessment (ORA 2)
# Currently this is used only by open assessment (ORA 2)
# We need to do this *before* retrieving the `StudentModule` model,
# We need to do this *before* retrieving the `StudentModule` model,
...
...
lms/djangoapps/instructor/tests/test_api.py
View file @
412f1205
...
@@ -8,7 +8,6 @@ import random
...
@@ -8,7 +8,6 @@ import random
import
pytz
import
pytz
import
io
import
io
import
json
import
json
import
os
import
requests
import
requests
import
shutil
import
shutil
import
tempfile
import
tempfile
...
...
lms/djangoapps/instructor/tests/test_enrollment.py
View file @
412f1205
...
@@ -13,7 +13,8 @@ from django.utils.translation import get_language
...
@@ -13,7 +13,8 @@ from django.utils.translation import get_language
from
django.utils.translation
import
override
as
override_language
from
django.utils.translation
import
override
as
override_language
from
nose.plugins.attrib
import
attr
from
nose.plugins.attrib
import
attr
from
student.tests.factories
import
UserFactory
from
student.tests.factories
import
UserFactory
from
xmodule.modulestore.tests.factories
import
CourseFactory
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore.tests.factories
import
CourseFactory
,
ItemFactory
from
student.models
import
CourseEnrollment
,
CourseEnrollmentAllowed
from
student.models
import
CourseEnrollment
,
CourseEnrollmentAllowed
from
instructor.enrollment
import
(
from
instructor.enrollment
import
(
...
@@ -295,31 +296,102 @@ class TestInstructorUnenrollDB(TestEnrollmentChangeBase):
...
@@ -295,31 +296,102 @@ class TestInstructorUnenrollDB(TestEnrollmentChangeBase):
@attr
(
'shard_1'
)
@attr
(
'shard_1'
)
class
TestInstructorEnrollmentStudentModule
(
TestCase
):
class
TestInstructorEnrollmentStudentModule
(
ModuleStore
TestCase
):
""" Test student module manipulations. """
""" Test student module manipulations. """
def
setUp
(
self
):
def
setUp
(
self
):
super
(
TestInstructorEnrollmentStudentModule
,
self
)
.
setUp
()
super
(
TestInstructorEnrollmentStudentModule
,
self
)
.
setUp
()
self
.
course_key
=
SlashSeparatedCourseKey
(
'fake'
,
'course'
,
'id'
)
store
=
modulestore
()
self
.
user
=
UserFactory
()
self
.
course
=
CourseFactory
(
name
=
'fake'
,
org
=
'course'
,
run
=
'id'
,
)
# pylint: disable=no-member
self
.
course_key
=
self
.
course
.
location
.
course_key
self
.
parent
=
ItemFactory
(
category
=
"library_content"
,
# pylint: disable=no-member
user_id
=
self
.
user
.
id
,
parent
=
self
.
course
,
publish_item
=
True
,
modulestore
=
store
,
)
self
.
child
=
ItemFactory
(
category
=
"html"
,
# pylint: disable=no-member
user_id
=
self
.
user
.
id
,
parent
=
self
.
parent
,
publish_item
=
True
,
modulestore
=
store
,
)
self
.
unrelated
=
ItemFactory
(
category
=
"html"
,
# pylint: disable=no-member
user_id
=
self
.
user
.
id
,
parent
=
self
.
course
,
publish_item
=
True
,
modulestore
=
store
,
)
parent_state
=
json
.
dumps
({
'attempts'
:
32
,
'otherstuff'
:
'alsorobots'
})
child_state
=
json
.
dumps
({
'attempts'
:
10
,
'whatever'
:
'things'
})
unrelated_state
=
json
.
dumps
({
'attempts'
:
12
,
'brains'
:
'zombie'
})
StudentModule
.
objects
.
create
(
student
=
self
.
user
,
course_id
=
self
.
course_key
,
module_state_key
=
self
.
parent
.
location
,
state
=
parent_state
,
)
StudentModule
.
objects
.
create
(
student
=
self
.
user
,
course_id
=
self
.
course_key
,
module_state_key
=
self
.
child
.
location
,
state
=
child_state
,
)
StudentModule
.
objects
.
create
(
student
=
self
.
user
,
course_id
=
self
.
course_key
,
module_state_key
=
self
.
unrelated
.
location
,
state
=
unrelated_state
,
)
def
test_reset_student_attempts
(
self
):
def
test_reset_student_attempts
(
self
):
user
=
UserFactory
()
msk
=
self
.
course_key
.
make_usage_key
(
'dummy'
,
'module'
)
msk
=
self
.
course_key
.
make_usage_key
(
'dummy'
,
'module'
)
original_state
=
json
.
dumps
({
'attempts'
:
32
,
'otherstuff'
:
'alsorobots'
})
original_state
=
json
.
dumps
({
'attempts'
:
32
,
'otherstuff'
:
'alsorobots'
})
StudentModule
.
objects
.
create
(
student
=
user
,
course_id
=
self
.
course_key
,
module_state_key
=
msk
,
state
=
original_state
)
StudentModule
.
objects
.
create
(
student
=
self
.
user
,
course_id
=
self
.
course_key
,
module_state_key
=
msk
,
state
=
original_state
)
# lambda to reload the module state from the database
# lambda to reload the module state from the database
module
=
lambda
:
StudentModule
.
objects
.
get
(
student
=
user
,
course_id
=
self
.
course_key
,
module_state_key
=
msk
)
module
=
lambda
:
StudentModule
.
objects
.
get
(
student
=
self
.
user
,
course_id
=
self
.
course_key
,
module_state_key
=
msk
)
self
.
assertEqual
(
json
.
loads
(
module
()
.
state
)[
'attempts'
],
32
)
self
.
assertEqual
(
json
.
loads
(
module
()
.
state
)[
'attempts'
],
32
)
reset_student_attempts
(
self
.
course_key
,
user
,
msk
)
reset_student_attempts
(
self
.
course_key
,
self
.
user
,
msk
)
self
.
assertEqual
(
json
.
loads
(
module
()
.
state
)[
'attempts'
],
0
)
self
.
assertEqual
(
json
.
loads
(
module
()
.
state
)[
'attempts'
],
0
)
def
test_delete_student_attempts
(
self
):
def
test_delete_student_attempts
(
self
):
user
=
UserFactory
()
msk
=
self
.
course_key
.
make_usage_key
(
'dummy'
,
'module'
)
msk
=
self
.
course_key
.
make_usage_key
(
'dummy'
,
'module'
)
original_state
=
json
.
dumps
({
'attempts'
:
32
,
'otherstuff'
:
'alsorobots'
})
original_state
=
json
.
dumps
({
'attempts'
:
32
,
'otherstuff'
:
'alsorobots'
})
StudentModule
.
objects
.
create
(
student
=
user
,
course_id
=
self
.
course_key
,
module_state_key
=
msk
,
state
=
original_state
)
StudentModule
.
objects
.
create
(
self
.
assertEqual
(
StudentModule
.
objects
.
filter
(
student
=
user
,
course_id
=
self
.
course_key
,
module_state_key
=
msk
)
.
count
(),
1
)
student
=
self
.
user
,
reset_student_attempts
(
self
.
course_key
,
user
,
msk
,
delete_module
=
True
)
course_id
=
self
.
course_key
,
self
.
assertEqual
(
StudentModule
.
objects
.
filter
(
student
=
user
,
course_id
=
self
.
course_key
,
module_state_key
=
msk
)
.
count
(),
0
)
module_state_key
=
msk
,
state
=
original_state
)
self
.
assertEqual
(
StudentModule
.
objects
.
filter
(
student
=
self
.
user
,
course_id
=
self
.
course_key
,
module_state_key
=
msk
)
.
count
(),
1
)
reset_student_attempts
(
self
.
course_key
,
self
.
user
,
msk
,
delete_module
=
True
)
self
.
assertEqual
(
StudentModule
.
objects
.
filter
(
student
=
self
.
user
,
course_id
=
self
.
course_key
,
module_state_key
=
msk
)
.
count
(),
0
)
def
test_delete_submission_scores
(
self
):
def
test_delete_submission_scores
(
self
):
user
=
UserFactory
()
user
=
UserFactory
()
...
@@ -353,6 +425,61 @@ class TestInstructorEnrollmentStudentModule(TestCase):
...
@@ -353,6 +425,61 @@ class TestInstructorEnrollmentStudentModule(TestCase):
score
=
sub_api
.
get_score
(
student_item
)
score
=
sub_api
.
get_score
(
student_item
)
self
.
assertIs
(
score
,
None
)
self
.
assertIs
(
score
,
None
)
def
get_state
(
self
,
location
):
"""Reload and grab the module state from the database"""
return
StudentModule
.
objects
.
get
(
student
=
self
.
user
,
course_id
=
self
.
course_key
,
module_state_key
=
location
)
.
state
def
test_reset_student_attempts_children
(
self
):
parent_state
=
json
.
loads
(
self
.
get_state
(
self
.
parent
.
location
))
self
.
assertEqual
(
parent_state
[
'attempts'
],
32
)
self
.
assertEqual
(
parent_state
[
'otherstuff'
],
'alsorobots'
)
child_state
=
json
.
loads
(
self
.
get_state
(
self
.
child
.
location
))
self
.
assertEqual
(
child_state
[
'attempts'
],
10
)
self
.
assertEqual
(
child_state
[
'whatever'
],
'things'
)
unrelated_state
=
json
.
loads
(
self
.
get_state
(
self
.
unrelated
.
location
))
self
.
assertEqual
(
unrelated_state
[
'attempts'
],
12
)
self
.
assertEqual
(
unrelated_state
[
'brains'
],
'zombie'
)
reset_student_attempts
(
self
.
course_key
,
self
.
user
,
self
.
parent
.
location
)
parent_state
=
json
.
loads
(
self
.
get_state
(
self
.
parent
.
location
))
self
.
assertEqual
(
json
.
loads
(
self
.
get_state
(
self
.
parent
.
location
))[
'attempts'
],
0
)
self
.
assertEqual
(
parent_state
[
'otherstuff'
],
'alsorobots'
)
child_state
=
json
.
loads
(
self
.
get_state
(
self
.
child
.
location
))
self
.
assertEqual
(
child_state
[
'attempts'
],
0
)
self
.
assertEqual
(
child_state
[
'whatever'
],
'things'
)
unrelated_state
=
json
.
loads
(
self
.
get_state
(
self
.
unrelated
.
location
))
self
.
assertEqual
(
unrelated_state
[
'attempts'
],
12
)
self
.
assertEqual
(
unrelated_state
[
'brains'
],
'zombie'
)
def
test_delete_submission_scores_attempts_children
(
self
):
parent_state
=
json
.
loads
(
self
.
get_state
(
self
.
parent
.
location
))
self
.
assertEqual
(
parent_state
[
'attempts'
],
32
)
self
.
assertEqual
(
parent_state
[
'otherstuff'
],
'alsorobots'
)
child_state
=
json
.
loads
(
self
.
get_state
(
self
.
child
.
location
))
self
.
assertEqual
(
child_state
[
'attempts'
],
10
)
self
.
assertEqual
(
child_state
[
'whatever'
],
'things'
)
unrelated_state
=
json
.
loads
(
self
.
get_state
(
self
.
unrelated
.
location
))
self
.
assertEqual
(
unrelated_state
[
'attempts'
],
12
)
self
.
assertEqual
(
unrelated_state
[
'brains'
],
'zombie'
)
reset_student_attempts
(
self
.
course_key
,
self
.
user
,
self
.
parent
.
location
,
delete_module
=
True
)
self
.
assertRaises
(
StudentModule
.
DoesNotExist
,
self
.
get_state
,
self
.
parent
.
location
)
self
.
assertRaises
(
StudentModule
.
DoesNotExist
,
self
.
get_state
,
self
.
child
.
location
)
unrelated_state
=
json
.
loads
(
self
.
get_state
(
self
.
unrelated
.
location
))
self
.
assertEqual
(
unrelated_state
[
'attempts'
],
12
)
self
.
assertEqual
(
unrelated_state
[
'brains'
],
'zombie'
)
class
EnrollmentObjects
(
object
):
class
EnrollmentObjects
(
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