Differences Between: [Versions 310 and 311] [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403] [Versions 39 and 310]
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 * Tests for the quiz_attempt class. 19 * 20 * @package mod_quiz 21 * @category test 22 * @copyright 2014 Tim Hunt 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 defined('MOODLE_INTERNAL') || die(); 27 28 global $CFG; 29 require_once($CFG->dirroot . '/mod/quiz/locallib.php'); 30 31 /** 32 * Tests for the quiz_attempt class. 33 * 34 * @copyright 2014 Tim Hunt 35 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 36 */ 37 class mod_quiz_attempt_testcase extends advanced_testcase { 38 39 /** 40 * Create quiz and attempt data with layout. 41 * 42 * @param string $layout layout to set. Like quiz attempt.layout. E.g. '1,2,0,3,4,0,'. 43 * @return quiz_attempt the new quiz_attempt object 44 */ 45 protected function create_quiz_and_attempt_with_layout($layout) { 46 $this->resetAfterTest(true); 47 48 // Make a user to do the quiz. 49 $user = $this->getDataGenerator()->create_user(); 50 $course = $this->getDataGenerator()->create_course(); 51 // Make a quiz. 52 $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz'); 53 $quiz = $quizgenerator->create_instance(['course' => $course->id, 54 'grade' => 100.0, 'sumgrades' => 2, 'layout' => $layout]); 55 56 $quizobj = quiz::create($quiz->id, $user->id); 57 58 59 $quba = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj->get_context()); 60 $quba->set_preferred_behaviour($quizobj->get_quiz()->preferredbehaviour); 61 62 $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question'); 63 $cat = $questiongenerator->create_question_category(); 64 65 $page = 1; 66 foreach (explode(',', $layout) as $slot) { 67 if ($slot == 0) { 68 $page += 1; 69 continue; 70 } 71 72 $question = $questiongenerator->create_question('shortanswer', null, ['category' => $cat->id]); 73 quiz_add_quiz_question($question->id, $quiz, $page); 74 } 75 76 $timenow = time(); 77 $attempt = quiz_create_attempt($quizobj, 1, false, $timenow, false, $user->id); 78 quiz_start_new_attempt($quizobj, $quba, $attempt, 1, $timenow); 79 quiz_attempt_save_started($quizobj, $quba, $attempt); 80 81 return quiz_attempt::create($attempt->id); 82 } 83 84 public function test_attempt_url() { 85 $attempt = $this->create_quiz_and_attempt_with_layout('1,2,0,3,4,0,5,6,0'); 86 87 $attemptid = $attempt->get_attempt()->id; 88 $cmid = $attempt->get_cmid(); 89 $url = '/mod/quiz/attempt.php'; 90 $params = ['attempt' => $attemptid, 'cmid' => $cmid, 'page' => 2]; 91 92 $this->assertEquals(new moodle_url($url, $params), $attempt->attempt_url(null, 2)); 93 94 $params['page'] = 1; 95 $this->assertEquals(new moodle_url($url, $params), $attempt->attempt_url(3)); 96 97 $questionattempt = $attempt->get_question_attempt(4); 98 $expecteanchor = $questionattempt->get_outer_question_div_unique_id(); 99 $this->assertEquals(new moodle_url($url, $params, $expecteanchor), $attempt->attempt_url(4)); 100 101 $this->assertEquals(new moodle_url('#'), $attempt->attempt_url(null, 2, 2)); 102 $this->assertEquals(new moodle_url('#'), $attempt->attempt_url(3, -1, 1)); 103 104 $questionattempt = $attempt->get_question_attempt(4); 105 $expecteanchor = $questionattempt->get_outer_question_div_unique_id(); 106 $this->assertEquals(new moodle_url(null, null, $expecteanchor, null), $attempt->attempt_url(4, -1, 1)); 107 108 // Summary page. 109 $url = '/mod/quiz/summary.php'; 110 unset($params['page']); 111 $this->assertEquals(new moodle_url($url, $params), $attempt->summary_url()); 112 113 // Review page. 114 $url = '/mod/quiz/review.php'; 115 $this->assertEquals(new moodle_url($url, $params), $attempt->review_url()); 116 117 $params['page'] = 1; 118 $this->assertEquals(new moodle_url($url, $params), $attempt->review_url(3, -1, false)); 119 $this->assertEquals(new moodle_url($url, $params, $expecteanchor), $attempt->review_url(4, -1, false)); 120 121 unset($params['page']); 122 $this->assertEquals(new moodle_url($url, $params), $attempt->review_url(null, 2, true)); 123 $this->assertEquals(new moodle_url($url, $params), $attempt->review_url(1, -1, true)); 124 125 $params['page'] = 2; 126 $this->assertEquals(new moodle_url($url, $params), $attempt->review_url(null, 2, false)); 127 unset($params['page']); 128 129 $params['showall'] = 0; 130 $this->assertEquals(new moodle_url($url, $params), $attempt->review_url(null, 0, false)); 131 $this->assertEquals(new moodle_url($url, $params), $attempt->review_url(1, -1, false)); 132 133 $params['page'] = 1; 134 unset($params['showall']); 135 $this->assertEquals(new moodle_url($url, $params), $attempt->review_url(3, -1, false)); 136 137 $params['page'] = 2; 138 $this->assertEquals(new moodle_url($url, $params), $attempt->review_url(null, 2)); 139 $this->assertEquals(new moodle_url('#'), $attempt->review_url(null, -1, null, 0)); 140 141 $questionattempt = $attempt->get_question_attempt(3); 142 $expecteanchor = '#' . $questionattempt->get_outer_question_div_unique_id(); 143 $this->assertEquals(new moodle_url($expecteanchor), $attempt->review_url(3, -1, null, 0)); 144 145 $questionattempt = $attempt->get_question_attempt(4); 146 $expecteanchor = '#' . $questionattempt->get_outer_question_div_unique_id(); 147 $this->assertEquals(new moodle_url($expecteanchor), $attempt->review_url(4, -1, null, 0)); 148 $this->assertEquals(new moodle_url('#'), $attempt->review_url(null, 2, true, 0)); 149 $this->assertEquals(new moodle_url('#'), $attempt->review_url(1, -1, true, 0)); 150 $this->assertEquals(new moodle_url($url, $params), $attempt->review_url(null, 2, false, 0)); 151 $this->assertEquals(new moodle_url('#'), $attempt->review_url(null, 0, false, 0)); 152 $this->assertEquals(new moodle_url('#'), $attempt->review_url(1, -1, false, 0)); 153 154 $params['page'] = 1; 155 $this->assertEquals(new moodle_url($url, $params), $attempt->review_url(3, -1, false, 0)); 156 157 // Setup another attempt. 158 $attempt = $this->create_quiz_and_attempt_with_layout( 159 '1,2,3,4,5,6,7,8,9,10,0,11,12,13,14,15,16,17,18,19,20,0,' . 160 '21,22,23,24,25,26,27,28,29,30,0,31,32,33,34,35,36,37,38,39,40,0,' . 161 '41,42,43,44,45,46,47,48,49,50,0,51,52,53,54,55,56,57,58,59,60,0'); 162 163 $attemptid = $attempt->get_attempt()->id; 164 $cmid = $attempt->get_cmid(); 165 $params = ['attempt' => $attemptid, 'cmid' => $cmid]; 166 $this->assertEquals(new moodle_url($url, $params), $attempt->review_url()); 167 168 $params['page'] = 2; 169 $this->assertEquals(new moodle_url($url, $params), $attempt->review_url(null, 2)); 170 171 $params['page'] = 1; 172 unset($params['showall']); 173 $this->assertEquals(new moodle_url($url, $params), $attempt->review_url(11, -1, false)); 174 175 $questionattempt = $attempt->get_question_attempt(12); 176 $expecteanchor = $questionattempt->get_outer_question_div_unique_id(); 177 $this->assertEquals(new moodle_url($url, $params, $expecteanchor), $attempt->review_url(12, -1, false)); 178 179 $params['showall'] = 1; 180 unset($params['page']); 181 $this->assertEquals(new moodle_url($url, $params), $attempt->review_url(null, 2, true)); 182 183 $this->assertEquals(new moodle_url($url, $params), $attempt->review_url(1, -1, true)); 184 $params['page'] = 2; 185 unset($params['showall']); 186 $this->assertEquals(new moodle_url($url, $params), $attempt->review_url(null, 2, false)); 187 unset($params['page']); 188 $this->assertEquals(new moodle_url($url, $params), $attempt->review_url(null, 0, false)); 189 $params['page'] = 1; 190 $this->assertEquals(new moodle_url($url, $params), $attempt->review_url(11, -1, false)); 191 $this->assertEquals(new moodle_url($url, $params, $expecteanchor), $attempt->review_url(12, -1, false)); 192 $params['page'] = 2; 193 $this->assertEquals(new moodle_url($url, $params), $attempt->review_url(null, 2)); 194 $this->assertEquals(new moodle_url('#'), $attempt->review_url(null, -1, null, 0)); 195 196 $questionattempt = $attempt->get_question_attempt(3); 197 $expecteanchor = $questionattempt->get_outer_question_div_unique_id(); 198 $this->assertEquals(new moodle_url(null, null, $expecteanchor), $attempt->review_url(3, -1, null, 0)); 199 200 $questionattempt = $attempt->get_question_attempt(4); 201 $expecteanchor = $questionattempt->get_outer_question_div_unique_id(); 202 $this->assertEquals(new moodle_url(null, null, $expecteanchor), $attempt->review_url(4, -1, null, 0)); 203 204 $this->assertEquals(new moodle_url('#'), $attempt->review_url(null, 2, true, 0)); 205 $this->assertEquals(new moodle_url('#'), $attempt->review_url(1, -1, true, 0)); 206 207 $params['page'] = 2; 208 $this->assertEquals(new moodle_url($url, $params), $attempt->review_url(null, 2, false, 0)); 209 $this->assertEquals(new moodle_url('#'), $attempt->review_url(null, 0, false, 0)); 210 $this->assertEquals(new moodle_url('#'), $attempt->review_url(1, -1, false, 0)); 211 212 $params['page'] = 1; 213 $this->assertEquals(new moodle_url($url, $params), $attempt->review_url(11, -1, false, 0)); 214 } 215 216 /** 217 * Tests attempt page titles when all questions are on a single page. 218 */ 219 public function test_attempt_titles_single() { 220 $attempt = $this->create_quiz_and_attempt_with_layout('1,2,0'); 221 222 // Attempt page. 223 $this->assertEquals('Quiz 1', $attempt->attempt_page_title(0)); 224 225 // Summary page. 226 $this->assertEquals('Quiz 1: Attempt summary', $attempt->summary_page_title()); 227 228 // Review page. 229 $this->assertEquals('Quiz 1: Attempt review', $attempt->review_page_title(0)); 230 } 231 232 /** 233 * Tests attempt page titles when questions are on multiple pages, but are reviewed on a single page. 234 */ 235 public function test_attempt_titles_multiple_single() { 236 $attempt = $this->create_quiz_and_attempt_with_layout('1,2,0,3,4,0,5,6,0'); 237 238 // Attempt page. 239 $this->assertEquals('Quiz 1 (page 1 of 3)', $attempt->attempt_page_title(0)); 240 $this->assertEquals('Quiz 1 (page 2 of 3)', $attempt->attempt_page_title(1)); 241 $this->assertEquals('Quiz 1 (page 3 of 3)', $attempt->attempt_page_title(2)); 242 243 // Summary page. 244 $this->assertEquals('Quiz 1: Attempt summary', $attempt->summary_page_title()); 245 246 // Review page. 247 $this->assertEquals('Quiz 1: Attempt review', $attempt->review_page_title(0, true)); 248 } 249 250 /** 251 * Tests attempt page titles when questions are on multiple pages, and they are reviewed on multiple pages as well. 252 */ 253 public function test_attempt_titles_multiple_multiple() { 254 $attempt = $this->create_quiz_and_attempt_with_layout( 255 '1,2,3,4,5,6,7,8,9,10,0,11,12,13,14,15,16,17,18,19,20,0,' . 256 '21,22,23,24,25,26,27,28,29,30,0,31,32,33,34,35,36,37,38,39,40,0,' . 257 '41,42,43,44,45,46,47,48,49,50,0,51,52,53,54,55,56,57,58,59,60,0'); 258 259 // Attempt page. 260 $this->assertEquals('Quiz 1 (page 1 of 6)', $attempt->attempt_page_title(0)); 261 $this->assertEquals('Quiz 1 (page 2 of 6)', $attempt->attempt_page_title(1)); 262 $this->assertEquals('Quiz 1 (page 6 of 6)', $attempt->attempt_page_title(5)); 263 264 // Summary page. 265 $this->assertEquals('Quiz 1: Attempt summary', $attempt->summary_page_title()); 266 267 // Review page. 268 $this->assertEquals('Quiz 1: Attempt review (page 1 of 6)', $attempt->review_page_title(0)); 269 $this->assertEquals('Quiz 1: Attempt review (page 2 of 6)', $attempt->review_page_title(1)); 270 $this->assertEquals('Quiz 1: Attempt review (page 6 of 6)', $attempt->review_page_title(5)); 271 272 // When all questions are shown. 273 $this->assertEquals('Quiz 1: Attempt review', $attempt->review_page_title(0, true)); 274 $this->assertEquals('Quiz 1: Attempt review', $attempt->review_page_title(1, true)); 275 } 276 277 public function test_is_participant() { 278 global $USER; 279 $this->resetAfterTest(); 280 $this->setAdminUser(); 281 $course = $this->getDataGenerator()->create_course(); 282 $student = $this->getDataGenerator()->create_and_enrol($course, 'student'); 283 $student2 = $this->getDataGenerator()->create_and_enrol($course, 'student', [], 'manual', 0, 0, ENROL_USER_SUSPENDED); 284 $quiz = $this->getDataGenerator()->create_module('quiz', array('course' => $course->id)); 285 $quizobj = quiz::create($quiz->id); 286 287 // Login as student. 288 $this->setUser($student); 289 // Convert to a lesson object. 290 $this->assertEquals(true, $quizobj->is_participant($student->id), 291 'Student is enrolled, active and can participate'); 292 293 // Login as student2. 294 $this->setUser($student2); 295 $this->assertEquals(false, $quizobj->is_participant($student2->id), 296 'Student is enrolled, suspended and can NOT participate'); 297 298 // Login as an admin. 299 $this->setAdminUser(); 300 $this->assertEquals(false, $quizobj->is_participant($USER->id), 301 'Admin is not enrolled and can NOT participate'); 302 303 $this->getDataGenerator()->enrol_user(2, $course->id); 304 $this->assertEquals(true, $quizobj->is_participant($USER->id), 305 'Admin is enrolled and can participate'); 306 307 $this->getDataGenerator()->enrol_user(2, $course->id, [], 'manual', 0, 0, ENROL_USER_SUSPENDED); 308 $this->assertEquals(true, $quizobj->is_participant($USER->id), 309 'Admin is enrolled, suspended and can participate'); 310 } 311 312 /** 313 * Test quiz_prepare_and_start_new_attempt function 314 */ 315 public function test_quiz_prepare_and_start_new_attempt() { 316 global $USER; 317 $this->resetAfterTest(); 318 319 // Create course. 320 $course = $this->getDataGenerator()->create_course(); 321 // Create students. 322 $student1 = $this->getDataGenerator()->create_and_enrol($course, 'student'); 323 $student2 = $this->getDataGenerator()->create_and_enrol($course, 'student'); 324 // Create quiz. 325 $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz'); 326 $quiz = $quizgenerator->create_instance(['course' => $course->id, 'grade' => 100.0, 'sumgrades' => 2, 'layout' => '1,0']); 327 // Create question and add it to quiz. 328 $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question'); 329 $cat = $questiongenerator->create_question_category(); 330 $question = $questiongenerator->create_question('shortanswer', null, ['category' => $cat->id]); 331 quiz_add_quiz_question($question->id, $quiz, 1); 332 333 $quizobj = quiz::create($quiz->id); 334 335 // Login as student1. 336 $this->setUser($student1); 337 // Create attempt for student1. 338 $attempt = quiz_prepare_and_start_new_attempt($quizobj, 1, null, false, [], []); 339 $this->assertEquals($student1->id, $attempt->userid); 340 $this->assertEquals(0, $attempt->preview); 341 342 // Login as student2. 343 $this->setUser($student2); 344 // Create attempt for student2. 345 $attempt = quiz_prepare_and_start_new_attempt($quizobj, 1, null, false, [], []); 346 $this->assertEquals($student2->id, $attempt->userid); 347 $this->assertEquals(0, $attempt->preview); 348 349 // Login as admin. 350 $this->setAdminUser(); 351 // Create attempt for student1. 352 $attempt = quiz_prepare_and_start_new_attempt($quizobj, 2, null, false, [], [], $student1->id); 353 $this->assertEquals($student1->id, $attempt->userid); 354 $this->assertEquals(0, $attempt->preview); 355 $student1attempt = $attempt; // Save for extra verification below. 356 // Create attempt for student2. 357 $attempt = quiz_prepare_and_start_new_attempt($quizobj, 2, null, false, [], [], $student2->id); 358 $this->assertEquals($student2->id, $attempt->userid); 359 $this->assertEquals(0, $attempt->preview); 360 // Create attempt for user id that the same with current $USER->id. 361 $attempt = quiz_prepare_and_start_new_attempt($quizobj, 2, null, false, [], [], $USER->id); 362 $this->assertEquals($USER->id, $attempt->userid); 363 $this->assertEquals(1, $attempt->preview); 364 365 // Check that the userid stored in the first step is the user the attempt is for, 366 // not the user who triggered the creation. 367 $quba = question_engine::load_questions_usage_by_activity($student1attempt->uniqueid); 368 $step = $quba->get_question_attempt(1)->get_step(0); 369 $this->assertEquals($student1->id, $step->get_user_id()); 370 } 371 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body