Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
problem-builder
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
problem-builder
Commits
468a2c86
Commit
468a2c86
authored
Aug 04, 2017
by
E. Kolpakov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
AnswerMixin student_view_user_state override + tests
parent
89da0f43
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
60 additions
and
13 deletions
+60
-13
problem_builder/answer.py
+16
-2
problem_builder/mixins.py
+11
-5
problem_builder/tests/unit/test_answer_mixin.py
+27
-0
problem_builder/tests/unit/test_mixins.py
+6
-6
No files found.
problem_builder/answer.py
View file @
468a2c86
...
...
@@ -32,7 +32,7 @@ from xblock.validation import ValidationMessage
from
xblockutils.resources
import
ResourceLoader
from
xblockutils.studio_editable
import
StudioEditableXBlockMixin
,
XBlockWithPreviewMixin
from
problem_builder.sub_api
import
SubmittingXBlockMixin
,
sub_api
from
.mixins
import
QuestionMixin
,
XBlockWithTranslationServiceMixin
from
.mixins
import
QuestionMixin
,
XBlockWithTranslationServiceMixin
,
StudentViewUserStateMixin
import
uuid
...
...
@@ -49,7 +49,7 @@ def _(text):
# Classes ###########################################################
class
AnswerMixin
(
XBlockWithPreviewMixin
,
XBlockWithTranslationServiceMixin
):
class
AnswerMixin
(
XBlockWithPreviewMixin
,
XBlockWithTranslationServiceMixin
,
StudentViewUserStateMixin
):
"""
Mixin to give an XBlock the ability to read/write data to the Answers DB table.
"""
...
...
@@ -115,6 +115,20 @@ class AnswerMixin(XBlockWithPreviewMixin, XBlockWithTranslationServiceMixin):
if
not
data
.
name
:
add_error
(
u"A Question ID is required."
)
def
student_view_user_state
(
self
,
context
=
None
):
"""
Returns a JSON representation of the student data of this XBlock,
retrievable from the Course Block API.
"""
result
=
super
(
AnswerMixin
,
self
)
.
student_view_user_state
(
context
)
answer_data
=
self
.
get_model_object
()
result
[
"answer_data"
]
=
{
"student_input"
:
answer_data
.
student_input
,
"created_on"
:
answer_data
.
created_on
,
"modified_on"
:
answer_data
.
modified_on
,
}
return
result
@XBlock.needs
(
"i18n"
)
class
AnswerBlock
(
SubmittingXBlockMixin
,
AnswerMixin
,
QuestionMixin
,
StudioEditableXBlockMixin
,
XBlock
):
...
...
problem_builder/mixins.py
View file @
468a2c86
from
lazy
import
lazy
from
xblock.core
import
XBlock
from
xblock.fields
import
String
,
Boolean
,
Float
,
Scope
,
UNIQUE_ID
from
xblock.fragment
import
Fragment
from
xblockutils.helpers
import
child_isinstance
...
...
@@ -180,21 +179,28 @@ class NoSettingsMixin(object):
class
StudentViewUserStateMixin
(
object
):
"""
Mixin to provide student_view_user_state view
"""
NESTED_BLOCKS_KEY
=
"components"
INCLUDE_SCOPES
=
(
Scope
.
user_state
,
Scope
.
user_info
,
Scope
.
preferences
)
def
student_user_view_user_state
(
self
,
context
=
None
):
def
student_view_user_state
(
self
,
context
=
None
):
"""
Returns a JSON representation of the student data of this XBlock,
retrievable from the Course Block API.
"""
result
=
{}
for
_
,
field
in
self
.
fields
.
iteritems
():
if
field
.
scope
in
self
.
INCLUDE_SCOPES
:
result
[
field
.
name
]
=
field
.
read_from
(
self
)
if
self
.
has_children
:
if
getattr
(
self
,
"has_children"
,
False
)
:
components
=
[]
for
child_id
in
self
.
children
:
child
=
self
.
runtime
.
get_block
(
child_id
)
if
hasattr
(
child
,
'student_
user_
view_user_state'
):
components
.
append
(
child
.
student_
user_
view_user_state
(
context
))
if
hasattr
(
child
,
'student_view_user_state'
):
components
.
append
(
child
.
student_view_user_state
(
context
))
result
[
self
.
NESTED_BLOCKS_KEY
]
=
components
...
...
problem_builder/tests/unit/test_answer_mixin.py
View file @
468a2c86
...
...
@@ -3,6 +3,8 @@ Unit tests for AnswerMixin.
"""
import
unittest
from
collections
import
namedtuple
from
datetime
import
datetime
from
django.utils.crypto
import
get_random_string
from
problem_builder.answer
import
AnswerMixin
...
...
@@ -28,6 +30,8 @@ class TestAnswerMixin(unittest.TestCase):
answer_mixin
=
AnswerMixin
()
answer_mixin
.
name
=
name
answer_mixin
.
runtime
=
self
.
FakeRuntime
(
course_id
,
student_id
)
answer_mixin
.
fields
=
{}
answer_mixin
.
has_children
=
False
return
answer_mixin
def
test_creates_model_instance
(
self
):
...
...
@@ -57,3 +61,26 @@ class TestAnswerMixin(unittest.TestCase):
answer_mixin
=
self
.
make_answer_mixin
(
course_id
=
course_id
)
model
=
answer_mixin
.
get_model_object
()
self
.
assertEqual
(
model
.
course_key
,
course_id
)
def
test_student_view_user_state
(
self
):
name
=
'test-course-key-2'
existing_model
=
Answer
(
name
=
name
,
student_id
=
self
.
anonymous_student_id
,
course_key
=
self
.
course_id
,
student_input
=
"Test"
,
created_on
=
datetime
(
2017
,
1
,
2
,
3
,
4
,
5
),
modified_on
=
datetime
(
2017
,
7
,
8
,
9
,
10
,
11
),
)
existing_model
.
save
()
answer_mixin
=
self
.
make_answer_mixin
(
name
=
name
)
student_view_user_state
=
answer_mixin
.
student_view_user_state
()
expected_user_state_data
=
{
"answer_data"
:
{
"student_input"
:
existing_model
.
student_input
,
"created_on"
:
existing_model
.
created_on
,
"modified_on"
:
existing_model
.
modified_on
,
}
}
self
.
assertEqual
(
student_view_user_state
,
expected_user_state_data
)
problem_builder/tests/unit/test_mixins.py
View file @
468a2c86
...
...
@@ -76,7 +76,7 @@ class TestStudentViewUserStateMixin(unittest.TestCase):
def
test_no_user_state_returns_empty
(
self
):
block
=
self
.
_build_block
(
XBlockWithNoUserState
,
{
"scope_settings"
:
"qwe"
,
"scope_content"
:
"ASD"
})
self
.
assertEqual
(
block
.
student_
user_
view_user_state
(),
{})
self
.
assertEqual
(
block
.
student_view_user_state
(),
{})
def
test_no_child_blocks_with_user_state
(
self
):
user_fields
=
{
...
...
@@ -91,13 +91,13 @@ class TestStudentViewUserStateMixin(unittest.TestCase):
block_fields
=
self
.
_merge_dicts
(
user_fields
,
other_fields
)
block
=
self
.
_build_block
(
XBlockNoChildrenWithUserState
,
block_fields
)
self
.
assertEqual
(
block
.
student_
user_
view_user_state
(),
user_fields
)
self
.
assertEqual
(
block
.
student_view_user_state
(),
user_fields
)
def
test_children_empty_no_user_state
(
self
):
block
=
self
.
_build_block
(
XBlockChildrenNoUserState
,
{
"scope_settings"
:
"qwe"
,
"scope_content"
:
"ASD"
})
self
.
assertEqual
(
block
.
children
,
[])
# precondition
self
.
assertEqual
(
block
.
student_
user_
view_user_state
(),
{
"components"
:
[]})
self
.
assertEqual
(
block
.
student_view_user_state
(),
{
"components"
:
[]})
def
test_children_no_user_state
(
self
):
block
=
self
.
_build_block
(
XBlockChildrenNoUserState
,
{
"scope_settings"
:
"qwe"
,
"scope_content"
:
"ASD"
})
...
...
@@ -111,7 +111,7 @@ class TestStudentViewUserStateMixin(unittest.TestCase):
self
.
assertEqual
(
self
.
_runtime
.
get_block
(
"child1"
),
no_user_state1
)
self
.
assertEqual
(
self
.
_runtime
.
get_block
(
"child2"
),
no_user_state2
)
student_user_state
=
block
.
student_
user_
view_user_state
()
student_user_state
=
block
.
student_view_user_state
()
expected
=
{
"components"
:
[{},
{}]}
self
.
assertEqual
(
student_user_state
,
expected
)
...
...
@@ -146,7 +146,7 @@ class TestStudentViewUserStateMixin(unittest.TestCase):
self
.
assertEqual
(
self
.
_runtime
.
get_block
(
"child1"
),
user_state1
)
self
.
assertEqual
(
self
.
_runtime
.
get_block
(
"child2"
),
user_state2
)
student_user_state
=
block
.
student_
user_
view_user_state
()
student_user_state
=
block
.
student_view_user_state
()
expected
=
{
"components"
:
[
user_fields1
,
user_fields2
]}
self
.
assertEqual
(
student_user_state
,
expected
)
...
...
@@ -181,7 +181,7 @@ class TestStudentViewUserStateMixin(unittest.TestCase):
self
.
assertEqual
(
block
.
children
,
nested
.
keys
())
self
.
assertEqual
(
self
.
_runtime
.
get_block
(
"child1"
),
user_state
)
student_user_state
=
block
.
student_
user_
view_user_state
()
student_user_state
=
block
.
student_view_user_state
()
expected
=
user_fields
.
copy
()
expected
[
"components"
]
=
[
nested_user_fields
]
...
...
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