with correct class
@@ -487,9 +480,7 @@ class FormulaEquationInputTemplateTest(TemplateTestCase):
self.context = {
'id': 2,
'value': 'PREFILLED_VALUE',
- 'status': 'unsubmitted',
- 'status_class': 'unanswered',
- 'status_display': u'unsubmitted',
+ 'status': Status('unsubmitted'),
'label': 'test',
'previewer': 'file.js',
'reported_status': 'REPORTED_STATUS',
@@ -525,9 +516,7 @@ class AnnotationInputTemplateTest(TemplateTestCase):
'options': [],
'has_options_value': False,
'debug': False,
- 'status': 'unsubmitted',
- 'status_class': 'unanswered',
- 'status_display': u'unsubmitted',
+ 'status': Status('unsubmitted'),
'return_to_annotation': False,
'msg': '
', }
super(AnnotationInputTemplateTest, self).setUp()
@@ -587,16 +576,16 @@ class AnnotationInputTemplateTest(TemplateTestCase):
('incorrect', 'incorrect')]
for (input_status, expected_css_class) in test_cases:
- self.context['status'] = input_status
+ self.context['status'] = Status(input_status)
xml = self.render_to_xml(self.context)
- xpath = "//span[@class='{0}']".format(expected_css_class)
+ xpath = "//span[@class='status {0}']".format(expected_css_class)
self.assert_has_xpath(xml, xpath, self.context)
# If individual options are being marked, then expect
# just the option to be marked incorrect, not the whole problem
self.context['has_options_value'] = True
- self.context['status'] = 'incorrect'
+ self.context['status'] = Status('incorrect')
xpath = "//span[@class='incorrect']"
xml = self.render_to_xml(self.context)
self.assert_no_xpath(xml, xpath, self.context)
@@ -687,9 +676,7 @@ class OptionInputTemplateTest(TemplateTestCase):
self.context = {
'id': 2,
'options': [],
- 'status': 'unsubmitted',
- 'status_class': 'unanswered',
- 'status_display': u'unanswered',
+ 'status': Status('unsubmitted'),
'label': 'test',
'value': 0
}
@@ -729,8 +716,7 @@ class OptionInputTemplateTest(TemplateTestCase):
('incomplete', 'status incorrect')]
for (input_status, expected_css_class) in test_cases:
- self.context['status'] = input_status
- self.context['status_class'] = expected_css_class.split(' ')[1]
+ self.context['status'] = Status(input_status)
xml = self.render_to_xml(self.context)
xpath = "//span[@class='{0}']".format(expected_css_class)
@@ -753,7 +739,7 @@ class DragAndDropTemplateTest(TemplateTestCase):
self.context = {'id': 2,
'drag_and_drop_json': '',
'value': 0,
- 'status': 'unsubmitted',
+ 'status': Status('unsubmitted'),
'msg': ''}
super(DragAndDropTemplateTest, self).setUp()
@@ -767,7 +753,7 @@ class DragAndDropTemplateTest(TemplateTestCase):
('incomplete', 'incorrect', 'incomplete')]
for (input_status, expected_css_class, expected_text) in test_cases:
- self.context['status'] = input_status
+ self.context['status'] = Status(input_status)
xml = self.render_to_xml(self.context)
# Expect a
with the status
@@ -814,9 +800,7 @@ class ChoiceTextGroupTemplateTest(TemplateTestCase):
{'tail_text': '', 'type': 'textinput', 'value': '', 'contents': 'choiceinput_1_textinput_0'}])]
self.context = {'id': '1',
'choices': choices,
- 'status': 'correct',
- 'status_class': 'correct',
- 'status_display': u'correct',
+ 'status': Status('correct'),
'input_type': 'radio',
'label': 'choicetext label',
'value': self.VALUE_DICT}
@@ -829,7 +813,7 @@ class ChoiceTextGroupTemplateTest(TemplateTestCase):
Section is used for checkbox, so inputting text does not deselect
"""
input_tags = ('radio', 'checkbox')
- self.context['status'] = 'correct'
+ self.context['status'] = Status('correct')
xpath = "//section[@id='forinput1_choiceinput_0bc']"
self.context['value'] = {}
@@ -842,7 +826,7 @@ class ChoiceTextGroupTemplateTest(TemplateTestCase):
"""Test conditions under which the entire problem
(not a particular option) is marked correct"""
- self.context['status'] = 'correct'
+ self.context['status'] = Status('correct')
self.context['input_type'] = 'checkbox'
self.context['value'] = self.VALUE_DICT
@@ -863,14 +847,14 @@ class ChoiceTextGroupTemplateTest(TemplateTestCase):
(not a particular option) is marked incorrect"""
grouping_tags = {'radio': 'label', 'checkbox': 'section'}
conditions = [
- {'status': 'incorrect', 'status_class': 'incorrect', 'input_type': 'radio', 'value': {}},
- {'status': 'incorrect', 'status_class': 'incorrect', 'input_type': 'checkbox', 'value': self.WRONG_CHOICE_CHECKBOX},
- {'status': 'incorrect', 'status_class': 'incorrect', 'input_type': 'checkbox', 'value': self.BOTH_CHOICE_CHECKBOX},
- {'status': 'incorrect', 'status_class': 'incorrect', 'input_type': 'checkbox', 'value': self.VALUE_DICT},
- {'status': 'incomplete', 'status_class': 'incorrect', 'input_type': 'radio', 'value': {}},
- {'status': 'incomplete', 'status_class': 'incorrect', 'input_type': 'checkbox', 'value': self.WRONG_CHOICE_CHECKBOX},
- {'status': 'incomplete', 'status_class': 'incorrect', 'input_type': 'checkbox', 'value': self.BOTH_CHOICE_CHECKBOX},
- {'status': 'incomplete', 'status_class': 'incorrect', 'input_type': 'checkbox', 'value': self.VALUE_DICT}]
+ {'status': Status('incorrect'), 'input_type': 'radio', 'value': {}},
+ {'status': Status('incorrect'), 'input_type': 'checkbox', 'value': self.WRONG_CHOICE_CHECKBOX},
+ {'status': Status('incorrect'), 'input_type': 'checkbox', 'value': self.BOTH_CHOICE_CHECKBOX},
+ {'status': Status('incorrect'), 'input_type': 'checkbox', 'value': self.VALUE_DICT},
+ {'status': Status('incomplete'), 'input_type': 'radio', 'value': {}},
+ {'status': Status('incomplete'), 'input_type': 'checkbox', 'value': self.WRONG_CHOICE_CHECKBOX},
+ {'status': Status('incomplete'), 'input_type': 'checkbox', 'value': self.BOTH_CHOICE_CHECKBOX},
+ {'status': Status('incomplete'), 'input_type': 'checkbox', 'value': self.VALUE_DICT}]
for test_conditions in conditions:
self.context.update(test_conditions)
@@ -894,15 +878,14 @@ class ChoiceTextGroupTemplateTest(TemplateTestCase):
grouping_tags = {'radio': 'label', 'checkbox': 'section'}
conditions = [
- {'status': 'unsubmitted', 'input_type': 'radio', 'value': {}},
- {'status': 'unsubmitted', 'input_type': 'radio', 'value': self.EMPTY_DICT},
- {'status': 'unsubmitted', 'input_type': 'checkbox', 'value': {}},
- {'status': 'unsubmitted', 'input_type': 'checkbox', 'value': self.EMPTY_DICT},
- {'status': 'unsubmitted', 'input_type': 'checkbox', 'value': self.VALUE_DICT},
- {'status': 'unsubmitted', 'input_type': 'checkbox', 'value': self.BOTH_CHOICE_CHECKBOX}]
+ {'status': Status('unsubmitted'), 'input_type': 'radio', 'value': {}},
+ {'status': Status('unsubmitted'), 'input_type': 'radio', 'value': self.EMPTY_DICT},
+ {'status': Status('unsubmitted'), 'input_type': 'checkbox', 'value': {}},
+ {'status': Status('unsubmitted'), 'input_type': 'checkbox', 'value': self.EMPTY_DICT},
+ {'status': Status('unsubmitted'), 'input_type': 'checkbox', 'value': self.VALUE_DICT},
+ {'status': Status('unsubmitted'), 'input_type': 'checkbox', 'value': self.BOTH_CHOICE_CHECKBOX}]
- self.context['status'] = 'unanswered'
- self.context['status_class'] = 'unanswered'
+ self.context['status'] = Status('unanswered')
for test_conditions in conditions:
self.context.update(test_conditions)
diff --git a/common/lib/capa/capa/tests/test_inputtypes.py b/common/lib/capa/capa/tests/test_inputtypes.py
index c1240c73bf..bef9e9c0f6 100644
--- a/common/lib/capa/capa/tests/test_inputtypes.py
+++ b/common/lib/capa/capa/tests/test_inputtypes.py
@@ -58,9 +58,7 @@ class OptionInputTest(unittest.TestCase):
'STATIC_URL': '/dummy-static/',
'value': 'Down',
'options': [('Up', 'Up'), ('Down', 'Down'), ('Don\'t know', 'Don\'t know')],
- 'status': 'answered',
- 'status_class': 'answered',
- 'status_display': 'answered',
+ 'status': inputtypes.Status('answered'),
'label': '',
'msg': '',
'inline': False,
@@ -120,9 +118,7 @@ class ChoiceGroupTest(unittest.TestCase):
'STATIC_URL': '/dummy-static/',
'id': 'sky_input',
'value': 'foil3',
- 'status': 'answered',
- 'status_class': 'answered',
- 'status_display': 'answered',
+ 'status': inputtypes.Status('answered'),
'label': '',
'msg': '',
'input_type': expected_input_type,
@@ -160,10 +156,10 @@ class JavascriptInputTest(unittest.TestCase):
display_file = "my_files/hi.js"
xml_str = """
""".format(
- params=params,
- ps=quote_attr(problem_state),
- dc=display_class, df=display_file)
+ display_class="{dc}" display_file="{df}"/>""".format(
+ params=params,
+ ps=quote_attr(problem_state),
+ dc=display_class, df=display_file)
element = etree.fromstring(xml_str)
@@ -175,9 +171,7 @@ class JavascriptInputTest(unittest.TestCase):
expected = {
'STATIC_URL': '/dummy-static/',
'id': 'prob_1_2',
- 'status': 'unanswered',
- 'status_class': 'unanswered',
- 'status_display': u'unanswered',
+ 'status': inputtypes.Status('unanswered'),
# 'label': '',
'msg': '',
'value': '3',
@@ -210,9 +204,7 @@ class TextLineTest(unittest.TestCase):
'STATIC_URL': '/dummy-static/',
'id': 'prob_1_2',
'value': 'BumbleBee',
- 'status': 'unanswered',
- 'status_class': 'unanswered',
- 'status_display': u'unanswered',
+ 'status': inputtypes.Status('unanswered'),
'label': 'testing 123',
'size': size,
'msg': '',
@@ -244,9 +236,7 @@ class TextLineTest(unittest.TestCase):
'STATIC_URL': '/dummy-static/',
'id': 'prob_1_2',
'value': 'BumbleBee',
- 'status': 'unanswered',
- 'status_class': 'unanswered',
- 'status_display': u'unanswered',
+ 'status': inputtypes.Status('unanswered'),
'label': '',
'size': size,
'msg': '',
@@ -290,9 +280,7 @@ class TextLineTest(unittest.TestCase):
'STATIC_URL': '/dummy-static/',
'id': 'prob_1_2',
'value': 'BumbleBee',
- 'status': 'unanswered',
- 'status_class': 'unanswered',
- 'status_display': u'unanswered',
+ 'status': inputtypes.Status('unanswered'),
'label': '',
'size': size,
'msg': '',
@@ -333,9 +321,7 @@ class FileSubmissionTest(unittest.TestCase):
expected = {
'STATIC_URL': '/dummy-static/',
'id': 'prob_1_2',
- 'status': 'queued',
- 'status_class': 'processing',
- 'status_display': u'queued',
+ 'status': inputtypes.Status('queued'),
'label': '',
'msg': the_input.submitted_msg,
'value': 'BumbleBee.py',
@@ -385,9 +371,7 @@ class CodeInputTest(unittest.TestCase):
'STATIC_URL': '/dummy-static/',
'id': 'prob_1_2',
'value': 'print "good evening"',
- 'status': 'queued',
- 'status_class': 'processing',
- 'status_display': u'queued',
+ 'status': inputtypes.Status('queued'),
# 'label': '',
'msg': the_input.submitted_msg,
'mode': mode,
@@ -441,9 +425,7 @@ class MatlabTest(unittest.TestCase):
'STATIC_URL': '/dummy-static/',
'id': 'prob_1_2',
'value': 'print "good evening"',
- 'status': 'queued',
- 'status_class': 'processing',
- 'status_display': u'queued',
+ 'status': inputtypes.Status('queued'),
# 'label': '',
'msg': self.the_input.submitted_msg,
'mode': self.mode,
@@ -474,9 +456,7 @@ class MatlabTest(unittest.TestCase):
'STATIC_URL': '/dummy-static/',
'id': 'prob_1_2',
'value': 'print "good evening"',
- 'status': 'queued',
- 'status_class': 'processing',
- 'status_display': u'queued',
+ 'status': inputtypes.Status('queued'),
# 'label': '',
'msg': the_input.submitted_msg,
'mode': self.mode,
@@ -507,9 +487,7 @@ class MatlabTest(unittest.TestCase):
'STATIC_URL': '/dummy-static/',
'id': 'prob_1_2',
'value': 'print "good evening"',
- 'status': status,
- 'status_class': status,
- 'status_display': unicode(status),
+ 'status': inputtypes.Status(status),
# 'label': '',
'msg': '',
'mode': self.mode,
@@ -540,9 +518,7 @@ class MatlabTest(unittest.TestCase):
'STATIC_URL': '/dummy-static/',
'id': 'prob_1_2',
'value': 'print "good evening"',
- 'status': 'queued',
- 'status_class': 'processing',
- 'status_display': u'queued',
+ 'status': inputtypes.Status('queued'),
# 'label': '',
'msg': the_input.submitted_msg,
'mode': self.mode,
@@ -657,7 +633,7 @@ class MatlabTest(unittest.TestCase):
output = self.the_input.get_html()
self.assertEqual(
etree.tostring(output),
- """
{\'status\': \'queued\', \'button_enabled\': True, \'linenumbers\': \'true\', \'rows\': \'10\', \'queue_len\': \'3\', \'mode\': \'\', \'cols\': \'80\', \'value\': \'print "good evening"\', \'status_class\': \'processing\', \'queue_msg\': \'\', \'STATIC_URL\': \'/dummy-static/\', \'msg\': u\'Submitted. As soon as a response is returned, this message will be replaced by that feedback.\', \'matlab_editor_js\': \'/dummy-static/js/vendor/CodeMirror/octave.js\', \'hidden\': \'\', \'status_display\': u\'queued\', \'id\': \'prob_1_2\', \'tabsize\': 4}
"""
+ """
{\'status\': Status(\'queued\'), \'button_enabled\': True, \'rows\': \'10\', \'queue_len\': \'3\', \'mode\': \'\', \'cols\': \'80\', \'STATIC_URL\': \'/dummy-static/\', \'linenumbers\': \'true\', \'queue_msg\': \'\', \'value\': \'print "good evening"\', \'msg\': u\'Submitted. As soon as a response is returned, this message will be replaced by that feedback.\', \'matlab_editor_js\': \'/dummy-static/js/vendor/CodeMirror/octave.js\', \'hidden\': \'\', \'id\': \'prob_1_2\', \'tabsize\': 4}
"""
)
# test html, that is correct HTML5 html, but is not parsable by XML parser.
@@ -775,9 +751,7 @@ class SchematicTest(unittest.TestCase):
'STATIC_URL': '/dummy-static/',
'id': 'prob_1_2',
'value': value,
- 'status': 'unsubmitted',
- 'status_class': 'unanswered',
- 'status_display': u'unanswered',
+ 'status': inputtypes.Status('unsubmitted'),
'label': '',
'msg': '',
'initial_value': initial_value,
@@ -821,9 +795,7 @@ class ImageInputTest(unittest.TestCase):
'STATIC_URL': '/dummy-static/',
'id': 'prob_1_2',
'value': value,
- 'status': 'unsubmitted',
- 'status_class': 'unanswered',
- 'status_display': u'unanswered',
+ 'status': inputtypes.Status('unsubmitted'),
'label': '',
'width': width,
'height': height,
@@ -878,9 +850,7 @@ class CrystallographyTest(unittest.TestCase):
'STATIC_URL': '/dummy-static/',
'id': 'prob_1_2',
'value': value,
- 'status': 'unsubmitted',
- 'status_class': 'unanswered',
- 'status_display': u'unanswered',
+ 'status': inputtypes.Status('unsubmitted'),
# 'label': '',
'msg': '',
'width': width,
@@ -922,9 +892,7 @@ class VseprTest(unittest.TestCase):
'STATIC_URL': '/dummy-static/',
'id': 'prob_1_2',
'value': value,
- 'status': 'unsubmitted',
- 'status_class': 'unanswered',
- 'status_display': u'unanswered',
+ 'status': inputtypes.Status('unsubmitted'),
'msg': '',
'width': width,
'height': height,
@@ -956,9 +924,7 @@ class ChemicalEquationTest(unittest.TestCase):
'STATIC_URL': '/dummy-static/',
'id': 'prob_1_2',
'value': 'H2OYeah',
- 'status': 'unanswered',
- 'status_class': 'unanswered',
- 'status_display': 'unanswered',
+ 'status': inputtypes.Status('unanswered'),
'label': '',
'msg': '',
'size': self.size,
@@ -1046,9 +1012,7 @@ class FormulaEquationTest(unittest.TestCase):
'STATIC_URL': '/dummy-static/',
'id': 'prob_1_2',
'value': 'x^2+1/2',
- 'status': 'unanswered',
- 'status_class': 'unanswered',
- 'status_display': u'unanswered',
+ 'status': inputtypes.Status('unanswered'),
'label': '',
'msg': '',
'size': self.size,
@@ -1155,20 +1119,20 @@ class DragAndDropTest(unittest.TestCase):
"target_outline": "false",
"base_image": "/dummy-static/images/about_1.png",
"draggables": [
-{"can_reuse": "", "label": "Label 1", "id": "1", "icon": "", "target_fields": []},
-{"can_reuse": "", "label": "cc", "id": "name_with_icon", "icon": "/dummy-static/images/cc.jpg", "target_fields": []},
-{"can_reuse": "", "label": "arrow-left", "id": "with_icon", "icon": "/dummy-static/images/arrow-left.png", "can_reuse": "", "target_fields": []},
-{"can_reuse": "", "label": "Label2", "id": "5", "icon": "", "can_reuse": "", "target_fields": []},
-{"can_reuse": "", "label": "Mute", "id": "2", "icon": "/dummy-static/images/mute.png", "can_reuse": "", "target_fields": []},
-{"can_reuse": "", "label": "spinner", "id": "name_label_icon3", "icon": "/dummy-static/images/spinner.gif", "can_reuse": "", "target_fields": []},
-{"can_reuse": "", "label": "Star", "id": "name4", "icon": "/dummy-static/images/volume.png", "can_reuse": "", "target_fields": []},
-{"can_reuse": "", "label": "Label3", "id": "7", "icon": "", "can_reuse": "", "target_fields": []}],
+ {"can_reuse": "", "label": "Label 1", "id": "1", "icon": "", "target_fields": []},
+ {"can_reuse": "", "label": "cc", "id": "name_with_icon", "icon": "/dummy-static/images/cc.jpg", "target_fields": []},
+ {"can_reuse": "", "label": "arrow-left", "id": "with_icon", "icon": "/dummy-static/images/arrow-left.png", "target_fields": []},
+ {"can_reuse": "", "label": "Label2", "id": "5", "icon": "", "target_fields": []},
+ {"can_reuse": "", "label": "Mute", "id": "2", "icon": "/dummy-static/images/mute.png", "target_fields": []},
+ {"can_reuse": "", "label": "spinner", "id": "name_label_icon3", "icon": "/dummy-static/images/spinner.gif", "target_fields": []},
+ {"can_reuse": "", "label": "Star", "id": "name4", "icon": "/dummy-static/images/volume.png", "target_fields": []},
+ {"can_reuse": "", "label": "Label3", "id": "7", "icon": "", "target_fields": []}],
"one_per_target": "True",
"targets": [
- {"y": "90", "x": "210", "id": "t1", "w": "90", "h": "90"},
- {"y": "160", "x": "370", "id": "t2", "w": "90", "h": "90"}
- ]
- }
+ {"y": "90", "x": "210", "id": "t1", "w": "90", "h": "90"},
+ {"y": "160", "x": "370", "id": "t2", "w": "90", "h": "90"}
+ ]
+ }
the_input = lookup_tag('drag_and_drop_input')(test_capa_system(), element, state)
@@ -1177,9 +1141,7 @@ class DragAndDropTest(unittest.TestCase):
'STATIC_URL': '/dummy-static/',
'id': 'prob_1_2',
'value': value,
- 'status': 'unsubmitted',
- 'status_class': 'unanswered',
- 'status_display': u'unanswered',
+ 'status': inputtypes.Status('unsubmitted'),
# 'label': '',
'msg': '',
'drag_and_drop_json': json.dumps(user_input)
@@ -1231,10 +1193,7 @@ class AnnotationInputTest(unittest.TestCase):
expected = {
'STATIC_URL': '/dummy-static/',
'id': 'annotation_input',
- 'value': value,
- 'status': 'answered',
- 'status_class': 'answered',
- 'status_display': 'answered',
+ 'status': inputtypes.Status('answered'),
# 'label': '',
'msg': '',
'title': 'foo',
@@ -1294,9 +1253,7 @@ class TestChoiceText(unittest.TestCase):
state = {
'value': '{}',
'id': 'choicetext_input',
- 'status': 'answered',
- 'status_class': 'answered',
- 'status_display': u'answered',
+ 'status': inputtypes.Status('answered'),
}
first_input = self.build_choice_element('numtolerance_input', 'choiceinput_0_textinput_0', 'false', '')
@@ -1352,3 +1309,63 @@ class TestChoiceText(unittest.TestCase):
"""
with self.assertRaisesRegexp(Exception, "Error in xml"):
self.check_group('checkboxtextgroup', 'invalid', 'checkbox')
+
+
+class TestStatus(unittest.TestCase):
+ """
+ Tests for Status class
+ """
+ def test_str(self):
+ """
+ Test stringifing Status objects
+ """
+ statobj = inputtypes.Status('test')
+ self.assertEqual(str(statobj), 'test')
+ self.assertEqual(unicode(statobj), u'test')
+
+ def test_classes(self):
+ """
+ Test that css classnames are correct
+ """
+ css_classes = [
+ ('unsubmitted', 'unanswered'),
+ ('incomplete', 'incorrect'),
+ ('queued', 'processing'),
+ ('correct', 'correct'),
+ ('test', 'test'),
+ ]
+ for status, classname in css_classes:
+ statobj = inputtypes.Status(status)
+ self.assertEqual(statobj.classname, classname)
+
+ def test_display_names(self):
+ """
+ Test that display names are correct
+ """
+ names = [
+ ('correct', u'correct'),
+ ('incorrect', u'incorrect'),
+ ('incomplete', u'incomplete'),
+ ('unanswered', u'unanswered'),
+ ('unsubmitted', u'unanswered'),
+ ('queued', u'processing'),
+ ('dave', u'dave'),
+ ]
+ for status, display_name in names:
+ statobj = inputtypes.Status(status)
+ self.assertEqual(statobj.display_name, display_name)
+
+ def test_translated_names(self):
+ """
+ Test that display names are "translated"
+ """
+ func = lambda t: t.upper()
+ # status is in the mapping
+ statobj = inputtypes.Status('queued', func)
+ self.assertEqual(statobj.display_name, u'PROCESSING')
+
+ # status is not in the mapping
+ statobj = inputtypes.Status('test', func)
+ self.assertEqual(statobj.display_name, u'test')
+ self.assertEqual(str(statobj), 'test')
+ self.assertEqual(statobj.classname, 'test')
diff --git a/common/lib/xmodule/xmodule/js/src/html/display.coffee b/common/lib/xmodule/xmodule/js/src/html/display.coffee
index 44c4f5e76b..c34919dc40 100644
--- a/common/lib/xmodule/xmodule/js/src/html/display.coffee
+++ b/common/lib/xmodule/xmodule/js/src/html/display.coffee
@@ -4,7 +4,8 @@ class @HTMLModule
@el = $(@element)
JavascriptLoader.executeModuleScripts(@el)
Collapsible.setCollapsibles(@el)
- MathJax.Hub.Queue ["Typeset", MathJax.Hub, @el[0]]
+ if MathJax?
+ MathJax.Hub.Queue ["Typeset", MathJax.Hub, @el[0]]
$: (selector) ->
$(selector, @el)