MDL-66259 qtype: add tests to all remaining involved qtypes
authorEloy Lafuente (stronk7) <stronk7@moodle.org>
Sat, 4 Apr 2020 23:43:41 +0000 (01:43 +0200)
committerEloy Lafuente (stronk7) <stronk7@moodle.org>
Fri, 24 Apr 2020 13:56:23 +0000 (15:56 +0200)
That way we get the load_question_data() method covered
and all the main data, options, hints checked.

question/type/calculated/tests/questiontype_test.php
question/type/multianswer/tests/questiontype_test.php
question/type/random/tests/questiontype_test.php
question/type/truefalse/tests/questiontype_test.php

index 89654c5..b4cb2dd 100644 (file)
@@ -67,6 +67,85 @@ class qtype_calculated_test extends advanced_testcase {
         $this->assertEquals(0.1, $this->qtype->get_random_guess_score($q));
     }
 
+    public function test_load_question() {
+        $this->resetAfterTest();
+
+        $syscontext = context_system::instance();
+        /** @var core_question_generator $generator */
+        $generator = $this->getDataGenerator()->get_plugin_generator('core_question');
+        $category = $generator->create_question_category(['contextid' => $syscontext->id]);
+
+        $fromform = test_question_maker::get_question_form_data('calculated');
+        $fromform->category = $category->id . ',' . $syscontext->id;
+
+        $question = new stdClass();
+        $question->category = $category->id;
+        $question->qtype = 'calculated';
+        $question->createdby = 0;
+
+        $this->qtype->save_question($question, $fromform);
+        $questiondata = question_bank::load_question_data($question->id);
+
+        $this->assertEquals(['id', 'category', 'parent', 'name', 'questiontext', 'questiontextformat',
+                'generalfeedback', 'generalfeedbackformat', 'defaultmark', 'penalty', 'qtype',
+                'length', 'stamp', 'version', 'hidden', 'timecreated', 'timemodified',
+                'createdby', 'modifiedby', 'idnumber', 'contextid', 'options', 'hints', 'categoryobject'],
+                array_keys(get_object_vars($questiondata)));
+        $this->assertEquals($category->id, $questiondata->category);
+        $this->assertEquals(0, $questiondata->parent);
+        $this->assertEquals($fromform->name, $questiondata->name);
+        $this->assertEquals($fromform->questiontext, $questiondata->questiontext);
+        $this->assertEquals($fromform->questiontextformat, $questiondata->questiontextformat);
+        $this->assertEquals('', $questiondata->generalfeedback);
+        $this->assertEquals(0, $questiondata->generalfeedbackformat);
+        $this->assertEquals($fromform->defaultmark, $questiondata->defaultmark);
+        $this->assertEquals(0, $questiondata->penalty);
+        $this->assertEquals('calculated', $questiondata->qtype);
+        $this->assertEquals(1, $questiondata->length);
+        $this->assertEquals(0, $questiondata->hidden);
+        $this->assertEquals($question->createdby, $questiondata->createdby);
+        $this->assertEquals($question->createdby, $questiondata->modifiedby);
+        $this->assertEquals('', $questiondata->idnumber);
+        $this->assertEquals($syscontext->id, $questiondata->contextid);
+        $this->assertEquals([], $questiondata->hints);
+
+        // Options.
+        $this->assertEquals($questiondata->id, $questiondata->options->question);
+        $this->assertEquals([], $questiondata->options->units);
+        // TODO: Are this four correct? The first one doesn't match, hence commented out.
+        // $this->assertEquals($fromform->unitgradingtypes, $questiondata->options->unitgradingtype);
+        $this->assertEquals($fromform->unitrole, $questiondata->options->showunits);
+        $this->assertEquals($fromform->unitpenalty, $questiondata->options->unitpenalty);
+        $this->assertEquals($fromform->unitsleft, $questiondata->options->unitsleft);
+
+        // Build the expected answer base.
+        $answerbase = [
+            'question' => $questiondata->id,
+            'answerformat' => 0,
+        ];
+        $expectedanswers = [];
+        foreach ($fromform->answer as $key => $value) {
+            $answer = $answerbase + [
+                'answer' => $fromform->answer[$key],
+                'fraction' => (float)$fromform->fraction[$key],
+                'tolerance' => $fromform->tolerance[$key],
+                'tolerancetype' => $fromform->tolerancetype[$key],
+                'correctanswerlength' => $fromform->correctanswerlength[$key],
+                'correctanswerformat' => $fromform->correctanswerformat[$key],
+                'feedback' => $fromform->feedback[$key]['text'],
+                'feedbackformat' => $fromform->feedback[$key]['format'],
+            ];
+            $expectedanswers[] = (object)$answer;
+        }
+        // Need to get rid of ids.
+        $gotanswers = array_map(function($answer) {
+                unset($answer->id);
+                return $answer;
+        }, $questiondata->options->answers);
+        // Compare answers.
+        $this->assertEquals($expectedanswers, array_values($gotanswers));
+    }
+
     protected function get_possible_response($ans, $tolerance, $type) {
         $a = new stdClass();
         $a->answer = $ans;
index ef93d14..b35645f 100644 (file)
@@ -115,6 +115,113 @@ class qtype_multianswer_test extends advanced_testcase {
         $this->assertEquals(0.1666667, $this->qtype->get_random_guess_score($q), '', 0.0000001);
     }
 
+    public function test_load_question() {
+        $this->resetAfterTest();
+
+        $syscontext = context_system::instance();
+        /** @var core_question_generator $generator */
+        $generator = $this->getDataGenerator()->get_plugin_generator('core_question');
+        $category = $generator->create_question_category(['contextid' => $syscontext->id]);
+
+        $fromform = test_question_maker::get_question_form_data('multianswer');
+        $fromform->category = $category->id . ',' . $syscontext->id;
+
+        $question = new stdClass();
+        $question->category = $category->id;
+        $question->qtype = 'multianswer';
+        $question->createdby = 0;
+
+        // TODO: Just check why is not consistent with others, $question should came back modified.
+        $question = $this->qtype->save_question($question, $fromform);
+
+        $questiondata = question_bank::load_question_data($question->id);
+
+        $this->assertEquals(['id', 'category', 'parent', 'name', 'questiontext', 'questiontextformat',
+                'generalfeedback', 'generalfeedbackformat', 'defaultmark', 'penalty', 'qtype',
+                'length', 'stamp', 'version', 'hidden', 'timecreated', 'timemodified',
+                'createdby', 'modifiedby', 'idnumber', 'contextid', 'options', 'hints', 'categoryobject'],
+                array_keys(get_object_vars($questiondata)));
+        $this->assertEquals($category->id, $questiondata->category);
+        $this->assertEquals(0, $questiondata->parent);
+        $this->assertEquals($fromform->name, $questiondata->name);
+        $this->assertEquals($fromform->questiontext, $questiondata->questiontext);
+        $this->assertEquals($fromform->questiontextformat, $questiondata->questiontextformat);
+        $this->assertEquals($fromform->generalfeedback['text'], $questiondata->generalfeedback);
+        $this->assertEquals($fromform->generalfeedback['format'], $questiondata->generalfeedbackformat);
+        $this->assertEquals($fromform->defaultmark, $questiondata->defaultmark);
+        $this->assertEquals(0, $questiondata->penalty);
+        $this->assertEquals('multianswer', $questiondata->qtype);
+        $this->assertEquals(1, $questiondata->length);
+        $this->assertEquals(0, $questiondata->hidden);
+        $this->assertEquals($question->createdby, $questiondata->createdby);
+        $this->assertEquals($question->createdby, $questiondata->modifiedby);
+        $this->assertEquals('', $questiondata->idnumber);
+        $this->assertEquals($syscontext->id, $questiondata->contextid);
+
+        // Build the expected hint base.
+        $hintbase = [
+            'questionid' => $questiondata->id,
+            'shownumcorrect' => 0,
+            'clearwrong' => 0,
+            'options' => null];
+        $expectedhints = [];
+        foreach ($fromform->hint as $key => $value) {
+            $hint = $hintbase + [
+                'hint' => $value['text'],
+                'hintformat' => $value['format'],
+            ];
+            $expectedhints[] = (object)$hint;
+        }
+        // Need to get rid of ids.
+        $gothints = array_map(function($hint) {
+            unset($hint->id);
+            return $hint;
+        }, $questiondata->hints);
+        // Compare hints.
+        $this->assertEquals($expectedhints, array_values($gothints));
+
+        // Options.
+        $this->assertEquals(['questions'], array_keys(get_object_vars($questiondata->options)));
+        $this->assertEquals(count($fromform->options->questions), count($questiondata->options->questions));
+
+        // Build the expected questions. We aren't going deeper to subquestion answers, options... that's another qtype job.
+        $expectedquestions = [];
+        foreach ($fromform->options->questions as $key => $value) {
+            $question = [
+                'id' => $value->id,
+                'category' => $category->id,
+                'parent' => $questiondata->id,
+                'name' => $value->name,
+                'questiontext' => $value->questiontext,
+                'questiontextformat' => $value->questiontextformat,
+                'generalfeedback' => $value->generalfeedback,
+                'generalfeedbackformat' => $value->generalfeedbackformat,
+                'defaultmark' => (float) $value->defaultmark,
+                'penalty' => (float)$value->penalty,
+                'qtype' => $value->qtype,
+                'length' => $value->length,
+                'stamp' => $value->stamp,
+                'hidden' => 0,
+                'timecreated' => $value->timecreated,
+                'timemodified' => $value->timemodified,
+                'createdby' => $value->createdby,
+                'modifiedby' => $value->modifiedby,
+            ];
+            $expectedquestions[] = (object)$question;
+        }
+        // Need to get rid of (version, idnumber, options, hints, maxmark). They are missing @ fromform.
+        $gotquestions = array_map(function($question) {
+                unset($question->version);
+                unset($question->idnumber);
+                unset($question->options);
+                unset($question->hints);
+                unset($question->maxmark);
+                return $question;
+        }, $questiondata->options->questions);
+        // Compare questions.
+        $this->assertEquals($expectedquestions, array_values($gotquestions));
+    }
+
     public function test_question_saving_twosubq() {
         $this->resetAfterTest(true);
         $this->setAdminUser();
index 8d84614..e294867 100644 (file)
@@ -27,6 +27,7 @@
 defined('MOODLE_INTERNAL') || die();
 
 global $CFG;
+require_once($CFG->dirroot . '/question/engine/tests/helpers.php');
 require_once($CFG->dirroot . '/question/type/random/questiontype.php');
 
 
@@ -59,6 +60,49 @@ class qtype_random_test extends advanced_testcase {
         $this->assertNull($this->qtype->get_random_guess_score(null));
     }
 
+    public function test_load_question() {
+        $this->resetAfterTest();
+
+        $syscontext = context_system::instance();
+        /** @var core_question_generator $generator */
+        $generator = $this->getDataGenerator()->get_plugin_generator('core_question');
+        $category = $generator->create_question_category(['contextid' => $syscontext->id]);
+
+        $fromform = test_question_maker::get_question_form_data('random');
+        $fromform->category = $category->id . ',' . $syscontext->id;
+
+        $question = new stdClass();
+        $question->category = $category->id;
+        $question->qtype = 'random';
+        $question->createdby = 0;
+
+        $this->qtype->save_question($question, $fromform);
+        $questiondata = question_bank::load_question_data($question->id);
+
+        $this->assertEquals(['id', 'category', 'parent', 'name', 'questiontext', 'questiontextformat',
+                'generalfeedback', 'generalfeedbackformat', 'defaultmark', 'penalty', 'qtype',
+                'length', 'stamp', 'version', 'hidden', 'timecreated', 'timemodified',
+                'createdby', 'modifiedby', 'idnumber', 'contextid', 'categoryobject'],
+                array_keys(get_object_vars($questiondata)));
+        $this->assertEquals($category->id, $questiondata->category);
+        // TODO: All this is nosense (in my brain, requires review.
+        $this->assertEquals($questiondata->id, $questiondata->parent); // parent points to self?
+        // $this->assertEquals($fromform->name, $questiondata->name); // fromform has empty name.
+        $this->assertEquals($fromform->questiontext, $questiondata->questiontext); // questiontext has 0 ?
+        $this->assertEquals($fromform->questiontextformat, $questiondata->questiontextformat);
+        $this->assertEquals('', $questiondata->generalfeedback);
+        $this->assertEquals(0, $questiondata->generalfeedbackformat);
+        $this->assertEquals(1, $questiondata->defaultmark); // Nothing @ fromform?
+        $this->assertEquals(0, $questiondata->penalty);
+        $this->assertEquals('random', $questiondata->qtype);
+        $this->assertEquals(1, $questiondata->length);
+        $this->assertEquals(0, $questiondata->hidden);
+        $this->assertEquals($question->createdby, $questiondata->createdby);
+        $this->assertEquals($question->createdby, $questiondata->modifiedby);
+        $this->assertEquals('', $questiondata->idnumber);
+        $this->assertEquals($syscontext->id, $questiondata->contextid);
+    }
+
     public function test_get_possible_responses() {
         $this->assertEquals(array(), $this->qtype->get_possible_responses(null));
     }
index d38fb76..2607982 100644 (file)
@@ -101,6 +101,7 @@ class qtype_truefalse_test extends advanced_testcase {
         $this->assertEquals($question->createdby, $questiondata->modifiedby);
         $this->assertEquals('', $questiondata->idnumber);
         $this->assertEquals($syscontext->id, $questiondata->contextid);
+        $this->assertEquals($questiondata->id, $questiondata->options->question);
         $this->assertEquals('True', $questiondata->options->answers[$questiondata->options->trueanswer]->answer);
         $this->assertEquals('False', $questiondata->options->answers[$questiondata->options->falseanswer]->answer);
         $this->assertEquals(1.0, $questiondata->options->answers[$questiondata->options->trueanswer]->fraction);