Differences Between: [Versions 400 and 403] [Versions 401 and 403] [Versions 402 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 use mod_quiz\quiz_attempt; 17 use mod_quiz\quiz_settings; 18 19 /** 20 * Helper trait for quiz question unit tests. 21 * 22 * This trait helps to execute different tests for quiz, for example if it needs to create a quiz, add question 23 * to the question, add random quetion to the quiz, do a backup or restore. 24 * 25 * @package mod_quiz 26 * @category test 27 * @copyright 2021 Catalyst IT Australia Pty Ltd 28 * @author Safat Shahin <safatshahin@catalyst-au.net> 29 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 30 */ 31 trait quiz_question_helper_test_trait { 32 33 /** @var \stdClass $course Test course to contain quiz. */ 34 protected $course; 35 36 /** @var \stdClass $quiz A test quiz. */ 37 protected $quiz; 38 39 /** @var \stdClass $user A test logged-in user. */ 40 protected $user; 41 42 /** 43 * Create a test quiz for the specified course. 44 * 45 * @param \stdClass $course 46 * @return \stdClass 47 */ 48 protected function create_test_quiz(\stdClass $course): \stdClass { 49 50 /** @var mod_quiz_generator $quizgenerator */ 51 $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz'); 52 53 return $quizgenerator->create_instance([ 54 'course' => $course->id, 55 'questionsperpage' => 0, 56 'grade' => 100.0, 57 'sumgrades' => 2, 58 ]); 59 } 60 61 /** 62 * Helper method to add regular questions in quiz. 63 * 64 * @param component_generator_base $questiongenerator 65 * @param \stdClass $quiz 66 * @param array $override 67 */ 68 protected function add_two_regular_questions($questiongenerator, \stdClass $quiz, $override = null): void { 69 // Create a couple of questions. 70 $cat = $questiongenerator->create_question_category($override); 71 72 $saq = $questiongenerator->create_question('shortanswer', null, ['category' => $cat->id]); 73 // Create another version. 74 $questiongenerator->update_question($saq); 75 quiz_add_quiz_question($saq->id, $quiz); 76 $numq = $questiongenerator->create_question('numerical', null, ['category' => $cat->id]); 77 // Create two version. 78 $questiongenerator->update_question($numq); 79 $questiongenerator->update_question($numq); 80 quiz_add_quiz_question($numq->id, $quiz); 81 } 82 83 /** 84 * Helper method to add random question to quiz. 85 * 86 * @param component_generator_base $questiongenerator 87 * @param \stdClass $quiz 88 * @param array $override 89 */ 90 protected function add_one_random_question($questiongenerator, \stdClass $quiz, $override = []): void { 91 // Create a random question. 92 $cat = $questiongenerator->create_question_category($override); 93 $questiongenerator->create_question('truefalse', null, ['category' => $cat->id]); 94 $questiongenerator->create_question('essay', null, ['category' => $cat->id]); 95 $this->add_random_questions($quiz->id, 0, $cat->id, 1); 96 } 97 98 /** 99 * Attempt questions for a quiz and user. 100 * 101 * @param \stdClass $quiz Quiz to attempt. 102 * @param \stdClass $user A user to attempt the quiz. 103 * @param int $attemptnumber 104 * @return array 105 */ 106 protected function attempt_quiz(\stdClass $quiz, \stdClass $user, $attemptnumber = 1): array { 107 $this->setUser($user); 108 109 $starttime = time(); 110 $quizobj = quiz_settings::create($quiz->id, $user->id); 111 112 $quba = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj->get_context()); 113 $quba->set_preferred_behaviour($quizobj->get_quiz()->preferredbehaviour); 114 115 // Start the attempt. 116 $attempt = quiz_create_attempt($quizobj, $attemptnumber, null, $starttime, false, $user->id); 117 quiz_start_new_attempt($quizobj, $quba, $attempt, $attemptnumber, $starttime); 118 quiz_attempt_save_started($quizobj, $quba, $attempt); 119 120 // Finish the attempt. 121 $attemptobj = quiz_attempt::create($attempt->id); 122 $attemptobj->process_finish($starttime, false); 123 124 $this->setUser(); 125 return [$quizobj, $quba, $attemptobj]; 126 } 127 128 /** 129 * A helper method to backup test quiz. 130 * 131 * @param \stdClass $quiz Quiz to attempt. 132 * @param \stdClass $user A user to attempt the quiz. 133 * @return string A backup ID ready to be restored. 134 */ 135 protected function backup_quiz(\stdClass $quiz, \stdClass $user): string { 136 global $CFG; 137 138 // Get the necessary files to perform backup and restore. 139 require_once($CFG->dirroot . '/backup/util/includes/backup_includes.php'); 140 require_once($CFG->dirroot . '/backup/util/includes/restore_includes.php'); 141 142 $backupid = 'test-question-backup-restore'; 143 144 $bc = new backup_controller(backup::TYPE_1ACTIVITY, $quiz->cmid, backup::FORMAT_MOODLE, 145 backup::INTERACTIVE_NO, backup::MODE_GENERAL, $user->id); 146 $bc->execute_plan(); 147 148 $results = $bc->get_results(); 149 $file = $results['backup_destination']; 150 $fp = get_file_packer('application/vnd.moodle.backup'); 151 $filepath = $CFG->dataroot . '/temp/backup/' . $backupid; 152 $file->extract_to_pathname($fp, $filepath); 153 $bc->destroy(); 154 155 return $backupid; 156 } 157 158 /** 159 * A helper method to restore provided backup. 160 * 161 * @param string $backupid Backup ID to restore. 162 * @param stdClass $course 163 * @param stdClass $user 164 */ 165 protected function restore_quiz(string $backupid, stdClass $course, stdClass $user): void { 166 $rc = new restore_controller($backupid, $course->id, 167 backup::INTERACTIVE_NO, backup::MODE_GENERAL, $user->id, backup::TARGET_CURRENT_ADDING); 168 $this->assertTrue($rc->execute_precheck()); 169 $rc->execute_plan(); 170 $rc->destroy(); 171 } 172 173 /** 174 * A helper method to emulate duplication of the quiz. 175 * 176 * @param stdClass $course 177 * @param stdClass $quiz 178 * @return \cm_info|null 179 */ 180 protected function duplicate_quiz($course, $quiz): ?\cm_info { 181 return duplicate_module($course, get_fast_modinfo($course)->get_cm($quiz->cmid)); 182 } 183 184 /** 185 * Add random questions to a quiz, with a filter condition based on a category ID. 186 * 187 * @param int $quizid The quiz to add the questions to. 188 * @param int $page The page number to add the questions to. 189 * @param int $categoryid The category ID to use for the filter condition. 190 * @param int $number The number of questions to add. 191 * @return void 192 */ 193 protected function add_random_questions(int $quizid, int $page, int $categoryid, int $number): void { 194 $settings = quiz_settings::create($quizid); 195 $structure = \mod_quiz\structure::create_for_quiz($settings); 196 $filtercondition = [ 197 'filter' => [ 198 'category' => [ 199 'jointype' => \qbank_managecategories\category_condition::JOINTYPE_DEFAULT, 200 'values' => [$categoryid], 201 'filteroptions' => ['includesubcategories' => false], 202 ], 203 ], 204 ]; 205 $structure->add_random_questions($page, $number, $filtercondition); 206 } 207 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body