See Release Notes
Long Term Support Release
Differences Between: [Versions 39 and 310] [Versions 39 and 311] [Versions 39 and 400] [Versions 39 and 401] [Versions 39 and 402] [Versions 39 and 403]
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 /** 18 * Unit tests for the {@link \mod_quiz\local\structure\slot_random} class. 19 * 20 * @package mod_quiz 21 * @category test 22 * @copyright 2018 Shamim Rezaie <shamim@moodle.com> 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 defined('MOODLE_INTERNAL') || die(); 27 28 /** 29 * Class mod_quiz_local_structure_slot_random_test 30 * Class for tests related to the {@link \mod_quiz\local\structure\slot_random} class. 31 * 32 * @copyright 2018 Shamim Rezaie <shamim@moodle.com> 33 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 34 */ 35 class mod_quiz_local_structure_slot_random_test extends advanced_testcase { 36 /** 37 * Constructor test. 38 */ 39 public function test_constructor() { 40 global $SITE; 41 42 $this->resetAfterTest(); 43 $this->setAdminUser(); 44 45 // Create a quiz. 46 $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz'); 47 $quiz = $quizgenerator->create_instance(array('course' => $SITE->id, 'questionsperpage' => 3, 'grade' => 100.0)); 48 49 // Create a question category in the system context. 50 $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question'); 51 $category = $questiongenerator->create_question_category(); 52 53 // Create a random question without adding it to a quiz. 54 // We don't want to use quiz_add_random_questions because that itself, instantiates an object from the slot_random class. 55 $form = new stdClass(); 56 $form->category = $category->id . ',' . $category->contextid; 57 $form->includesubcategories = true; 58 $form->fromtags = []; 59 $form->defaultmark = 1; 60 $form->hidden = 1; 61 $form->stamp = make_unique_id_code(); 62 $question = new stdClass(); 63 $question->qtype = 'random'; 64 $question = question_bank::get_qtype('random')->save_question($question, $form); 65 66 $randomslotdata = new stdClass(); 67 $randomslotdata->quizid = $quiz->id; 68 $randomslotdata->questionid = $question->id; 69 $randomslotdata->questioncategoryid = $category->id; 70 $randomslotdata->includingsubcategories = 1; 71 $randomslotdata->maxmark = 1; 72 73 $randomslot = new \mod_quiz\local\structure\slot_random($randomslotdata); 74 75 $rc = new ReflectionClass('\mod_quiz\local\structure\slot_random'); 76 $rcp = $rc->getProperty('record'); 77 $rcp->setAccessible(true); 78 $record = $rcp->getValue($randomslot); 79 80 $this->assertEquals($quiz->id, $record->quizid); 81 $this->assertEquals($question->id, $record->questionid); 82 $this->assertEquals($category->id, $record->questioncategoryid); 83 $this->assertEquals(1, $record->includingsubcategories); 84 $this->assertEquals(1, $record->maxmark); 85 } 86 87 public function test_get_quiz_quiz() { 88 global $SITE, $DB; 89 90 $this->resetAfterTest(); 91 $this->setAdminUser(); 92 93 // Create a quiz. 94 $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz'); 95 $quiz = $quizgenerator->create_instance(array('course' => $SITE->id, 'questionsperpage' => 3, 'grade' => 100.0)); 96 97 // Create a question category in the system context. 98 $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question'); 99 $category = $questiongenerator->create_question_category(); 100 101 quiz_add_random_questions($quiz, 0, $category->id, 1, false); 102 103 // Get the random question's id. It is at the first slot. 104 $questionid = $DB->get_field('quiz_slots', 'questionid', array('quizid' => $quiz->id, 'slot' => 1)); 105 106 $randomslotdata = new stdClass(); 107 $randomslotdata->quizid = $quiz->id; 108 $randomslotdata->questionid = $questionid; 109 $randomslotdata->questioncategoryid = $category->id; 110 $randomslotdata->includingsubcategories = 1; 111 $randomslotdata->maxmark = 1; 112 113 $randomslot = new \mod_quiz\local\structure\slot_random($randomslotdata); 114 115 // The create_instance had injected an additional cmid propery to the quiz. Let's remove that. 116 unset($quiz->cmid); 117 118 $this->assertEquals($quiz, $randomslot->get_quiz()); 119 } 120 121 public function test_set_quiz() { 122 global $SITE, $DB; 123 124 $this->resetAfterTest(); 125 $this->setAdminUser(); 126 127 // Create a quiz. 128 $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz'); 129 $quiz = $quizgenerator->create_instance(array('course' => $SITE->id, 'questionsperpage' => 3, 'grade' => 100.0)); 130 131 // Create a question category in the system context. 132 $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question'); 133 $category = $questiongenerator->create_question_category(); 134 135 quiz_add_random_questions($quiz, 0, $category->id, 1, false); 136 137 // Get the random question's id. It is at the first slot. 138 $questionid = $DB->get_field('quiz_slots', 'questionid', array('quizid' => $quiz->id, 'slot' => 1)); 139 140 $randomslotdata = new stdClass(); 141 $randomslotdata->quizid = $quiz->id; 142 $randomslotdata->questionid = $questionid; 143 $randomslotdata->questioncategoryid = $category->id; 144 $randomslotdata->includingsubcategories = 1; 145 $randomslotdata->maxmark = 1; 146 147 $randomslot = new \mod_quiz\local\structure\slot_random($randomslotdata); 148 149 // The create_instance had injected an additional cmid propery to the quiz. Let's remove that. 150 unset($quiz->cmid); 151 152 $randomslot->set_quiz($quiz); 153 154 $rc = new ReflectionClass('\mod_quiz\local\structure\slot_random'); 155 $rcp = $rc->getProperty('quiz'); 156 $rcp->setAccessible(true); 157 $quizpropery = $rcp->getValue($randomslot); 158 159 $this->assertEquals($quiz, $quizpropery); 160 } 161 162 private function setup_for_test_tags($tagnames) { 163 global $SITE, $DB; 164 165 // Create a quiz. 166 $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz'); 167 $quiz = $quizgenerator->create_instance(array('course' => $SITE->id, 'questionsperpage' => 3, 'grade' => 100.0)); 168 169 // Create a question category in the system context. 170 $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question'); 171 $category = $questiongenerator->create_question_category(); 172 173 quiz_add_random_questions($quiz, 0, $category->id, 1, false); 174 175 // Get the random question's id. It is at the first slot. 176 $questionid = $DB->get_field('quiz_slots', 'questionid', array('quizid' => $quiz->id, 'slot' => 1)); 177 178 $randomslotdata = new stdClass(); 179 $randomslotdata->quizid = $quiz->id; 180 $randomslotdata->questionid = $questionid; 181 $randomslotdata->questioncategoryid = $category->id; 182 $randomslotdata->includingsubcategories = 1; 183 $randomslotdata->maxmark = 1; 184 185 $randomslot = new \mod_quiz\local\structure\slot_random($randomslotdata); 186 187 // Create tags. 188 foreach ($tagnames as $tagname) { 189 $tagrecord = array( 190 'isstandard' => 1, 191 'flag' => 0, 192 'rawname' => $tagname, 193 'description' => $tagname . ' desc' 194 ); 195 $tags[$tagname] = $this->getDataGenerator()->create_tag($tagrecord); 196 } 197 198 return array($randomslot, $tags); 199 } 200 201 public function test_set_tags() { 202 $this->resetAfterTest(); 203 $this->setAdminUser(); 204 205 list($randomslot, $tags) = $this->setup_for_test_tags(['foo', 'bar']); 206 $randomslot->set_tags([$tags['foo'], $tags['bar']]); 207 208 $rc = new ReflectionClass('\mod_quiz\local\structure\slot_random'); 209 $rcp = $rc->getProperty('tags'); 210 $rcp->setAccessible(true); 211 $tagspropery = $rcp->getValue($randomslot); 212 213 $this->assertEquals([ 214 $tags['foo']->id => $tags['foo'], 215 $tags['bar']->id => $tags['bar'], 216 ], $tagspropery); 217 } 218 219 public function test_set_tags_twice() { 220 $this->resetAfterTest(); 221 $this->setAdminUser(); 222 223 list($randomslot, $tags) = $this->setup_for_test_tags(['foo', 'bar', 'baz']); 224 225 // Set tags for the first time. 226 $randomslot->set_tags([$tags['foo'], $tags['bar']]); 227 // Now set the tags again. 228 $randomslot->set_tags([$tags['baz']]); 229 230 $rc = new ReflectionClass('\mod_quiz\local\structure\slot_random'); 231 $rcp = $rc->getProperty('tags'); 232 $rcp->setAccessible(true); 233 $tagspropery = $rcp->getValue($randomslot); 234 235 $this->assertEquals([ 236 $tags['baz']->id => $tags['baz'], 237 ], $tagspropery); 238 } 239 240 public function test_set_tags_duplicates() { 241 $this->resetAfterTest(); 242 $this->setAdminUser(); 243 244 list($randomslot, $tags) = $this->setup_for_test_tags(['foo', 'bar', 'baz']); 245 246 $randomslot->set_tags([$tags['foo'], $tags['bar'], $tags['foo']]); 247 248 $rc = new ReflectionClass('\mod_quiz\local\structure\slot_random'); 249 $rcp = $rc->getProperty('tags'); 250 $rcp->setAccessible(true); 251 $tagspropery = $rcp->getValue($randomslot); 252 253 $this->assertEquals([ 254 $tags['foo']->id => $tags['foo'], 255 $tags['bar']->id => $tags['bar'], 256 ], $tagspropery); 257 } 258 259 public function test_set_tags_by_id() { 260 $this->resetAfterTest(); 261 $this->setAdminUser(); 262 263 list($randomslot, $tags) = $this->setup_for_test_tags(['foo', 'bar', 'baz']); 264 265 $randomslot->set_tags_by_id([$tags['foo']->id, $tags['bar']->id]); 266 267 $rc = new ReflectionClass('\mod_quiz\local\structure\slot_random'); 268 $rcp = $rc->getProperty('tags'); 269 $rcp->setAccessible(true); 270 $tagspropery = $rcp->getValue($randomslot); 271 272 // The set_tags_by_id function only retrieves id and name fields of the tag object. 273 $this->assertCount(2, $tagspropery); 274 $this->assertArrayHasKey($tags['foo']->id, $tagspropery); 275 $this->assertArrayHasKey($tags['bar']->id, $tagspropery); 276 $this->assertEquals( 277 (object)['id' => $tags['foo']->id, 'name' => $tags['foo']->name], 278 $tagspropery[$tags['foo']->id]->to_object() 279 ); 280 $this->assertEquals( 281 (object)['id' => $tags['bar']->id, 'name' => $tags['bar']->name], 282 $tagspropery[$tags['bar']->id]->to_object() 283 ); 284 } 285 286 public function test_set_tags_by_id_twice() { 287 $this->resetAfterTest(); 288 $this->setAdminUser(); 289 290 list($randomslot, $tags) = $this->setup_for_test_tags(['foo', 'bar', 'baz']); 291 292 // Set tags for the first time. 293 $randomslot->set_tags_by_id([$tags['foo']->id, $tags['bar']->id]); 294 // Now set the tags again. 295 $randomslot->set_tags_by_id([$tags['baz']->id]); 296 297 $rc = new ReflectionClass('\mod_quiz\local\structure\slot_random'); 298 $rcp = $rc->getProperty('tags'); 299 $rcp->setAccessible(true); 300 $tagspropery = $rcp->getValue($randomslot); 301 302 // The set_tags_by_id function only retrieves id and name fields of the tag object. 303 $this->assertCount(1, $tagspropery); 304 $this->assertArrayHasKey($tags['baz']->id, $tagspropery); 305 $this->assertEquals( 306 (object)['id' => $tags['baz']->id, 'name' => $tags['baz']->name], 307 $tagspropery[$tags['baz']->id]->to_object() 308 ); 309 } 310 311 public function test_set_tags_by_id_duplicates() { 312 $this->resetAfterTest(); 313 $this->setAdminUser(); 314 315 list($randomslot, $tags) = $this->setup_for_test_tags(['foo', 'bar', 'baz']); 316 317 $randomslot->set_tags_by_id([$tags['foo']->id, $tags['bar']->id], $tags['foo']->id); 318 319 $rc = new ReflectionClass('\mod_quiz\local\structure\slot_random'); 320 $rcp = $rc->getProperty('tags'); 321 $rcp->setAccessible(true); 322 $tagspropery = $rcp->getValue($randomslot); 323 324 // The set_tags_by_id function only retrieves id and name fields of the tag object. 325 $this->assertCount(2, $tagspropery); 326 $this->assertArrayHasKey($tags['foo']->id, $tagspropery); 327 $this->assertArrayHasKey($tags['bar']->id, $tagspropery); 328 $this->assertEquals( 329 (object)['id' => $tags['foo']->id, 'name' => $tags['foo']->name], 330 $tagspropery[$tags['foo']->id]->to_object() 331 ); 332 $this->assertEquals( 333 (object)['id' => $tags['bar']->id, 'name' => $tags['bar']->name], 334 $tagspropery[$tags['bar']->id]->to_object() 335 ); 336 } 337 338 public function test_insert() { 339 global $SITE, $DB; 340 341 $this->resetAfterTest(); 342 $this->setAdminUser(); 343 344 // Create a quiz. 345 $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz'); 346 $quiz = $quizgenerator->create_instance(array('course' => $SITE->id, 'questionsperpage' => 3, 'grade' => 100.0)); 347 348 // Create a question category in the system context. 349 $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question'); 350 $category = $questiongenerator->create_question_category(); 351 352 // Create a random question without adding it to a quiz. 353 $form = new stdClass(); 354 $form->category = $category->id . ',' . $category->contextid; 355 $form->includesubcategories = true; 356 $form->fromtags = []; 357 $form->defaultmark = 1; 358 $form->hidden = 1; 359 $form->stamp = make_unique_id_code(); 360 $question = new stdClass(); 361 $question->qtype = 'random'; 362 $question = question_bank::get_qtype('random')->save_question($question, $form); 363 364 // Prepare 2 tags. 365 $tagrecord = array( 366 'isstandard' => 1, 367 'flag' => 0, 368 'rawname' => 'foo', 369 'description' => 'foo desc' 370 ); 371 $footag = $this->getDataGenerator()->create_tag($tagrecord); 372 $tagrecord = array( 373 'isstandard' => 1, 374 'flag' => 0, 375 'rawname' => 'bar', 376 'description' => 'bar desc' 377 ); 378 $bartag = $this->getDataGenerator()->create_tag($tagrecord); 379 380 $randomslotdata = new stdClass(); 381 $randomslotdata->quizid = $quiz->id; 382 $randomslotdata->questionid = $question->id; 383 $randomslotdata->questioncategoryid = $category->id; 384 $randomslotdata->includingsubcategories = 1; 385 $randomslotdata->maxmark = 1; 386 387 // Insert the random question to the quiz. 388 $randomslot = new \mod_quiz\local\structure\slot_random($randomslotdata); 389 $randomslot->set_tags([$footag, $bartag]); 390 $randomslot->insert(1); // Put the question on the first page of the quiz. 391 392 // Get the random question's quiz_slot. It is at the first slot. 393 $quizslot = $DB->get_record('quiz_slots', array('quizid' => $quiz->id, 'slot' => 1)); 394 // Get the random question's tags from quiz_slot_tags. It is at the first slot. 395 $quizslottags = $DB->get_records('quiz_slot_tags', array('slotid' => $quizslot->id)); 396 397 $this->assertEquals($question->id, $quizslot->questionid); 398 $this->assertEquals($category->id, $quizslot->questioncategoryid); 399 $this->assertEquals(1, $quizslot->includingsubcategories); 400 $this->assertEquals(1, $quizslot->maxmark); 401 402 $this->assertCount(2, $quizslottags); 403 $this->assertEquals( 404 [ 405 ['tagid' => $footag->id, 'tagname' => $footag->name], 406 ['tagid' => $bartag->id, 'tagname' => $bartag->name] 407 ], 408 array_map(function($slottag) { 409 return ['tagid' => $slottag->tagid, 'tagname' => $slottag->tagname]; 410 }, $quizslottags), 411 '', 0.0, 10, true); 412 } 413 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body