Differences Between: [Versions 310 and 311] [Versions 311 and 401] [Versions 311 and 402] [Versions 311 and 403] [Versions 39 and 311]
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 core_search; 18 19 use advanced_testcase; 20 use context_course; 21 use core_mocksearch\search\mock_search_area; 22 use mock_search\engine; 23 use testable_core_search; 24 use stdClass; 25 26 /** 27 * Unit tests for search document. 28 * 29 * @package core_search 30 * @category test 31 * @copyright 2016 Eric Merrill {@link http://www.merrilldigital.com} 32 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 33 * @coversDefaultClass \core_search\document 34 */ 35 class document_test extends \advanced_testcase { 36 37 /** 38 * Setup to ensure that fixtures are loaded. 39 */ 40 public static function setupBeforeClass(): void { 41 global $CFG; 42 require_once($CFG->dirroot . '/search/tests/fixtures/testable_core_search.php'); 43 require_once($CFG->dirroot . '/search/tests/fixtures/mock_search_area.php'); 44 } 45 46 /** 47 * @var Instace of core_search_generator. 48 */ 49 protected $generator = null; 50 51 public function setUp(): void { 52 $this->resetAfterTest(); 53 set_config('enableglobalsearch', true); 54 55 // Set \core_search::instance to the mock_search_engine as we don't require the search engine to be working to test this. 56 $search = \testable_core_search::instance(); 57 58 $this->generator = self::getDataGenerator()->get_plugin_generator('core_search'); 59 $this->generator->setup(); 60 } 61 62 /** 63 * Adding this test here as get_areas_user_accesses process is the same, results just depend on the context level. 64 * 65 * @covers ::export_for_template 66 * @return void 67 */ 68 public function test_search_user_accesses() { 69 global $PAGE; 70 71 $area = new mock_search_area(); 72 $renderer = $PAGE->get_renderer('core_search'); 73 $engine = new engine(); 74 75 $course = $this->getDataGenerator()->create_course(['fullname' => 'Course & Title']); 76 $user = $this->getDataGenerator()->create_user(['firstname' => 'User', 'lastname' => 'Escape & Name']); 77 $this->getDataGenerator()->enrol_user($user->id, $course->id, 'teacher'); 78 $this->setAdminUser(); 79 80 // Make a record to enter in the search area. 81 $record = new stdClass(); 82 $record->title = 'Escape & Title'; 83 $record->content = 'Escape & Content'; 84 $record->description1 = 'Escape & Description1'; 85 $record->description2 = 'Escape & Description2'; 86 $record->userid = $user->id; 87 $record->courseid = $course->id; 88 $record = $this->generator->create_record($record); 89 90 // Convert to a 'doc data' type format. 91 $docdata = $area->convert_record_to_doc_array($record); 92 93 // First see that the docuemnt has the right information, unescaped. 94 $doc = $engine->to_document($area, $docdata); 95 $this->assertEquals('Escape & Title', $doc->get('title')); 96 $this->assertEquals('Escape & Content', $doc->get('content')); 97 $this->assertEquals('Escape & Description1', $doc->get('description1')); 98 $this->assertEquals('Escape & Description2', $doc->get('description2')); 99 $this->assertEquals('User Escape & Name', $doc->get('userfullname')); 100 $this->assertEquals('Course & Title', $doc->get('coursefullname')); 101 102 // Export for template, and see if it is escaped. 103 $export = $doc->export_for_template($renderer); 104 $this->assertEquals('Escape & Title', $export['title']); 105 $this->assertEquals('Escape & Content', $export['content']); 106 $this->assertEquals('Escape & Description1', $export['description1']); 107 $this->assertEquals('Escape & Description2', $export['description2']); 108 $this->assertEquals('User Escape & Name', $export['userfullname']); 109 $this->assertEquals('Course & Title', $export['coursefullname']); 110 } 111 112 /** 113 * Test we can set and get document icon. 114 * 115 * @covers ::set_doc_icon 116 */ 117 public function test_get_and_set_doc_icon() { 118 $document = $this->getMockBuilder('\core_search\document') 119 ->disableOriginalConstructor() 120 ->getMockForAbstractClass(); 121 122 $this->assertNull($document->get_doc_icon()); 123 124 $docicon = new \core_search\document_icon('test_name', 'test_component'); 125 $document->set_doc_icon($docicon); 126 127 $this->assertEquals($docicon, $document->get_doc_icon()); 128 } 129 130 public function tearDown(): void { 131 // For unit tests before PHP 7, teardown is called even on skip. So only do our teardown if we did setup. 132 if ($this->generator) { 133 // Moodle DML freaks out if we don't teardown the temp table after each run. 134 $this->generator->teardown(); 135 $this->generator = null; 136 } 137 } 138 139 /** 140 * Test the document author visibility depending on the user capabilities. 141 * 142 * @covers ::export_for_template 143 * @dataProvider document_author_visibility_provider 144 * @param string $rolename the role name 145 * @param array $capexceptions the capabilities exceptions 146 * @param bool $expected the expected author visibility 147 * @param bool $owndocument if the resulting document belongs to the current user 148 */ 149 public function test_document_author_visibility( 150 string $rolename = 'editingteacher', 151 array $capexceptions = [], 152 bool $expected = true, 153 bool $owndocument = false 154 ) { 155 global $DB, $PAGE; 156 157 $area = new mock_search_area(); 158 $renderer = $PAGE->get_renderer('core_search'); 159 $engine = new engine(); 160 161 $course = $this->getDataGenerator()->create_course(['fullname' => 'Course & Title']); 162 $context = context_course::instance($course->id); 163 164 $roleid = $DB->get_field('role', 'id', ['shortname' => $rolename]); 165 foreach ($capexceptions as $capability) { 166 assign_capability($capability, CAP_PROHIBIT, $roleid, $context->id); 167 } 168 169 $user = $this->getDataGenerator()->create_user(['firstname' => 'Test', 'lastname' => 'User']); 170 $this->getDataGenerator()->enrol_user($user->id, $course->id, $rolename); 171 $this->setUser($user); 172 173 if ($owndocument) { 174 $author = $user; 175 } else { 176 $author = $this->getDataGenerator()->create_user(['firstname' => 'User', 'lastname' => 'Escape & Name']); 177 $this->getDataGenerator()->enrol_user($author->id, $course->id, 'student'); 178 } 179 180 // Make a record to enter in the search area. 181 $record = new stdClass(); 182 $record->title = 'Escape & Title'; 183 $record->content = 'Escape & Content'; 184 $record->description1 = 'Escape & Description1'; 185 $record->description2 = 'Escape & Description2'; 186 $record->userid = $author->id; 187 $record->courseid = $course->id; 188 $record->contextid = $context->id; 189 $record = $this->generator->create_record($record); 190 191 // Convert to a 'doc data' type format. 192 $docdata = $area->convert_record_to_doc_array($record); 193 194 // First see that the document has the user information. 195 $doc = $engine->to_document($area, $docdata); 196 $this->assertEquals(fullname($author), $doc->get('userfullname')); 197 198 // Export for template, and see if it the user information is exported. 199 $export = $doc->export_for_template($renderer); 200 201 if ($expected) { 202 $authorname = htmlentities(fullname($author)); 203 $this->assertEquals($authorname, $export['userfullname']); 204 } else { 205 $this->assertArrayNotHasKey('userfullname', $export); 206 } 207 } 208 209 /** 210 * Data provider for test_document_author_visibility(). 211 * 212 * @return array 213 */ 214 public function document_author_visibility_provider(): array { 215 return [ 216 'Teacher' => [ 217 'rolename' => 'editingteacher', 218 'capexceptions' => [], 219 'expected' => true, 220 'owndocument' => false, 221 ], 222 'Non editing teacher' => [ 223 'rolename' => 'teacher', 224 'capexceptions' => [], 225 'expected' => true, 226 'owndocument' => false, 227 ], 228 'Student' => [ 229 'rolename' => 'student', 230 'capexceptions' => [], 231 'expected' => true, 232 'owndocument' => false, 233 ], 234 // Adding capability exceptions. 235 'Student without view profiles' => [ 236 'rolename' => 'student', 237 'capexceptions' => ['moodle/user:viewdetails'], 238 'expected' => false, 239 'owndocument' => false, 240 ], 241 'Student without view participants' => [ 242 'rolename' => 'student', 243 'capexceptions' => ['moodle/course:viewparticipants'], 244 'expected' => false, 245 'owndocument' => false, 246 ], 247 'Student without view participants or profiles' => [ 248 'rolename' => 'student', 249 'capexceptions' => ['moodle/user:viewdetails', 'moodle/course:viewparticipants'], 250 'expected' => false, 251 'owndocument' => false, 252 ], 253 // Users should be able to see its own documents. 254 'Student author without view profiles' => [ 255 'rolename' => 'student', 256 'capexceptions' => ['moodle/user:viewdetails'], 257 'expected' => true, 258 'owndocument' => true, 259 ], 260 'Student author without view participants' => [ 261 'rolename' => 'student', 262 'capexceptions' => ['moodle/course:viewparticipants'], 263 'expected' => true, 264 'owndocument' => true, 265 ], 266 'Student author without view participants or profiles' => [ 267 'rolename' => 'student', 268 'capexceptions' => ['moodle/user:viewdetails', 'moodle/course:viewparticipants'], 269 'expected' => true, 270 'owndocument' => true, 271 ], 272 273 ]; 274 } 275 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body