MDL-76849 qtype_truefalse: Include question number in answer fields
[moodle.git] / search / tests / document_test.php
blobb7acda2ac4daff383284aff78a18cf028ac3acc2
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.
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/>.
17 namespace core_search;
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;
26 /**
27 * Unit tests for search document.
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
35 class document_test extends \advanced_testcase {
37 /**
38 * Setup to ensure that fixtures are loaded.
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');
46 /**
47 * @var Instace of core_search_generator.
49 protected $generator = null;
51 public function setUp(): void {
52 $this->resetAfterTest();
53 set_config('enableglobalsearch', true);
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();
58 $this->generator = self::getDataGenerator()->get_plugin_generator('core_search');
59 $this->generator->setup();
62 /**
63 * Adding this test here as get_areas_user_accesses process is the same, results just depend on the context level.
65 * @covers ::export_for_template
66 * @return void
68 public function test_search_user_accesses() {
69 global $PAGE;
71 $area = new mock_search_area();
72 $renderer = $PAGE->get_renderer('core_search');
73 $engine = new engine();
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();
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);
90 // Convert to a 'doc data' type format.
91 $docdata = $area->convert_record_to_doc_array($record);
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'));
102 // Export for template, and see if it is escaped.
103 $export = $doc->export_for_template($renderer);
104 $this->assertEquals('Escape &amp; Title', $export['title']);
105 $this->assertEquals('Escape &amp; Content', $export['content']);
106 $this->assertEquals('Escape &amp; Description1', $export['description1']);
107 $this->assertEquals('Escape &amp; Description2', $export['description2']);
108 $this->assertEquals('User Escape &amp; Name', $export['userfullname']);
109 $this->assertEquals('Course &amp; Title', $export['coursefullname']);
113 * Test we can set and get document icon.
115 * @covers ::set_doc_icon
117 public function test_get_and_set_doc_icon() {
118 $document = $this->getMockBuilder('\core_search\document')
119 ->disableOriginalConstructor()
120 ->getMockForAbstractClass();
122 $this->assertNull($document->get_doc_icon());
124 $docicon = new \core_search\document_icon('test_name', 'test_component');
125 $document->set_doc_icon($docicon);
127 $this->assertEquals($docicon, $document->get_doc_icon());
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;
140 * Test the document author visibility depending on the user capabilities.
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
149 public function test_document_author_visibility(
150 string $rolename = 'editingteacher',
151 array $capexceptions = [],
152 bool $expected = true,
153 bool $owndocument = false
155 global $DB, $PAGE;
157 $area = new mock_search_area();
158 $renderer = $PAGE->get_renderer('core_search');
159 $engine = new engine();
161 $course = $this->getDataGenerator()->create_course(['fullname' => 'Course & Title']);
162 $context = context_course::instance($course->id);
164 $roleid = $DB->get_field('role', 'id', ['shortname' => $rolename]);
165 foreach ($capexceptions as $capability) {
166 assign_capability($capability, CAP_PROHIBIT, $roleid, $context->id);
169 $user = $this->getDataGenerator()->create_user(['firstname' => 'Test', 'lastname' => 'User']);
170 $this->getDataGenerator()->enrol_user($user->id, $course->id, $rolename);
171 $this->setUser($user);
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');
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);
191 // Convert to a 'doc data' type format.
192 $docdata = $area->convert_record_to_doc_array($record);
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'));
198 // Export for template, and see if it the user information is exported.
199 $export = $doc->export_for_template($renderer);
201 if ($expected) {
202 $authorname = htmlentities(fullname($author));
203 $this->assertEquals($authorname, $export['userfullname']);
204 } else {
205 $this->assertArrayNotHasKey('userfullname', $export);
210 * Data provider for test_document_author_visibility().
212 * @return array
214 public function document_author_visibility_provider(): array {
215 return [
216 'Teacher' => [
217 'rolename' => 'editingteacher',
218 'capexceptions' => [],
219 'expected' => true,
220 'owndocument' => false,
222 'Non editing teacher' => [
223 'rolename' => 'teacher',
224 'capexceptions' => [],
225 'expected' => true,
226 'owndocument' => false,
228 'Student' => [
229 'rolename' => 'student',
230 'capexceptions' => [],
231 'expected' => true,
232 'owndocument' => false,
234 // Adding capability exceptions.
235 'Student without view profiles' => [
236 'rolename' => 'student',
237 'capexceptions' => ['moodle/user:viewdetails'],
238 'expected' => false,
239 'owndocument' => false,
241 'Student without view participants' => [
242 'rolename' => 'student',
243 'capexceptions' => ['moodle/course:viewparticipants'],
244 'expected' => false,
245 'owndocument' => false,
247 'Student without view participants or profiles' => [
248 'rolename' => 'student',
249 'capexceptions' => ['moodle/user:viewdetails', 'moodle/course:viewparticipants'],
250 'expected' => false,
251 'owndocument' => false,
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,
260 'Student author without view participants' => [
261 'rolename' => 'student',
262 'capexceptions' => ['moodle/course:viewparticipants'],
263 'expected' => true,
264 'owndocument' => true,
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,