Skip to content

Commit

Permalink
MDL-74752 qtype_multianswer: implement regrading hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
timhunt committed May 31, 2022
1 parent 5990158 commit 9d40a13
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 0 deletions.
1 change: 1 addition & 0 deletions question/type/multianswer/lang/en/qtype_multianswer.php
Expand Up @@ -67,6 +67,7 @@
$string['questiontypechanged'] = 'Question type changed';
$string['questiontypechangedcomment'] = 'At least one question type has been changed.<br />Did you add, delete or move a question?<br />Look ahead.';
$string['questionusedinquiz'] = 'This question is used in {$a->nb_of_quiz} quiz(s), total attempt(s) : {$a->nb_of_attempts} ';
$string['regradeissuenumsubquestionschanged'] = 'The number embedded sub-questions in the question has changed.';
$string['storedqtype'] = 'Stored question type {$a}';
$string['subqresponse'] = 'part {$a->i}: {$a->response}';
$string['unknownquestiontypeofsubquestion'] = 'Unknown question type: {$a->type} of question part # {$a->sub}';
Expand Down
37 changes: 37 additions & 0 deletions question/type/multianswer/question.php
Expand Up @@ -78,6 +78,43 @@ public function apply_attempt_state(question_attempt_step $step) {
}
}

public function validate_can_regrade_with_other_version(question_definition $otherversion): ?string {
$basemessage = parent::validate_can_regrade_with_other_version($otherversion);
if ($basemessage) {
return $basemessage;
}

if (count($this->subquestions) != count($otherversion->subquestions)) {
return get_string('regradeissuenumsubquestionschanged', 'qtype_multianswer');
}

foreach ($this->subquestions as $i => $subq) {
$subqmessage = $subq->validate_can_regrade_with_other_version($otherversion->subquestions[$i]);
if ($subqmessage) {
return $subqmessage;
}
}

return null;
}

public function update_attempt_state_data_for_new_version(
question_attempt_step $oldstep, question_definition $oldquestion) {
parent::update_attempt_state_data_for_new_version($oldstep, $oldquestion);

$result = [];
foreach ($this->subquestions as $i => $subq) {
$substep = $this->get_substep($oldstep, $i);
$statedata = $subq->update_attempt_state_data_for_new_version(
$substep, $oldquestion->subquestions[$i]);
foreach ($statedata as $name => $value) {
$result[$substep->add_prefix($name)] = $value;
}
}

return $result;
}

public function get_question_summary() {
$summary = $this->html_to_text($this->questiontext, $this->questiontextformat);
foreach ($this->subquestions as $i => $subq) {
Expand Down
97 changes: 97 additions & 0 deletions question/type/multianswer/tests/question_test.php
Expand Up @@ -32,6 +32,7 @@
* @package qtype_multianswer
* @copyright 2011 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @covers \qtype_multianswer_question
*/
class question_test extends \advanced_testcase {
public function test_get_expected_data() {
Expand Down Expand Up @@ -252,4 +253,100 @@ public function test_get_question_definition_for_external_rendering() {
$options = $question->get_question_definition_for_external_rendering($qa, $displayoptions);
$this->assertNull($options);
}

/**
* Helper method to make a simulated second version of the standard multianswer test question.
*
* The key think is that all the answer ids are changed (increased by 20).
*
* @param \qtype_multianswer_question $question
* @return \qtype_multianswer_question
*/
protected function make_second_version(
\qtype_multianswer_question $question): \qtype_multianswer_question {
$newquestion = fullclone($question);

$newquestion->subquestions[1]->answers = [
36 => new \question_answer(16, 'Apple', 0.3333333,
'Good', FORMAT_HTML),
37 => new \question_answer(17, 'Burger', -0.5,
'', FORMAT_HTML),
38 => new \question_answer(18, 'Hot dog', -0.5,
'Not a fruit', FORMAT_HTML),
39 => new \question_answer(19, 'Pizza', -0.5,
'', FORMAT_HTML),
40 => new \question_answer(20, 'Orange', 0.3333333,
'Correct', FORMAT_HTML),
41 => new \question_answer(21, 'Banana', 0.3333333,
'', FORMAT_HTML),
];

$newquestion->subquestions[2]->answers = [
42 => new \question_answer(22, 'Raddish', 0.5,
'Good', FORMAT_HTML),
43 => new \question_answer(23, 'Chocolate', -0.5,
'', FORMAT_HTML),
44 => new \question_answer(24, 'Biscuit', -0.5,
'Not a vegetable', FORMAT_HTML),
45 => new \question_answer(25, 'Cheese', -0.5,
'', FORMAT_HTML),
46 => new \question_answer(26, 'Carrot', 0.5,
'Correct', FORMAT_HTML),
];

return $newquestion;
}

public function test_validate_can_regrade_with_other_version_ok() {
/** @var \qtype_multianswer_question $question */
$question = \test_question_maker::make_question('multianswer', 'multiple');

$newquestion = $this->make_second_version($question);

$this->assertNull($newquestion->validate_can_regrade_with_other_version($question));
}

public function test_validate_can_regrade_with_other_version_wrong_subquestions() {
/** @var \qtype_multianswer_question $question */
$question = \test_question_maker::make_question('multianswer', 'multiple');

$newquestion = $this->make_second_version($question);
unset($newquestion->subquestions[2]);

$this->assertEquals(
get_string('regradeissuenumsubquestionschanged', 'qtype_multianswer'),
$newquestion->validate_can_regrade_with_other_version($question));
}

public function test_validate_can_regrade_with_other_version_one_wrong_subquestion() {
/** @var \qtype_multianswer_question $question */
$question = \test_question_maker::make_question('multianswer', 'multiple');

$newquestion = $this->make_second_version($question);
unset($newquestion->subquestions[1]->answers[41]);

$this->assertEquals(
get_string('regradeissuenumchoiceschanged', 'qtype_multichoice'),
$newquestion->validate_can_regrade_with_other_version($question));
}

public function test_update_attempt_state_date_from_old_version_ok() {
/** @var \qtype_multianswer_question $question */
$question = \test_question_maker::make_question('multianswer', 'multiple');

$newquestion = $this->make_second_version($question);

$oldstep = new question_attempt_step();
$oldstep->set_qt_var('_sub1_order', '16,17,18,19,20,21');
$oldstep->set_qt_var('_sub2_order', '22,23,24,25,26');

$expected = [
'_sub1_order' => '36,37,38,39,40,41',
'_sub2_order' => '42,43,44,45,46',
];

$this->assertEquals($expected,
$newquestion->update_attempt_state_data_for_new_version($oldstep, $question));
}

}

0 comments on commit 9d40a13

Please sign in to comment.