1
0
mirror of https://github.com/moodle/moodle.git synced 2025-04-14 04:52:36 +02:00

MDL-78008 qtype_multianswer: random guess score with missing subqs

Sometimes, due to other bugs, subquestions can get lost, so the code
needs to be robust to this.
This commit is contained in:
Tim Hunt 2023-05-12 12:22:17 +01:00
parent 6ca70dd59f
commit 0d0868ee97
2 changed files with 45 additions and 6 deletions
question/type/multianswer

@ -314,11 +314,18 @@ class qtype_multianswer extends question_type {
$fractionsum = 0;
$fractionmax = 0;
foreach ($questiondata->options->questions as $key => $subqdata) {
if ($subqdata->qtype == 'subquestion_replacement') {
continue;
}
$fractionmax += $subqdata->defaultmark;
$fractionsum += question_bank::get_qtype(
$subqdata->qtype)->get_random_guess_score($subqdata);
}
return $fractionsum / $fractionmax;
if ($fractionmax > question_utils::MARK_TOLERANCE) {
return $fractionsum / $fractionmax;
} else {
return null;
}
}
public function move_files($questionid, $oldcontextid, $newcontextid) {

@ -34,9 +34,10 @@ require_once($CFG->dirroot . '/question/type/multianswer/edit_multianswer_form.p
/**
* Unit tests for the multianswer question definition class.
*
* @package qtype_multianswer
* @copyright 2011 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @package qtype_multianswer
* @copyright 2011 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @covers \qtype_multianswer
*/
class question_type_test extends \advanced_testcase {
/** @var qtype_multianswer instance of the question type class to test. */
@ -112,15 +113,46 @@ class question_type_test extends \advanced_testcase {
}
public function test_get_random_guess_score() {
$q = \test_question_maker::get_question_data('multianswer', 'twosubq');
$q = test_question_maker::get_question_data('multianswer', 'twosubq');
$this->assertEqualsWithDelta(0.1666667, $this->qtype->get_random_guess_score($q), 0.0000001);
}
public function test_get_random_guess_score_with_missing_subquestion() {
global $DB;
$this->resetAfterTest();
// Create a question referring to a subquesion that has got lost (which happens some time).
/** @var \core_question_generator $generator */
$generator = $this->getDataGenerator()->get_plugin_generator('core_question');
$category = $generator->create_question_category();
$question = $generator->create_question('multianswer', 'twosubq', ['category' => $category->id]);
// Add a non-existent subquestion id to the list.
$sequence = $DB->get_field('question_multianswer', 'sequence', ['question' => $question->id], MUST_EXIST);
$DB->set_field('question_multianswer', 'sequence', $sequence . ',-1', ['question' => $question->id]);
// Verify that computing the random guess score does not give an error.
$questiondata = question_bank::load_question_data($question->id);
$this->assertEqualsWithDelta(0.1666667, $this->qtype->get_random_guess_score($questiondata), 0.0000001);
}
public function test_get_random_guess_score_with_all_missing_subquestions() {
$this->resetAfterTest();
// Create a question where all subquestions are missing.
$questiondata = test_question_maker::get_question_data('multianswer', 'twosubq');
foreach ($questiondata->options->questions as $subq) {
$subq->qtype = 'subquestion_replacement';
}
// Verify that computing the random guess score does not give an error.
$this->assertNull($this->qtype->get_random_guess_score($questiondata));
}
public function test_load_question() {
$this->resetAfterTest();
$syscontext = \context_system::instance();
/** @var core_question_generator $generator */
/** @var \core_question_generator $generator */
$generator = $this->getDataGenerator()->get_plugin_generator('core_question');
$category = $generator->create_question_category(['contextid' => $syscontext->id]);