+
% endif
% if hidden:
@@ -23,7 +23,7 @@
% for description_id, description_text in response_data['descriptions'].items():
${description_text}
% endfor
-
${trailing_text}
-
- ${status.display_tooltip}
-
+<%include file="status_span.html" args="status=status, status_id=id"/>
diff --git a/common/lib/capa/capa/tests/helpers.py b/common/lib/capa/capa/tests/helpers.py
index 8947a93552..83479d4654 100644
--- a/common/lib/capa/capa/tests/helpers.py
+++ b/common/lib/capa/capa/tests/helpers.py
@@ -22,7 +22,8 @@ def get_template(template_name):
Return template for a capa inputtype.
"""
return TemplateLookup(
- directories=[path(__file__).dirname().dirname() / 'templates']
+ directories=[path(__file__).dirname().dirname() / 'templates'],
+ default_filters=['decode.utf8']
).get_template(template_name)
diff --git a/common/lib/capa/capa/tests/test_html_render.py b/common/lib/capa/capa/tests/test_html_render.py
index c2a9491855..b5d969cc69 100644
--- a/common/lib/capa/capa/tests/test_html_render.py
+++ b/common/lib/capa/capa/tests/test_html_render.py
@@ -1,16 +1,17 @@
"""
CAPA HTML rendering tests.
"""
-import ddt
-import unittest
-from lxml import etree
-import os
import textwrap
+import unittest
+import ddt
import mock
+import os
+from capa.tests.helpers import test_capa_system, new_loncapa_problem
+from lxml import etree
+from openedx.core.djangolib.markup import HTML
from .response_xml_factory import StringResponseXMLFactory, CustomResponseXMLFactory
-from capa.tests.helpers import test_capa_system, new_loncapa_problem
@ddt.ddt
@@ -190,7 +191,7 @@ class CapaHtmlRenderTest(unittest.TestCase):
'trailing_text': '',
'size': None,
'response_data': {'label': 'Test question', 'descriptions': {}},
- 'describedby_html': ''
+ 'describedby_html': HTML('aria-describedby="status_1_2_1"')
}
expected_solution_context = {'id': '1_solution_1'}
diff --git a/common/lib/capa/capa/tests/test_input_templates.py b/common/lib/capa/capa/tests/test_input_templates.py
index a4f8eae3dd..dd3ed08e12 100644
--- a/common/lib/capa/capa/tests/test_input_templates.py
+++ b/common/lib/capa/capa/tests/test_input_templates.py
@@ -2,15 +2,16 @@
Tests for the logic in input type mako templates.
"""
-from collections import OrderedDict
-import unittest
-import capa
-import os.path
import json
-from lxml import etree
-from mako.template import Template as MakoTemplate
-from mako import exceptions
+import unittest
+from collections import OrderedDict
+
from capa.inputtypes import Status
+from capa.tests.helpers import capa_render_template
+from lxml import etree
+from mako import exceptions
+from openedx.core.djangolib.markup import HTML
+
from xmodule.stringify import stringify_children
@@ -23,7 +24,7 @@ class TemplateError(Exception):
class TemplateTestCase(unittest.TestCase):
"""
- Utilitites for testing templates.
+ Utilities for testing templates.
"""
# Subclasses override this to specify the file name of the template
@@ -46,16 +47,9 @@ class TemplateTestCase(unittest.TestCase):
def setUp(self):
"""
- Load the template under test.
+ Initialize the context.
"""
super(TemplateTestCase, self).setUp()
- capa_path = capa.__path__[0]
- self.template_path = os.path.join(capa_path,
- 'templates',
- self.TEMPLATE_NAME)
- with open(self.template_path) as f:
- self.template = MakoTemplate(f.read(), default_filters=['decode.utf8'])
-
self.context = {}
def render_to_xml(self, context_dict):
@@ -66,7 +60,7 @@ class TemplateTestCase(unittest.TestCase):
# add dummy STATIC_URL to template context
context_dict.setdefault("STATIC_URL", "/dummy-static/")
try:
- xml_str = self.template.render_unicode(**context_dict)
+ xml_str = capa_render_template(self.TEMPLATE_NAME, context_dict)
except:
raise TemplateError(exceptions.text_error_template().render())
@@ -196,10 +190,10 @@ class TemplateTestCase(unittest.TestCase):
# (used to by CSS to draw the green check / red x)
self.assert_has_text(
xml,
- "//span[@class=normalize-space('status {}')]/span[@class='sr']".format(
+ "//span[@class='status {}']/span[@class='sr']".format(
div_class if status_class else ''
),
- self.context['status'].display_tooltip
+ self.context['status'].display_name
)
def assert_label(self, xpath=None, aria_label=False):
@@ -259,7 +253,7 @@ class ChoiceGroupTemplateTest(TemplateTestCase):
'name_array_suffix': '1',
'value': '3',
'response_data': self.RESPONSE_DATA,
- 'describedby_html': self.DESCRIBEDBY,
+ 'describedby_html': HTML(self.DESCRIBEDBY),
}
def test_problem_marked_correct(self):
@@ -290,11 +284,9 @@ class ChoiceGroupTemplateTest(TemplateTestCase):
(not a particular option) is marked incorrect.
"""
conditions = [
- {'status': Status('incorrect'), 'input_type': 'radio', 'value': ''},
{'status': Status('incorrect'), 'input_type': 'checkbox', 'value': []},
{'status': Status('incorrect'), 'input_type': 'checkbox', 'value': ['2']},
{'status': Status('incorrect'), 'input_type': 'checkbox', 'value': ['2', '3']},
- {'status': Status('incomplete'), 'input_type': 'radio', 'value': ''},
{'status': Status('incomplete'), 'input_type': 'checkbox', 'value': []},
{'status': Status('incomplete'), 'input_type': 'checkbox', 'value': ['2']},
{'status': Status('incomplete'), 'input_type': 'checkbox', 'value': ['2', '3']}]
@@ -506,7 +498,7 @@ class TextlineTemplateTest(TemplateTestCase):
'preprocessor': None,
'trailing_text': None,
'response_data': self.RESPONSE_DATA,
- 'describedby_html': self.DESCRIBEDBY,
+ 'describedby_html': HTML(self.DESCRIBEDBY),
}
def test_section_class(self):
@@ -526,7 +518,7 @@ class TextlineTemplateTest(TemplateTestCase):
"""
Verify status information.
"""
- self.assert_status(status_div=True)
+ self.assert_status(status_class=True)
def test_label(self):
"""
@@ -632,7 +624,7 @@ class FormulaEquationInputTemplateTest(TemplateTestCase):
'reported_status': 'REPORTED_STATUS',
'trailing_text': None,
'response_data': self.RESPONSE_DATA,
- 'describedby_html': self.DESCRIBEDBY,
+ 'describedby_html': HTML(self.DESCRIBEDBY),
}
def test_no_size(self):
@@ -657,7 +649,7 @@ class FormulaEquationInputTemplateTest(TemplateTestCase):
"""
Verify status information.
"""
- self.assert_status(status_div=True)
+ self.assert_status(status_class=True)
def test_label(self):
"""
@@ -852,7 +844,7 @@ class OptionInputTemplateTest(TemplateTestCase):
'value': 0,
'default_option_text': 'Select an option',
'response_data': self.RESPONSE_DATA,
- 'describedby_html': self.DESCRIBEDBY,
+ 'describedby_html': HTML(self.DESCRIBEDBY),
}
def test_select_options(self):
@@ -929,8 +921,8 @@ class DragAndDropTemplateTest(TemplateTestCase):
xpath = "//div[@class='{0}']".format(expected_css_class)
self.assert_has_xpath(xml, xpath, self.context)
- # Expect a
with the status
- xpath = "//p[@class='status drag-and-drop--status']/span[@class='sr']"
+ # Expect a with the status
+ xpath = "//span[@class='status {0}']/span[@class='sr']".format(expected_css_class)
self.assert_has_text(xml, xpath, expected_text, exact=False)
def test_drag_and_drop_json_html(self):
@@ -1206,7 +1198,7 @@ class CodeinputTemplateTest(TemplateTestCase):
'aria_label': 'python editor',
'code_mirror_exit_message': 'Press ESC then TAB or click outside of the code editor to exit',
'response_data': self.RESPONSE_DATA,
- 'describedby': self.DESCRIBEDBY,
+ 'describedby': HTML(self.DESCRIBEDBY),
}
def test_label(self):
diff --git a/common/lib/capa/capa/tests/test_inputtypes.py b/common/lib/capa/capa/tests/test_inputtypes.py
index d94ab947ea..496dff0802 100644
--- a/common/lib/capa/capa/tests/test_inputtypes.py
+++ b/common/lib/capa/capa/tests/test_inputtypes.py
@@ -16,27 +16,27 @@ TODO:
- test funny xml chars -- should never get xml parse error if things are escaped properly.
"""
-from collections import OrderedDict
import json
-from lxml import etree
-from lxml.html import fromstring
-import unittest
import textwrap
+import unittest
import xml.sax.saxutils as saxutils
+from collections import OrderedDict
-from capa.tests.helpers import test_capa_system
from capa import inputtypes
from capa.checker import DemoSystem
-from mock import ANY, patch
-from pyparsing import ParseException
-
+from capa.tests.helpers import test_capa_system
from capa.xqueue_interface import XQUEUE_TIMEOUT
+from lxml import etree
+from lxml.html import fromstring
+from mock import ANY, patch
+from openedx.core.djangolib.markup import HTML
+from pyparsing import ParseException
# just a handy shortcut
lookup_tag = inputtypes.registry.get_class_for_tag
-DESCRIBEDBY = 'aria-describedby="desc-1 desc-2"'
+DESCRIBEDBY = HTML('aria-describedby="status_{status_id} desc-1 desc-2"')
DESCRIPTIONS = OrderedDict([('desc-1', 'description text 1'), ('desc-2', 'description text 2')])
RESPONSE_DATA = {
'label': 'question text 101',
@@ -67,7 +67,7 @@ class OptionInputTest(unittest.TestCase):
option_input = lookup_tag('optioninput')(test_capa_system(), element, state)
context = option_input._get_render_context() # pylint: disable=protected-access
-
+ prob_id = 'sky_input'
expected = {
'STATIC_URL': '/dummy-static/',
'value': 'Down',
@@ -75,10 +75,10 @@ class OptionInputTest(unittest.TestCase):
'status': inputtypes.Status('answered'),
'msg': '',
'inline': False,
- 'id': 'sky_input',
+ 'id': prob_id,
'default_option_text': 'Select an option',
'response_data': RESPONSE_DATA,
- 'describedby_html': DESCRIBEDBY
+ 'describedby_html': DESCRIBEDBY.format(status_id='sky_input')
}
self.assertEqual(context, expected)
@@ -147,7 +147,7 @@ class ChoiceGroupTest(unittest.TestCase):
'submitted_message': 'Answer received.',
'name_array_suffix': expected_suffix, # what is this for??
'response_data': RESPONSE_DATA,
- 'describedby_html': DESCRIBEDBY
+ 'describedby_html': DESCRIBEDBY.format(status_id='sky_input')
}
self.assertEqual(context, expected)
@@ -189,10 +189,10 @@ class JavascriptInputTest(unittest.TestCase):
the_input = lookup_tag('javascriptinput')(test_capa_system(), element, state)
context = the_input._get_render_context() # pylint: disable=protected-access
-
+ prob_id = 'prob_1_2'
expected = {
'STATIC_URL': '/dummy-static/',
- 'id': 'prob_1_2',
+ 'id': prob_id,
'status': inputtypes.Status('unanswered'),
'msg': '',
'value': '3',
@@ -201,7 +201,7 @@ class JavascriptInputTest(unittest.TestCase):
'display_class': display_class,
'problem_state': problem_state,
'response_data': RESPONSE_DATA,
- 'describedby_html': DESCRIBEDBY
+ 'describedby_html': DESCRIBEDBY.format(status_id=prob_id)
}
self.assertEqual(context, expected)
@@ -225,10 +225,10 @@ class TextLineTest(unittest.TestCase):
the_input = lookup_tag('textline')(test_capa_system(), element, state)
context = the_input._get_render_context() # pylint: disable=protected-access
-
+ prob_id = 'prob_1_2'
expected = {
'STATIC_URL': '/dummy-static/',
- 'id': 'prob_1_2',
+ 'id': prob_id,
'value': 'BumbleBee',
'status': inputtypes.Status('unanswered'),
'size': size,
@@ -239,7 +239,7 @@ class TextLineTest(unittest.TestCase):
'trailing_text': '',
'preprocessor': None,
'response_data': RESPONSE_DATA,
- 'describedby_html': DESCRIBEDBY
+ 'describedby_html': DESCRIBEDBY.format(status_id=prob_id)
}
self.assertEqual(context, expected)
@@ -261,10 +261,10 @@ class TextLineTest(unittest.TestCase):
the_input = lookup_tag('textline')(test_capa_system(), element, state)
context = the_input._get_render_context() # pylint: disable=protected-access
-
+ prob_id = 'prob_1_2'
expected = {
'STATIC_URL': '/dummy-static/',
- 'id': 'prob_1_2',
+ 'id': prob_id,
'value': 'BumbleBee',
'status': inputtypes.Status('unanswered'),
'size': size,
@@ -278,7 +278,7 @@ class TextLineTest(unittest.TestCase):
'script_src': script,
},
'response_data': RESPONSE_DATA,
- 'describedby_html': DESCRIBEDBY
+ 'describedby_html': DESCRIBEDBY.format(status_id=prob_id)
}
self.assertEqual(context, expected)
@@ -309,10 +309,10 @@ class TextLineTest(unittest.TestCase):
the_input = lookup_tag('textline')(test_capa_system(), element, state)
context = the_input._get_render_context() # pylint: disable=protected-access
-
+ prob_id = 'prob_1_2'
expected = {
'STATIC_URL': '/dummy-static/',
- 'id': 'prob_1_2',
+ 'id': prob_id,
'value': 'BumbleBee',
'status': inputtypes.Status('unanswered'),
'size': size,
@@ -323,7 +323,7 @@ class TextLineTest(unittest.TestCase):
'trailing_text': expected_text,
'preprocessor': None,
'response_data': RESPONSE_DATA,
- 'describedby_html': DESCRIBEDBY
+ 'describedby_html': DESCRIBEDBY.format(status_id=prob_id)
}
self.assertEqual(context, expected)
@@ -355,10 +355,10 @@ class FileSubmissionTest(unittest.TestCase):
the_input = input_class(test_capa_system(), element, state)
context = the_input._get_render_context() # pylint: disable=protected-access
-
+ prob_id = 'prob_1_2'
expected = {
'STATIC_URL': '/dummy-static/',
- 'id': 'prob_1_2',
+ 'id': prob_id,
'status': inputtypes.Status('queued'),
'msg': the_input.submitted_msg,
'value': 'BumbleBee.py',
@@ -366,7 +366,7 @@ class FileSubmissionTest(unittest.TestCase):
'allowed_files': '["runme.py", "nooooo.rb", "ohai.java"]',
'required_files': '["cookies.py"]',
'response_data': RESPONSE_DATA,
- 'describedby_html': DESCRIBEDBY
+ 'describedby_html': DESCRIBEDBY.format(status_id=prob_id)
}
self.assertEqual(context, expected)
@@ -407,10 +407,10 @@ class CodeInputTest(unittest.TestCase):
the_input = input_class(test_capa_system(), element, state)
context = the_input._get_render_context() # pylint: disable=protected-access
-
+ prob_id = 'prob_1_2'
expected = {
'STATIC_URL': '/dummy-static/',
- 'id': 'prob_1_2',
+ 'id': prob_id,
'value': 'print "good evening"',
'status': inputtypes.Status('queued'),
'msg': the_input.submitted_msg,
@@ -424,7 +424,7 @@ class CodeInputTest(unittest.TestCase):
'aria_label': '{mode} editor'.format(mode=mode),
'code_mirror_exit_message': 'Press ESC then TAB or click outside of the code editor to exit',
'response_data': RESPONSE_DATA,
- 'describedby_html': DESCRIBEDBY
+ 'describedby_html': DESCRIBEDBY.format(status_id=prob_id)
}
self.assertEqual(context, expected)
@@ -486,7 +486,7 @@ class MatlabTest(unittest.TestCase):
'queue_len': '3',
'matlab_editor_js': '/dummy-static/js/vendor/CodeMirror/octave.js',
'response_data': {},
- 'describedby_html': ''
+ 'describedby_html': HTML('aria-describedby="status_prob_1_2"')
}
self.assertEqual(context, expected)
@@ -503,10 +503,10 @@ class MatlabTest(unittest.TestCase):
the_input = self.input_class(test_capa_system(), elt, state)
context = the_input._get_render_context() # pylint: disable=protected-access
-
+ prob_id = 'prob_1_2'
expected = {
'STATIC_URL': '/dummy-static/',
- 'id': 'prob_1_2',
+ 'id': prob_id,
'value': 'print "good evening"',
'status': inputtypes.Status('queued'),
'msg': the_input.submitted_msg,
@@ -521,7 +521,7 @@ class MatlabTest(unittest.TestCase):
'queue_len': '3',
'matlab_editor_js': '/dummy-static/js/vendor/CodeMirror/octave.js',
'response_data': RESPONSE_DATA,
- 'describedby_html': DESCRIBEDBY
+ 'describedby_html': DESCRIBEDBY.format(status_id=prob_id)
}
self.assertEqual(context, expected)
@@ -535,12 +535,12 @@ class MatlabTest(unittest.TestCase):
'response_data': RESPONSE_DATA
}
elt = etree.fromstring(self.xml)
-
+ prob_id = 'prob_1_2'
the_input = self.input_class(test_capa_system(), elt, state)
context = the_input._get_render_context() # pylint: disable=protected-access
expected = {
'STATIC_URL': '/dummy-static/',
- 'id': 'prob_1_2',
+ 'id': prob_id,
'value': 'print "good evening"',
'status': inputtypes.Status(status),
'msg': '',
@@ -555,7 +555,7 @@ class MatlabTest(unittest.TestCase):
'queue_len': '0',
'matlab_editor_js': '/dummy-static/js/vendor/CodeMirror/octave.js',
'response_data': RESPONSE_DATA,
- 'describedby_html': DESCRIBEDBY
+ 'describedby_html': DESCRIBEDBY.format(status_id=prob_id)
}
self.assertEqual(context, expected)
@@ -569,12 +569,12 @@ class MatlabTest(unittest.TestCase):
'response_data': RESPONSE_DATA
}
elt = etree.fromstring(self.xml)
-
+ prob_id = 'prob_1_2'
the_input = self.input_class(test_capa_system(), elt, state)
context = the_input._get_render_context() # pylint: disable=protected-access
expected = {
'STATIC_URL': '/dummy-static/',
- 'id': 'prob_1_2',
+ 'id': prob_id,
'value': 'print "good evening"',
'status': inputtypes.Status('queued'),
'msg': the_input.submitted_msg,
@@ -589,7 +589,7 @@ class MatlabTest(unittest.TestCase):
'queue_len': '1',
'matlab_editor_js': '/dummy-static/js/vendor/CodeMirror/octave.js',
'response_data': RESPONSE_DATA,
- 'describedby_html': DESCRIBEDBY
+ 'describedby_html': DESCRIBEDBY.format(status_id=prob_id)
}
self.assertEqual(context, expected)
@@ -713,7 +713,8 @@ class MatlabTest(unittest.TestCase):
\'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\', \'describedby_html\': \'\',
+ \'hidden\': \'\', \'id\': \'prob_1_2\',
+ \'describedby_html\': Markup(u\'aria-describedby="status_prob_1_2"\'),
\'response_data\': {}}
""").replace('\n', ' ').strip()
)
@@ -804,9 +805,10 @@ class MatlabTest(unittest.TestCase):
context = self.the_input._get_render_context() # pylint: disable=protected-access
self.maxDiff = None
+ prob_id = 'prob_1_2'
expected = {
'STATIC_URL': '/dummy-static/',
- 'id': 'prob_1_2',
+ 'id': prob_id,
'value': 'print "good evening"',
'status': inputtypes.Status('queued'),
'msg': self.the_input.submitted_msg,
@@ -821,7 +823,7 @@ class MatlabTest(unittest.TestCase):
'queue_len': '3',
'matlab_editor_js': '/dummy-static/js/vendor/CodeMirror/octave.js',
'response_data': {},
- 'describedby_html': ''
+ 'describedby_html': 'aria-describedby="status_{id}"'.format(id=prob_id)
}
self.assertEqual(context, expected)
@@ -917,10 +919,10 @@ class SchematicTest(unittest.TestCase):
the_input = lookup_tag('schematic')(test_capa_system(), element, state)
context = the_input._get_render_context() # pylint: disable=protected-access
-
+ prob_id = 'prob_1_2'
expected = {
'STATIC_URL': '/dummy-static/',
- 'id': 'prob_1_2',
+ 'id': prob_id,
'value': value,
'status': inputtypes.Status('unsubmitted'),
'msg': '',
@@ -932,7 +934,7 @@ class SchematicTest(unittest.TestCase):
'analyses': analyses,
'submit_analyses': submit_analyses,
'response_data': RESPONSE_DATA,
- 'describedby_html': DESCRIBEDBY
+ 'describedby_html': DESCRIBEDBY.format(status_id=prob_id)
}
self.assertEqual(context, expected)
@@ -965,10 +967,10 @@ class ImageInputTest(unittest.TestCase):
the_input = lookup_tag('imageinput')(test_capa_system(), element, state)
context = the_input._get_render_context() # pylint: disable=protected-access
-
+ prob_id = 'prob_1_2'
expected = {
'STATIC_URL': '/dummy-static/',
- 'id': 'prob_1_2',
+ 'id': prob_id,
'value': value,
'status': inputtypes.Status('unsubmitted'),
'width': width,
@@ -978,7 +980,7 @@ class ImageInputTest(unittest.TestCase):
'gy': egy,
'msg': '',
'response_data': RESPONSE_DATA,
- 'describedby_html': DESCRIBEDBY
+ 'describedby_html': DESCRIBEDBY.format(status_id=prob_id)
}
self.assertEqual(context, expected)
@@ -1024,17 +1026,17 @@ class CrystallographyTest(unittest.TestCase):
the_input = lookup_tag('crystallography')(test_capa_system(), element, state)
context = the_input._get_render_context() # pylint: disable=protected-access
-
+ prob_id = 'prob_1_2'
expected = {
'STATIC_URL': '/dummy-static/',
- 'id': 'prob_1_2',
+ 'id': prob_id,
'value': value,
'status': inputtypes.Status('unsubmitted'),
'msg': '',
'width': width,
'height': height,
'response_data': RESPONSE_DATA,
- 'describedby_html': DESCRIBEDBY
+ 'describedby_html': DESCRIBEDBY.format(status_id=prob_id)
}
self.assertEqual(context, expected)
@@ -1070,10 +1072,10 @@ class VseprTest(unittest.TestCase):
the_input = lookup_tag('vsepr_input')(test_capa_system(), element, state)
context = the_input._get_render_context() # pylint: disable=protected-access
-
+ prob_id = 'prob_1_2'
expected = {
'STATIC_URL': '/dummy-static/',
- 'id': 'prob_1_2',
+ 'id': prob_id,
'value': value,
'status': inputtypes.Status('unsubmitted'),
'msg': '',
@@ -1082,7 +1084,7 @@ class VseprTest(unittest.TestCase):
'molecules': molecules,
'geometries': geometries,
'response_data': RESPONSE_DATA,
- 'describedby_html': DESCRIBEDBY
+ 'describedby_html': DESCRIBEDBY.format(status_id=prob_id)
}
self.assertEqual(context, expected)
@@ -1108,17 +1110,17 @@ class ChemicalEquationTest(unittest.TestCase):
def test_rendering(self):
''' Verify that the render context matches the expected render context'''
context = self.the_input._get_render_context() # pylint: disable=protected-access
-
+ prob_id = 'prob_1_2'
expected = {
'STATIC_URL': '/dummy-static/',
- 'id': 'prob_1_2',
+ 'id': prob_id,
'value': 'H2OYeah',
'status': inputtypes.Status('unanswered'),
'msg': '',
'size': self.size,
'previewer': '/dummy-static/js/capa/chemical_equation_preview.js',
'response_data': RESPONSE_DATA,
- 'describedby_html': DESCRIBEDBY
+ 'describedby_html': DESCRIBEDBY.format(status_id=prob_id)
}
self.assertEqual(context, expected)
@@ -1201,10 +1203,10 @@ class FormulaEquationTest(unittest.TestCase):
Verify that the render context matches the expected render context
"""
context = self.the_input._get_render_context() # pylint: disable=protected-access
-
+ prob_id = 'prob_1_2'
expected = {
'STATIC_URL': '/dummy-static/',
- 'id': 'prob_1_2',
+ 'id': prob_id,
'value': 'x^2+1/2',
'status': inputtypes.Status('unanswered'),
'msg': '',
@@ -1213,7 +1215,7 @@ class FormulaEquationTest(unittest.TestCase):
'inline': False,
'trailing_text': '',
'response_data': RESPONSE_DATA,
- 'describedby_html': DESCRIBEDBY
+ 'describedby_html': DESCRIBEDBY.format(status_id=prob_id)
}
self.assertEqual(context, expected)
@@ -1247,10 +1249,10 @@ class FormulaEquationTest(unittest.TestCase):
the_input = lookup_tag('formulaequationinput')(test_capa_system(), element, state)
context = the_input._get_render_context() # pylint: disable=protected-access
-
+ prob_id = 'prob_1_2'
expected = {
'STATIC_URL': '/dummy-static/',
- 'id': 'prob_1_2',
+ 'id': prob_id,
'value': 'x^2+1/2',
'status': inputtypes.Status('unanswered'),
'msg': '',
@@ -1259,7 +1261,7 @@ class FormulaEquationTest(unittest.TestCase):
'inline': False,
'trailing_text': expected_text,
'response_data': RESPONSE_DATA,
- 'describedby_html': DESCRIBEDBY
+ 'describedby_html': DESCRIBEDBY.format(status_id=prob_id)
}
self.assertEqual(context, expected)
@@ -1381,17 +1383,17 @@ class DragAndDropTest(unittest.TestCase):
}
the_input = lookup_tag('drag_and_drop_input')(test_capa_system(), element, state)
-
+ prob_id = 'prob_1_2'
context = the_input._get_render_context() # pylint: disable=protected-access
expected = {
'STATIC_URL': '/dummy-static/',
- 'id': 'prob_1_2',
+ 'id': prob_id,
'value': value,
'status': inputtypes.Status('unsubmitted'),
'msg': '',
'drag_and_drop_json': json.dumps(user_input),
'response_data': RESPONSE_DATA,
- 'describedby_html': DESCRIBEDBY
+ 'describedby_html': DESCRIBEDBY.format(status_id=prob_id)
}
# as we are dumping 'draggables' dicts while dumping user_input, string
@@ -1437,10 +1439,10 @@ class AnnotationInputTest(unittest.TestCase):
the_input = lookup_tag(tag)(test_capa_system(), element, state)
context = the_input._get_render_context() # pylint: disable=protected-access
-
+ prob_id = 'annotation_input'
expected = {
'STATIC_URL': '/dummy-static/',
- 'id': 'annotation_input',
+ 'id': prob_id,
'status': inputtypes.Status('answered'),
'msg': '',
'title': 'foo',
@@ -1460,7 +1462,7 @@ class AnnotationInputTest(unittest.TestCase):
'debug': False,
'return_to_annotation': True,
'response_data': RESPONSE_DATA,
- 'describedby_html': DESCRIBEDBY
+ 'describedby_html': DESCRIBEDBY.format(status_id=prob_id)
}
self.maxDiff = None
@@ -1499,9 +1501,10 @@ class TestChoiceText(unittest.TestCase):
{tag}>
""".format(tag=tag, choice_tag=choice_tag)
element = etree.fromstring(xml_str)
+ prob_id = 'choicetext_input'
state = {
'value': '{}',
- 'id': 'choicetext_input',
+ 'id': prob_id,
'status': inputtypes.Status('answered'),
'response_data': RESPONSE_DATA
}
@@ -1516,7 +1519,6 @@ class TestChoiceText(unittest.TestCase):
('choiceinput_0', [first_choice_content, first_input]),
('choiceinput_1', [second_choice_content, second_input, second_choice_text])
]
-
expected = {
'STATIC_URL': '/dummy-static/',
'msg': '',
@@ -1525,7 +1527,7 @@ class TestChoiceText(unittest.TestCase):
'show_correctness': 'always',
'submitted_message': 'Answer received.',
'response_data': RESPONSE_DATA,
- 'describedby_html': DESCRIBEDBY
+ 'describedby_html': DESCRIBEDBY.format(status_id=prob_id)
}
expected.update(state)
the_input = lookup_tag(tag)(test_capa_system(), element, state)
diff --git a/common/lib/xmodule/xmodule/css/capa/display.scss b/common/lib/xmodule/xmodule/css/capa/display.scss
index 013cdf078f..212a5e834d 100644
--- a/common/lib/xmodule/xmodule/css/capa/display.scss
+++ b/common/lib/xmodule/xmodule/css/capa/display.scss
@@ -23,9 +23,6 @@
// ====================
$annotation-yellow: rgba(255,255,10,0.3);
$color-copy-tip: rgb(100,100,100);
-$correct: $green-d2;
-$partially-correct: $green-d2;
-$incorrect: $red;
// FontAwesome Icon code
// ====================
@@ -50,11 +47,13 @@ $asterisk-icon: '\f069'; // .fa-asterisk
// ====================
@mixin status-icon($color: $gray, $fontAwesomeIcon: "\f00d"){
- &:after {
- @extend %use-font-awesome;
- color: $color;
- font-size: 1.2em;
- content: $fontAwesomeIcon;
+ .status-icon {
+ &:after {
+ @extend %use-font-awesome;
+ color: $color;
+ font-size: 1.2em;
+ content: $fontAwesomeIcon;
+ }
}
}
@@ -318,6 +317,12 @@ div.problem {
@include status-icon($incorrect, $cross-icon);
}
+ &.unsubmitted,
+ &.unanswered {
+ .status-icon {
+ content: '';
+ }
+ }
}
}
}
@@ -818,12 +823,14 @@ div.problem {
}
.status {
- &:after {
- content: ''; // clear out correct or incorrect icon
+ .status-icon {
+ &:after {
+ content: '';
+ }
}
}
-
}
+
}
.trailing_text {
diff --git a/common/lib/xmodule/xmodule/js/src/capa/display.js b/common/lib/xmodule/xmodule/js/src/capa/display.js
index d24e4f98e3..bf65745fb8 100644
--- a/common/lib/xmodule/xmodule/js/src/capa/display.js
+++ b/common/lib/xmodule/xmodule/js/src/capa/display.js
@@ -962,7 +962,6 @@
$status = $('#status_' + id);
if ($status[0]) {
$status.removeClass().addClass('unanswered');
- $status.empty().css('display', 'inline-block');
} else {
$('
', {
class: 'unanswered',
@@ -979,8 +978,8 @@
id = ($select.attr('id').match(/^input_(.*)$/))[1];
return $select.on('change', function() {
return $('#status_' + id).removeClass().addClass('unanswered')
- .find('span')
- .text(gettext('Status: unsubmitted'));
+ .find('.sr')
+ .text(gettext('unsubmitted'));
});
},
textline: function(element) {
diff --git a/common/static/sass/edx-pattern-library-shims/base/_variables.scss b/common/static/sass/edx-pattern-library-shims/base/_variables.scss
index def96c46c2..317eb2fa5a 100644
--- a/common/static/sass/edx-pattern-library-shims/base/_variables.scss
+++ b/common/static/sass/edx-pattern-library-shims/base/_variables.scss
@@ -144,6 +144,13 @@ $success-color: rgb(0, 155, 0) !default;
$warning-color: rgb(255, 192, 31) !default;
$warning-color-accent: rgb(255, 252, 221) !default;
+
+// CAPA correctness color to be consistent with Alert styles above
+$correct: $success-color;
+$partially-correct: $success-color;
+$incorrect: $error-color;
+
+
// BUTTONS
// disabled button
diff --git a/lms/djangoapps/instructor_task/tests/test_tasks_helper.py b/lms/djangoapps/instructor_task/tests/test_tasks_helper.py
index 12b3d4681d..19ebc28a6a 100644
--- a/lms/djangoapps/instructor_task/tests/test_tasks_helper.py
+++ b/lms/djangoapps/instructor_task/tests/test_tasks_helper.py
@@ -617,12 +617,12 @@ class TestProblemGradeReport(TestReportMixin, InstructorTaskModuleTestCase):
metadata={'graded': True},
display_name='Problem Vertical'
)
- self.define_option_problem(u'Pröblem1', parent=vertical)
+ self.define_option_problem(u'Problem1', parent=vertical)
- self.submit_student_answer(self.student_1.username, u'Pröblem1', ['Option 1'])
+ self.submit_student_answer(self.student_1.username, u'Problem1', ['Option 1'])
result = upload_problem_grade_report(None, None, self.course.id, None, 'graded')
self.assertDictContainsSubset({'action_name': 'graded', 'attempted': 2, 'succeeded': 2, 'failed': 0}, result)
- problem_name = u'Homework 1: Problem - Pröblem1'
+ problem_name = u'Homework 1: Problem - Problem1'
header_row = self.csv_header_row + [problem_name + ' (Earned)', problem_name + ' (Possible)']
self.verify_rows_in_csv([
dict(zip(
@@ -646,7 +646,7 @@ class TestProblemGradeReport(TestReportMixin, InstructorTaskModuleTestCase):
@patch('lms.djangoapps.instructor_task.tasks_helper._get_current_task')
@patch('lms.djangoapps.instructor_task.tasks_helper.iterate_grades_for')
- @ddt.data(u'Cannöt grade student', '')
+ @ddt.data(u'Cannot grade student', '')
def test_grading_failure(self, error_message, mock_iterate_grades_for, _mock_current_task):
"""
Test that any grading errors are properly reported in the progress
@@ -683,8 +683,8 @@ class TestProblemReportSplitTestContent(TestReportMixin, TestConditionalContent,
def setUp(self):
super(TestProblemReportSplitTestContent, self).setUp()
- self.problem_a_url = u'pröblem_a_url'
- self.problem_b_url = u'pröblem_b_url'
+ self.problem_a_url = u'problem_a_url'
+ self.problem_b_url = u'problem_b_url'
self.define_option_problem(self.problem_a_url, parent=self.vertical_a)
self.define_option_problem(self.problem_b_url, parent=self.vertical_b)
@@ -711,7 +711,7 @@ class TestProblemReportSplitTestContent(TestReportMixin, TestConditionalContent,
{'action_name': 'graded', 'attempted': 2, 'succeeded': 2, 'failed': 0}, result
)
- problem_names = [u'Homework 1: Problem - pröblem_a_url', u'Homework 1: Problem - pröblem_b_url']
+ problem_names = [u'Homework 1: Problem - problem_a_url', u'Homework 1: Problem - problem_b_url']
header_row = [u'Student ID', u'Email', u'Username', u'Final Grade']
for problem in problem_names:
header_row += [problem + ' (Earned)', problem + ' (Possible)']
@@ -817,12 +817,12 @@ class TestProblemReportCohortedContent(TestReportMixin, ContentGroupTestCase, In
display_name='Problem Vertical'
)
self.define_option_problem(
- u"Pröblem0",
+ u"Problem0",
parent=vertical,
group_access={self.course.user_partitions[0].id: [self.course.user_partitions[0].groups[0].id]}
)
self.define_option_problem(
- u"Pröblem1",
+ u"Problem1",
parent=vertical,
group_access={self.course.user_partitions[0].id: [self.course.user_partitions[0].groups[1].id]}
)
@@ -845,20 +845,20 @@ class TestProblemReportCohortedContent(TestReportMixin, ContentGroupTestCase, In
))
def test_cohort_content(self):
- self.submit_student_answer(self.alpha_user.username, u'Pröblem0', ['Option 1', 'Option 1'])
- resp = self.submit_student_answer(self.alpha_user.username, u'Pröblem1', ['Option 1', 'Option 1'])
+ self.submit_student_answer(self.alpha_user.username, u'Problem0', ['Option 1', 'Option 1'])
+ resp = self.submit_student_answer(self.alpha_user.username, u'Problem1', ['Option 1', 'Option 1'])
self.assertEqual(resp.status_code, 404)
- resp = self.submit_student_answer(self.beta_user.username, u'Pröblem0', ['Option 1', 'Option 2'])
+ resp = self.submit_student_answer(self.beta_user.username, u'Problem0', ['Option 1', 'Option 2'])
self.assertEqual(resp.status_code, 404)
- self.submit_student_answer(self.beta_user.username, u'Pröblem1', ['Option 1', 'Option 2'])
+ self.submit_student_answer(self.beta_user.username, u'Problem1', ['Option 1', 'Option 2'])
with patch('lms.djangoapps.instructor_task.tasks_helper._get_current_task'):
result = upload_problem_grade_report(None, None, self.course.id, None, 'graded')
self.assertDictContainsSubset(
{'action_name': 'graded', 'attempted': 4, 'succeeded': 4, 'failed': 0}, result
)
- problem_names = [u'Homework 1: Problem - Pröblem0', u'Homework 1: Problem - Pröblem1']
+ problem_names = [u'Homework 1: Problem - Problem0', u'Homework 1: Problem - Problem1']
header_row = [u'Student ID', u'Email', u'Username', u'Final Grade']
for problem in problem_names:
header_row += [problem + ' (Earned)', problem + ' (Possible)']