Skip to content

Commit 614b057

Browse files
committed
bugfixes, tests for accessibility labels
1 parent b0ff235 commit 614b057

File tree

4 files changed

+129
-12
lines changed

4 files changed

+129
-12
lines changed

renderer.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,6 @@ protected function create_dropdown_mc_answer(qtype_formulas_part $part, $answeri
311311
$currentanswer = $qa->get_last_qt_var($variablename);
312312
$inputname = $qa->get_qt_field_name($variablename);
313313

314-
$inputattributes['type'] = 'radio';
315314
$inputattributes['name'] = $inputname;
316315
$inputattributes['value'] = $currentanswer;
317316
$inputattributes['id'] = $inputname;
@@ -426,7 +425,7 @@ protected function create_input_box(qtype_formulas_part $part, $answerindex,
426425
// Examples are "Answer field for part X", "Answer field X for part Y" or "Answer and unit for part X".
427426
$labeldata = new stdClass();
428427
$labelstring = 'answer';
429-
if (substr($variablename, -2) === '_u') {
428+
if ($answerindex === self::UNIT_FIELD) {
430429
$labelstring .= 'unit';
431430
} else if (substr($variablename, -1) === '_') {
432431
$labelstring .= 'combinedunit';
@@ -447,7 +446,6 @@ protected function create_input_box(qtype_formulas_part $part, $answerindex,
447446

448447
$output = $label['html'];
449448
$output .= html_writer::empty_tag('input', $inputattributes);
450-
$output .= html_writer::end_tag('span');
451449

452450
return $output;
453451
}

tests/helper.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ protected static function make_a_formulas_question() {
9898
*
9999
* @return qtype_formulas_part
100100
*/
101-
protected static function make_a_formulas_part(): qtype_formulas_part {
101+
public static function make_a_formulas_part(): qtype_formulas_part {
102102
question_bank::load_question_definition_classes('formulas');
103103

104104
$p = new qtype_formulas_part();

tests/question_test.php

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
* @covers \qtype_formulas_part
4848
* @covers \qtype_formulas
4949
*/
50-
final class question_test extends \basic_testcase {
50+
final class question_test extends \advanced_testcase {
5151

5252
/**
5353
* Create a question object of a certain type, as defined in the helper.php file.
@@ -476,6 +476,30 @@ public function test_get_question_summary_threeparts(): void {
476476
$q->get_question_summary());
477477
}
478478

479+
public function test_translate_mc_answers_for_feedback(): void {
480+
$q = $this->get_test_formulas_question('testsinglenum');
481+
482+
// Change the part's text to use a multi-choice answer field.
483+
$q->varsglobal = 'options = ["foo", "bar"]';
484+
$q->parts[0]->subqtext = '{_0:options}';
485+
486+
// Start the attempt (to initialize everything) and check the translation works.
487+
$q->start_attempt(new question_attempt_step(), 1);
488+
$translation = $q->parts[0]->translate_mc_answers_for_feedback(['0_0' => '1']);
489+
self::assertArrayHasKey('0_0', $translation);
490+
self::assertEquals('bar', $translation['0_0']);
491+
492+
// Change the variable reference to a bad name and check whether the error is caught.
493+
$q->parts[0]->subqtext = '{_0:xxx}';
494+
$q->start_attempt(new question_attempt_step(), 1);
495+
$translation = $q->parts[0]->translate_mc_answers_for_feedback(['0_0' => '1']);
496+
self::assertDebuggingCalled(
497+
'Could not translate multiple choice index back to its value. This should not happen. Please file a bug report.'
498+
);
499+
self::assertArrayHasKey('0_0', $translation);
500+
self::assertEquals('1', $translation['0_0']);
501+
}
502+
479503
public function test_get_question_summary_test2(): void {
480504
$q = $this->get_test_formulas_question('test4');
481505
$q->start_attempt(new question_attempt_step(), 1);

tests/renderer_test.php

Lines changed: 102 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -311,26 +311,42 @@ public function test_render_mc_question(): void {
311311
$this->get_contains_num_parts_correct(1)
312312
);
313313
$this->check_current_mark(0.7);
314+
315+
// Restart with immediate feedback to check the radio box is disabled when showing the feedback.
316+
$this->start_attempt_at_question($q, 'immediatefeedback', 1);
317+
$this->process_submission(['0_0' => '1', '-submit' => 1]);
318+
$this->check_current_output(
319+
$this->get_contains_radio_expectation(['id' => $this->quba->get_field_prefix($this->slot) . '0_0_0'], false, false),
320+
$this->get_contains_radio_expectation(['id' => $this->quba->get_field_prefix($this->slot) . '0_0_1'], false, true),
321+
$this->get_contains_radio_expectation(['id' => $this->quba->get_field_prefix($this->slot) . '0_0_2'], false, false),
322+
$this->get_contains_radio_expectation(['id' => $this->quba->get_field_prefix($this->slot) . '0_0_3'], false, false),
323+
);
314324
}
315325

316326
public function test_render_mce_question(): void {
317-
// Create a single part multiple choice (radio) question.
327+
// Create a single part multiple choice (dropdown) question.
318328
$q = $this->get_test_formulas_question('testmce');
319329
$this->start_attempt_at_question($q, 'immediatefeedback', 1);
320330

321331
$this->render();
322-
$this->check_output_contains_selectoptions(
323-
$this->get_contains_select_expectation('0_0', ['Dog', 'Cat', 'Bird', 'Fish'])
324-
);
332+
// Using check_current_output to make sure that the <select> is actually there. Using
333+
// check_output_contains_selectoptions only makes sure that the options are there
334+
// *among* existing <select>s; if no <select> is there, the options do not need to exist.
325335
$this->check_current_output(
326-
$this->get_does_not_contain_specific_feedback_expectation()
336+
new \question_contains_tag_with_attribute('select', 'name', $this->quba->get_field_prefix($this->slot) . '0_0'),
337+
$this->get_does_not_contain_specific_feedback_expectation(),
338+
new \question_contains_tag_with_contents('label', 'Answer'),
339+
new \question_contains_tag_with_attribute('label', 'class', 'subq accesshide'),
340+
);
341+
$this->check_output_contains_selectoptions(
342+
$this->get_contains_select_expectation('0_0', ['Dog', 'Cat', 'Bird', 'Fish'], 0)
327343
);
328344

329345
// Submit wrong answer.
330346
$this->process_submission(['0_0' => '0', '-submit' => 1]);
331347
$this->check_current_state(question_state::$gradedwrong);
332348
$this->check_output_contains_selectoptions(
333-
$this->get_contains_select_expectation('0_0', ['Dog', 'Cat', 'Bird', 'Fish'], 0)
349+
$this->get_contains_select_expectation('0_0', ['Dog', 'Cat', 'Bird', 'Fish'], 0)
334350
);
335351
$this->check_current_mark(0);
336352
$this->check_output_contains_lang_string('correctansweris', 'qtype_formulas', 'Cat');
@@ -340,12 +356,91 @@ public function test_render_mce_question(): void {
340356
$this->process_submission(['0_0' => '1', '-submit' => 1]);
341357
$this->check_current_state(question_state::$gradedright);
342358
$this->check_output_contains_selectoptions(
343-
$this->get_contains_select_expectation('0_0', ['Dog', 'Cat', 'Bird', 'Fish'], 1)
359+
$this->get_contains_select_expectation('0_0', ['Dog', 'Cat', 'Bird', 'Fish'], 1, false)
344360
);
345361
$this->check_current_mark(1);
346362
$this->check_output_contains_lang_string('correctansweris', 'qtype_formulas', 'Cat');
347363
}
348364

365+
public function test_render_mc_question_with_missing_options(): void {
366+
// Create a single part multiple choice (dropdown) question.
367+
$q = $this->get_test_formulas_question('testmce');
368+
$q->parts[0]->subqtext = '{_0:xxxx}';
369+
$this->start_attempt_at_question($q, 'immediatefeedback', 1);
370+
371+
$this->render();
372+
// The options are not available, so a text box should be rendered instead.
373+
$this->check_output_contains_text_input('0_0', '', true);
374+
$this->check_current_output(
375+
new \question_contains_tag_with_contents('label', 'Answer'),
376+
);
377+
378+
// Create a single part multiple choice (radio) question.
379+
$q = $this->get_test_formulas_question('testmc');
380+
$q->parts[0]->subqtext = '{_0:xxxx}';
381+
$this->start_attempt_at_question($q, 'immediatefeedback', 1);
382+
383+
$this->render();
384+
// The options are not available, so a text box should be rendered instead.
385+
$this->check_output_contains_text_input('0_0', '', true);
386+
$this->check_current_output(
387+
new \question_contains_tag_with_contents('label', 'Answer'),
388+
);
389+
}
390+
391+
public function test_render_mce_accessibility_labels(): void {
392+
// FIXME: also with no other answer field
393+
// Create a single part multiple choice (dropdown) question.
394+
$q = $this->get_test_formulas_question('testmce');
395+
$q->parts[0]->numbox = 2;
396+
$q->parts[0]->answer = '[1, 1]';
397+
398+
$this->start_attempt_at_question($q, 'immediatefeedback', 1);
399+
$this->check_current_output(
400+
new \question_contains_tag_with_contents('label', 'Answer field 1'),
401+
new \question_contains_tag_with_contents('label', 'Answer field 2'),
402+
);
403+
404+
// Create a two-part multiple choice (dropdown) question.
405+
$q->numparts = 2;
406+
$q->textfragments = [0 => $q->parts[0]->subqtext, 1 => '', 2 => ''];
407+
$q->parts[] = qtype_formulas_test_helper::make_a_formulas_part();
408+
$q->parts[1]->numbox = 2;
409+
$q->parts[1]->partindex = 1;
410+
$q->parts[1]->answer = '[1, 1]';
411+
412+
$this->start_attempt_at_question($q, 'immediatefeedback', 1);
413+
$this->check_current_output(
414+
new \question_contains_tag_with_contents('label', 'Answer field 1 for part 1'),
415+
new \question_contains_tag_with_contents('label', 'Answer field 2 for part 1'),
416+
new \question_contains_tag_with_contents('label', 'Answer field 1 for part 2'),
417+
new \question_contains_tag_with_contents('label', 'Answer field 2 for part 2'),
418+
);
419+
}
420+
421+
public function test_render_textbox_accessibility_labels(): void {
422+
// Create a multi-part question with a combined and a separate unit field.
423+
$q = $this->get_test_formulas_question('testmethodsinparts');
424+
$this->start_attempt_at_question($q, 'immediatefeedback', 1);
425+
$this->check_current_output(
426+
new \question_contains_tag_with_contents('label', 'Answer and unit for part 1'),
427+
new \question_contains_tag_with_contents('label', 'Answer for part 2'),
428+
new \question_contains_tag_with_contents('label', 'Unit for part 2'),
429+
new \question_contains_tag_with_contents('label', 'Answer for part 3'),
430+
new \question_contains_tag_with_contents('label', 'Answer for part 4'),
431+
);
432+
433+
// Create a multi-part question with a combined and a separate unit field.
434+
$q = $this->get_test_formulas_question('testtwoandtwo');
435+
$this->start_attempt_at_question($q, 'immediatefeedback', 1);
436+
$this->check_current_output(
437+
new \question_contains_tag_with_contents('label', 'Answer field 1 for part 1'),
438+
new \question_contains_tag_with_contents('label', 'Answer field 2 for part 1'),
439+
new \question_contains_tag_with_contents('label', 'Answer field 1 for part 2'),
440+
new \question_contains_tag_with_contents('label', 'Answer field 2 for part 2'),
441+
);
442+
}
443+
349444
public function test_question_with_hint(): void {
350445
// Create a single part multiple choice (radio) question.
351446
$q = $this->get_test_formulas_question('testsinglenum');

0 commit comments

Comments
 (0)