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 17 namespace qbank_bulkmove; 18 19 use core_question\local\bank\question_edit_contexts; 20 21 defined('MOODLE_INTERNAL') || die(); 22 23 global $CFG; 24 require_once($CFG->dirroot . '/question/editlib.php'); 25 26 /** 27 * Bulk move helper tests. 28 * 29 * @package qbank_bulkmove 30 * @copyright 2021 Catalyst IT Australia Pty Ltd 31 * @author Safat Shahin <safatshahin@catalyst-au.net> 32 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 33 * @coversDefaultClass \qbank_bulkmove\helper 34 */ 35 class helper_test extends \advanced_testcase { 36 37 /** 38 * @var false|object|\stdClass|null $cat 39 */ 40 protected $cat; 41 42 /** 43 * @var \stdClass $questiondata1 44 */ 45 protected $questiondata1; 46 47 /** 48 * @var \stdClass $questiondata2 49 */ 50 protected $questiondata2; 51 52 /** 53 * @var bool|\context|\context_course $context 54 */ 55 protected $context; 56 57 /** 58 * @var \core_question\local\bank\question_edit_contexts $contexts 59 */ 60 protected $contexts; 61 62 /** 63 * @var \stdClass $course 64 */ 65 protected $course; 66 67 /** 68 * @var array $rawdata 69 */ 70 protected $rawdata; 71 72 /** 73 * @var object $secondcategory 74 */ 75 protected $secondcategory; 76 77 /** 78 * Setup the test. 79 */ 80 protected function helper_setup(): void { 81 $this->resetAfterTest(); 82 $this->setAdminUser(); 83 $generator = $this->getDataGenerator(); 84 /** @var \core_question_generator $questiongenerator */ 85 $questiongenerator = $generator->get_plugin_generator('core_question'); 86 87 // Create a course. 88 $this->course = $generator->create_course(); 89 $this->context = \context_course::instance($this->course->id); 90 91 // Create a question in the default category. 92 $this->contexts = new question_edit_contexts($this->context); 93 $this->cat = question_make_default_categories($this->contexts->all()); 94 $this->questiondata1 = $questiongenerator->create_question('numerical', null, 95 ['name' => 'Example question', 'category' => $this->cat->id]); 96 97 // Create a second category to move questions. 98 $this->secondcategory = $questiongenerator->create_question_category(['contextid' => $this->context->id, 99 'parent' => $this->cat->id]); 100 101 // Ensure the question is not in the cache. 102 $cache = \cache::make('core', 'questiondata'); 103 $cache->delete($this->questiondata1->id); 104 105 $this->questiondata2 = $questiongenerator->create_question('numerical', null, 106 ['name' => 'Example question second', 'category' => $this->cat->id]); 107 108 // Ensure the question is not in the cache. 109 $cache = \cache::make('core', 'questiondata'); 110 $cache->delete($this->questiondata2->id); 111 112 // Posted raw data. 113 $this->rawdata = [ 114 'courseid' => $this->course->id, 115 'cat' => "{$this->cat->id},{$this->context->id}", 116 'qpage' => '0', 117 "q{$this->questiondata1->id}" => '1', 118 "q{$this->questiondata2->id}" => '1', 119 'move' => 'Move to' 120 ]; 121 } 122 123 /** 124 * Count how many questions in the list belong to the given category. 125 * 126 * @param string $categoryid a category id 127 * @param array $questionids list of question ids 128 * @return int 129 */ 130 private function count_category_questions(string $categoryid, array $questionids): int { 131 global $DB; 132 $this->assertNotEmpty($questionids); 133 list($insql, $inparams) = $DB->get_in_or_equal($questionids, SQL_PARAMS_NAMED); 134 $sql = "SELECT COUNT(q.id) 135 FROM {question} q 136 JOIN {question_versions} qv ON qv.questionid = q.id 137 JOIN {question_bank_entries} qbe ON qbe.id = qv.questionbankentryid 138 JOIN {question_categories} qc ON qc.id = qbe.questioncategoryid 139 WHERE qc.id = :categoryid 140 AND q.id $insql"; 141 142 return $DB->count_records_sql($sql, array_merge(['categoryid' => $categoryid], $inparams)); 143 } 144 145 /** 146 * Assert that the given category contains following questions 147 * 148 * @param string $categoryid a category id 149 * @param array $questionids list of question ids 150 * @return void 151 */ 152 protected function assert_category_contains_questions(string $categoryid, array $questionids) { 153 // The category need to contain all the questions. 154 $this->assertEquals(count($questionids), $this->count_category_questions($categoryid, $questionids)); 155 } 156 157 /** 158 * Assert that the given category does not contain following questions 159 * 160 * @param string $categoryid a category id 161 * @param array $questionids list of question ids 162 * @return void 163 */ 164 protected function assert_category_does_not_contain_questions(string $categoryid, array $questionids) { 165 // The category does not contain any question. 166 $this->assertEquals(0, $this->count_category_questions($categoryid, $questionids)); 167 } 168 169 /** 170 * Test bulk move of questions. 171 * 172 * @covers ::bulk_move_questions 173 */ 174 public function test_bulk_move_questions() { 175 global $DB; 176 $this->helper_setup(); 177 178 // Get the processed question ids. 179 $questionlist = $this->process_question_ids_test(); 180 $questionids = array_map('intval', explode(',', $questionlist)); 181 182 // Verify that the questions are available in the current view. 183 $this->assert_category_contains_questions($this->cat->id, $questionids); 184 helper::bulk_move_questions($questionlist, $this->secondcategory); 185 186 // Verify the questions are not in the current category. 187 $this->assert_category_does_not_contain_questions($this->cat->id, $questionids); 188 189 // Verify the questions are in the new category. 190 $this->assert_category_contains_questions($this->secondcategory->id, $questionids); 191 } 192 193 /** 194 * Test the question processing and return the question list. 195 * 196 * @return mixed 197 * @covers ::process_question_ids 198 */ 199 protected function process_question_ids_test() { 200 // Test the raw data processing. 201 list($questionids, $questionlist) = helper::process_question_ids($this->rawdata); 202 $this->assertEquals([$this->questiondata1->id, $this->questiondata2->id], $questionids); 203 $this->assertEquals("{$this->questiondata1->id},{$this->questiondata2->id}", $questionlist); 204 return $questionlist; 205 } 206 207 /** 208 * Test the question displaydata. 209 * 210 * @covers ::get_displaydata 211 */ 212 public function test_get_displaydata() { 213 $this->helper_setup(); 214 $coursecontext = \context_course::instance($this->course->id); 215 $contexts = new question_edit_contexts($coursecontext); 216 $addcontexts = $contexts->having_cap('moodle/question:add'); 217 $url = new \moodle_url('/question/bank/bulkmove/move.php'); 218 $displaydata = \qbank_bulkmove\helper::get_displaydata($addcontexts, $url, $url); 219 $this->assertStringContainsString('Test question category 1', $displaydata['categorydropdown']); 220 $this->assertStringContainsString('Default for Category 1', $displaydata['categorydropdown']); 221 $this->assertEquals($url, $displaydata ['moveurl']); 222 $this->assertEquals($url, $displaydata ['returnurl']); 223 } 224 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body