From 2e95ee0fb2a96cd0ea36d18f1a97afdd968cd5ab Mon Sep 17 00:00:00 2001 From: Laurent David Date: Tue, 8 Aug 2023 07:25:28 +0200 Subject: [PATCH] MDL-71414 mod_h5pactivity: Add a new "None" message * In matching types of questions, sometimes the user does not answer all questions. We now display "None" in the result report. The answer can be either correct or incorrect. * Fix "unknown" answer constant name. --- mod/h5pactivity/classes/output/result.php | 4 +- .../classes/output/result/matching.php | 8 +- mod/h5pactivity/lang/en/h5pactivity.php | 3 +- .../tests/output/result/result_test.php | 253 ++++++++++-------- 4 files changed, 149 insertions(+), 119 deletions(-) diff --git a/mod/h5pactivity/classes/output/result.php b/mod/h5pactivity/classes/output/result.php index acb8339d8ea..67f681ae2b7 100644 --- a/mod/h5pactivity/classes/output/result.php +++ b/mod/h5pactivity/classes/output/result.php @@ -57,7 +57,7 @@ class result implements renderable, templatable { /** Pass answer state. */ const FAIL = 6; - /** Unkown answer state. */ + /** Unknown answer state. */ const UNKNOWN = 7; /** Text answer state. */ @@ -284,7 +284,7 @@ class result implements renderable, templatable { self::UNCHECKED => 'unchecked', self::PASS => 'pass', self::FAIL => 'fail', - self::UNKNOWN => 'unkown', + self::UNKNOWN => 'unknown', self::TEXT => 'text', ]; $state = $states[$state] ?? self::UNKNOWN; diff --git a/mod/h5pactivity/classes/output/result/matching.php b/mod/h5pactivity/classes/output/result/matching.php index 2979fa183a8..6fd415eb32b 100644 --- a/mod/h5pactivity/classes/output/result/matching.php +++ b/mod/h5pactivity/classes/output/result/matching.php @@ -107,7 +107,13 @@ class matching extends result { // Fill in unchecked options. foreach ($options as $option) { if (!isset($option->useranswer)) { - $option->useranswer = $this->get_answer(parent::UNCHECKED, ''); + if (!empty($option->correctanswers)) { + $option->useranswer = $this->get_answer(parent::INCORRECT, + get_string('answer_noanswer', 'mod_h5pactivity')); + } else { + $option->useranswer = $this->get_answer(parent::CORRECT, + get_string('answer_noanswer', 'mod_h5pactivity')); + } } } diff --git a/mod/h5pactivity/lang/en/h5pactivity.php b/mod/h5pactivity/lang/en/h5pactivity.php index 136642ea3f9..0cc0f89e6ef 100644 --- a/mod/h5pactivity/lang/en/h5pactivity.php +++ b/mod/h5pactivity/lang/en/h5pactivity.php @@ -32,8 +32,9 @@ $string['answer_fail'] = 'Incorrect answer'; $string['answer_incorrect'] = 'Your answer is incorrect'; $string['answer_pass'] = 'Correct answer'; $string['answer_unchecked'] = 'Answer unchecked'; -$string['answer_unknown'] = 'Unknown answer'; +$string['answer_unknown'] = 'Unkown answer'; $string['answer_text'] = 'Answer text'; +$string['answer_noanswer'] = 'None'; $string['areapackage'] = 'Package file'; $string['attempt'] = 'Attempt'; $string['attempt_average'] = 'Attempts average scored'; diff --git a/mod/h5pactivity/tests/output/result/result_test.php b/mod/h5pactivity/tests/output/result/result_test.php index 297b84f14f6..64184abd78f 100644 --- a/mod/h5pactivity/tests/output/result/result_test.php +++ b/mod/h5pactivity/tests/output/result/result_test.php @@ -28,6 +28,144 @@ use mod_h5pactivity\local\manager; * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class result_test extends \advanced_testcase { + /** + * Data provider for result export_options test + * + * @return array[] + */ + public static function result_data_provider(): array { + return [ + 'fill-in with case sensitive' => [ + 'result' => [ + 'interactiontype' => 'fill-in', + 'description' => '

Fill in the missing words

+

Meow .... this is a __________

+

Bark... this is a __________

', + 'correctpattern' => '["{case_matters=true}cat[,]dog"]', + 'response' => 'Cat[,]dog', + 'additionals' => '{"extensions":{"http:\\/\\/h5p.org\\/x-api\\/h5p-local-content-id":31,' + . '"https:\\/\\/h5p.org\\/x-api\\/case-sensitivity":true,' + . '"https:\\/\\/h5p.org\\/x-api\\/alternatives":[["cat"],["dog"]]},"contextExtensions":{}}', + ], + 'useranswers' => [ + 'Gap #1 - cat' => (object) ['answer' => 'Cat', 'incorrect' => true], + 'Gap #2 - dog' => (object) ['answer' => 'dog', 'correct' => true], + ], + ], + 'fill-in with case insensitive' => [ + 'result' => [ + 'interactiontype' => 'fill-in', + 'description' => '

Fill in the missing words

+

Meow .... this is a __________

+

Bark... this is a __________

', + 'correctpattern' => '["{case_matters=false}cat[,]dog"]', + 'response' => 'Cat[,]dog', + 'additionals' => '{"extensions":{"http:\\/\\/h5p.org\\/x-api\\/h5p-local-content-id":31,' + . '"https:\\/\\/h5p.org\\/x-api\\/case-sensitivity":false,' + . '"https:\\/\\/h5p.org\\/x-api\\/alternatives":[["cat"],["dog"]]},"contextExtensions":{}}', + ], + 'useranswers' => [ + 'Gap #1 - cat' => (object) ['answer' => 'Cat', 'correct' => true], + 'Gap #2 - dog' => (object) ['answer' => 'dog', 'correct' => true], + ], + ], + 'drag and drop' => [ + 'result' => [ + 'interactiontype' => 'matching', + 'description' => 'Drag and Drop Test', + 'correctpattern' => '["0[.]0[,]0[.]2[,]1[.]1[,]1[.]0"]', + 'response' => '0[.]0[,]1[.]1[,]0[.]2[,]0[.]3', + 'additionals' => '{"source":[{"id":"0","description":{"en-US":"Answer 1 (DZ1 and DZ2)\n"}},' + . '{"id":"1","description":{"en-US":"Anwser 2 (DZ2)\n"}},' + . '{"id":"2","description":{"en-US":"Anwser 3 (DZ1)\n"}},' + . '{"id":"3","description":{"en-US":"Anwser 4 (neither)\n"}}],' + . '"target":[{"id":"0","description":{"en-US":"Dropzone 1\n"}},' + . '{"id":"1","description":{"en-US":"Dropzone 2\n"}}],' + . '"extensions":{"http:\/\/h5p.org\/x-api\/h5p-local-content-id":41,' + . '"http:\/\/h5p.org\/x-api\/h5p-subContentId":"59590246-f16e-4855-8dd6-c80e892ef96b"},' + . '"contextExtensions":{}}', + ], + 'useranswers' => [ + 'Answer 1 (DZ1 and DZ2) - Dropzone 1, Dropzone 2' => (object) ['answer' => 'Dropzone 1', 'correct' => true], + 'Anwser 2 (DZ2) - Dropzone 2' => (object) ['answer' => 'Dropzone 2', 'correct' => true], + 'Anwser 3 (DZ1) - Dropzone 1' => (object) ['answer' => 'Dropzone 1', 'correct' => true], + 'Anwser 4 (neither) - ' => (object) ['answer' => 'Dropzone 1', 'incorrect' => true], + ], + ], + 'drag and drop with no answer' => [ + 'result' => [ + 'interactiontype' => 'matching', + 'description' => 'Drag and Drop Test', + 'correctpattern' => '["0[.]0[,]0[.]2[,]1[.]1[,]1[.]0"]', + 'response' => '1[.]0[,]1[.]1', + 'additionals' => '{"source":[{"id":"0","description":{"en-US":"Answer 1 (DZ1 and DZ2)\n"}},' + . '{"id":"1","description":{"en-US":"Anwser 2 (DZ2)\n"}},' + . '{"id":"2","description":{"en-US":"Anwser 3 (DZ1)\n"}},' + . '{"id":"3","description":{"en-US":"Anwser 4 (neither)\n"}}],' + . '"target":[{"id":"0","description":{"en-US":"Dropzone 1\n"}},' + . '{"id":"1","description":{"en-US":"Dropzone 2\n"}}],' + . '"extensions":{"http:\/\/h5p.org\/x-api\/h5p-local-content-id":41,' + . '"http:\/\/h5p.org\/x-api\/h5p-subContentId":"59590246-f16e-4855-8dd6-c80e892ef96b"},' + . '"contextExtensions":{}}', + ], + 'useranswers' => [ + 'Answer 1 (DZ1 and DZ2) - Dropzone 1, Dropzone 2' => (object) ['answer' => 'Dropzone 2', 'correct' => true], + 'Anwser 2 (DZ2) - Dropzone 2' => (object) ['answer' => 'Dropzone 2', 'correct' => true], + 'Anwser 3 (DZ1) - Dropzone 1' => (object) ['answer' => 'None', 'incorrect' => true], + 'Anwser 4 (neither) - ' => (object) ['answer' => 'None', 'correct' => true], + ], + ], + 'sort the paragraph text' => [ + 'result' => [ + 'interactiontype' => 'sequencing', + 'description' => 'SortParagraphs', + 'correctpattern' => '["0[,]1[,]2[,]3[,]4"]', + 'response' => '0[,]1[,]3[,]2[,]4', + 'additionals' => '{"choices":[{"id":0,"description":{"en":"First I wake up at 7.30 am\\n",' + . '"en-US":"First I wake up at 7.30 am\\n"}}' + . ',{"id":1,"description":{"en":"Next I get dressed\\n","en-US":"Next I get dressed\\n"}},' + . '{"id":2,"description":{"en":"Afterward I have breakfast\\n","en-US":"Afterward I have breakfast\\n"}},' + . '{"id":3,"description":{"en":"I brush my teeth\\n","en-US":"I brush my teeth\\n"}},' + . '{"id":4,"description":{"en":"Finally I go school\\n","en-US":"Finally I go school\\n"}}],' + . + '"extensions":{"http:\\/\\/h5p.org\\/x-api\\/h5p-local-content-id":39,' + . '"https:\\/\\/h5p.org\\/x-api\\/duplicates-interchangeable":1},"contextExtensions":{}}', + ], + 'useranswers' => [ + '#1 - First I wake up at 7.30 am' => (object) ['answer' => 'Correct answer', 'pass' => true], + '#2 - Next I get dressed' => (object) ['answer' => 'Correct answer', 'pass' => true], + '#3 - Afterward I have breakfast' => (object) ['answer' => 'Incorrect answer', 'fail' => true], + '#4 - I brush my teeth' => (object) ['answer' => 'Incorrect answer', 'fail' => true], + '#5 - Finally I go school' => (object) ['answer' => 'Correct answer', 'pass' => true], + ], + ], + 'sequencing images' => [ + 'result' => [ + 'interactiontype' => 'sequencing', + 'description' => 'Order the planets from smallest to largest', + 'correctpattern' => '["item_3[,]item_0[,]item_7[,]item_1[,]item_5[,]item_2[,]item_4[,]item_6"]', + 'response' => 'item_0[,]item_1[,]item_3[,]item_2[,]item_5[,]item_4[,]item_6[,]item_7', + 'additionals' => '{"choices":[{"id":"item_3","description":{"en-US":"Mercury"}},' + . '{"id":"item_0","description":{"en-US":"Mars"}},{"id":"item_7","description":{"en-US":"Earth"}},' + . '{"id":"item_1","description":{"en-US":"Venus"}},{"id":"item_5","description":{"en-US":"Uranus"}},' + . '{"id":"item_2","description":{"en-US":"Neptune"}},{"id":"item_4","description":{"en-US":"Saturn"}},' + . '{"id":"item_6","description":{"en-US":"Jupiter"}}],"extensions":' + . '{"http:\/\/h5p.org\/x-api\/h5p-local-content-id":43},"contextExtensions":{}}', + ], + 'useranswers' => [ + '#1 - Mercury' => (object) ['answer' => 'Correct answer', 'pass' => true], + '#2 - Mars' => (object) ['answer' => 'Correct answer', 'pass' => true], + '#3 - Earth' => (object) ['answer' => 'Incorrect answer', 'fail' => true], + '#4 - Venus' => (object) ['answer' => 'Incorrect answer', 'fail' => true], + '#5 - Uranus' => (object) ['answer' => 'Incorrect answer', 'fail' => true], + '#6 - Neptune' => (object) ['answer' => 'Incorrect answer', 'fail' => true], + '#7 - Saturn' => (object) ['answer' => 'Correct answer', 'pass' => true], + '#8 - Jupiter' => (object) ['answer' => 'Correct answer', 'pass' => true], + ], + ], + ]; + } + /** * Test result export_options * @@ -87,119 +225,4 @@ class result_test extends \advanced_testcase { $useranswersdata = array_combine($keys, $useranswersdata); $this->assertEquals($expecteduseranswers, $useranswersdata); } - - /** - * Data provider for result export_options test - * - * @return array[] - */ - public function result_data_provider(): array { - return [ - 'fill-in with case sensitive' => [ - 'result' => [ - 'interactiontype' => 'fill-in', - 'description' => '

Fill in the missing words

-

Meow .... this is a __________

-

Bark... this is a __________

', - 'correctpattern' => '["{case_matters=true}cat[,]dog"]', - 'response' => 'Cat[,]dog', - 'additionals' => '{"extensions":{"http:\\/\\/h5p.org\\/x-api\\/h5p-local-content-id":31,' - . '"https:\\/\\/h5p.org\\/x-api\\/case-sensitivity":true,' - . '"https:\\/\\/h5p.org\\/x-api\\/alternatives":[["cat"],["dog"]]},"contextExtensions":{}}', - ], - 'useranswers' => [ - 'Gap #1 - cat' => (object) ['answer' => 'Cat', 'incorrect' => true], - 'Gap #2 - dog' => (object) ['answer' => 'dog', 'correct' => true], - ], - ], - 'fill-in with case insensitive' => [ - 'result' => [ - 'interactiontype' => 'fill-in', - 'description' => '

Fill in the missing words

-

Meow .... this is a __________

-

Bark... this is a __________

', - 'correctpattern' => '["{case_matters=false}cat[,]dog"]', - 'response' => 'Cat[,]dog', - 'additionals' => '{"extensions":{"http:\\/\\/h5p.org\\/x-api\\/h5p-local-content-id":31,' - . '"https:\\/\\/h5p.org\\/x-api\\/case-sensitivity":false,' - . '"https:\\/\\/h5p.org\\/x-api\\/alternatives":[["cat"],["dog"]]},"contextExtensions":{}}', - ], - 'useranswers' => [ - 'Gap #1 - cat' => (object) ['answer' => 'Cat', 'correct' => true], - 'Gap #2 - dog' => (object) ['answer' => 'dog', 'correct' => true], - ], - ], - 'drag and drop' => [ - 'result' => [ - 'interactiontype' => 'matching', - 'description' => 'Drag and Drop Test', - 'correctpattern' => '["0[.]0[,]0[.]2[,]1[.]1[,]1[.]0"]', - 'response' => '0[.]0[,]1[.]1[,]0[.]2[,]0[.]3', - 'additionals' => '{"source":[{"id":"0","description":{"en-US":"Answer 1 (DZ1 and DZ2)\n"}},' - . '{"id":"1","description":{"en-US":"Anwser 2 (DZ2)\n"}},' - . '{"id":"2","description":{"en-US":"Anwser 3 (DZ1)\n"}},' - . '{"id":"3","description":{"en-US":"Anwser 4 (neither)\n"}}],' - . '"target":[{"id":"0","description":{"en-US":"Dropzone 1\n"}},' - . '{"id":"1","description":{"en-US":"Dropzone 2\n"}}],' - . '"extensions":{"http:\/\/h5p.org\/x-api\/h5p-local-content-id":41,' - . '"http:\/\/h5p.org\/x-api\/h5p-subContentId":"59590246-f16e-4855-8dd6-c80e892ef96b"},' - . '"contextExtensions":{}}', - ], - 'useranswers' => [ - 'Answer 1 (DZ1 and DZ2) - Dropzone 1, Dropzone 2' => (object) ['answer' => 'Dropzone 1', 'correct' => true, ], - 'Anwser 2 (DZ2) - Dropzone 2' => (object) ['answer' => 'Dropzone 2', 'correct' => true, ], - 'Anwser 3 (DZ1) - Dropzone 1' => (object) ['answer' => 'Dropzone 1', 'correct' => true, ], - 'Anwser 4 (neither) - ' => (object) ['answer' => 'Dropzone 1', 'incorrect' => true, ] - ], - ], - 'sort the paragraph text' => [ - 'result' => [ - 'interactiontype' => 'sequencing', - 'description' => 'SortParagraphs', - 'correctpattern' => '["0[,]1[,]2[,]3[,]4"]', - 'response' => '0[,]1[,]3[,]2[,]4', - 'additionals' => '{"choices":[{"id":0,"description":{"en":"First I wake up at 7.30 am\\n",' - . '"en-US":"First I wake up at 7.30 am\\n"}}' - . ',{"id":1,"description":{"en":"Next I get dressed\\n","en-US":"Next I get dressed\\n"}},' - . '{"id":2,"description":{"en":"Afterward I have breakfast\\n","en-US":"Afterward I have breakfast\\n"}},' - . '{"id":3,"description":{"en":"I brush my teeth\\n","en-US":"I brush my teeth\\n"}},' - . '{"id":4,"description":{"en":"Finally I go school\\n","en-US":"Finally I go school\\n"}}],' - . - '"extensions":{"http:\\/\\/h5p.org\\/x-api\\/h5p-local-content-id":39,' - . '"https:\\/\\/h5p.org\\/x-api\\/duplicates-interchangeable":1},"contextExtensions":{}}', - ], - 'useranswers' => [ - '#1 - First I wake up at 7.30 am' => (object) ['answer' => 'Correct answer', 'pass' => true, ], - '#2 - Next I get dressed' => (object) ['answer' => 'Correct answer', 'pass' => true, ], - '#3 - Afterward I have breakfast' => (object) ['answer' => 'Incorrect answer', 'fail' => true, ], - '#4 - I brush my teeth' => (object) ['answer' => 'Incorrect answer', 'fail' => true, ], - '#5 - Finally I go school' => (object) ['answer' => 'Correct answer', 'pass' => true, ], - ], - ], - 'sequencing images' => [ - 'result' => [ - 'interactiontype' => 'sequencing', - 'description' => 'Order the planets from smallest to largest', - 'correctpattern' => '["item_3[,]item_0[,]item_7[,]item_1[,]item_5[,]item_2[,]item_4[,]item_6"]', - 'response' => 'item_0[,]item_1[,]item_3[,]item_2[,]item_5[,]item_4[,]item_6[,]item_7', - 'additionals' => '{"choices":[{"id":"item_3","description":{"en-US":"Mercury"}},' - . '{"id":"item_0","description":{"en-US":"Mars"}},{"id":"item_7","description":{"en-US":"Earth"}},' - . '{"id":"item_1","description":{"en-US":"Venus"}},{"id":"item_5","description":{"en-US":"Uranus"}},' - . '{"id":"item_2","description":{"en-US":"Neptune"}},{"id":"item_4","description":{"en-US":"Saturn"}},' - . '{"id":"item_6","description":{"en-US":"Jupiter"}}],"extensions":' - . '{"http:\/\/h5p.org\/x-api\/h5p-local-content-id":43},"contextExtensions":{}}', - ], - 'useranswers' => [ - '#1 - Mercury' => (object) ['answer' => 'Correct answer', 'pass' => true, ], - '#2 - Mars' => (object) ['answer' => 'Correct answer', 'pass' => true, ], - '#3 - Earth' => (object) ['answer' => 'Incorrect answer', 'fail' => true, ], - '#4 - Venus' => (object) ['answer' => 'Incorrect answer', 'fail' => true, ], - '#5 - Uranus' => (object) ['answer' => 'Incorrect answer', 'fail' => true, ], - '#6 - Neptune' => (object) ['answer' => 'Incorrect answer', 'fail' => true, ], - '#7 - Saturn' => (object) ['answer' => 'Correct answer', 'pass' => true, ], - '#8 - Jupiter' => (object) ['answer' => 'Correct answer', 'pass' => true, ], - ], - ] - ]; - } }