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
7f19d489
Commit
7f19d489
authored
Apr 04, 2013
by
Calen Pennington
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1795 from MITx/feature/cale/use-open-source-xblock
Migrate to the open source XBlock repo
parents
b7c8a697
039ccb83
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
77 additions
and
77 deletions
+77
-77
common/lib/xmodule/xmodule/abtest_module.py
+1
-1
common/lib/xmodule/xmodule/capa_module.py
+6
-6
common/lib/xmodule/xmodule/combined_open_ended_module.py
+5
-5
common/lib/xmodule/xmodule/peer_grading_module.py
+1
-1
common/lib/xmodule/xmodule/poll_module.py
+2
-2
common/lib/xmodule/xmodule/randomize_module.py
+1
-1
common/lib/xmodule/xmodule/seq_module.py
+1
-1
common/lib/xmodule/xmodule/timelimit_module.py
+3
-3
common/lib/xmodule/xmodule/video_module.py
+1
-1
common/lib/xmodule/xmodule/videoalpha_module.py
+1
-1
lms/djangoapps/courseware/grades.py
+2
-2
lms/djangoapps/courseware/model_data.py
+23
-23
lms/djangoapps/courseware/models.py
+2
-2
lms/djangoapps/courseware/tests/test_model_data.py
+27
-27
local-requirements.txt
+1
-1
No files found.
common/lib/xmodule/xmodule/abtest_module.py
View file @
7f19d489
...
...
@@ -33,7 +33,7 @@ def group_from_value(groups, v):
class
ABTestFields
(
object
):
group_portions
=
Object
(
help
=
"What proportions of students should go in each group"
,
default
=
{
DEFAULT
:
1
},
scope
=
Scope
.
content
)
group_assignments
=
Object
(
help
=
"What group this user belongs to"
,
scope
=
Scope
.
student_
preferences
,
default
=
{})
group_assignments
=
Object
(
help
=
"What group this user belongs to"
,
scope
=
Scope
.
preferences
,
default
=
{})
group_content
=
Object
(
help
=
"What content to display to each group"
,
scope
=
Scope
.
content
,
default
=
{
DEFAULT
:
[]})
experiment
=
String
(
help
=
"Experiment that this A/B test belongs to"
,
scope
=
Scope
.
content
)
has_children
=
True
...
...
common/lib/xmodule/xmodule/capa_module.py
View file @
7f19d489
...
...
@@ -83,7 +83,7 @@ class ComplexEncoder(json.JSONEncoder):
class
CapaFields
(
object
):
attempts
=
StringyInteger
(
help
=
"Number of attempts taken by the student on this problem"
,
default
=
0
,
scope
=
Scope
.
student
_state
)
attempts
=
StringyInteger
(
help
=
"Number of attempts taken by the student on this problem"
,
default
=
0
,
scope
=
Scope
.
user
_state
)
max_attempts
=
StringyInteger
(
help
=
"Maximum number of attempts that a student is allowed"
,
scope
=
Scope
.
settings
)
due
=
Date
(
help
=
"Date that this problem is due by"
,
scope
=
Scope
.
settings
)
graceperiod
=
Timedelta
(
help
=
"Amount of time after the due date that submissions will be accepted"
,
scope
=
Scope
.
settings
)
...
...
@@ -91,12 +91,12 @@ class CapaFields(object):
force_save_button
=
Boolean
(
help
=
"Whether to force the save button to appear on the page"
,
scope
=
Scope
.
settings
,
default
=
False
)
rerandomize
=
Randomization
(
help
=
"When to rerandomize the problem"
,
default
=
"always"
,
scope
=
Scope
.
settings
)
data
=
String
(
help
=
"XML data for the problem"
,
scope
=
Scope
.
content
)
correct_map
=
Object
(
help
=
"Dictionary with the correctness of current student answers"
,
scope
=
Scope
.
student
_state
,
default
=
{})
input_state
=
Object
(
help
=
"Dictionary for maintaining the state of inputtypes"
,
scope
=
Scope
.
student
_state
)
student_answers
=
Object
(
help
=
"Dictionary with the current student responses"
,
scope
=
Scope
.
student
_state
)
done
=
Boolean
(
help
=
"Whether the student has answered the problem"
,
scope
=
Scope
.
student
_state
)
correct_map
=
Object
(
help
=
"Dictionary with the correctness of current student answers"
,
scope
=
Scope
.
user
_state
,
default
=
{})
input_state
=
Object
(
help
=
"Dictionary for maintaining the state of inputtypes"
,
scope
=
Scope
.
user
_state
)
student_answers
=
Object
(
help
=
"Dictionary with the current student responses"
,
scope
=
Scope
.
user
_state
)
done
=
Boolean
(
help
=
"Whether the student has answered the problem"
,
scope
=
Scope
.
user
_state
)
display_name
=
String
(
help
=
"Display name for this module"
,
scope
=
Scope
.
settings
)
seed
=
StringyInteger
(
help
=
"Random seed for this student"
,
scope
=
Scope
.
student
_state
)
seed
=
StringyInteger
(
help
=
"Random seed for this student"
,
scope
=
Scope
.
user
_state
)
weight
=
StringyFloat
(
help
=
"How much to weight this problem by"
,
scope
=
Scope
.
settings
)
markdown
=
String
(
help
=
"Markdown source of this module"
,
scope
=
Scope
.
settings
)
...
...
common/lib/xmodule/xmodule/combined_open_ended_module.py
View file @
7f19d489
...
...
@@ -50,14 +50,14 @@ class VersionInteger(Integer):
class
CombinedOpenEndedFields
(
object
):
display_name
=
String
(
help
=
"Display name for this module"
,
default
=
"Open Ended Grading"
,
scope
=
Scope
.
settings
)
current_task_number
=
Integer
(
help
=
"Current task that the student is on."
,
default
=
0
,
scope
=
Scope
.
student
_state
)
task_states
=
List
(
help
=
"List of state dictionaries of each task within this module."
,
scope
=
Scope
.
student
_state
)
current_task_number
=
Integer
(
help
=
"Current task that the student is on."
,
default
=
0
,
scope
=
Scope
.
user
_state
)
task_states
=
List
(
help
=
"List of state dictionaries of each task within this module."
,
scope
=
Scope
.
user
_state
)
state
=
String
(
help
=
"Which step within the current task that the student is on."
,
default
=
"initial"
,
scope
=
Scope
.
student
_state
)
scope
=
Scope
.
user
_state
)
student_attempts
=
Integer
(
help
=
"Number of attempts taken by the student on this problem"
,
default
=
0
,
scope
=
Scope
.
student
_state
)
scope
=
Scope
.
user
_state
)
ready_to_reset
=
Boolean
(
help
=
"If the problem is ready to be reset or not."
,
default
=
False
,
scope
=
Scope
.
student
_state
)
scope
=
Scope
.
user
_state
)
attempts
=
Integer
(
help
=
"Maximum number of attempts that a student is allowed."
,
default
=
1
,
scope
=
Scope
.
settings
)
is_graded
=
Boolean
(
help
=
"Whether or not the problem is graded."
,
default
=
False
,
scope
=
Scope
.
settings
)
accept_file_upload
=
Boolean
(
help
=
"Whether or not the problem accepts file uploads."
,
default
=
False
,
...
...
common/lib/xmodule/xmodule/peer_grading_module.py
View file @
7f19d489
...
...
@@ -38,7 +38,7 @@ class PeerGradingFields(object):
max_grade
=
Integer
(
help
=
"The maximum grade that a student can receieve for this problem."
,
default
=
MAX_SCORE
,
scope
=
Scope
.
settings
)
student_data_for_location
=
Object
(
help
=
"Student data for a given peer grading problem."
,
default
=
json
.
dumps
({}),
scope
=
Scope
.
student
_state
)
scope
=
Scope
.
user
_state
)
weight
=
StringyFloat
(
help
=
"How much to weight this problem by"
,
scope
=
Scope
.
settings
)
...
...
common/lib/xmodule/xmodule/poll_module.py
View file @
7f19d489
...
...
@@ -30,8 +30,8 @@ class PollFields(object):
# Name of poll to use in links to this poll
display_name
=
String
(
help
=
"Display name for this module"
,
scope
=
Scope
.
settings
)
voted
=
Boolean
(
help
=
"Whether this student has voted on the poll"
,
scope
=
Scope
.
student
_state
,
default
=
False
)
poll_answer
=
String
(
help
=
"Student answer"
,
scope
=
Scope
.
student
_state
,
default
=
''
)
voted
=
Boolean
(
help
=
"Whether this student has voted on the poll"
,
scope
=
Scope
.
user
_state
,
default
=
False
)
poll_answer
=
String
(
help
=
"Student answer"
,
scope
=
Scope
.
user
_state
,
default
=
''
)
poll_answers
=
Object
(
help
=
"All possible answers for the poll fro other students"
,
scope
=
Scope
.
content
)
answers
=
List
(
help
=
"Poll answers from xml"
,
scope
=
Scope
.
content
,
default
=
[])
...
...
common/lib/xmodule/xmodule/randomize_module.py
View file @
7f19d489
...
...
@@ -10,7 +10,7 @@ log = logging.getLogger('mitx.' + __name__)
class
RandomizeFields
(
object
):
choice
=
Integer
(
help
=
"Which random child was chosen"
,
scope
=
Scope
.
student
_state
)
choice
=
Integer
(
help
=
"Which random child was chosen"
,
scope
=
Scope
.
user
_state
)
class
RandomizeModule
(
RandomizeFields
,
XModule
):
...
...
common/lib/xmodule/xmodule/seq_module.py
View file @
7f19d489
...
...
@@ -23,7 +23,7 @@ class SequenceFields(object):
# NOTE: Position is 1-indexed. This is silly, but there are now student
# positions saved on prod, so it's not easy to fix.
position
=
Integer
(
help
=
"Last tab viewed in this sequence"
,
scope
=
Scope
.
student
_state
)
position
=
Integer
(
help
=
"Last tab viewed in this sequence"
,
scope
=
Scope
.
user
_state
)
class
SequenceModule
(
SequenceFields
,
XModule
):
...
...
common/lib/xmodule/xmodule/timelimit_module.py
View file @
7f19d489
...
...
@@ -16,9 +16,9 @@ log = logging.getLogger(__name__)
class
TimeLimitFields
(
object
):
beginning_at
=
Float
(
help
=
"The time this timer was started"
,
scope
=
Scope
.
student
_state
)
ending_at
=
Float
(
help
=
"The time this timer will end"
,
scope
=
Scope
.
student
_state
)
accomodation_code
=
String
(
help
=
"A code indicating accommodations to be given the student"
,
scope
=
Scope
.
student
_state
)
beginning_at
=
Float
(
help
=
"The time this timer was started"
,
scope
=
Scope
.
user
_state
)
ending_at
=
Float
(
help
=
"The time this timer will end"
,
scope
=
Scope
.
user
_state
)
accomodation_code
=
String
(
help
=
"A code indicating accommodations to be given the student"
,
scope
=
Scope
.
user
_state
)
time_expired_redirect_url
=
String
(
help
=
"Url to redirect users to after the timelimit has expired"
,
scope
=
Scope
.
settings
)
duration
=
Float
(
help
=
"The length of this timer"
,
scope
=
Scope
.
settings
)
suppress_toplevel_navigation
=
Boolean
(
help
=
"Whether the toplevel navigation should be suppressed when viewing this module"
,
scope
=
Scope
.
settings
)
...
...
common/lib/xmodule/xmodule/video_module.py
View file @
7f19d489
...
...
@@ -19,7 +19,7 @@ log = logging.getLogger(__name__)
class
VideoFields
(
object
):
data
=
String
(
help
=
"XML data for the problem"
,
scope
=
Scope
.
content
)
position
=
Integer
(
help
=
"Current position in the video"
,
scope
=
Scope
.
student
_state
,
default
=
0
)
position
=
Integer
(
help
=
"Current position in the video"
,
scope
=
Scope
.
user
_state
,
default
=
0
)
display_name
=
String
(
help
=
"Display name for this module"
,
scope
=
Scope
.
settings
)
...
...
common/lib/xmodule/xmodule/videoalpha_module.py
View file @
7f19d489
...
...
@@ -21,7 +21,7 @@ log = logging.getLogger(__name__)
class
VideoAlphaFields
(
object
):
data
=
String
(
help
=
"XML data for the problem"
,
scope
=
Scope
.
content
)
position
=
Integer
(
help
=
"Current position in the video"
,
scope
=
Scope
.
student
_state
,
default
=
0
)
position
=
Integer
(
help
=
"Current position in the video"
,
scope
=
Scope
.
user
_state
,
default
=
0
)
display_name
=
String
(
help
=
"Display name for this module"
,
scope
=
Scope
.
settings
)
...
...
lms/djangoapps/courseware/grades.py
View file @
7f19d489
...
...
@@ -165,7 +165,7 @@ def grade(student, request, course, model_data_cache=None, keep_raw_scores=False
# Create a fake key to pull out a StudentModule object from the ModelDataCache
key
=
LmsKeyValueStore
.
Key
(
Scope
.
student
_state
,
Scope
.
user
_state
,
student
.
id
,
moduledescriptor
.
location
,
None
...
...
@@ -370,7 +370,7 @@ def get_score(course_id, user, problem_descriptor, module_creator, model_data_ca
# Create a fake KeyValueStore key to pull out the StudentModule
key
=
LmsKeyValueStore
.
Key
(
Scope
.
student
_state
,
Scope
.
user
_state
,
user
.
id
,
problem_descriptor
.
location
,
None
...
...
lms/djangoapps/courseware/model_data.py
View file @
7f19d489
...
...
@@ -134,7 +134,7 @@ class ModelDataCache(object):
"""
if
scope
in
(
Scope
.
children
,
Scope
.
parent
):
return
[]
elif
scope
==
Scope
.
student
_state
:
elif
scope
==
Scope
.
user
_state
:
return
self
.
_chunked_query
(
StudentModule
,
'module_state_key__in'
,
...
...
@@ -159,7 +159,7 @@ class ModelDataCache(object):
),
field_name__in
=
set
(
field
.
name
for
field
in
fields
),
)
elif
scope
==
Scope
.
student_
preferences
:
elif
scope
==
Scope
.
preferences
:
return
self
.
_chunked_query
(
XModuleStudentPrefsField
,
'module_type__in'
,
...
...
@@ -167,7 +167,7 @@ class ModelDataCache(object):
student
=
self
.
user
.
pk
,
field_name__in
=
set
(
field
.
name
for
field
in
fields
),
)
elif
scope
==
Scope
.
student
_info
:
elif
scope
==
Scope
.
user
_info
:
return
self
.
_query
(
XModuleStudentInfoField
,
student
=
self
.
user
.
pk
,
...
...
@@ -190,15 +190,15 @@ class ModelDataCache(object):
"""
Return the key used in the ModelDataCache for the specified KeyValueStore key
"""
if
key
.
scope
==
Scope
.
student
_state
:
if
key
.
scope
==
Scope
.
user
_state
:
return
(
key
.
scope
,
key
.
block_scope_id
.
url
())
elif
key
.
scope
==
Scope
.
content
:
return
(
key
.
scope
,
key
.
block_scope_id
.
url
(),
key
.
field_name
)
elif
key
.
scope
==
Scope
.
settings
:
return
(
key
.
scope
,
'
%
s-
%
s'
%
(
self
.
course_id
,
key
.
block_scope_id
.
url
()),
key
.
field_name
)
elif
key
.
scope
==
Scope
.
student_
preferences
:
elif
key
.
scope
==
Scope
.
preferences
:
return
(
key
.
scope
,
key
.
block_scope_id
,
key
.
field_name
)
elif
key
.
scope
==
Scope
.
student
_info
:
elif
key
.
scope
==
Scope
.
user
_info
:
return
(
key
.
scope
,
key
.
field_name
)
def
_cache_key_from_field_object
(
self
,
scope
,
field_object
):
...
...
@@ -206,15 +206,15 @@ class ModelDataCache(object):
Return the key used in the ModelDataCache for the specified scope and
field
"""
if
scope
==
Scope
.
student
_state
:
if
scope
==
Scope
.
user
_state
:
return
(
scope
,
field_object
.
module_state_key
)
elif
scope
==
Scope
.
content
:
return
(
scope
,
field_object
.
definition_id
,
field_object
.
field_name
)
elif
scope
==
Scope
.
settings
:
return
(
scope
,
field_object
.
usage_id
,
field_object
.
field_name
)
elif
scope
==
Scope
.
student_
preferences
:
elif
scope
==
Scope
.
preferences
:
return
(
scope
,
field_object
.
module_type
,
field_object
.
field_name
)
elif
scope
==
Scope
.
student
_info
:
elif
scope
==
Scope
.
user
_info
:
return
(
scope
,
field_object
.
field_name
)
def
find
(
self
,
key
):
...
...
@@ -237,7 +237,7 @@ class ModelDataCache(object):
if
field_object
is
not
None
:
return
field_object
if
key
.
scope
==
Scope
.
student
_state
:
if
key
.
scope
==
Scope
.
user
_state
:
field_object
,
_
=
StudentModule
.
objects
.
get_or_create
(
course_id
=
self
.
course_id
,
student
=
self
.
user
,
...
...
@@ -255,13 +255,13 @@ class ModelDataCache(object):
field_name
=
key
.
field_name
,
usage_id
=
'
%
s-
%
s'
%
(
self
.
course_id
,
key
.
block_scope_id
.
url
()),
)
elif
key
.
scope
==
Scope
.
student_
preferences
:
elif
key
.
scope
==
Scope
.
preferences
:
field_object
,
_
=
XModuleStudentPrefsField
.
objects
.
get_or_create
(
field_name
=
key
.
field_name
,
module_type
=
key
.
block_scope_id
,
student
=
self
.
user
,
)
elif
key
.
scope
==
Scope
.
student
_info
:
elif
key
.
scope
==
Scope
.
user
_info
:
field_object
,
_
=
XModuleStudentInfoField
.
objects
.
get_or_create
(
field_name
=
key
.
field_name
,
student
=
self
.
user
,
...
...
@@ -281,12 +281,12 @@ class LmsKeyValueStore(KeyValueStore):
If the scope to write to is not one of the 5 named scopes:
Scope.content
Scope.settings
Scope.
student
_state
Scope.
student_
preferences
Scope.
student
_info
Scope.
user
_state
Scope.preferences
Scope.
user
_info
then an InvalidScopeError will be raised.
Data for Scope.
student
_state is stored as StudentModule objects via the django orm.
Data for Scope.
user
_state is stored as StudentModule objects via the django orm.
Data for the other scopes is stored in individual objects that are named for the
scope involved and have the field name as a key
...
...
@@ -297,9 +297,9 @@ class LmsKeyValueStore(KeyValueStore):
_allowed_scopes
=
(
Scope
.
content
,
Scope
.
settings
,
Scope
.
student
_state
,
Scope
.
student_
preferences
,
Scope
.
student
_info
,
Scope
.
user
_state
,
Scope
.
preferences
,
Scope
.
user
_info
,
Scope
.
children
,
)
...
...
@@ -321,7 +321,7 @@ class LmsKeyValueStore(KeyValueStore):
if
field_object
is
None
:
raise
KeyError
(
key
.
field_name
)
if
key
.
scope
==
Scope
.
student
_state
:
if
key
.
scope
==
Scope
.
user
_state
:
return
json
.
loads
(
field_object
.
state
)[
key
.
field_name
]
else
:
return
json
.
loads
(
field_object
.
value
)
...
...
@@ -335,7 +335,7 @@ class LmsKeyValueStore(KeyValueStore):
if
key
.
scope
not
in
self
.
_allowed_scopes
:
raise
InvalidScopeError
(
key
.
scope
)
if
key
.
scope
==
Scope
.
student
_state
:
if
key
.
scope
==
Scope
.
user
_state
:
state
=
json
.
loads
(
field_object
.
state
)
state
[
key
.
field_name
]
=
value
field_object
.
state
=
json
.
dumps
(
state
)
...
...
@@ -355,7 +355,7 @@ class LmsKeyValueStore(KeyValueStore):
if
field_object
is
None
:
raise
KeyError
(
key
.
field_name
)
if
key
.
scope
==
Scope
.
student
_state
:
if
key
.
scope
==
Scope
.
user
_state
:
state
=
json
.
loads
(
field_object
.
state
)
del
state
[
key
.
field_name
]
field_object
.
state
=
json
.
dumps
(
state
)
...
...
@@ -377,7 +377,7 @@ class LmsKeyValueStore(KeyValueStore):
if
field_object
is
None
:
return
False
if
key
.
scope
==
Scope
.
student
_state
:
if
key
.
scope
==
Scope
.
user
_state
:
return
key
.
field_name
in
json
.
loads
(
field_object
.
state
)
else
:
return
True
...
...
lms/djangoapps/courseware/models.py
View file @
7f19d489
...
...
@@ -165,7 +165,7 @@ class XModuleSettingsField(models.Model):
class
XModuleStudentPrefsField
(
models
.
Model
):
"""
Stores data set in the Scope.
student_
preferences scope by an xmodule field
Stores data set in the Scope.preferences scope by an xmodule field
"""
class
Meta
:
...
...
@@ -199,7 +199,7 @@ class XModuleStudentPrefsField(models.Model):
class
XModuleStudentInfoField
(
models
.
Model
):
"""
Stores data set in the Scope.
student_
preferences scope by an xmodule field
Stores data set in the Scope.preferences scope by an xmodule field
"""
class
Meta
:
...
...
lms/djangoapps/courseware/tests/test_model_data.py
View file @
7f19d489
...
...
@@ -32,9 +32,9 @@ course_id = 'edX/test_course/test'
content_key
=
partial
(
LmsKeyValueStore
.
Key
,
Scope
.
content
,
None
,
location
(
'def_id'
))
settings_key
=
partial
(
LmsKeyValueStore
.
Key
,
Scope
.
settings
,
None
,
location
(
'def_id'
))
student_state_key
=
partial
(
LmsKeyValueStore
.
Key
,
Scope
.
student
_state
,
'user'
,
location
(
'def_id'
))
student_prefs_key
=
partial
(
LmsKeyValueStore
.
Key
,
Scope
.
student_
preferences
,
'user'
,
'problem'
)
student_info_key
=
partial
(
LmsKeyValueStore
.
Key
,
Scope
.
student
_info
,
'user'
,
None
)
user_state_key
=
partial
(
LmsKeyValueStore
.
Key
,
Scope
.
user
_state
,
'user'
,
location
(
'def_id'
))
prefs_key
=
partial
(
LmsKeyValueStore
.
Key
,
Scope
.
preferences
,
'user'
,
'problem'
)
user_info_key
=
partial
(
LmsKeyValueStore
.
Key
,
Scope
.
user
_info
,
'user'
,
None
)
class
UserFactory
(
factory
.
Factory
):
...
...
@@ -115,13 +115,13 @@ class TestInvalidScopes(TestCase):
def
setUp
(
self
):
self
.
desc_md
=
{}
self
.
user
=
UserFactory
.
create
()
self
.
mdc
=
ModelDataCache
([
mock_descriptor
([
mock_field
(
Scope
.
student
_state
,
'a_field'
)])],
course_id
,
self
.
user
)
self
.
mdc
=
ModelDataCache
([
mock_descriptor
([
mock_field
(
Scope
.
user
_state
,
'a_field'
)])],
course_id
,
self
.
user
)
self
.
kvs
=
LmsKeyValueStore
(
self
.
desc_md
,
self
.
mdc
)
def
test_invalid_scopes
(
self
):
for
scope
in
(
Scope
(
student
=
True
,
block
=
BlockScope
.
DEFINITION
),
Scope
(
student
=
False
,
block
=
BlockScope
.
TYPE
),
Scope
(
student
=
False
,
block
=
BlockScope
.
ALL
)):
for
scope
in
(
Scope
(
user
=
True
,
block
=
BlockScope
.
DEFINITION
),
Scope
(
user
=
False
,
block
=
BlockScope
.
TYPE
),
Scope
(
user
=
False
,
block
=
BlockScope
.
ALL
)):
self
.
assertRaises
(
InvalidScopeError
,
self
.
kvs
.
get
,
LmsKeyValueStore
.
Key
(
scope
,
None
,
None
,
'field'
))
self
.
assertRaises
(
InvalidScopeError
,
self
.
kvs
.
set
,
LmsKeyValueStore
.
Key
(
scope
,
None
,
None
,
'field'
),
'value'
)
self
.
assertRaises
(
InvalidScopeError
,
self
.
kvs
.
delete
,
LmsKeyValueStore
.
Key
(
scope
,
None
,
None
,
'field'
))
...
...
@@ -134,48 +134,48 @@ class TestStudentModuleStorage(TestCase):
self
.
desc_md
=
{}
student_module
=
StudentModuleFactory
(
state
=
json
.
dumps
({
'a_field'
:
'a_value'
}))
self
.
user
=
student_module
.
student
self
.
mdc
=
ModelDataCache
([
mock_descriptor
([
mock_field
(
Scope
.
student
_state
,
'a_field'
)])],
course_id
,
self
.
user
)
self
.
mdc
=
ModelDataCache
([
mock_descriptor
([
mock_field
(
Scope
.
user
_state
,
'a_field'
)])],
course_id
,
self
.
user
)
self
.
kvs
=
LmsKeyValueStore
(
self
.
desc_md
,
self
.
mdc
)
def
test_get_existing_field
(
self
):
"Test that getting an existing field in an existing StudentModule works"
self
.
assertEquals
(
'a_value'
,
self
.
kvs
.
get
(
student
_state_key
(
'a_field'
)))
self
.
assertEquals
(
'a_value'
,
self
.
kvs
.
get
(
user
_state_key
(
'a_field'
)))
def
test_get_missing_field
(
self
):
"Test that getting a missing field from an existing StudentModule raises a KeyError"
self
.
assertRaises
(
KeyError
,
self
.
kvs
.
get
,
student
_state_key
(
'not_a_field'
))
self
.
assertRaises
(
KeyError
,
self
.
kvs
.
get
,
user
_state_key
(
'not_a_field'
))
def
test_set_existing_field
(
self
):
"Test that setting an existing
student
_state field changes the value"
self
.
kvs
.
set
(
student
_state_key
(
'a_field'
),
'new_value'
)
"Test that setting an existing
user
_state field changes the value"
self
.
kvs
.
set
(
user
_state_key
(
'a_field'
),
'new_value'
)
self
.
assertEquals
(
1
,
StudentModule
.
objects
.
all
()
.
count
())
self
.
assertEquals
({
'a_field'
:
'new_value'
},
json
.
loads
(
StudentModule
.
objects
.
all
()[
0
]
.
state
))
def
test_set_missing_field
(
self
):
"Test that setting a new
student
_state field changes the value"
self
.
kvs
.
set
(
student
_state_key
(
'not_a_field'
),
'new_value'
)
"Test that setting a new
user
_state field changes the value"
self
.
kvs
.
set
(
user
_state_key
(
'not_a_field'
),
'new_value'
)
self
.
assertEquals
(
1
,
StudentModule
.
objects
.
all
()
.
count
())
self
.
assertEquals
({
'a_field'
:
'a_value'
,
'not_a_field'
:
'new_value'
},
json
.
loads
(
StudentModule
.
objects
.
all
()[
0
]
.
state
))
def
test_delete_existing_field
(
self
):
"Test that deleting an existing field removes it from the StudentModule"
self
.
kvs
.
delete
(
student
_state_key
(
'a_field'
))
self
.
kvs
.
delete
(
user
_state_key
(
'a_field'
))
self
.
assertEquals
(
1
,
StudentModule
.
objects
.
all
()
.
count
())
self
.
assertRaises
(
KeyError
,
self
.
kvs
.
get
,
student
_state_key
(
'not_a_field'
))
self
.
assertRaises
(
KeyError
,
self
.
kvs
.
get
,
user
_state_key
(
'not_a_field'
))
def
test_delete_missing_field
(
self
):
"Test that deleting a missing field from an existing StudentModule raises a KeyError"
self
.
assertRaises
(
KeyError
,
self
.
kvs
.
delete
,
student
_state_key
(
'not_a_field'
))
self
.
assertRaises
(
KeyError
,
self
.
kvs
.
delete
,
user
_state_key
(
'not_a_field'
))
self
.
assertEquals
(
1
,
StudentModule
.
objects
.
all
()
.
count
())
self
.
assertEquals
({
'a_field'
:
'a_value'
},
json
.
loads
(
StudentModule
.
objects
.
all
()[
0
]
.
state
))
def
test_has_existing_field
(
self
):
"Test that `has` returns True for existing fields in StudentModules"
self
.
assertTrue
(
self
.
kvs
.
has
(
student
_state_key
(
'a_field'
)))
self
.
assertTrue
(
self
.
kvs
.
has
(
user
_state_key
(
'a_field'
)))
def
test_has_missing_field
(
self
):
"Test that `has` returns False for missing fields in StudentModule"
self
.
assertFalse
(
self
.
kvs
.
has
(
student
_state_key
(
'not_a_field'
)))
self
.
assertFalse
(
self
.
kvs
.
has
(
user
_state_key
(
'not_a_field'
)))
class
TestMissingStudentModule
(
TestCase
):
...
...
@@ -187,14 +187,14 @@ class TestMissingStudentModule(TestCase):
def
test_get_field_from_missing_student_module
(
self
):
"Test that getting a field from a missing StudentModule raises a KeyError"
self
.
assertRaises
(
KeyError
,
self
.
kvs
.
get
,
student
_state_key
(
'a_field'
))
self
.
assertRaises
(
KeyError
,
self
.
kvs
.
get
,
user
_state_key
(
'a_field'
))
def
test_set_field_in_missing_student_module
(
self
):
"Test that setting a field in a missing StudentModule creates the student module"
self
.
assertEquals
(
0
,
len
(
self
.
mdc
.
cache
))
self
.
assertEquals
(
0
,
StudentModule
.
objects
.
all
()
.
count
())
self
.
kvs
.
set
(
student
_state_key
(
'a_field'
),
'a_value'
)
self
.
kvs
.
set
(
user
_state_key
(
'a_field'
),
'a_value'
)
self
.
assertEquals
(
1
,
len
(
self
.
mdc
.
cache
))
self
.
assertEquals
(
1
,
StudentModule
.
objects
.
all
()
.
count
())
...
...
@@ -207,11 +207,11 @@ class TestMissingStudentModule(TestCase):
def
test_delete_field_from_missing_student_module
(
self
):
"Test that deleting a field from a missing StudentModule raises a KeyError"
self
.
assertRaises
(
KeyError
,
self
.
kvs
.
delete
,
student
_state_key
(
'a_field'
))
self
.
assertRaises
(
KeyError
,
self
.
kvs
.
delete
,
user
_state_key
(
'a_field'
))
def
test_has_field_for_missing_student_module
(
self
):
"Test that `has` returns False for missing StudentModules"
self
.
assertFalse
(
self
.
kvs
.
has
(
student
_state_key
(
'a_field'
)))
self
.
assertFalse
(
self
.
kvs
.
has
(
user
_state_key
(
'a_field'
)))
class
StorageTestBase
(
object
):
...
...
@@ -286,13 +286,13 @@ class TestContentStorage(StorageTestBase, TestCase):
class
TestStudentPrefsStorage
(
StorageTestBase
,
TestCase
):
factory
=
StudentPrefsFactory
scope
=
Scope
.
student_
preferences
key_factory
=
student_
prefs_key
scope
=
Scope
.
preferences
key_factory
=
prefs_key
storage_class
=
XModuleStudentPrefsField
class
TestStudentInfoStorage
(
StorageTestBase
,
TestCase
):
factory
=
StudentInfoFactory
scope
=
Scope
.
student
_info
key_factory
=
student
_info_key
scope
=
Scope
.
user
_info
key_factory
=
user
_info_key
storage_class
=
XModuleStudentInfoField
local-requirements.txt
View file @
7f19d489
...
...
@@ -6,4 +6,4 @@
# XBlock:
# Might change frequently, so put it in local-requirements.txt,
# but conceptually is an external package, so it is in a separate repo.
-e git+
ssh://git@github.com/MITx/xmodule-debugger@9a4f883a
#egg=XBlock
-e git+
https://github.com/edx/XBlock.git@96d8f5f4
#egg=XBlock
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