support descriptons for multiple inputs group
TNL-5403
This commit is contained in:
@@ -937,12 +937,26 @@ class LoncapaProblem(object):
|
||||
if len(inputfields) > 1:
|
||||
response.set('multiple_inputtypes', 'true')
|
||||
group_label_tag = response.find('label')
|
||||
group_description_tags = response.findall('description')
|
||||
group_label_tag_id = u'multiinput-group-label-{}'.format(responsetype_id)
|
||||
group_label_tag_text = ''
|
||||
if group_label_tag is not None:
|
||||
group_label_tag.tag = 'p'
|
||||
group_label_tag.set('id', responsetype_id)
|
||||
group_label_tag.set('id', group_label_tag_id)
|
||||
group_label_tag.set('class', 'multi-inputs-group-label')
|
||||
group_label_tag_text = stringify_children(group_label_tag)
|
||||
response.set('multiinput-group-label-id', group_label_tag_id)
|
||||
|
||||
group_description_ids = []
|
||||
for index, group_description_tag in enumerate(group_description_tags):
|
||||
group_description_tag_id = u'multiinput-group-description-{}-{}'.format(responsetype_id, index)
|
||||
group_description_tag.tag = 'p'
|
||||
group_description_tag.set('id', group_description_tag_id)
|
||||
group_description_tag.set('class', 'multi-inputs-group-description question-description')
|
||||
group_description_ids.append(group_description_tag_id)
|
||||
|
||||
if group_description_ids:
|
||||
response.set('multiinput-group_description_ids', ' '.join(group_description_ids))
|
||||
|
||||
for inputfield in inputfields:
|
||||
problem_data[inputfield.get('id')] = {
|
||||
|
||||
@@ -272,7 +272,12 @@ class LoncapaResponse(object):
|
||||
content = etree.SubElement(tree, 'div')
|
||||
content.set('class', 'multi-inputs-group')
|
||||
content.set('role', 'group')
|
||||
content.set('aria-labelledby', response_id)
|
||||
|
||||
if self.xml.get('multiinput-group-label-id'):
|
||||
content.set('aria-labelledby', self.xml.get('multiinput-group-label-id'))
|
||||
|
||||
if self.xml.get('multiinput-group_description_ids'):
|
||||
content.set('aria-describedby', self.xml.get('multiinput-group_description_ids'))
|
||||
else:
|
||||
content = tree
|
||||
|
||||
|
||||
@@ -468,6 +468,11 @@ class CAPAMultiInputProblemTest(unittest.TestCase):
|
||||
def assert_problem_html(self, problme_html, group_label, *input_labels):
|
||||
"""
|
||||
Verify that correct html is rendered for multiple inputtypes.
|
||||
|
||||
Arguments:
|
||||
problme_html (str): problem HTML
|
||||
group_label (str or None): multi input group label or None if label is not present
|
||||
input_labels (tuple): individual input labels
|
||||
"""
|
||||
html = etree.XML(problme_html)
|
||||
|
||||
@@ -477,12 +482,16 @@ class CAPAMultiInputProblemTest(unittest.TestCase):
|
||||
)
|
||||
self.assertEqual(len(multi_inputs_group), 1)
|
||||
|
||||
# verify that multi input group label <p> tag exists and its
|
||||
# id matches with correct multi input group aria-labelledby
|
||||
multi_inputs_group_label_id = multi_inputs_group[0].attrib.get('aria-labelledby')
|
||||
multi_inputs_group_label = html.xpath('//p[@id="{}"]'.format(multi_inputs_group_label_id))
|
||||
self.assertEqual(len(multi_inputs_group_label), 1)
|
||||
self.assertEqual(multi_inputs_group_label[0].text, group_label)
|
||||
if group_label is None:
|
||||
# if multi inputs group label is not present then there shouldn't be `aria-labelledby` attribute
|
||||
self.assertEqual(multi_inputs_group[0].attrib.get('aria-labelledby'), None)
|
||||
else:
|
||||
# verify that multi input group label <p> tag exists and its
|
||||
# id matches with correct multi input group aria-labelledby
|
||||
multi_inputs_group_label_id = multi_inputs_group[0].attrib.get('aria-labelledby')
|
||||
multi_inputs_group_label = html.xpath('//p[@id="{}"]'.format(multi_inputs_group_label_id))
|
||||
self.assertEqual(len(multi_inputs_group_label), 1)
|
||||
self.assertEqual(multi_inputs_group_label[0].text, group_label)
|
||||
|
||||
# verify that label for each input comes only once
|
||||
for input_label in input_labels:
|
||||
@@ -490,22 +499,26 @@ class CAPAMultiInputProblemTest(unittest.TestCase):
|
||||
input_label_element = multi_inputs_group[0].xpath('//*[normalize-space(text())="{}"]'.format(input_label))
|
||||
self.assertEqual(len(input_label_element), 1)
|
||||
|
||||
def test_optionresponse(self):
|
||||
@ddt.unpack
|
||||
@ddt.data(
|
||||
{'label_html': '<label>Choose the correct color</label>', 'group_label': 'Choose the correct color'},
|
||||
{'label_html': '', 'group_label': None}
|
||||
)
|
||||
def test_optionresponse(self, label_html, group_label):
|
||||
"""
|
||||
Verify that optionresponse problem with multiple inputtypes is rendered correctly.
|
||||
"""
|
||||
group_label = 'Choose the correct color'
|
||||
input1_label = 'What color is the sky?'
|
||||
input2_label = 'What color are pine needles?'
|
||||
xml = """
|
||||
<problem>
|
||||
<optionresponse>
|
||||
<label>{}</label>
|
||||
<optioninput options="('yellow','blue','green')" correct="blue" label="{}"/>
|
||||
<optioninput options="('yellow','blue','green')" correct="green" label="{}"/>
|
||||
{label_html}
|
||||
<optioninput options="('yellow','blue','green')" correct="blue" label="{input1_label}"/>
|
||||
<optioninput options="('yellow','blue','green')" correct="green" label="{input2_label}"/>
|
||||
</optionresponse>
|
||||
</problem>
|
||||
""".format(group_label, input1_label, input2_label)
|
||||
""".format(label_html=label_html, input1_label=input1_label, input2_label=input2_label)
|
||||
problem = self.capa_problem(xml)
|
||||
self.assert_problem_html(problem.get_html(), group_label, input1_label, input2_label)
|
||||
|
||||
@@ -537,3 +550,43 @@ class CAPAMultiInputProblemTest(unittest.TestCase):
|
||||
""".format(group_label, input1_label, input2_label, inputtype=inputtype))
|
||||
problem = self.capa_problem(xml)
|
||||
self.assert_problem_html(problem.get_html(), group_label, input1_label, input2_label)
|
||||
|
||||
@ddt.unpack
|
||||
@ddt.data(
|
||||
{
|
||||
'descriptions': ('desc1', 'desc2'),
|
||||
'descriptions_html': '<description>desc1</description><description>desc2</description>'
|
||||
},
|
||||
{
|
||||
'descriptions': (),
|
||||
'descriptions_html': ''
|
||||
}
|
||||
)
|
||||
def test_descriptions(self, descriptions, descriptions_html):
|
||||
"""
|
||||
Verify that groups descriptions are rendered correctly.
|
||||
"""
|
||||
xml = """
|
||||
<problem>
|
||||
<optionresponse>
|
||||
<label>group label</label>
|
||||
{descriptions_html}
|
||||
<optioninput options="('yellow','blue','green')" correct="blue" label="first label"/>
|
||||
<optioninput options="('yellow','blue','green')" correct="green" label="second label"/>
|
||||
</optionresponse>
|
||||
</problem>
|
||||
""".format(descriptions_html=descriptions_html)
|
||||
problem = self.capa_problem(xml)
|
||||
problem_html = etree.XML(problem.get_html())
|
||||
|
||||
multi_inputs_group = problem_html.xpath('//div[@class="multi-inputs-group"]')[0]
|
||||
description_ids = multi_inputs_group.attrib.get('aria-describedby', '').split()
|
||||
|
||||
# Verify that number of descriptions matches description_ids
|
||||
self.assertEqual(len(description_ids), len(descriptions))
|
||||
|
||||
# For each description, check its order and text is correct
|
||||
for index, description_id in enumerate(description_ids):
|
||||
description_element = multi_inputs_group.xpath('//p[@id="{}"]'.format(description_id))
|
||||
self.assertEqual(len(description_element), 1)
|
||||
self.assertEqual(description_element[0].text, descriptions[index])
|
||||
|
||||
Reference in New Issue
Block a user