| 1 | efrain | 1 | <?php
 | 
        
           |  |  | 2 | // This file is part of Moodle - http://moodle.org/
 | 
        
           |  |  | 3 | //
 | 
        
           |  |  | 4 | // Moodle is free software: you can redistribute it and/or modify
 | 
        
           |  |  | 5 | // it under the terms of the GNU General Public License as published by
 | 
        
           |  |  | 6 | // the Free Software Foundation, either version 3 of the License, or
 | 
        
           |  |  | 7 | // (at your option) any later version.
 | 
        
           |  |  | 8 | //
 | 
        
           |  |  | 9 | // Moodle is distributed in the hope that it will be useful,
 | 
        
           |  |  | 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
        
           |  |  | 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
        
           |  |  | 12 | // GNU General Public License for more details.
 | 
        
           |  |  | 13 | //
 | 
        
           |  |  | 14 | // You should have received a copy of the GNU General Public License
 | 
        
           |  |  | 15 | // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 | 
        
           |  |  | 16 |   | 
        
           |  |  | 17 | namespace core_question;
 | 
        
           |  |  | 18 |   | 
        
           |  |  | 19 | use core_question\local\bank\question_version_status;
 | 
        
           |  |  | 20 | use core_question\output\question_version_info;
 | 
        
           |  |  | 21 | use question_bank;
 | 
        
           |  |  | 22 |   | 
        
           |  |  | 23 | /**
 | 
        
           |  |  | 24 |  * Question version unit tests.
 | 
        
           |  |  | 25 |  *
 | 
        
           |  |  | 26 |  * @package    core_question
 | 
        
           |  |  | 27 |  * @copyright  2021 Catalyst IT Australia Pty Ltd
 | 
        
           |  |  | 28 |  * @author     Guillermo Gomez Arias <guillermogomez@catalyst-au.net>
 | 
        
           |  |  | 29 |  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 | 
        
           |  |  | 30 |  * @coversDefaultClass \question_bank
 | 
        
           |  |  | 31 |  */
 | 
        
           |  |  | 32 | class version_test extends \advanced_testcase {
 | 
        
           |  |  | 33 |   | 
        
           |  |  | 34 |     /**
 | 
        
           |  |  | 35 |      * @var \context_module module context.
 | 
        
           |  |  | 36 |      */
 | 
        
           |  |  | 37 |     protected $context;
 | 
        
           |  |  | 38 |   | 
        
           |  |  | 39 |     /**
 | 
        
           |  |  | 40 |      * @var \stdClass course object.
 | 
        
           |  |  | 41 |      */
 | 
        
           |  |  | 42 |     protected $course;
 | 
        
           |  |  | 43 |   | 
        
           |  |  | 44 |     /**
 | 
        
           |  |  | 45 |      * @var \component_generator_base question generator.
 | 
        
           |  |  | 46 |      */
 | 
        
           |  |  | 47 |     protected $qgenerator;
 | 
        
           |  |  | 48 |   | 
        
           |  |  | 49 |     /**
 | 
        
           |  |  | 50 |      * @var \stdClass quiz object.
 | 
        
           |  |  | 51 |      */
 | 
        
           |  |  | 52 |     protected $quiz;
 | 
        
           |  |  | 53 |   | 
        
           |  |  | 54 |     /**
 | 
        
           |  |  | 55 |      * Called before every test.
 | 
        
           |  |  | 56 |      */
 | 
        
           |  |  | 57 |     protected function setUp(): void {
 | 
        
           |  |  | 58 |         parent::setUp();
 | 
        
           |  |  | 59 |         self::setAdminUser();
 | 
        
           |  |  | 60 |         $this->resetAfterTest();
 | 
        
           |  |  | 61 |   | 
        
           |  |  | 62 |         $datagenerator = $this->getDataGenerator();
 | 
        
           |  |  | 63 |         $this->course = $datagenerator->create_course();
 | 
        
           |  |  | 64 |         $this->quiz = $datagenerator->create_module('quiz', ['course' => $this->course->id]);
 | 
        
           |  |  | 65 |         $this->qgenerator = $datagenerator->get_plugin_generator('core_question');
 | 
        
           |  |  | 66 |         $this->context = \context_module::instance($this->quiz->cmid);
 | 
        
           |  |  | 67 |     }
 | 
        
           |  |  | 68 |   | 
        
           |  |  | 69 |     protected function tearDown(): void {
 | 
        
           |  |  | 70 |         question_version_info::$pendingdefinitions = [];
 | 
        
           |  |  | 71 |         parent::tearDown();
 | 
        
           |  |  | 72 |     }
 | 
        
           |  |  | 73 |   | 
        
           |  |  | 74 |     /**
 | 
        
           |  |  | 75 |      * Test if creating a question a new version and bank entry records are created.
 | 
        
           |  |  | 76 |      *
 | 
        
           |  |  | 77 |      * @covers ::load_question
 | 
        
           |  |  | 78 |      */
 | 
        
           | 11 | efrain | 79 |     public function test_make_question_create_version_and_bank_entry(): void {
 | 
        
           | 1 | efrain | 80 |         global $DB;
 | 
        
           |  |  | 81 |   | 
        
           |  |  | 82 |         $qcategory = $this->qgenerator->create_question_category(['contextid' => $this->context->id]);
 | 
        
           |  |  | 83 |         $question = $this->qgenerator->create_question('shortanswer', null, ['category' => $qcategory->id]);
 | 
        
           |  |  | 84 |   | 
        
           |  |  | 85 |         // Get the question object after creating a question.
 | 
        
           |  |  | 86 |         $questiondefinition = question_bank::load_question($question->id);
 | 
        
           |  |  | 87 |   | 
        
           |  |  | 88 |         // The version and bank entry in the object should be the same.
 | 
        
           |  |  | 89 |         $sql = "SELECT qv.id AS versionid, qv.questionbankentryid
 | 
        
           |  |  | 90 |                   FROM {question} q
 | 
        
           |  |  | 91 |                   JOIN {question_versions} qv ON qv.questionid = q.id
 | 
        
           |  |  | 92 |                   JOIN {question_bank_entries} qbe ON qbe.id = qv.questionbankentryid
 | 
        
           |  |  | 93 |                  WHERE q.id = ?";
 | 
        
           |  |  | 94 |         $questionversion = $DB->get_record_sql($sql, [$questiondefinition->id]);
 | 
        
           |  |  | 95 |         $this->assertEquals($questionversion->versionid, $questiondefinition->versionid);
 | 
        
           |  |  | 96 |         $this->assertEquals($questionversion->questionbankentryid, $questiondefinition->questionbankentryid);
 | 
        
           |  |  | 97 |   | 
        
           |  |  | 98 |         // If a question is updated, a new version should be created.
 | 
        
           |  |  | 99 |         $question = $this->qgenerator->update_question($question, null, ['name' => 'This is a new version']);
 | 
        
           |  |  | 100 |         $newquestiondefinition = question_bank::load_question($question->id);
 | 
        
           |  |  | 101 |         // The version should be 2.
 | 
        
           |  |  | 102 |         $this->assertEquals('2', $newquestiondefinition->version);
 | 
        
           |  |  | 103 |   | 
        
           |  |  | 104 |         // Both versions should be in same bank entry.
 | 
        
           |  |  | 105 |         $this->assertEquals($questiondefinition->questionbankentryid, $newquestiondefinition->questionbankentryid);
 | 
        
           |  |  | 106 |     }
 | 
        
           |  |  | 107 |   | 
        
           |  |  | 108 |     /**
 | 
        
           |  |  | 109 |      * Test if deleting a question the related version and bank entry records are deleted.
 | 
        
           |  |  | 110 |      *
 | 
        
           |  |  | 111 |      * @covers ::load_question
 | 
        
           |  |  | 112 |      * @covers ::question_delete_question
 | 
        
           |  |  | 113 |      */
 | 
        
           | 11 | efrain | 114 |     public function test_delete_question_delete_versions(): void {
 | 
        
           | 1 | efrain | 115 |         global $DB;
 | 
        
           |  |  | 116 |   | 
        
           |  |  | 117 |         $qcategory = $this->qgenerator->create_question_category(['contextid' => $this->context->id]);
 | 
        
           |  |  | 118 |         $question = $this->qgenerator->create_question('shortanswer', null, ['category' => $qcategory->id]);
 | 
        
           |  |  | 119 |         $questionfirstversionid = $question->id;
 | 
        
           |  |  | 120 |   | 
        
           |  |  | 121 |         // Create a new version and try to remove it.
 | 
        
           |  |  | 122 |         $question = $this->qgenerator->update_question($question, null, ['name' => 'This is a new version']);
 | 
        
           |  |  | 123 |   | 
        
           |  |  | 124 |         // The new version and bank entry record should exist.
 | 
        
           |  |  | 125 |         $sql = "SELECT q.id, qv.id AS versionid, qv.questionbankentryid
 | 
        
           |  |  | 126 |                   FROM {question} q
 | 
        
           |  |  | 127 |                   JOIN {question_versions} qv ON qv.questionid = q.id
 | 
        
           |  |  | 128 |                   JOIN {question_bank_entries} qbe ON qbe.id = qv.questionbankentryid
 | 
        
           |  |  | 129 |                  WHERE q.id = ?";
 | 
        
           |  |  | 130 |         $questionobject = $DB->get_records_sql($sql, [$question->id]);
 | 
        
           |  |  | 131 |         $this->assertCount(1, $questionobject);
 | 
        
           |  |  | 132 |   | 
        
           |  |  | 133 |         // Try to delete new version.
 | 
        
           |  |  | 134 |         question_delete_question($question->id);
 | 
        
           |  |  | 135 |   | 
        
           |  |  | 136 |         // The version record should not exist.
 | 
        
           |  |  | 137 |         $sql = "SELECT qv.*
 | 
        
           |  |  | 138 |                   FROM {question_versions} qv
 | 
        
           |  |  | 139 |                  WHERE qv.id = ?";
 | 
        
           |  |  | 140 |         $questionversion = $DB->get_record_sql($sql, [$questionobject[$question->id]->versionid]);
 | 
        
           |  |  | 141 |         $this->assertFalse($questionversion);
 | 
        
           |  |  | 142 |   | 
        
           |  |  | 143 |         // The bank entry record should exist because there is an older version.
 | 
        
           |  |  | 144 |         $sql = "SELECT qbe.*
 | 
        
           |  |  | 145 |                   FROM {question_bank_entries} qbe
 | 
        
           |  |  | 146 |                  WHERE qbe.id = ?";
 | 
        
           |  |  | 147 |         $questionbankentry = $DB->get_records_sql($sql, [$questionobject[$question->id]->questionbankentryid]);
 | 
        
           |  |  | 148 |         $this->assertCount(1, $questionbankentry);
 | 
        
           |  |  | 149 |   | 
        
           |  |  | 150 |         // Now remove the first version.
 | 
        
           |  |  | 151 |         question_delete_question($questionfirstversionid);
 | 
        
           |  |  | 152 |         $sql = "SELECT qbe.*
 | 
        
           |  |  | 153 |                   FROM {question_bank_entries} qbe
 | 
        
           |  |  | 154 |                  WHERE qbe.id = ?";
 | 
        
           |  |  | 155 |         $questionbankentry = $DB->get_record_sql($sql, [$questionobject[$question->id]->questionbankentryid]);
 | 
        
           |  |  | 156 |         // The bank entry record should not exist.
 | 
        
           |  |  | 157 |         $this->assertFalse($questionbankentry);
 | 
        
           |  |  | 158 |     }
 | 
        
           |  |  | 159 |   | 
        
           |  |  | 160 |     /**
 | 
        
           |  |  | 161 |      * Test if deleting a question will not break a quiz.
 | 
        
           |  |  | 162 |      *
 | 
        
           |  |  | 163 |      * @covers ::load_question
 | 
        
           |  |  | 164 |      * @covers ::quiz_add_quiz_question
 | 
        
           |  |  | 165 |      * @covers ::question_delete_question
 | 
        
           |  |  | 166 |      */
 | 
        
           | 11 | efrain | 167 |     public function test_delete_question_in_use(): void {
 | 
        
           | 1 | efrain | 168 |         global $DB;
 | 
        
           |  |  | 169 |   | 
        
           |  |  | 170 |         $qcategory = $this->qgenerator->create_question_category(['contextid' => $this->context->id]);
 | 
        
           |  |  | 171 |         $question = $this->qgenerator->create_question('shortanswer', null, ['category' => $qcategory->id]);
 | 
        
           |  |  | 172 |         $questionfirstversionid = $question->id;
 | 
        
           |  |  | 173 |   | 
        
           |  |  | 174 |         // Create a new version and try to remove it after adding it to a quiz.
 | 
        
           |  |  | 175 |         $question = $this->qgenerator->update_question($question, null, ['name' => 'This is a new version']);
 | 
        
           |  |  | 176 |   | 
        
           |  |  | 177 |         // Add it to the quiz.
 | 
        
           |  |  | 178 |         quiz_add_quiz_question($question->id, $this->quiz);
 | 
        
           |  |  | 179 |   | 
        
           |  |  | 180 |         // Try to delete new version.
 | 
        
           |  |  | 181 |         question_delete_question($question->id);
 | 
        
           |  |  | 182 |         // Try to delete old version.
 | 
        
           |  |  | 183 |         question_delete_question($questionfirstversionid);
 | 
        
           |  |  | 184 |   | 
        
           |  |  | 185 |         // The used question version should exist even after trying to remove it, but now hidden.
 | 
        
           |  |  | 186 |         $questionversion2 = question_bank::load_question($question->id);
 | 
        
           |  |  | 187 |         $this->assertEquals($question->id, $questionversion2->id);
 | 
        
           |  |  | 188 |         $this->assertEquals(question_version_status::QUESTION_STATUS_HIDDEN, $questionversion2->status);
 | 
        
           |  |  | 189 |   | 
        
           |  |  | 190 |         // The unused version should be completely gone.
 | 
        
           |  |  | 191 |         $this->assertFalse($DB->record_exists('question', ['id' => $questionfirstversionid]));
 | 
        
           |  |  | 192 |     }
 | 
        
           |  |  | 193 |   | 
        
           |  |  | 194 |     /**
 | 
        
           |  |  | 195 |      * Test if moving a category will not break a quiz.
 | 
        
           |  |  | 196 |      *
 | 
        
           |  |  | 197 |      * @covers ::load_question
 | 
        
           |  |  | 198 |      * @covers ::quiz_add_quiz_question
 | 
        
           |  |  | 199 |      */
 | 
        
           | 11 | efrain | 200 |     public function test_move_category_with_questions(): void {
 | 
        
           | 1 | efrain | 201 |         global $DB;
 | 
        
           |  |  | 202 |   | 
        
           |  |  | 203 |         $qcategory = $this->qgenerator->create_question_category(['contextid' => $this->context->id]);
 | 
        
           |  |  | 204 |         $qcategorychild = $this->qgenerator->create_question_category(['contextid' => $this->context->id,
 | 
        
           |  |  | 205 |             'parent' => $qcategory->id]);
 | 
        
           |  |  | 206 |         $systemcontext = \context_system::instance();
 | 
        
           |  |  | 207 |         $qcategorysys = $this->qgenerator->create_question_category(['contextid' => $systemcontext->id]);
 | 
        
           |  |  | 208 |         $question = $this->qgenerator->create_question('shortanswer', null, ['category' => $qcategorychild->id]);
 | 
        
           |  |  | 209 |         $questiondefinition = question_bank::load_question($question->id);
 | 
        
           |  |  | 210 |   | 
        
           |  |  | 211 |         // Add it to the quiz.
 | 
        
           |  |  | 212 |         quiz_add_quiz_question($question->id, $this->quiz);
 | 
        
           |  |  | 213 |   | 
        
           |  |  | 214 |         // Move the category to system context.
 | 
        
           |  |  | 215 |         $contexts = new \core_question\local\bank\question_edit_contexts($systemcontext);
 | 
        
           |  |  | 216 |         $qcobject = new \qbank_managecategories\question_category_object(null,
 | 
        
           |  |  | 217 |             new \moodle_url('/question/bank/managecategories/category.php', ['courseid' => SITEID]),
 | 
        
           |  |  | 218 |             $contexts->having_one_edit_tab_cap('categories'), 0, null, 0,
 | 
        
           |  |  | 219 |             $contexts->having_cap('moodle/question:add'));
 | 
        
           |  |  | 220 |         $qcobject->move_questions_and_delete_category($qcategorychild->id, $qcategorysys->id);
 | 
        
           |  |  | 221 |   | 
        
           |  |  | 222 |         // The bank entry record should point to the new category in order to not break quizzes.
 | 
        
           |  |  | 223 |         $sql = "SELECT qbe.questioncategoryid
 | 
        
           |  |  | 224 |                   FROM {question_bank_entries} qbe
 | 
        
           |  |  | 225 |                  WHERE qbe.id = ?";
 | 
        
           |  |  | 226 |         $questionbankentry = $DB->get_record_sql($sql, [$questiondefinition->questionbankentryid]);
 | 
        
           |  |  | 227 |         $this->assertEquals($qcategorysys->id, $questionbankentry->questioncategoryid);
 | 
        
           |  |  | 228 |     }
 | 
        
           |  |  | 229 |   | 
        
           |  |  | 230 |     /**
 | 
        
           |  |  | 231 |      * Test that all versions will have the same bank entry idnumber value.
 | 
        
           |  |  | 232 |      *
 | 
        
           |  |  | 233 |      * @covers ::load_question
 | 
        
           |  |  | 234 |      */
 | 
        
           | 11 | efrain | 235 |     public function test_id_number_in_bank_entry(): void {
 | 
        
           | 1 | efrain | 236 |         global $DB;
 | 
        
           |  |  | 237 |   | 
        
           |  |  | 238 |         $qcategory = $this->qgenerator->create_question_category(['contextid' => $this->context->id]);
 | 
        
           |  |  | 239 |         $question = $this->qgenerator->create_question('shortanswer', null,
 | 
        
           |  |  | 240 |             [
 | 
        
           |  |  | 241 |                 'category' => $qcategory->id,
 | 
        
           |  |  | 242 |                 'idnumber' => 'id1'
 | 
        
           |  |  | 243 |             ]);
 | 
        
           |  |  | 244 |         $questionid1 = $question->id;
 | 
        
           |  |  | 245 |   | 
        
           |  |  | 246 |         // Create a new version and try to remove it after adding it to a quiz.
 | 
        
           |  |  | 247 |         $question = $this->qgenerator->update_question($question, null, ['idnumber' => 'id2']);
 | 
        
           |  |  | 248 |         $questionid2 = $question->id;
 | 
        
           |  |  | 249 |         // Change the id number and get the question object.
 | 
        
           |  |  | 250 |         $question = $this->qgenerator->update_question($question, null, ['idnumber' => 'id3']);
 | 
        
           |  |  | 251 |         $questionid3 = $question->id;
 | 
        
           |  |  | 252 |   | 
        
           |  |  | 253 |         // The new version and bank entry record should exist.
 | 
        
           |  |  | 254 |         $questiondefinition = question_bank::load_question($question->id);
 | 
        
           |  |  | 255 |         $sql = "SELECT q.id AS questionid, qv.id AS versionid, qbe.id AS questionbankentryid, qbe.idnumber
 | 
        
           |  |  | 256 |                   FROM {question_bank_entries} qbe
 | 
        
           |  |  | 257 |                   JOIN {question_versions} qv ON qv.questionbankentryid = qbe.id
 | 
        
           |  |  | 258 |                   JOIN {question} q ON q.id = qv.questionid
 | 
        
           |  |  | 259 |                  WHERE qbe.id = ?";
 | 
        
           |  |  | 260 |         $questionbankentry = $DB->get_records_sql($sql, [$questiondefinition->questionbankentryid]);
 | 
        
           |  |  | 261 |   | 
        
           |  |  | 262 |         // We should have 3 versions and 1 question bank entry with the same idnumber.
 | 
        
           |  |  | 263 |         $this->assertCount(3, $questionbankentry);
 | 
        
           |  |  | 264 |         $this->assertEquals($questionbankentry[$questionid1]->idnumber, 'id3');
 | 
        
           |  |  | 265 |         $this->assertEquals($questionbankentry[$questionid2]->idnumber, 'id3');
 | 
        
           |  |  | 266 |         $this->assertEquals($questionbankentry[$questionid3]->idnumber, 'id3');
 | 
        
           |  |  | 267 |     }
 | 
        
           |  |  | 268 |   | 
        
           |  |  | 269 |     /**
 | 
        
           |  |  | 270 |      * Test that all the versions are available from the method.
 | 
        
           |  |  | 271 |      *
 | 
        
           |  |  | 272 |      * @covers ::get_all_versions_of_question
 | 
        
           |  |  | 273 |      */
 | 
        
           | 11 | efrain | 274 |     public function test_get_all_versions_of_question(): void {
 | 
        
           | 1 | efrain | 275 |         $qcategory = $this->qgenerator->create_question_category(['contextid' => $this->context->id]);
 | 
        
           |  |  | 276 |         $question = $this->qgenerator->create_question('shortanswer', null,
 | 
        
           |  |  | 277 |             [
 | 
        
           |  |  | 278 |                 'category' => $qcategory->id,
 | 
        
           |  |  | 279 |                 'idnumber' => 'id1'
 | 
        
           |  |  | 280 |             ]);
 | 
        
           |  |  | 281 |         $questionid1 = $question->id;
 | 
        
           |  |  | 282 |   | 
        
           |  |  | 283 |         // Create a new version.
 | 
        
           |  |  | 284 |         $question = $this->qgenerator->update_question($question, null, ['idnumber' => 'id2']);
 | 
        
           |  |  | 285 |         $questionid2 = $question->id;
 | 
        
           |  |  | 286 |         // Change the id number and get the question object.
 | 
        
           |  |  | 287 |         $question = $this->qgenerator->update_question($question, null, ['idnumber' => 'id3']);
 | 
        
           |  |  | 288 |         $questionid3 = $question->id;
 | 
        
           |  |  | 289 |   | 
        
           |  |  | 290 |         $questiondefinition = question_bank::get_all_versions_of_question($question->id);
 | 
        
           |  |  | 291 |   | 
        
           |  |  | 292 |         // Test the versions are available.
 | 
        
           |  |  | 293 |         $this->assertEquals(array_slice($questiondefinition, 0, 1)[0]->questionid, $questionid3);
 | 
        
           |  |  | 294 |         $this->assertEquals(array_slice($questiondefinition, 1, 1)[0]->questionid, $questionid2);
 | 
        
           |  |  | 295 |         $this->assertEquals(array_slice($questiondefinition, 2, 1)[0]->questionid, $questionid1);
 | 
        
           |  |  | 296 |     }
 | 
        
           |  |  | 297 |   | 
        
           |  |  | 298 |     /**
 | 
        
           |  |  | 299 |      * Test that all the versions of questions are available from the method.
 | 
        
           |  |  | 300 |      *
 | 
        
           |  |  | 301 |      * @covers ::get_all_versions_of_questions
 | 
        
           |  |  | 302 |      */
 | 
        
           | 11 | efrain | 303 |     public function test_get_all_versions_of_questions(): void {
 | 
        
           | 1 | efrain | 304 |         global $DB;
 | 
        
           |  |  | 305 |   | 
        
           |  |  | 306 |         $questionversions = [];
 | 
        
           |  |  | 307 |         $qcategory = $this->qgenerator->create_question_category(['contextid' => $this->context->id]);
 | 
        
           |  |  | 308 |         $question = $this->qgenerator->create_question('shortanswer', null,
 | 
        
           |  |  | 309 |             [
 | 
        
           |  |  | 310 |                 'category' => $qcategory->id,
 | 
        
           |  |  | 311 |                 'idnumber' => 'id1'
 | 
        
           |  |  | 312 |             ]);
 | 
        
           |  |  | 313 |         $questionversions[1] = $question->id;
 | 
        
           |  |  | 314 |   | 
        
           |  |  | 315 |         // Create a new version.
 | 
        
           |  |  | 316 |         $question = $this->qgenerator->update_question($question, null, ['idnumber' => 'id2']);
 | 
        
           |  |  | 317 |         $questionversions[2] = $question->id;
 | 
        
           |  |  | 318 |         // Change the id number and get the question object.
 | 
        
           |  |  | 319 |         $question = $this->qgenerator->update_question($question, null, ['idnumber' => 'id3']);
 | 
        
           |  |  | 320 |         $questionversions[3] = $question->id;
 | 
        
           |  |  | 321 |   | 
        
           |  |  | 322 |         $questionbankentryid = $DB->get_record('question_versions', ['questionid' => $question->id], 'questionbankentryid');
 | 
        
           |  |  | 323 |   | 
        
           |  |  | 324 |         $questionversionsofquestions = question_bank::get_all_versions_of_questions([$question->id]);
 | 
        
           |  |  | 325 |         $questionbankentryids = array_keys($questionversionsofquestions)[0];
 | 
        
           |  |  | 326 |         $this->assertEquals($questionbankentryid->questionbankentryid, $questionbankentryids);
 | 
        
           |  |  | 327 |         $this->assertEquals($questionversions, $questionversionsofquestions[$questionbankentryids]);
 | 
        
           |  |  | 328 |     }
 | 
        
           |  |  | 329 |   | 
        
           |  |  | 330 |     /**
 | 
        
           |  |  | 331 |      * Test population of latestversion field in question_definition objects
 | 
        
           |  |  | 332 |      *
 | 
        
           |  |  | 333 |      * When an instance of question_definition is created, it is added to an array of pending definitions which
 | 
        
           |  |  | 334 |      * do not yet have the latestversion field populated. When one definition has its latestversion property accessed,
 | 
        
           |  |  | 335 |      * all pending definitions have their latestversion field populated at once.
 | 
        
           |  |  | 336 |      *
 | 
        
           |  |  | 337 |      * @covers \core_question\output\question_version_info::populate_latest_versions()
 | 
        
           |  |  | 338 |      * @return void
 | 
        
           |  |  | 339 |      */
 | 
        
           | 11 | efrain | 340 |     public function test_populate_definition_latestversions(): void {
 | 
        
           | 1 | efrain | 341 |         $qcategory = $this->qgenerator->create_question_category(['contextid' => $this->context->id]);
 | 
        
           |  |  | 342 |         $question1 = $this->qgenerator->create_question('shortanswer', null, ['category' => $qcategory->id]);
 | 
        
           |  |  | 343 |         $question2 = $this->qgenerator->create_question('shortanswer', null, ['category' => $qcategory->id]);
 | 
        
           |  |  | 344 |         $question3 = $this->qgenerator->update_question($question2, null, ['idnumber' => 'id2']);
 | 
        
           |  |  | 345 |   | 
        
           |  |  | 346 |         $latestversioninspector = new \ReflectionProperty('question_definition', 'latestversion');
 | 
        
           |  |  | 347 |         $this->assertEmpty(question_version_info::$pendingdefinitions);
 | 
        
           |  |  | 348 |   | 
        
           |  |  | 349 |         $questiondef1 = question_bank::load_question($question1->id);
 | 
        
           |  |  | 350 |         $questiondef2 = question_bank::load_question($question2->id);
 | 
        
           |  |  | 351 |         $questiondef3 = question_bank::load_question($question3->id);
 | 
        
           |  |  | 352 |   | 
        
           |  |  | 353 |         $this->assertContains($questiondef1, question_version_info::$pendingdefinitions);
 | 
        
           |  |  | 354 |         $this->assertContains($questiondef2, question_version_info::$pendingdefinitions);
 | 
        
           |  |  | 355 |         $this->assertContains($questiondef3, question_version_info::$pendingdefinitions);
 | 
        
           |  |  | 356 |         $this->assertNull($latestversioninspector->getValue($questiondef1));
 | 
        
           |  |  | 357 |         $this->assertNull($latestversioninspector->getValue($questiondef2));
 | 
        
           |  |  | 358 |         $this->assertNull($latestversioninspector->getValue($questiondef3));
 | 
        
           |  |  | 359 |   | 
        
           |  |  | 360 |         // Read latestversion from one definition. This should populate the field in all pending definitions.
 | 
        
           |  |  | 361 |         $latestversion1 = $questiondef1->latestversion;
 | 
        
           |  |  | 362 |   | 
        
           |  |  | 363 |         $this->assertEmpty(question_version_info::$pendingdefinitions);
 | 
        
           |  |  | 364 |         $this->assertNotNull($latestversioninspector->getValue($questiondef1));
 | 
        
           |  |  | 365 |         $this->assertNotNull($latestversioninspector->getValue($questiondef2));
 | 
        
           |  |  | 366 |         $this->assertNotNull($latestversioninspector->getValue($questiondef3));
 | 
        
           |  |  | 367 |         $this->assertEquals($latestversion1, $latestversioninspector->getValue($questiondef1));
 | 
        
           |  |  | 368 |         $this->assertEquals($questiondef1->version, $questiondef1->latestversion);
 | 
        
           |  |  | 369 |         $this->assertNotEquals($questiondef2->version, $questiondef2->latestversion);
 | 
        
           |  |  | 370 |         $this->assertEquals($questiondef3->version, $questiondef3->latestversion);
 | 
        
           |  |  | 371 |     }
 | 
        
           |  |  | 372 | }
 |