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
42c543b7
Commit
42c543b7
authored
Jan 17, 2014
by
Ned Batchelder
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2183 from edx/ned/add-i18n-for-inputtypes
Ned/add i18n for inputtypes
parents
e74ddf81
fe5d2c74
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
236 additions
and
158 deletions
+236
-158
common/lib/capa/capa/capa_problem.py
+71
-29
common/lib/capa/capa/inputtypes.py
+17
-16
common/lib/capa/capa/responsetypes.py
+48
-44
common/lib/capa/capa/tests/__init__.py
+18
-20
common/lib/capa/capa/tests/test_customrender.py
+6
-6
common/lib/capa/capa/tests/test_html_render.py
+6
-6
common/lib/capa/capa/tests/test_inputtypes.py
+26
-26
common/lib/capa/capa/tests/test_responsetypes.py
+27
-9
common/lib/xmodule/xmodule/capa_base.py
+17
-2
No files found.
common/lib/capa/capa/capa_problem.py
View file @
42c543b7
...
@@ -63,37 +63,79 @@ log = logging.getLogger(__name__)
...
@@ -63,37 +63,79 @@ log = logging.getLogger(__name__)
# main class for this module
# main class for this module
class
LoncapaSystem
(
object
):
"""
An encapsulation of resources needed from the outside.
These interfaces are collected here so that a caller of LoncapaProblem
can provide these resources however make sense for their environment, and
this code can remain independent.
Attributes:
i18n: an object implementing the `gettext.Translations` interface so
that we can use `.ugettext` to localize strings.
See :class:`ModuleSystem` for documentation of other attributes.
"""
def
__init__
(
# pylint: disable=invalid-name
self
,
ajax_url
,
anonymous_student_id
,
cache
,
can_execute_unsafe_code
,
DEBUG
,
# pylint: disable=invalid-name
filestore
,
i18n
,
node_path
,
render_template
,
seed
,
# Why do we do this if we have self.seed?
STATIC_URL
,
# pylint: disable=invalid-name
xqueue
,
):
self
.
ajax_url
=
ajax_url
self
.
anonymous_student_id
=
anonymous_student_id
self
.
cache
=
cache
self
.
can_execute_unsafe_code
=
can_execute_unsafe_code
self
.
DEBUG
=
DEBUG
# pylint: disable=invalid-name
self
.
filestore
=
filestore
self
.
i18n
=
i18n
self
.
node_path
=
node_path
self
.
render_template
=
render_template
self
.
seed
=
seed
# Why do we do this if we have self.seed?
self
.
STATIC_URL
=
STATIC_URL
# pylint: disable=invalid-name
self
.
xqueue
=
xqueue
class
LoncapaProblem
(
object
):
class
LoncapaProblem
(
object
):
'''
'''
Main class for capa Problems.
Main class for capa Problems.
'''
'''
def
__init__
(
self
,
problem_text
,
id
,
state
=
None
,
seed
=
None
,
system
=
None
):
def
__init__
(
self
,
problem_text
,
id
,
capa_system
,
state
=
None
,
seed
=
None
):
'''
"""
Initializes capa Problem.
Initializes capa Problem.
Arguments:
Arguments:
- problem_text (string): xml defining the problem
problem_text (string): xml defining the problem.
- id (string): identifier for this problem; often a filename (no spaces)
id (string): identifier for this problem, often a filename (no spaces).
- seed (int): random number generator seed (int)
capa_system (LoncapaSystem): LoncapaSystem instance which provides OS,
- state (dict): containing the following keys:
rendering, user context, and other resources.
- 'seed' - (int) random number generator seed
state (dict): containing the following keys:
- 'student_answers' - (dict) maps input id to the stored answer for that input
- `seed` (int) random number generator seed
- 'correct_map' (CorrectMap) a map of each input to their 'correctness'
- `student_answers` (dict) maps input id to the stored answer for that input
- 'done' - (bool) indicates whether or not this problem is considered done
- `correct_map` (CorrectMap) a map of each input to their 'correctness'
- 'input_state' - (dict) maps input_id to a dictionary that holds the state for that input
- `done` (bool) indicates whether or not this problem is considered done
- system (ModuleSystem): ModuleSystem instance which provides OS,
- `input_state` (dict) maps input_id to a dictionary that holds the state for that input
rendering, and user context
seed (int): random number generator seed.
'''
"""
## Initialize class variables from state
## Initialize class variables from state
self
.
do_reset
()
self
.
do_reset
()
self
.
problem_id
=
id
self
.
problem_id
=
id
self
.
system
=
system
self
.
capa_system
=
capa_system
if
self
.
system
is
None
:
raise
Exception
()
state
=
state
or
{}
state
=
state
or
{}
...
@@ -412,8 +454,8 @@ class LoncapaProblem(object):
...
@@ -412,8 +454,8 @@ class LoncapaProblem(object):
filename
=
inc
.
get
(
'file'
)
filename
=
inc
.
get
(
'file'
)
if
filename
is
not
None
:
if
filename
is
not
None
:
try
:
try
:
# open using
Module
System OSFS filestore
# open using
Loncapa
System OSFS filestore
ifp
=
self
.
system
.
filestore
.
open
(
filename
)
ifp
=
self
.
capa_
system
.
filestore
.
open
(
filename
)
except
Exception
as
err
:
except
Exception
as
err
:
log
.
warning
(
log
.
warning
(
'Error
%
s in problem xml include:
%
s'
%
(
'Error
%
s in problem xml include:
%
s'
%
(
...
@@ -422,12 +464,12 @@ class LoncapaProblem(object):
...
@@ -422,12 +464,12 @@ class LoncapaProblem(object):
)
)
log
.
warning
(
log
.
warning
(
'Cannot find file
%
s in
%
s'
%
(
'Cannot find file
%
s in
%
s'
%
(
filename
,
self
.
system
.
filestore
filename
,
self
.
capa_
system
.
filestore
)
)
)
)
# if debugging, don't fail - just log error
# if debugging, don't fail - just log error
# TODO (vshnayder): need real error handling, display to users
# TODO (vshnayder): need real error handling, display to users
if
not
self
.
system
.
get
(
'DEBUG'
)
:
if
not
self
.
capa_system
.
DEBUG
:
raise
raise
else
:
else
:
continue
continue
...
@@ -443,7 +485,7 @@ class LoncapaProblem(object):
...
@@ -443,7 +485,7 @@ class LoncapaProblem(object):
log
.
warning
(
'Cannot parse XML in
%
s'
%
(
filename
))
log
.
warning
(
'Cannot parse XML in
%
s'
%
(
filename
))
# if debugging, don't fail - just log error
# if debugging, don't fail - just log error
# TODO (vshnayder): same as above
# TODO (vshnayder): same as above
if
not
self
.
system
.
get
(
'DEBUG'
)
:
if
not
self
.
capa_system
.
DEBUG
:
raise
raise
else
:
else
:
continue
continue
...
@@ -476,9 +518,9 @@ class LoncapaProblem(object):
...
@@ -476,9 +518,9 @@ class LoncapaProblem(object):
continue
continue
# path is an absolute path or a path relative to the data dir
# path is an absolute path or a path relative to the data dir
dir
=
os
.
path
.
join
(
self
.
system
.
filestore
.
root_path
,
dir
)
dir
=
os
.
path
.
join
(
self
.
capa_
system
.
filestore
.
root_path
,
dir
)
# Check that we are within the filestore tree.
# Check that we are within the filestore tree.
reldir
=
os
.
path
.
relpath
(
dir
,
self
.
system
.
filestore
.
root_path
)
reldir
=
os
.
path
.
relpath
(
dir
,
self
.
capa_
system
.
filestore
.
root_path
)
if
".."
in
reldir
:
if
".."
in
reldir
:
log
.
warning
(
"Ignoring Python directory outside of course:
%
r"
%
dir
)
log
.
warning
(
"Ignoring Python directory outside of course:
%
r"
%
dir
)
continue
continue
...
@@ -527,9 +569,9 @@ class LoncapaProblem(object):
...
@@ -527,9 +569,9 @@ class LoncapaProblem(object):
context
,
context
,
random_seed
=
self
.
seed
,
random_seed
=
self
.
seed
,
python_path
=
python_path
,
python_path
=
python_path
,
cache
=
self
.
system
.
cache
,
cache
=
self
.
capa_
system
.
cache
,
slug
=
self
.
problem_id
,
slug
=
self
.
problem_id
,
unsafely
=
self
.
system
.
can_execute_unsafe_code
(),
unsafely
=
self
.
capa_
system
.
can_execute_unsafe_code
(),
)
)
except
Exception
as
err
:
except
Exception
as
err
:
log
.
exception
(
"Error while execing script code: "
+
all_code
)
log
.
exception
(
"Error while execing script code: "
+
all_code
)
...
@@ -600,7 +642,7 @@ class LoncapaProblem(object):
...
@@ -600,7 +642,7 @@ class LoncapaProblem(object):
input_type_cls
=
inputtypes
.
registry
.
get_class_for_tag
(
problemtree
.
tag
)
input_type_cls
=
inputtypes
.
registry
.
get_class_for_tag
(
problemtree
.
tag
)
# save the input type so that we can make ajax calls on it if we need to
# save the input type so that we can make ajax calls on it if we need to
self
.
inputs
[
input_id
]
=
input_type_cls
(
self
.
system
,
problemtree
,
state
)
self
.
inputs
[
input_id
]
=
input_type_cls
(
self
.
capa_
system
,
problemtree
,
state
)
return
self
.
inputs
[
input_id
]
.
get_html
()
return
self
.
inputs
[
input_id
]
.
get_html
()
# let each Response render itself
# let each Response render itself
...
@@ -613,7 +655,7 @@ class LoncapaProblem(object):
...
@@ -613,7 +655,7 @@ class LoncapaProblem(object):
# let each custom renderer render itself:
# let each custom renderer render itself:
if
problemtree
.
tag
in
customrender
.
registry
.
registered_tags
():
if
problemtree
.
tag
in
customrender
.
registry
.
registered_tags
():
renderer_class
=
customrender
.
registry
.
get_class_for_tag
(
problemtree
.
tag
)
renderer_class
=
customrender
.
registry
.
get_class_for_tag
(
problemtree
.
tag
)
renderer
=
renderer_class
(
self
.
system
,
problemtree
)
renderer
=
renderer_class
(
self
.
capa_
system
,
problemtree
)
return
renderer
.
get_html
()
return
renderer
.
get_html
()
# otherwise, render children recursively, and copy over attributes
# otherwise, render children recursively, and copy over attributes
...
@@ -670,7 +712,7 @@ class LoncapaProblem(object):
...
@@ -670,7 +712,7 @@ class LoncapaProblem(object):
# instantiate capa Response
# instantiate capa Response
responsetype_cls
=
responsetypes
.
registry
.
get_class_for_tag
(
response
.
tag
)
responsetype_cls
=
responsetypes
.
registry
.
get_class_for_tag
(
response
.
tag
)
responder
=
responsetype_cls
(
response
,
inputfields
,
self
.
context
,
self
.
system
)
responder
=
responsetype_cls
(
response
,
inputfields
,
self
.
context
,
self
.
capa_
system
)
# save in list in self
# save in list in self
self
.
responders
[
response
]
=
responder
self
.
responders
[
response
]
=
responder
...
...
common/lib/capa/capa/inputtypes.py
View file @
42c543b7
...
@@ -128,7 +128,7 @@ class InputTypeBase(object):
...
@@ -128,7 +128,7 @@ class InputTypeBase(object):
"""
"""
Instantiate an InputType class. Arguments:
Instantiate an InputType class. Arguments:
- system :
ModuleSystem
instance which provides OS, rendering, and user context.
- system :
LoncapaModule
instance which provides OS, rendering, and user context.
Specifically, must have a render_template function.
Specifically, must have a render_template function.
- xml : Element tree of this Input element
- xml : Element tree of this Input element
- state : a dictionary with optional keys:
- state : a dictionary with optional keys:
...
@@ -146,7 +146,7 @@ class InputTypeBase(object):
...
@@ -146,7 +146,7 @@ class InputTypeBase(object):
self
.
xml
=
xml
self
.
xml
=
xml
self
.
tag
=
xml
.
tag
self
.
tag
=
xml
.
tag
self
.
system
=
system
self
.
capa_
system
=
system
# NOTE: ID should only come from one place. If it comes from multiple,
# NOTE: ID should only come from one place. If it comes from multiple,
# we use state first, XML second (in case the xml changed, but we have
# we use state first, XML second (in case the xml changed, but we have
...
@@ -257,7 +257,7 @@ class InputTypeBase(object):
...
@@ -257,7 +257,7 @@ class InputTypeBase(object):
'value'
:
self
.
value
,
'value'
:
self
.
value
,
'status'
:
self
.
status
,
'status'
:
self
.
status
,
'msg'
:
self
.
msg
,
'msg'
:
self
.
msg
,
'STATIC_URL'
:
self
.
system
.
STATIC_URL
,
'STATIC_URL'
:
self
.
capa_
system
.
STATIC_URL
,
}
}
context
.
update
((
a
,
v
)
for
(
context
.
update
((
a
,
v
)
for
(
a
,
v
)
in
self
.
loaded_attributes
.
iteritems
()
if
a
in
self
.
to_render
)
a
,
v
)
in
self
.
loaded_attributes
.
iteritems
()
if
a
in
self
.
to_render
)
...
@@ -282,7 +282,7 @@ class InputTypeBase(object):
...
@@ -282,7 +282,7 @@ class InputTypeBase(object):
context
=
self
.
_get_render_context
()
context
=
self
.
_get_render_context
()
html
=
self
.
system
.
render_template
(
self
.
template
,
context
)
html
=
self
.
capa_
system
.
render_template
(
self
.
template
,
context
)
return
etree
.
XML
(
html
)
return
etree
.
XML
(
html
)
...
@@ -505,9 +505,9 @@ class JSInput(InputTypeBase):
...
@@ -505,9 +505,9 @@ class JSInput(InputTypeBase):
def
_extra_context
(
self
):
def
_extra_context
(
self
):
context
=
{
context
=
{
'jschannel_loader'
:
'{static_url}js/capa/src/jschannel.js'
.
format
(
'jschannel_loader'
:
'{static_url}js/capa/src/jschannel.js'
.
format
(
static_url
=
self
.
system
.
STATIC_URL
),
static_url
=
self
.
capa_
system
.
STATIC_URL
),
'jsinput_loader'
:
'{static_url}js/capa/src/jsinput.js'
.
format
(
'jsinput_loader'
:
'{static_url}js/capa/src/jsinput.js'
.
format
(
static_url
=
self
.
system
.
STATIC_URL
),
static_url
=
self
.
capa_
system
.
STATIC_URL
),
'saved_state'
:
self
.
value
'saved_state'
:
self
.
value
}
}
...
@@ -822,18 +822,19 @@ class MatlabInput(CodeInput):
...
@@ -822,18 +822,19 @@ class MatlabInput(CodeInput):
- 'message' - message to be rendered in case of error
- 'message' - message to be rendered in case of error
'''
'''
# only send data if xqueue exists
# only send data if xqueue exists
if
self
.
system
.
xqueue
is
None
:
if
self
.
capa_
system
.
xqueue
is
None
:
return
{
'success'
:
False
,
'message'
:
'Cannot connect to the queue'
}
return
{
'success'
:
False
,
'message'
:
'Cannot connect to the queue'
}
# pull relevant info out of get
# pull relevant info out of get
response
=
data
[
'submission'
]
response
=
data
[
'submission'
]
# construct xqueue headers
# construct xqueue headers
qinterface
=
self
.
system
.
xqueue
[
'interface'
]
qinterface
=
self
.
capa_
system
.
xqueue
[
'interface'
]
qtime
=
datetime
.
utcnow
()
.
strftime
(
xqueue_interface
.
dateformat
)
qtime
=
datetime
.
utcnow
()
.
strftime
(
xqueue_interface
.
dateformat
)
callback_url
=
self
.
system
.
xqueue
[
'construct_callback'
](
'ungraded_response'
)
callback_url
=
self
.
capa_system
.
xqueue
[
'construct_callback'
](
'ungraded_response'
)
anonymous_student_id
=
self
.
system
.
anonymous_student_id
anonymous_student_id
=
self
.
capa_system
.
anonymous_student_id
queuekey
=
xqueue_interface
.
make_hashkey
(
str
(
self
.
system
.
seed
)
+
qtime
+
# TODO: Why is this using self.capa_system.seed when we have self.seed???
queuekey
=
xqueue_interface
.
make_hashkey
(
str
(
self
.
capa_system
.
seed
)
+
qtime
+
anonymous_student_id
+
anonymous_student_id
+
self
.
input_id
)
self
.
input_id
)
xheader
=
xqueue_interface
.
make_xheader
(
xheader
=
xqueue_interface
.
make_xheader
(
...
@@ -1006,7 +1007,7 @@ class ChemicalEquationInput(InputTypeBase):
...
@@ -1006,7 +1007,7 @@ class ChemicalEquationInput(InputTypeBase):
"""
"""
return
{
return
{
'previewer'
:
'{static_url}js/capa/chemical_equation_preview.js'
.
format
(
'previewer'
:
'{static_url}js/capa/chemical_equation_preview.js'
.
format
(
static_url
=
self
.
system
.
STATIC_URL
),
static_url
=
self
.
capa_
system
.
STATIC_URL
),
}
}
def
handle_ajax
(
self
,
dispatch
,
data
):
def
handle_ajax
(
self
,
dispatch
,
data
):
...
@@ -1091,7 +1092,7 @@ class FormulaEquationInput(InputTypeBase):
...
@@ -1091,7 +1092,7 @@ class FormulaEquationInput(InputTypeBase):
return
{
return
{
'previewer'
:
'{static_url}js/capa/src/formula_equation_preview.js'
.
format
(
'previewer'
:
'{static_url}js/capa/src/formula_equation_preview.js'
.
format
(
static_url
=
self
.
system
.
STATIC_URL
),
static_url
=
self
.
capa_
system
.
STATIC_URL
),
'reported_status'
:
reported_status
,
'reported_status'
:
reported_status
,
}
}
...
@@ -1274,7 +1275,7 @@ class EditAMoleculeInput(InputTypeBase):
...
@@ -1274,7 +1275,7 @@ class EditAMoleculeInput(InputTypeBase):
"""
"""
context
=
{
context
=
{
'applet_loader'
:
'{static_url}js/capa/editamolecule.js'
.
format
(
'applet_loader'
:
'{static_url}js/capa/editamolecule.js'
.
format
(
static_url
=
self
.
system
.
STATIC_URL
),
static_url
=
self
.
capa_
system
.
STATIC_URL
),
}
}
return
context
return
context
...
@@ -1310,7 +1311,7 @@ class DesignProtein2dInput(InputTypeBase):
...
@@ -1310,7 +1311,7 @@ class DesignProtein2dInput(InputTypeBase):
"""
"""
context
=
{
context
=
{
'applet_loader'
:
'{static_url}js/capa/design-protein-2d.js'
.
format
(
'applet_loader'
:
'{static_url}js/capa/design-protein-2d.js'
.
format
(
static_url
=
self
.
system
.
STATIC_URL
),
static_url
=
self
.
capa_
system
.
STATIC_URL
),
}
}
return
context
return
context
...
@@ -1346,7 +1347,7 @@ class EditAGeneInput(InputTypeBase):
...
@@ -1346,7 +1347,7 @@ class EditAGeneInput(InputTypeBase):
"""
"""
context
=
{
context
=
{
'applet_loader'
:
'{static_url}js/capa/edit-a-gene.js'
.
format
(
'applet_loader'
:
'{static_url}js/capa/edit-a-gene.js'
.
format
(
static_url
=
self
.
system
.
STATIC_URL
),
static_url
=
self
.
capa_
system
.
STATIC_URL
),
}
}
return
context
return
context
...
...
common/lib/capa/capa/responsetypes.py
View file @
42c543b7
...
@@ -129,20 +129,20 @@ class LoncapaResponse(object):
...
@@ -129,20 +129,20 @@ class LoncapaResponse(object):
allowed_inputfields
=
[]
allowed_inputfields
=
[]
required_attributes
=
[]
required_attributes
=
[]
def
__init__
(
self
,
xml
,
inputfields
,
context
,
system
=
None
):
def
__init__
(
self
,
xml
,
inputfields
,
context
,
system
):
'''
'''
Init is passed the following arguments:
Init is passed the following arguments:
- xml : ElementTree of this Response
- xml : ElementTree of this Response
- inputfields : ordered list of ElementTrees for each input entry field in this Response
- inputfields : ordered list of ElementTrees for each input entry field in this Response
- context : script processor context
- context : script processor context
- system :
Module
System instance which provides OS, rendering, and user context
- system :
Loncapa
System instance which provides OS, rendering, and user context
'''
'''
self
.
xml
=
xml
self
.
xml
=
xml
self
.
inputfields
=
inputfields
self
.
inputfields
=
inputfields
self
.
context
=
context
self
.
context
=
context
self
.
system
=
system
self
.
capa_
system
=
system
self
.
id
=
xml
.
get
(
'id'
)
self
.
id
=
xml
.
get
(
'id'
)
...
@@ -298,7 +298,7 @@ class LoncapaResponse(object):
...
@@ -298,7 +298,7 @@ class LoncapaResponse(object):
python_path
=
self
.
context
[
'python_path'
],
python_path
=
self
.
context
[
'python_path'
],
slug
=
self
.
id
,
slug
=
self
.
id
,
random_seed
=
self
.
context
[
'seed'
],
random_seed
=
self
.
context
[
'seed'
],
unsafely
=
self
.
system
.
can_execute_unsafe_code
(),
unsafely
=
self
.
capa_
system
.
can_execute_unsafe_code
(),
)
)
except
Exception
as
err
:
except
Exception
as
err
:
msg
=
'Error
%
s in evaluating hint function
%
s'
%
(
err
,
hintfn
)
msg
=
'Error
%
s in evaluating hint function
%
s'
%
(
err
,
hintfn
)
...
@@ -444,7 +444,7 @@ class JavascriptResponse(LoncapaResponse):
...
@@ -444,7 +444,7 @@ class JavascriptResponse(LoncapaResponse):
# manually being compiled to DATA_DIR/js/compiled.
# manually being compiled to DATA_DIR/js/compiled.
# latestTimestamp = 0
# latestTimestamp = 0
# basepath = self.system.filestore.root_path + '/js/'
# basepath = self.
capa_
system.filestore.root_path + '/js/'
# for filename in (self.display_dependencies + [self.display]):
# for filename in (self.display_dependencies + [self.display]):
# filepath = basepath + filename
# filepath = basepath + filename
# timestamp = os.stat(filepath).st_mtime
# timestamp = os.stat(filepath).st_mtime
...
@@ -467,7 +467,7 @@ class JavascriptResponse(LoncapaResponse):
...
@@ -467,7 +467,7 @@ class JavascriptResponse(LoncapaResponse):
# outfile.close()
# outfile.close()
# TODO this should also be fixed when the above is fixed.
# TODO this should also be fixed when the above is fixed.
filename
=
self
.
system
.
ajax_url
.
split
(
'/'
)[
-
1
]
+
'.js'
filename
=
self
.
capa_
system
.
ajax_url
.
split
(
'/'
)[
-
1
]
+
'.js'
self
.
display_filename
=
'compiled/'
+
filename
self
.
display_filename
=
'compiled/'
+
filename
def
parse_xml
(
self
):
def
parse_xml
(
self
):
...
@@ -510,16 +510,16 @@ class JavascriptResponse(LoncapaResponse):
...
@@ -510,16 +510,16 @@ class JavascriptResponse(LoncapaResponse):
def
get_node_env
(
self
):
def
get_node_env
(
self
):
js_dir
=
os
.
path
.
join
(
self
.
system
.
filestore
.
root_path
,
'js'
)
js_dir
=
os
.
path
.
join
(
self
.
capa_
system
.
filestore
.
root_path
,
'js'
)
tmp_env
=
os
.
environ
.
copy
()
tmp_env
=
os
.
environ
.
copy
()
node_path
=
self
.
system
.
node_path
+
":"
+
os
.
path
.
normpath
(
js_dir
)
node_path
=
self
.
capa_
system
.
node_path
+
":"
+
os
.
path
.
normpath
(
js_dir
)
tmp_env
[
"NODE_PATH"
]
=
node_path
tmp_env
[
"NODE_PATH"
]
=
node_path
return
tmp_env
return
tmp_env
def
call_node
(
self
,
args
):
def
call_node
(
self
,
args
):
# Node.js code is un-sandboxed. If the
XModule
System says we aren't
# Node.js code is un-sandboxed. If the
Loncapa
System says we aren't
# allowed to run unsafe code, then stop now.
# allowed to run unsafe code, then stop now.
if
not
self
.
system
.
can_execute_unsafe_code
():
if
not
self
.
capa_
system
.
can_execute_unsafe_code
():
raise
LoncapaProblemError
(
"Execution of unsafe Javascript code is not allowed."
)
raise
LoncapaProblemError
(
"Execution of unsafe Javascript code is not allowed."
)
subprocess_args
=
[
"node"
]
subprocess_args
=
[
"node"
]
...
@@ -875,8 +875,9 @@ class NumericalResponse(LoncapaResponse):
...
@@ -875,8 +875,9 @@ class NumericalResponse(LoncapaResponse):
correct_ans
=
evaluator
({},
{},
self
.
correct_answer
)
correct_ans
=
evaluator
({},
{},
self
.
correct_answer
)
except
Exception
:
except
Exception
:
log
.
debug
(
"Content error--answer '
%
s' is not a valid number"
,
self
.
correct_answer
)
log
.
debug
(
"Content error--answer '
%
s' is not a valid number"
,
self
.
correct_answer
)
_
=
self
.
capa_system
.
i18n
.
ugettext
raise
StudentInputError
(
raise
StudentInputError
(
"There was a problem with the staff answer to this problem"
_
(
"There was a problem with the staff answer to this problem"
)
)
)
return
correct_ans
return
correct_ans
...
@@ -1154,7 +1155,7 @@ class CustomResponse(LoncapaResponse):
...
@@ -1154,7 +1155,7 @@ class CustomResponse(LoncapaResponse):
python_path
=
self
.
context
[
'python_path'
],
python_path
=
self
.
context
[
'python_path'
],
slug
=
self
.
id
,
slug
=
self
.
id
,
random_seed
=
self
.
context
[
'seed'
],
random_seed
=
self
.
context
[
'seed'
],
unsafely
=
self
.
system
.
can_execute_unsafe_code
(),
unsafely
=
self
.
capa_
system
.
can_execute_unsafe_code
(),
)
)
return
globals_dict
[
'cfn_return'
]
return
globals_dict
[
'cfn_return'
]
return
check_function
return
check_function
...
@@ -1169,8 +1170,8 @@ class CustomResponse(LoncapaResponse):
...
@@ -1169,8 +1170,8 @@ class CustomResponse(LoncapaResponse):
else
:
else
:
answer_src
=
answer
.
get
(
'src'
)
answer_src
=
answer
.
get
(
'src'
)
if
answer_src
is
not
None
:
if
answer_src
is
not
None
:
self
.
code
=
self
.
system
.
filesystem
.
open
(
# TODO: this code seems not to be used any more since self.capa_system.filesystem doesn't exist.
'src/'
+
answer_src
)
.
read
()
self
.
code
=
self
.
capa_system
.
filesystem
.
open
(
'src/'
+
answer_src
)
.
read
()
else
:
else
:
self
.
code
=
answer
.
text
self
.
code
=
answer
.
text
...
@@ -1249,8 +1250,8 @@ class CustomResponse(LoncapaResponse):
...
@@ -1249,8 +1250,8 @@ class CustomResponse(LoncapaResponse):
'testdat'
:
'hello world'
,
'testdat'
:
'hello world'
,
})
})
#
pass self.system.debug to cfn
#
Pass DEBUG to the check function.
self
.
context
[
'debug'
]
=
self
.
system
.
DEBUG
self
.
context
[
'debug'
]
=
self
.
capa_
system
.
DEBUG
# Run the check function
# Run the check function
self
.
execute_check_function
(
idset
,
submission
)
self
.
execute_check_function
(
idset
,
submission
)
...
@@ -1275,10 +1276,10 @@ class CustomResponse(LoncapaResponse):
...
@@ -1275,10 +1276,10 @@ class CustomResponse(LoncapaResponse):
safe_exec
.
safe_exec
(
safe_exec
.
safe_exec
(
self
.
code
,
self
.
code
,
self
.
context
,
self
.
context
,
cache
=
self
.
system
.
cache
,
cache
=
self
.
capa_
system
.
cache
,
slug
=
self
.
id
,
slug
=
self
.
id
,
random_seed
=
self
.
context
[
'seed'
],
random_seed
=
self
.
context
[
'seed'
],
unsafely
=
self
.
system
.
can_execute_unsafe_code
(),
unsafely
=
self
.
capa_
system
.
can_execute_unsafe_code
(),
)
)
except
Exception
as
err
:
except
Exception
as
err
:
self
.
_handle_exec_exception
(
err
)
self
.
_handle_exec_exception
(
err
)
...
@@ -1470,18 +1471,21 @@ ScoreMessage = namedtuple('ScoreMessage', ['valid', 'correct', 'points', 'msg'])
...
@@ -1470,18 +1471,21 @@ ScoreMessage = namedtuple('ScoreMessage', ['valid', 'correct', 'points', 'msg'])
@registry.register
@registry.register
class
CodeResponse
(
LoncapaResponse
):
class
CodeResponse
(
LoncapaResponse
):
"""
"""
Grade student code using an external queueing server, called 'xqueue'
Grade student code using an external queueing server, called 'xqueue'.
Expects 'xqueue' dict in ModuleSystem with the following keys that are needed by CodeResponse:
Expects 'xqueue' dict in LoncapaSystem with the following keys that are
system.xqueue = { 'interface': XqueueInterface object,
needed by CodeResponse::
'construct_callback': Per-StudentModule callback URL
constructor, defaults to using 'score_update'
capa_system.xqueue = {
as the correct dispatch (function),
'interface': XQueueInterface object.
'default_queuename': Default queuename to submit request (string)
'construct_callback': Per-StudentModule callback URL constructor,
}
defaults to using 'score_update' as the correct dispatch (function).
'default_queuename': Default queue name to submit request (string).
}
External requests are only submitted for student submission grading, not
for getting reference answers.
External requests are only submitted for student submission grading
(i.e. and not for getting reference answers)
"""
"""
tags
=
[
'coderesponse'
]
tags
=
[
'coderesponse'
]
...
@@ -1504,8 +1508,8 @@ class CodeResponse(LoncapaResponse):
...
@@ -1504,8 +1508,8 @@ class CodeResponse(LoncapaResponse):
self
.
url
=
xml
.
get
(
'url'
,
None
)
self
.
url
=
xml
.
get
(
'url'
,
None
)
# We do not support xqueue within Studio.
# We do not support xqueue within Studio.
if
self
.
system
.
xqueue
is
not
None
:
if
self
.
capa_
system
.
xqueue
is
not
None
:
default_queuename
=
self
.
system
.
xqueue
[
'default_queuename'
]
default_queuename
=
self
.
capa_
system
.
xqueue
[
'default_queuename'
]
else
:
else
:
default_queuename
=
None
default_queuename
=
None
self
.
queue_name
=
xml
.
get
(
'queuename'
,
default_queuename
)
self
.
queue_name
=
xml
.
get
(
'queuename'
,
default_queuename
)
...
@@ -1548,7 +1552,7 @@ class CodeResponse(LoncapaResponse):
...
@@ -1548,7 +1552,7 @@ class CodeResponse(LoncapaResponse):
raise
Exception
(
err
)
raise
Exception
(
err
)
# We do not support xqueue within Studio.
# We do not support xqueue within Studio.
if
self
.
system
.
xqueue
is
None
:
if
self
.
capa_
system
.
xqueue
is
None
:
cmap
=
CorrectMap
()
cmap
=
CorrectMap
()
cmap
.
set
(
self
.
answer_id
,
queuestate
=
None
,
cmap
.
set
(
self
.
answer_id
,
queuestate
=
None
,
msg
=
'Error checking problem: no external queueing server is configured.'
)
msg
=
'Error checking problem: no external queueing server is configured.'
)
...
@@ -1557,16 +1561,16 @@ class CodeResponse(LoncapaResponse):
...
@@ -1557,16 +1561,16 @@ class CodeResponse(LoncapaResponse):
# Prepare xqueue request
# Prepare xqueue request
#------------------------------------------------------------
#------------------------------------------------------------
qinterface
=
self
.
system
.
xqueue
[
'interface'
]
qinterface
=
self
.
capa_
system
.
xqueue
[
'interface'
]
qtime
=
datetime
.
strftime
(
datetime
.
now
(
UTC
),
xqueue_interface
.
dateformat
)
qtime
=
datetime
.
strftime
(
datetime
.
now
(
UTC
),
xqueue_interface
.
dateformat
)
anonymous_student_id
=
self
.
system
.
anonymous_student_id
anonymous_student_id
=
self
.
capa_
system
.
anonymous_student_id
# Generate header
# Generate header
queuekey
=
xqueue_interface
.
make_hashkey
(
queuekey
=
xqueue_interface
.
make_hashkey
(
str
(
self
.
system
.
seed
)
+
qtime
+
anonymous_student_id
+
self
.
answer_id
str
(
self
.
capa_
system
.
seed
)
+
qtime
+
anonymous_student_id
+
self
.
answer_id
)
)
callback_url
=
self
.
system
.
xqueue
[
'construct_callback'
]()
callback_url
=
self
.
capa_
system
.
xqueue
[
'construct_callback'
]()
xheader
=
xqueue_interface
.
make_xheader
(
xheader
=
xqueue_interface
.
make_xheader
(
lms_callback_url
=
callback_url
,
lms_callback_url
=
callback_url
,
lms_key
=
queuekey
,
lms_key
=
queuekey
,
...
@@ -1748,8 +1752,8 @@ class ExternalResponse(LoncapaResponse):
...
@@ -1748,8 +1752,8 @@ class ExternalResponse(LoncapaResponse):
if
answer
is
not
None
:
if
answer
is
not
None
:
answer_src
=
answer
.
get
(
'src'
)
answer_src
=
answer
.
get
(
'src'
)
if
answer_src
is
not
None
:
if
answer_src
is
not
None
:
self
.
code
=
self
.
system
.
filesystem
.
open
(
# TODO: this code seems not to be used any more since self.capa_system.filesystem doesn't exist.
'src/'
+
answer_src
)
.
read
()
self
.
code
=
self
.
capa_system
.
filesystem
.
open
(
'src/'
+
answer_src
)
.
read
()
else
:
else
:
self
.
code
=
answer
.
text
self
.
code
=
answer
.
text
else
:
else
:
...
@@ -1791,7 +1795,7 @@ class ExternalResponse(LoncapaResponse):
...
@@ -1791,7 +1795,7 @@ class ExternalResponse(LoncapaResponse):
log
.
error
(
msg
)
log
.
error
(
msg
)
raise
Exception
(
msg
)
raise
Exception
(
msg
)
if
self
.
system
.
DEBUG
:
if
self
.
capa_
system
.
DEBUG
:
log
.
info
(
'response =
%
s'
,
req
.
text
)
log
.
info
(
'response =
%
s'
,
req
.
text
)
if
(
not
req
.
text
)
or
(
not
req
.
text
.
strip
()):
if
(
not
req
.
text
)
or
(
not
req
.
text
.
strip
()):
...
@@ -1830,7 +1834,7 @@ class ExternalResponse(LoncapaResponse):
...
@@ -1830,7 +1834,7 @@ class ExternalResponse(LoncapaResponse):
rxml
=
self
.
do_external_request
(
'get_score'
,
extra_payload
)
rxml
=
self
.
do_external_request
(
'get_score'
,
extra_payload
)
except
Exception
as
err
:
# pylint: disable=W0703
except
Exception
as
err
:
# pylint: disable=W0703
log
.
error
(
'Error
%
s'
,
err
)
log
.
error
(
'Error
%
s'
,
err
)
if
self
.
system
.
DEBUG
:
if
self
.
capa_
system
.
DEBUG
:
cmap
.
set_dict
(
dict
(
zip
(
sorted
(
cmap
.
set_dict
(
dict
(
zip
(
sorted
(
self
.
answer_ids
),
[
'incorrect'
]
*
len
(
idset
))))
self
.
answer_ids
),
[
'incorrect'
]
*
len
(
idset
))))
cmap
.
set_property
(
cmap
.
set_property
(
...
@@ -1862,7 +1866,7 @@ class ExternalResponse(LoncapaResponse):
...
@@ -1862,7 +1866,7 @@ class ExternalResponse(LoncapaResponse):
exans
=
json
.
loads
(
rxml
.
find
(
'expected'
)
.
text
)
exans
=
json
.
loads
(
rxml
.
find
(
'expected'
)
.
text
)
except
Exception
as
err
:
# pylint: disable=W0703
except
Exception
as
err
:
# pylint: disable=W0703
log
.
error
(
'Error
%
s'
,
err
)
log
.
error
(
'Error
%
s'
,
err
)
if
self
.
system
.
DEBUG
:
if
self
.
capa_
system
.
DEBUG
:
msg
=
'<span class="inline-error">
%
s</span>'
%
str
(
msg
=
'<span class="inline-error">
%
s</span>'
%
str
(
err
)
.
replace
(
'<'
,
'<'
)
err
)
.
replace
(
'<'
,
'<'
)
exans
=
[
''
]
*
len
(
self
.
answer_ids
)
exans
=
[
''
]
*
len
(
self
.
answer_ids
)
...
@@ -2100,7 +2104,7 @@ class SchematicResponse(LoncapaResponse):
...
@@ -2100,7 +2104,7 @@ class SchematicResponse(LoncapaResponse):
answer_src
=
answer
.
get
(
'src'
)
answer_src
=
answer
.
get
(
'src'
)
if
answer_src
is
not
None
:
if
answer_src
is
not
None
:
# Untested; never used
# Untested; never used
self
.
code
=
self
.
system
.
filestore
.
open
(
'src/'
+
answer_src
)
.
read
()
self
.
code
=
self
.
capa_
system
.
filestore
.
open
(
'src/'
+
answer_src
)
.
read
()
else
:
else
:
self
.
code
=
answer
.
text
self
.
code
=
answer
.
text
...
@@ -2114,10 +2118,10 @@ class SchematicResponse(LoncapaResponse):
...
@@ -2114,10 +2118,10 @@ class SchematicResponse(LoncapaResponse):
safe_exec
.
safe_exec
(
safe_exec
.
safe_exec
(
self
.
code
,
self
.
code
,
self
.
context
,
self
.
context
,
cache
=
self
.
system
.
cache
,
cache
=
self
.
capa_
system
.
cache
,
slug
=
self
.
id
,
slug
=
self
.
id
,
random_seed
=
self
.
context
[
'seed'
],
random_seed
=
self
.
context
[
'seed'
],
unsafely
=
self
.
system
.
can_execute_unsafe_code
(),
unsafely
=
self
.
capa_
system
.
can_execute_unsafe_code
(),
)
)
except
Exception
as
err
:
except
Exception
as
err
:
msg
=
'Error
%
s in evaluating SchematicResponse'
%
err
msg
=
'Error
%
s in evaluating SchematicResponse'
%
err
...
...
common/lib/capa/capa/tests/__init__.py
View file @
42c543b7
import
fs.osfs
"""Tools for helping with testing capa."""
import
gettext
import
os
import
os
import
os.path
import
os.path
from
capa.capa_problem
import
LoncapaProblem
import
fs.osfs
from
xmodule.x_module
import
ModuleSystem
from
capa.capa_problem
import
LoncapaProblem
,
LoncapaSystem
from
mock
import
Mock
,
MagicMock
from
mock
import
Mock
,
MagicMock
import
xml.sax.saxutils
as
saxutils
import
xml.sax.saxutils
as
saxutils
...
@@ -26,34 +29,29 @@ xqueue_interface = MagicMock()
...
@@ -26,34 +29,29 @@ xqueue_interface = MagicMock()
xqueue_interface
.
send_to_queue
.
return_value
=
(
0
,
'Success!'
)
xqueue_interface
.
send_to_queue
.
return_value
=
(
0
,
'Success!'
)
def
test_system
():
def
test_
capa_
system
():
"""
"""
Construct a mock
Module
System instance.
Construct a mock
Loncapa
System instance.
"""
"""
the_system
=
Mock
(
the_system
=
Mock
(
spec
=
Module
System
,
spec
=
Loncapa
System
,
ajax_url
=
'/dummy-ajax-url'
,
ajax_url
=
'/dummy-ajax-url'
,
STATIC_URL
=
'/dummy-static/'
,
anonymous_student_id
=
'student'
,
cache
=
None
,
can_execute_unsafe_code
=
lambda
:
False
,
DEBUG
=
True
,
DEBUG
=
True
,
track_function
=
Mock
(),
filestore
=
fs
.
osfs
.
OSFS
(
os
.
path
.
join
(
TEST_DIR
,
"test_files"
)),
get_module
=
Mock
(),
i18n
=
gettext
.
NullTranslations
(),
node_path
=
os
.
environ
.
get
(
"NODE_PATH"
,
"/usr/local/lib/node_modules"
),
render_template
=
tst_render_template
,
render_template
=
tst_render_template
,
replace_urls
=
Mock
(),
user
=
Mock
(),
seed
=
0
,
seed
=
0
,
filestore
=
fs
.
osfs
.
OSFS
(
os
.
path
.
join
(
TEST_DIR
,
"test_files"
)),
STATIC_URL
=
'/dummy-static/'
,
debug
=
True
,
hostname
=
"edx.org"
,
xqueue
=
{
'interface'
:
xqueue_interface
,
'construct_callback'
:
calledback_url
,
'default_queuename'
:
'testqueue'
,
'waittime'
:
10
},
xqueue
=
{
'interface'
:
xqueue_interface
,
'construct_callback'
:
calledback_url
,
'default_queuename'
:
'testqueue'
,
'waittime'
:
10
},
node_path
=
os
.
environ
.
get
(
"NODE_PATH"
,
"/usr/local/lib/node_modules"
),
anonymous_student_id
=
'student'
,
cache
=
None
,
can_execute_unsafe_code
=
lambda
:
False
,
)
)
return
the_system
return
the_system
def
new_loncapa_problem
(
xml
,
system
=
None
):
def
new_loncapa_problem
(
xml
,
capa_
system
=
None
):
"""Construct a `LoncapaProblem` suitable for unit tests."""
"""Construct a `LoncapaProblem` suitable for unit tests."""
return
LoncapaProblem
(
xml
,
id
=
'1'
,
seed
=
723
,
system
=
system
or
test
_system
())
return
LoncapaProblem
(
xml
,
id
=
'1'
,
seed
=
723
,
capa_system
=
capa_system
or
test_capa
_system
())
common/lib/capa/capa/tests/test_customrender.py
View file @
42c543b7
...
@@ -2,7 +2,7 @@ from lxml import etree
...
@@ -2,7 +2,7 @@ from lxml import etree
import
unittest
import
unittest
import
xml.sax.saxutils
as
saxutils
import
xml.sax.saxutils
as
saxutils
from
.
import
test_system
from
.
import
test_
capa_
system
from
capa
import
customrender
from
capa
import
customrender
# just a handy shortcut
# just a handy shortcut
...
@@ -11,7 +11,7 @@ lookup_tag = customrender.registry.get_class_for_tag
...
@@ -11,7 +11,7 @@ lookup_tag = customrender.registry.get_class_for_tag
def
extract_context
(
xml
):
def
extract_context
(
xml
):
"""
"""
Given an xml element corresponding to the output of test_system.render_template, get back the
Given an xml element corresponding to the output of test_
capa_
system.render_template, get back the
original context
original context
"""
"""
return
eval
(
xml
.
text
)
return
eval
(
xml
.
text
)
...
@@ -26,7 +26,7 @@ class HelperTest(unittest.TestCase):
...
@@ -26,7 +26,7 @@ class HelperTest(unittest.TestCase):
Make sure that our helper function works!
Make sure that our helper function works!
'''
'''
def
check
(
self
,
d
):
def
check
(
self
,
d
):
xml
=
etree
.
XML
(
test_system
()
.
render_template
(
'blah'
,
d
))
xml
=
etree
.
XML
(
test_
capa_
system
()
.
render_template
(
'blah'
,
d
))
self
.
assertEqual
(
d
,
extract_context
(
xml
))
self
.
assertEqual
(
d
,
extract_context
(
xml
))
def
test_extract_context
(
self
):
def
test_extract_context
(
self
):
...
@@ -46,11 +46,11 @@ class SolutionRenderTest(unittest.TestCase):
...
@@ -46,11 +46,11 @@ class SolutionRenderTest(unittest.TestCase):
xml_str
=
"""<solution id="solution_12">{s}</solution>"""
.
format
(
s
=
solution
)
xml_str
=
"""<solution id="solution_12">{s}</solution>"""
.
format
(
s
=
solution
)
element
=
etree
.
fromstring
(
xml_str
)
element
=
etree
.
fromstring
(
xml_str
)
renderer
=
lookup_tag
(
'solution'
)(
test_system
(),
element
)
renderer
=
lookup_tag
(
'solution'
)(
test_
capa_
system
(),
element
)
self
.
assertEqual
(
renderer
.
id
,
'solution_12'
)
self
.
assertEqual
(
renderer
.
id
,
'solution_12'
)
# Our test_system "renders" templates to a div with the repr of the context.
# Our test_
capa_
system "renders" templates to a div with the repr of the context.
xml
=
renderer
.
get_html
()
xml
=
renderer
.
get_html
()
context
=
extract_context
(
xml
)
context
=
extract_context
(
xml
)
self
.
assertEqual
(
context
,
{
'id'
:
'solution_12'
})
self
.
assertEqual
(
context
,
{
'id'
:
'solution_12'
})
...
@@ -65,7 +65,7 @@ class MathRenderTest(unittest.TestCase):
...
@@ -65,7 +65,7 @@ class MathRenderTest(unittest.TestCase):
xml_str
=
"""<math>{tex}</math>"""
.
format
(
tex
=
latex_in
)
xml_str
=
"""<math>{tex}</math>"""
.
format
(
tex
=
latex_in
)
element
=
etree
.
fromstring
(
xml_str
)
element
=
etree
.
fromstring
(
xml_str
)
renderer
=
lookup_tag
(
'math'
)(
test_system
(),
element
)
renderer
=
lookup_tag
(
'math'
)(
test_
capa_
system
(),
element
)
self
.
assertEqual
(
renderer
.
mathstr
,
mathjax_out
)
self
.
assertEqual
(
renderer
.
mathstr
,
mathjax_out
)
...
...
common/lib/capa/capa/tests/test_html_render.py
View file @
42c543b7
...
@@ -6,14 +6,14 @@ import textwrap
...
@@ -6,14 +6,14 @@ import textwrap
import
mock
import
mock
from
.response_xml_factory
import
StringResponseXMLFactory
,
CustomResponseXMLFactory
from
.response_xml_factory
import
StringResponseXMLFactory
,
CustomResponseXMLFactory
from
.
import
test_system
,
new_loncapa_problem
from
.
import
test_
capa_
system
,
new_loncapa_problem
class
CapaHtmlRenderTest
(
unittest
.
TestCase
):
class
CapaHtmlRenderTest
(
unittest
.
TestCase
):
def
setUp
(
self
):
def
setUp
(
self
):
super
(
CapaHtmlRenderTest
,
self
)
.
setUp
()
super
(
CapaHtmlRenderTest
,
self
)
.
setUp
()
self
.
system
=
test
_system
()
self
.
capa_system
=
test_capa
_system
()
def
test_blank_problem
(
self
):
def
test_blank_problem
(
self
):
"""
"""
...
@@ -44,7 +44,7 @@ class CapaHtmlRenderTest(unittest.TestCase):
...
@@ -44,7 +44,7 @@ class CapaHtmlRenderTest(unittest.TestCase):
"""
)
"""
)
# Create the problem
# Create the problem
problem
=
new_loncapa_problem
(
xml_str
,
system
=
self
.
system
)
problem
=
new_loncapa_problem
(
xml_str
,
capa_system
=
self
.
capa_
system
)
# Render the HTML
# Render the HTML
rendered_html
=
etree
.
XML
(
problem
.
get_html
())
rendered_html
=
etree
.
XML
(
problem
.
get_html
())
...
@@ -119,12 +119,12 @@ class CapaHtmlRenderTest(unittest.TestCase):
...
@@ -119,12 +119,12 @@ class CapaHtmlRenderTest(unittest.TestCase):
xml_str
=
StringResponseXMLFactory
()
.
build_xml
(
**
kwargs
)
xml_str
=
StringResponseXMLFactory
()
.
build_xml
(
**
kwargs
)
# Mock out the template renderer
# Mock out the template renderer
the_system
=
test_system
()
the_system
=
test_
capa_
system
()
the_system
.
render_template
=
mock
.
Mock
()
the_system
.
render_template
=
mock
.
Mock
()
the_system
.
render_template
.
return_value
=
"<div>Input Template Render</div>"
the_system
.
render_template
.
return_value
=
"<div>Input Template Render</div>"
# Create the problem and render the HTML
# Create the problem and render the HTML
problem
=
new_loncapa_problem
(
xml_str
,
system
=
the_system
)
problem
=
new_loncapa_problem
(
xml_str
,
capa_
system
=
the_system
)
rendered_html
=
etree
.
XML
(
problem
.
get_html
())
rendered_html
=
etree
.
XML
(
problem
.
get_html
())
# Expect problem has been turned into a <div>
# Expect problem has been turned into a <div>
...
@@ -253,7 +253,7 @@ class CapaHtmlRenderTest(unittest.TestCase):
...
@@ -253,7 +253,7 @@ class CapaHtmlRenderTest(unittest.TestCase):
self
.
assertRegexpMatches
(
the_html
,
r"<div>\s+</div>"
)
self
.
assertRegexpMatches
(
the_html
,
r"<div>\s+</div>"
)
def
_create_test_file
(
self
,
path
,
content_str
):
def
_create_test_file
(
self
,
path
,
content_str
):
test_fp
=
self
.
system
.
filestore
.
open
(
path
,
"w"
)
test_fp
=
self
.
capa_
system
.
filestore
.
open
(
path
,
"w"
)
test_fp
.
write
(
content_str
)
test_fp
.
write
(
content_str
)
test_fp
.
close
()
test_fp
.
close
()
...
...
common/lib/capa/capa/tests/test_inputtypes.py
View file @
42c543b7
...
@@ -22,7 +22,7 @@ from lxml import etree
...
@@ -22,7 +22,7 @@ from lxml import etree
import
unittest
import
unittest
import
xml.sax.saxutils
as
saxutils
import
xml.sax.saxutils
as
saxutils
from
.
import
test_system
from
.
import
test_
capa_
system
from
capa
import
inputtypes
from
capa
import
inputtypes
from
mock
import
ANY
,
patch
from
mock
import
ANY
,
patch
from
pyparsing
import
ParseException
from
pyparsing
import
ParseException
...
@@ -47,7 +47,7 @@ class OptionInputTest(unittest.TestCase):
...
@@ -47,7 +47,7 @@ class OptionInputTest(unittest.TestCase):
state
=
{
'value'
:
'Down'
,
state
=
{
'value'
:
'Down'
,
'id'
:
'sky_input'
,
'id'
:
'sky_input'
,
'status'
:
'answered'
}
'status'
:
'answered'
}
option_input
=
lookup_tag
(
'optioninput'
)(
test_system
(),
element
,
state
)
option_input
=
lookup_tag
(
'optioninput'
)(
test_
capa_
system
(),
element
,
state
)
context
=
option_input
.
_get_render_context
()
# pylint: disable=W0212
context
=
option_input
.
_get_render_context
()
# pylint: disable=W0212
...
@@ -106,7 +106,7 @@ class ChoiceGroupTest(unittest.TestCase):
...
@@ -106,7 +106,7 @@ class ChoiceGroupTest(unittest.TestCase):
'id'
:
'sky_input'
,
'id'
:
'sky_input'
,
'status'
:
'answered'
}
'status'
:
'answered'
}
the_input
=
lookup_tag
(
tag
)(
test_system
(),
element
,
state
)
the_input
=
lookup_tag
(
tag
)(
test_
capa_
system
(),
element
,
state
)
context
=
the_input
.
_get_render_context
()
# pylint: disable=W0212
context
=
the_input
.
_get_render_context
()
# pylint: disable=W0212
...
@@ -159,7 +159,7 @@ class JavascriptInputTest(unittest.TestCase):
...
@@ -159,7 +159,7 @@ class JavascriptInputTest(unittest.TestCase):
element
=
etree
.
fromstring
(
xml_str
)
element
=
etree
.
fromstring
(
xml_str
)
state
=
{
'value'
:
'3'
,
}
state
=
{
'value'
:
'3'
,
}
the_input
=
lookup_tag
(
'javascriptinput'
)(
test_system
(),
element
,
state
)
the_input
=
lookup_tag
(
'javascriptinput'
)(
test_
capa_
system
(),
element
,
state
)
context
=
the_input
.
_get_render_context
()
# pylint: disable=W0212
context
=
the_input
.
_get_render_context
()
# pylint: disable=W0212
...
@@ -190,7 +190,7 @@ class TextLineTest(unittest.TestCase):
...
@@ -190,7 +190,7 @@ class TextLineTest(unittest.TestCase):
element
=
etree
.
fromstring
(
xml_str
)
element
=
etree
.
fromstring
(
xml_str
)
state
=
{
'value'
:
'BumbleBee'
,
}
state
=
{
'value'
:
'BumbleBee'
,
}
the_input
=
lookup_tag
(
'textline'
)(
test_system
(),
element
,
state
)
the_input
=
lookup_tag
(
'textline'
)(
test_
capa_
system
(),
element
,
state
)
context
=
the_input
.
_get_render_context
()
# pylint: disable=W0212
context
=
the_input
.
_get_render_context
()
# pylint: disable=W0212
...
@@ -221,7 +221,7 @@ class TextLineTest(unittest.TestCase):
...
@@ -221,7 +221,7 @@ class TextLineTest(unittest.TestCase):
element
=
etree
.
fromstring
(
xml_str
)
element
=
etree
.
fromstring
(
xml_str
)
state
=
{
'value'
:
'BumbleBee'
,
}
state
=
{
'value'
:
'BumbleBee'
,
}
the_input
=
lookup_tag
(
'textline'
)(
test_system
(),
element
,
state
)
the_input
=
lookup_tag
(
'textline'
)(
test_
capa_
system
(),
element
,
state
)
context
=
the_input
.
_get_render_context
()
# pylint: disable=W0212
context
=
the_input
.
_get_render_context
()
# pylint: disable=W0212
...
@@ -264,7 +264,7 @@ class TextLineTest(unittest.TestCase):
...
@@ -264,7 +264,7 @@ class TextLineTest(unittest.TestCase):
element
=
etree
.
fromstring
(
xml_str
)
element
=
etree
.
fromstring
(
xml_str
)
state
=
{
'value'
:
'BumbleBee'
,
}
state
=
{
'value'
:
'BumbleBee'
,
}
the_input
=
lookup_tag
(
'textline'
)(
test_system
(),
element
,
state
)
the_input
=
lookup_tag
(
'textline'
)(
test_
capa_
system
(),
element
,
state
)
context
=
the_input
.
_get_render_context
()
# pylint: disable=W0212
context
=
the_input
.
_get_render_context
()
# pylint: disable=W0212
...
@@ -305,7 +305,7 @@ class FileSubmissionTest(unittest.TestCase):
...
@@ -305,7 +305,7 @@ class FileSubmissionTest(unittest.TestCase):
'status'
:
'incomplete'
,
'status'
:
'incomplete'
,
'feedback'
:
{
'message'
:
'3'
},
}
'feedback'
:
{
'message'
:
'3'
},
}
input_class
=
lookup_tag
(
'filesubmission'
)
input_class
=
lookup_tag
(
'filesubmission'
)
the_input
=
input_class
(
test_system
(),
element
,
state
)
the_input
=
input_class
(
test_
capa_
system
(),
element
,
state
)
context
=
the_input
.
_get_render_context
()
# pylint: disable=W0212
context
=
the_input
.
_get_render_context
()
# pylint: disable=W0212
...
@@ -353,7 +353,7 @@ class CodeInputTest(unittest.TestCase):
...
@@ -353,7 +353,7 @@ class CodeInputTest(unittest.TestCase):
'feedback'
:
{
'message'
:
'3'
},
}
'feedback'
:
{
'message'
:
'3'
},
}
input_class
=
lookup_tag
(
'codeinput'
)
input_class
=
lookup_tag
(
'codeinput'
)
the_input
=
input_class
(
test_system
(),
element
,
state
)
the_input
=
input_class
(
test_
capa_
system
(),
element
,
state
)
context
=
the_input
.
_get_render_context
()
# pylint: disable=W0212
context
=
the_input
.
_get_render_context
()
# pylint: disable=W0212
...
@@ -405,7 +405,7 @@ class MatlabTest(unittest.TestCase):
...
@@ -405,7 +405,7 @@ class MatlabTest(unittest.TestCase):
'feedback'
:
{
'message'
:
'3'
},
}
'feedback'
:
{
'message'
:
'3'
},
}
self
.
input_class
=
lookup_tag
(
'matlabinput'
)
self
.
input_class
=
lookup_tag
(
'matlabinput'
)
self
.
the_input
=
self
.
input_class
(
test_system
(),
elt
,
state
)
self
.
the_input
=
self
.
input_class
(
test_
capa_
system
(),
elt
,
state
)
def
test_rendering
(
self
):
def
test_rendering
(
self
):
context
=
self
.
the_input
.
_get_render_context
()
# pylint: disable=W0212
context
=
self
.
the_input
.
_get_render_context
()
# pylint: disable=W0212
...
@@ -436,7 +436,7 @@ class MatlabTest(unittest.TestCase):
...
@@ -436,7 +436,7 @@ class MatlabTest(unittest.TestCase):
'feedback'
:
{
'message'
:
'3'
},
}
'feedback'
:
{
'message'
:
'3'
},
}
elt
=
etree
.
fromstring
(
self
.
xml
)
elt
=
etree
.
fromstring
(
self
.
xml
)
the_input
=
self
.
input_class
(
test_system
(),
elt
,
state
)
the_input
=
self
.
input_class
(
test_
capa_
system
(),
elt
,
state
)
context
=
the_input
.
_get_render_context
()
# pylint: disable=W0212
context
=
the_input
.
_get_render_context
()
# pylint: disable=W0212
expected
=
{
expected
=
{
...
@@ -466,7 +466,7 @@ class MatlabTest(unittest.TestCase):
...
@@ -466,7 +466,7 @@ class MatlabTest(unittest.TestCase):
}
}
elt
=
etree
.
fromstring
(
self
.
xml
)
elt
=
etree
.
fromstring
(
self
.
xml
)
the_input
=
self
.
input_class
(
test_system
(),
elt
,
state
)
the_input
=
self
.
input_class
(
test_
capa_
system
(),
elt
,
state
)
context
=
the_input
.
_get_render_context
()
# pylint: disable=W0212
context
=
the_input
.
_get_render_context
()
# pylint: disable=W0212
expected
=
{
expected
=
{
'STATIC_URL'
:
'/dummy-static/'
,
'STATIC_URL'
:
'/dummy-static/'
,
...
@@ -494,7 +494,7 @@ class MatlabTest(unittest.TestCase):
...
@@ -494,7 +494,7 @@ class MatlabTest(unittest.TestCase):
}
}
elt
=
etree
.
fromstring
(
self
.
xml
)
elt
=
etree
.
fromstring
(
self
.
xml
)
the_input
=
self
.
input_class
(
test_system
(),
elt
,
state
)
the_input
=
self
.
input_class
(
test_
capa_
system
(),
elt
,
state
)
context
=
the_input
.
_get_render_context
()
# pylint: disable=W0212
context
=
the_input
.
_get_render_context
()
# pylint: disable=W0212
expected
=
{
expected
=
{
'STATIC_URL'
:
'/dummy-static/'
,
'STATIC_URL'
:
'/dummy-static/'
,
...
@@ -519,7 +519,7 @@ class MatlabTest(unittest.TestCase):
...
@@ -519,7 +519,7 @@ class MatlabTest(unittest.TestCase):
data
=
{
'submission'
:
'x = 1234;'
}
data
=
{
'submission'
:
'x = 1234;'
}
response
=
self
.
the_input
.
handle_ajax
(
"plot"
,
data
)
response
=
self
.
the_input
.
handle_ajax
(
"plot"
,
data
)
test_system
()
.
xqueue
[
'interface'
]
.
send_to_queue
.
assert_called_with
(
header
=
ANY
,
body
=
ANY
)
test_
capa_
system
()
.
xqueue
[
'interface'
]
.
send_to_queue
.
assert_called_with
(
header
=
ANY
,
body
=
ANY
)
self
.
assertTrue
(
response
[
'success'
])
self
.
assertTrue
(
response
[
'success'
])
self
.
assertTrue
(
self
.
the_input
.
input_state
[
'queuekey'
]
is
not
None
)
self
.
assertTrue
(
self
.
the_input
.
input_state
[
'queuekey'
]
is
not
None
)
...
@@ -528,7 +528,7 @@ class MatlabTest(unittest.TestCase):
...
@@ -528,7 +528,7 @@ class MatlabTest(unittest.TestCase):
def
test_plot_data_failure
(
self
):
def
test_plot_data_failure
(
self
):
data
=
{
'submission'
:
'x = 1234;'
}
data
=
{
'submission'
:
'x = 1234;'
}
error_message
=
'Error message!'
error_message
=
'Error message!'
test_system
()
.
xqueue
[
'interface'
]
.
send_to_queue
.
return_value
=
(
1
,
error_message
)
test_
capa_
system
()
.
xqueue
[
'interface'
]
.
send_to_queue
.
return_value
=
(
1
,
error_message
)
response
=
self
.
the_input
.
handle_ajax
(
"plot"
,
data
)
response
=
self
.
the_input
.
handle_ajax
(
"plot"
,
data
)
self
.
assertFalse
(
response
[
'success'
])
self
.
assertFalse
(
response
[
'success'
])
self
.
assertEqual
(
response
[
'message'
],
error_message
)
self
.
assertEqual
(
response
[
'message'
],
error_message
)
...
@@ -544,7 +544,7 @@ class MatlabTest(unittest.TestCase):
...
@@ -544,7 +544,7 @@ class MatlabTest(unittest.TestCase):
'feedback'
:
{
'message'
:
'3'
},
}
'feedback'
:
{
'message'
:
'3'
},
}
elt
=
etree
.
fromstring
(
self
.
xml
)
elt
=
etree
.
fromstring
(
self
.
xml
)
the_input
=
self
.
input_class
(
test_system
(),
elt
,
state
)
the_input
=
self
.
input_class
(
test_
capa_
system
(),
elt
,
state
)
inner_msg
=
'hello!'
inner_msg
=
'hello!'
queue_msg
=
json
.
dumps
({
'msg'
:
inner_msg
})
queue_msg
=
json
.
dumps
({
'msg'
:
inner_msg
})
...
@@ -562,7 +562,7 @@ class MatlabTest(unittest.TestCase):
...
@@ -562,7 +562,7 @@ class MatlabTest(unittest.TestCase):
'feedback'
:
{
'message'
:
'3'
},
}
'feedback'
:
{
'message'
:
'3'
},
}
elt
=
etree
.
fromstring
(
self
.
xml
)
elt
=
etree
.
fromstring
(
self
.
xml
)
the_input
=
self
.
input_class
(
test_system
(),
elt
,
state
)
the_input
=
self
.
input_class
(
test_
capa_
system
(),
elt
,
state
)
inner_msg
=
'hello!'
inner_msg
=
'hello!'
queue_msg
=
json
.
dumps
({
'msg'
:
inner_msg
})
queue_msg
=
json
.
dumps
({
'msg'
:
inner_msg
})
...
@@ -601,7 +601,7 @@ class SchematicTest(unittest.TestCase):
...
@@ -601,7 +601,7 @@ class SchematicTest(unittest.TestCase):
state
=
{
'value'
:
value
,
state
=
{
'value'
:
value
,
'status'
:
'unsubmitted'
}
'status'
:
'unsubmitted'
}
the_input
=
lookup_tag
(
'schematic'
)(
test_system
(),
element
,
state
)
the_input
=
lookup_tag
(
'schematic'
)(
test_
capa_
system
(),
element
,
state
)
context
=
the_input
.
_get_render_context
()
# pylint: disable=W0212
context
=
the_input
.
_get_render_context
()
# pylint: disable=W0212
...
@@ -643,7 +643,7 @@ class ImageInputTest(unittest.TestCase):
...
@@ -643,7 +643,7 @@ class ImageInputTest(unittest.TestCase):
state
=
{
'value'
:
value
,
state
=
{
'value'
:
value
,
'status'
:
'unsubmitted'
}
'status'
:
'unsubmitted'
}
the_input
=
lookup_tag
(
'imageinput'
)(
test_system
(),
element
,
state
)
the_input
=
lookup_tag
(
'imageinput'
)(
test_
capa_
system
(),
element
,
state
)
context
=
the_input
.
_get_render_context
()
# pylint: disable=W0212
context
=
the_input
.
_get_render_context
()
# pylint: disable=W0212
...
@@ -697,7 +697,7 @@ class CrystallographyTest(unittest.TestCase):
...
@@ -697,7 +697,7 @@ class CrystallographyTest(unittest.TestCase):
state
=
{
'value'
:
value
,
state
=
{
'value'
:
value
,
'status'
:
'unsubmitted'
}
'status'
:
'unsubmitted'
}
the_input
=
lookup_tag
(
'crystallography'
)(
test_system
(),
element
,
state
)
the_input
=
lookup_tag
(
'crystallography'
)(
test_
capa_
system
(),
element
,
state
)
context
=
the_input
.
_get_render_context
()
# pylint: disable=W0212
context
=
the_input
.
_get_render_context
()
# pylint: disable=W0212
...
@@ -738,7 +738,7 @@ class VseprTest(unittest.TestCase):
...
@@ -738,7 +738,7 @@ class VseprTest(unittest.TestCase):
state
=
{
'value'
:
value
,
state
=
{
'value'
:
value
,
'status'
:
'unsubmitted'
}
'status'
:
'unsubmitted'
}
the_input
=
lookup_tag
(
'vsepr_input'
)(
test_system
(),
element
,
state
)
the_input
=
lookup_tag
(
'vsepr_input'
)(
test_
capa_
system
(),
element
,
state
)
context
=
the_input
.
_get_render_context
()
# pylint: disable=W0212
context
=
the_input
.
_get_render_context
()
# pylint: disable=W0212
...
@@ -768,7 +768,7 @@ class ChemicalEquationTest(unittest.TestCase):
...
@@ -768,7 +768,7 @@ class ChemicalEquationTest(unittest.TestCase):
element
=
etree
.
fromstring
(
xml_str
)
element
=
etree
.
fromstring
(
xml_str
)
state
=
{
'value'
:
'H2OYeah'
,
}
state
=
{
'value'
:
'H2OYeah'
,
}
self
.
the_input
=
lookup_tag
(
'chemicalequationinput'
)(
test_system
(),
element
,
state
)
self
.
the_input
=
lookup_tag
(
'chemicalequationinput'
)(
test_
capa_
system
(),
element
,
state
)
def
test_rendering
(
self
):
def
test_rendering
(
self
):
''' Verify that the render context matches the expected render context'''
''' Verify that the render context matches the expected render context'''
...
@@ -853,7 +853,7 @@ class FormulaEquationTest(unittest.TestCase):
...
@@ -853,7 +853,7 @@ class FormulaEquationTest(unittest.TestCase):
element
=
etree
.
fromstring
(
xml_str
)
element
=
etree
.
fromstring
(
xml_str
)
state
=
{
'value'
:
'x^2+1/2'
}
state
=
{
'value'
:
'x^2+1/2'
}
self
.
the_input
=
lookup_tag
(
'formulaequationinput'
)(
test_system
(),
element
,
state
)
self
.
the_input
=
lookup_tag
(
'formulaequationinput'
)(
test_
capa_
system
(),
element
,
state
)
def
test_rendering
(
self
):
def
test_rendering
(
self
):
"""
"""
...
@@ -1005,7 +1005,7 @@ class DragAndDropTest(unittest.TestCase):
...
@@ -1005,7 +1005,7 @@ class DragAndDropTest(unittest.TestCase):
]
]
}
}
the_input
=
lookup_tag
(
'drag_and_drop_input'
)(
test_system
(),
element
,
state
)
the_input
=
lookup_tag
(
'drag_and_drop_input'
)(
test_
capa_
system
(),
element
,
state
)
context
=
the_input
.
_get_render_context
()
# pylint: disable=W0212
context
=
the_input
.
_get_render_context
()
# pylint: disable=W0212
expected
=
{
expected
=
{
...
@@ -1056,7 +1056,7 @@ class AnnotationInputTest(unittest.TestCase):
...
@@ -1056,7 +1056,7 @@ class AnnotationInputTest(unittest.TestCase):
tag
=
'annotationinput'
tag
=
'annotationinput'
the_input
=
lookup_tag
(
tag
)(
test_system
(),
element
,
state
)
the_input
=
lookup_tag
(
tag
)(
test_
capa_
system
(),
element
,
state
)
context
=
the_input
.
_get_render_context
()
# pylint: disable=W0212
context
=
the_input
.
_get_render_context
()
# pylint: disable=W0212
...
@@ -1146,7 +1146,7 @@ class TestChoiceText(unittest.TestCase):
...
@@ -1146,7 +1146,7 @@ class TestChoiceText(unittest.TestCase):
'submitted_message'
:
'Answer received.'
'submitted_message'
:
'Answer received.'
}
}
expected
.
update
(
state
)
expected
.
update
(
state
)
the_input
=
lookup_tag
(
tag
)(
test_system
(),
element
,
state
)
the_input
=
lookup_tag
(
tag
)(
test_
capa_
system
(),
element
,
state
)
context
=
the_input
.
_get_render_context
()
# pylint: disable=W0212
context
=
the_input
.
_get_render_context
()
# pylint: disable=W0212
self
.
assertEqual
(
context
,
expected
)
self
.
assertEqual
(
context
,
expected
)
...
...
common/lib/capa/capa/tests/test_responsetypes.py
View file @
42c543b7
...
@@ -13,7 +13,7 @@ import textwrap
...
@@ -13,7 +13,7 @@ import textwrap
import
requests
import
requests
import
mock
import
mock
from
.
import
new_loncapa_problem
,
test_system
from
.
import
new_loncapa_problem
,
test_
capa_
system
import
calc
import
calc
from
capa.responsetypes
import
LoncapaProblemError
,
\
from
capa.responsetypes
import
LoncapaProblemError
,
\
...
@@ -37,9 +37,9 @@ class ResponseTest(unittest.TestCase):
...
@@ -37,9 +37,9 @@ class ResponseTest(unittest.TestCase):
if
self
.
xml_factory_class
:
if
self
.
xml_factory_class
:
self
.
xml_factory
=
self
.
xml_factory_class
()
self
.
xml_factory
=
self
.
xml_factory_class
()
def
build_problem
(
self
,
system
=
None
,
**
kwargs
):
def
build_problem
(
self
,
capa_
system
=
None
,
**
kwargs
):
xml
=
self
.
xml_factory
.
build_xml
(
**
kwargs
)
xml
=
self
.
xml_factory
.
build_xml
(
**
kwargs
)
return
new_loncapa_problem
(
xml
,
system
=
system
)
return
new_loncapa_problem
(
xml
,
capa_system
=
capa_
system
)
def
assert_grade
(
self
,
problem
,
submission
,
expected_correctness
,
msg
=
None
):
def
assert_grade
(
self
,
problem
,
submission
,
expected_correctness
,
msg
=
None
):
input_dict
=
{
'1_2_1'
:
submission
}
input_dict
=
{
'1_2_1'
:
submission
}
...
@@ -1022,10 +1022,10 @@ class JavascriptResponseTest(ResponseTest):
...
@@ -1022,10 +1022,10 @@ class JavascriptResponseTest(ResponseTest):
coffee_file_path
=
os
.
path
.
dirname
(
__file__
)
+
"/test_files/js/*.coffee"
coffee_file_path
=
os
.
path
.
dirname
(
__file__
)
+
"/test_files/js/*.coffee"
os
.
system
(
"node_modules/.bin/coffee -c
%
s"
%
(
coffee_file_path
))
os
.
system
(
"node_modules/.bin/coffee -c
%
s"
%
(
coffee_file_path
))
system
=
test
_system
()
capa_system
=
test_capa
_system
()
system
.
can_execute_unsafe_code
=
lambda
:
True
capa_
system
.
can_execute_unsafe_code
=
lambda
:
True
problem
=
self
.
build_problem
(
problem
=
self
.
build_problem
(
system
=
system
,
capa_system
=
capa_
system
,
generator_src
=
"test_problem_generator.js"
,
generator_src
=
"test_problem_generator.js"
,
grader_src
=
"test_problem_grader.js"
,
grader_src
=
"test_problem_grader.js"
,
display_class
=
"TestProblemDisplay"
,
display_class
=
"TestProblemDisplay"
,
...
@@ -1040,12 +1040,12 @@ class JavascriptResponseTest(ResponseTest):
...
@@ -1040,12 +1040,12 @@ class JavascriptResponseTest(ResponseTest):
def
test_cant_execute_javascript
(
self
):
def
test_cant_execute_javascript
(
self
):
# If the system says to disallow unsafe code execution, then making
# If the system says to disallow unsafe code execution, then making
# this problem will raise an exception.
# this problem will raise an exception.
system
=
test
_system
()
capa_system
=
test_capa
_system
()
system
.
can_execute_unsafe_code
=
lambda
:
False
capa_
system
.
can_execute_unsafe_code
=
lambda
:
False
with
self
.
assertRaises
(
LoncapaProblemError
):
with
self
.
assertRaises
(
LoncapaProblemError
):
self
.
build_problem
(
self
.
build_problem
(
system
=
system
,
capa_system
=
capa_
system
,
generator_src
=
"test_problem_generator.js"
,
generator_src
=
"test_problem_generator.js"
,
grader_src
=
"test_problem_grader.js"
,
grader_src
=
"test_problem_grader.js"
,
display_class
=
"TestProblemDisplay"
,
display_class
=
"TestProblemDisplay"
,
...
@@ -1140,6 +1140,24 @@ class NumericalResponseTest(ResponseTest):
...
@@ -1140,6 +1140,24 @@ class NumericalResponseTest(ResponseTest):
"Content error--answer '
%
s' is not a valid number"
,
staff_ans
"Content error--answer '
%
s' is not a valid number"
,
staff_ans
)
)
@mock.patch
(
'capa.responsetypes.log'
)
def
test_responsetype_i18n
(
self
,
mock_log
):
"""Test that LoncapaSystem has an i18n that works."""
staff_ans
=
"clearly bad syntax )[+1e"
problem
=
self
.
build_problem
(
answer
=
staff_ans
,
tolerance
=
1e-3
)
class
FakeTranslations
(
object
):
"""A fake gettext.Translations object."""
def
ugettext
(
self
,
text
):
"""Return the 'translation' of `text`."""
if
text
==
"There was a problem with the staff answer to this problem"
:
text
=
"TRANSLATED!"
return
text
problem
.
capa_system
.
i18n
=
FakeTranslations
()
with
self
.
assertRaisesRegexp
(
StudentInputError
,
"TRANSLATED!"
):
self
.
assert_grade
(
problem
,
'1+j'
,
'correct'
)
def
test_grade_infinity
(
self
):
def
test_grade_infinity
(
self
):
"""
"""
Check that infinity doesn't automatically get marked correct.
Check that infinity doesn't automatically get marked correct.
...
...
common/lib/xmodule/xmodule/capa_base.py
View file @
42c543b7
...
@@ -11,7 +11,7 @@ import sys
...
@@ -11,7 +11,7 @@ import sys
from
pkg_resources
import
resource_string
from
pkg_resources
import
resource_string
from
capa.capa_problem
import
LoncapaProblem
from
capa.capa_problem
import
LoncapaProblem
,
LoncapaSystem
from
capa.responsetypes
import
StudentInputError
,
\
from
capa.responsetypes
import
StudentInputError
,
\
ResponseError
,
LoncapaProblemError
ResponseError
,
LoncapaProblemError
from
capa.util
import
convert_files_to_filenames
from
capa.util
import
convert_files_to_filenames
...
@@ -260,12 +260,27 @@ class CapaMixin(CapaFields):
...
@@ -260,12 +260,27 @@ class CapaMixin(CapaFields):
if
text
is
None
:
if
text
is
None
:
text
=
self
.
data
text
=
self
.
data
capa_system
=
LoncapaSystem
(
ajax_url
=
self
.
runtime
.
ajax_url
,
anonymous_student_id
=
self
.
runtime
.
anonymous_student_id
,
cache
=
self
.
runtime
.
cache
,
can_execute_unsafe_code
=
self
.
runtime
.
can_execute_unsafe_code
,
DEBUG
=
self
.
runtime
.
DEBUG
,
filestore
=
self
.
runtime
.
filestore
,
i18n
=
self
.
runtime
.
service
(
self
,
"i18n"
),
node_path
=
self
.
runtime
.
node_path
,
render_template
=
self
.
runtime
.
render_template
,
seed
=
self
.
runtime
.
seed
,
# Why do we do this if we have self.seed?
STATIC_URL
=
self
.
runtime
.
STATIC_URL
,
xqueue
=
self
.
runtime
.
xqueue
,
)
return
LoncapaProblem
(
return
LoncapaProblem
(
problem_text
=
text
,
problem_text
=
text
,
id
=
self
.
location
.
html_id
(),
id
=
self
.
location
.
html_id
(),
state
=
state
,
state
=
state
,
seed
=
self
.
seed
,
seed
=
self
.
seed
,
system
=
self
.
runtime
,
capa_system
=
capa_system
,
)
)
def
get_state_for_lcp
(
self
):
def
get_state_for_lcp
(
self
):
...
...
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