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 * Glossary search unit tests. 19 * 20 * @package mod_glossary 21 * @category test 22 * @copyright 2016 David Monllao {@link http://www.davidmonllao.com} 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 namespace mod_glossary\search; 27 28 defined('MOODLE_INTERNAL') || die(); 29 30 global $CFG; 31 require_once($CFG->dirroot . '/search/tests/fixtures/testable_core_search.php'); 32 require_once($CFG->dirroot . '/mod/glossary/tests/generator/lib.php'); 33 34 /** 35 * Provides the unit tests for glossary search. 36 * 37 * @package mod_glossary 38 * @category test 39 * @copyright 2016 David Monllao {@link http://www.davidmonllao.com} 40 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 41 */ 42 class search_test extends \advanced_testcase { 43 44 /** 45 * @var string Area id 46 */ 47 protected $entryareaid = null; 48 49 public function setUp(): void { 50 $this->resetAfterTest(true); 51 set_config('enableglobalsearch', true); 52 53 // Set \core_search::instance to the mock_search_engine as we don't require the search engine to be working to test this. 54 $search = \testable_core_search::instance(); 55 56 $this->entryareaid = \core_search\manager::generate_areaid('mod_glossary', 'entry'); 57 } 58 59 /** 60 * Availability. 61 * 62 * @return void 63 */ 64 public function test_search_enabled() { 65 66 $searcharea = \core_search\manager::get_search_area($this->entryareaid); 67 list($componentname, $varname) = $searcharea->get_config_var_name(); 68 69 // Enabled by default once global search is enabled. 70 $this->assertTrue($searcharea->is_enabled()); 71 72 set_config($varname . '_enabled', 0, $componentname); 73 $this->assertFalse($searcharea->is_enabled()); 74 75 set_config($varname . '_enabled', 1, $componentname); 76 $this->assertTrue($searcharea->is_enabled()); 77 } 78 79 /** 80 * Indexing contents. 81 * 82 * @return void 83 */ 84 public function test_entries_indexing() { 85 global $DB; 86 87 $searcharea = \core_search\manager::get_search_area($this->entryareaid); 88 $this->assertInstanceOf('\mod_glossary\search\entry', $searcharea); 89 90 $user1 = self::getDataGenerator()->create_user(); 91 $user2 = self::getDataGenerator()->create_user(); 92 93 $course1 = self::getDataGenerator()->create_course(); 94 $course2 = self::getDataGenerator()->create_course(); 95 96 $this->getDataGenerator()->enrol_user($user1->id, $course1->id, 'student'); 97 $this->getDataGenerator()->enrol_user($user2->id, $course1->id, 'student'); 98 99 $record = new \stdClass(); 100 $record->course = $course1->id; 101 102 $this->setUser($user1); 103 104 // Approved entries by default glossary. 105 $glossary1 = self::getDataGenerator()->create_module('glossary', $record); 106 $entry1 = self::getDataGenerator()->get_plugin_generator('mod_glossary')->create_content($glossary1); 107 $entry2 = self::getDataGenerator()->get_plugin_generator('mod_glossary')->create_content($glossary1); 108 109 // All records. 110 $recordset = $searcharea->get_recordset_by_timestamp(0); 111 $this->assertTrue($recordset->valid()); 112 $nrecords = 0; 113 foreach ($recordset as $record) { 114 $this->assertInstanceOf('stdClass', $record); 115 $doc = $searcharea->get_document($record); 116 $this->assertInstanceOf('\core_search\document', $doc); 117 118 // Static caches are working. 119 $dbreads = $DB->perf_get_reads(); 120 $doc = $searcharea->get_document($record); 121 122 // The +1 is because we are not caching glossary alias (keywords) as they depend on a single entry. 123 $this->assertEquals($dbreads + 1, $DB->perf_get_reads()); 124 $this->assertInstanceOf('\core_search\document', $doc); 125 $nrecords++; 126 } 127 // If there would be an error/failure in the foreach above the recordset would be closed on shutdown. 128 $recordset->close(); 129 $this->assertEquals(2, $nrecords); 130 131 // The +2 is to prevent race conditions. 132 $recordset = $searcharea->get_recordset_by_timestamp(time() + 2); 133 134 // No new records. 135 $this->assertFalse($recordset->valid()); 136 $recordset->close(); 137 138 // Create a second glossary with one entry. 139 $glossary2 = self::getDataGenerator()->create_module('glossary', ['course' => $course1->id]); 140 self::getDataGenerator()->get_plugin_generator('mod_glossary')->create_content($glossary2); 141 142 // Test indexing with each activity then combined course context. 143 $rs = $searcharea->get_document_recordset(0, \context_module::instance($glossary1->cmid)); 144 $this->assertEquals(2, iterator_count($rs)); 145 $rs->close(); 146 $rs = $searcharea->get_document_recordset(0, \context_module::instance($glossary2->cmid)); 147 $this->assertEquals(1, iterator_count($rs)); 148 $rs->close(); 149 $rs = $searcharea->get_document_recordset(0, \context_course::instance($course1->id)); 150 $this->assertEquals(3, iterator_count($rs)); 151 $rs->close(); 152 } 153 154 /** 155 * Document contents. 156 * 157 * @return void 158 */ 159 public function test_entries_document() { 160 global $DB; 161 162 $searcharea = \core_search\manager::get_search_area($this->entryareaid); 163 164 $user = self::getDataGenerator()->create_user(); 165 $course1 = self::getDataGenerator()->create_course(); 166 $this->getDataGenerator()->enrol_user($user->id, $course1->id, 'teacher'); 167 168 $record = new \stdClass(); 169 $record->course = $course1->id; 170 171 $this->setUser($user); 172 $glossary = self::getDataGenerator()->create_module('glossary', $record); 173 $entry = self::getDataGenerator()->get_plugin_generator('mod_glossary')->create_content($glossary); 174 $entry->course = $glossary->course; 175 176 $doc = $searcharea->get_document($entry); 177 $this->assertInstanceOf('\core_search\document', $doc); 178 $this->assertEquals($entry->id, $doc->get('itemid')); 179 $this->assertEquals($course1->id, $doc->get('courseid')); 180 $this->assertEquals($user->id, $doc->get('userid')); 181 $this->assertEquals($entry->concept, $doc->get('title')); 182 $this->assertEquals($entry->definition, $doc->get('content')); 183 } 184 185 /** 186 * Document accesses. 187 * 188 * @return void 189 */ 190 public function test_entries_access() { 191 global $DB; 192 193 // Returns the instance as long as the component is supported. 194 $searcharea = \core_search\manager::get_search_area($this->entryareaid); 195 196 $user1 = self::getDataGenerator()->create_user(); 197 $user2 = self::getDataGenerator()->create_user(); 198 199 $course1 = self::getDataGenerator()->create_course(); 200 $course2 = self::getDataGenerator()->create_course(); 201 202 $this->getDataGenerator()->enrol_user($user1->id, $course1->id, 'teacher'); 203 $this->getDataGenerator()->enrol_user($user2->id, $course1->id, 'student'); 204 205 $record = new \stdClass(); 206 $record->course = $course1->id; 207 208 // Approved entries by default glossary, created by teacher. 209 $this->setUser($user1); 210 $glossary1 = self::getDataGenerator()->create_module('glossary', $record); 211 $teacherapproved = self::getDataGenerator()->get_plugin_generator('mod_glossary')->create_content($glossary1); 212 $teachernotapproved = self::getDataGenerator()->get_plugin_generator('mod_glossary')->create_content($glossary1, array('approved' => false)); 213 214 // Entries need to be approved and created by student. 215 $glossary2 = self::getDataGenerator()->create_module('glossary', $record); 216 $this->setUser($user2); 217 $studentapproved = self::getDataGenerator()->get_plugin_generator('mod_glossary')->create_content($glossary2); 218 $studentnotapproved = self::getDataGenerator()->get_plugin_generator('mod_glossary')->create_content($glossary2, array('approved' => false)); 219 220 // Activity hidden to students. 221 $this->setUser($user1); 222 $glossary3 = self::getDataGenerator()->create_module('glossary', $record); 223 $hidden = self::getDataGenerator()->get_plugin_generator('mod_glossary')->create_content($glossary3); 224 set_coursemodule_visible($glossary3->cmid, 0); 225 226 $this->setUser($user2); 227 $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($teacherapproved->id)); 228 $this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($teachernotapproved->id)); 229 $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($studentapproved->id)); 230 $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($studentnotapproved->id)); 231 $this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($hidden->id)); 232 } 233 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body