Proyectos de Subversion Moodle

Rev

Rev 11 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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
 * Course global search unit tests.
19
 *
20
 * @package     core_course
21
 * @category    phpunit
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 core_course\search;
27
 
28
defined('MOODLE_INTERNAL') || die();
29
 
30
global $CFG;
31
require_once($CFG->dirroot . '/search/tests/fixtures/testable_core_search.php');
32
 
33
/**
34
 * Provides the unit tests for course global search.
35
 *
36
 * @package     core
37
 * @category    phpunit
38
 * @copyright   2016 David Monllao {@link http://www.davidmonllao.com}
39
 * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
40
 */
1441 ariadna 41
final class search_test extends \advanced_testcase {
1 efrain 42
 
43
    /**
44
     * @var string Area id
45
     */
46
    protected $coursesareaid = null;
47
 
48
    /**
49
     * @var string Area id for sections
50
     */
51
    protected $sectionareaid = null;
52
 
53
    /**
54
     * @var string Area id for custom fields.
55
     */
56
    protected $customfieldareaid = null;
57
 
58
    public function setUp(): void {
1441 ariadna 59
        parent::setUp();
1 efrain 60
        $this->resetAfterTest(true);
61
        set_config('enableglobalsearch', true);
62
 
63
        $this->coursesareaid = \core_search\manager::generate_areaid('core_course', 'course');
64
        $this->sectionareaid = \core_search\manager::generate_areaid('core_course', 'section');
65
        $this->customfieldareaid = \core_search\manager::generate_areaid('core_course', 'customfield');
66
 
67
        // Set \core_search::instance to the mock_search_engine as we don't require the search engine to be working to test this.
68
        $search = \testable_core_search::instance();
69
    }
70
 
71
    /**
72
     * Indexing courses contents.
73
     *
74
     * @return void
75
     */
11 efrain 76
    public function test_courses_indexing(): void {
1 efrain 77
 
78
        // Returns the instance as long as the area is supported.
79
        $searcharea = \core_search\manager::get_search_area($this->coursesareaid);
80
        $this->assertInstanceOf('\core_course\search\course', $searcharea);
81
 
82
        $user1 = self::getDataGenerator()->create_user();
83
        $user2 = self::getDataGenerator()->create_user();
84
 
85
        $course1 = self::getDataGenerator()->create_course();
86
        $course2 = self::getDataGenerator()->create_course();
87
 
88
        $this->getDataGenerator()->enrol_user($user1->id, $course1->id, 'student');
89
        $this->getDataGenerator()->enrol_user($user2->id, $course1->id, 'student');
90
 
91
        $record = new \stdClass();
92
        $record->course = $course1->id;
93
 
94
        // All records.
95
        $recordset = $searcharea->get_recordset_by_timestamp(0);
96
        $this->assertTrue($recordset->valid());
97
        $nrecords = 0;
98
        foreach ($recordset as $record) {
99
            $this->assertInstanceOf('stdClass', $record);
100
            $doc = $searcharea->get_document($record);
101
            $this->assertInstanceOf('\core_search\document', $doc);
102
            $nrecords++;
103
        }
104
        // If there would be an error/failure in the foreach above the recordset would be closed on shutdown.
105
        $recordset->close();
106
        $this->assertEquals(3, $nrecords);
107
 
108
        // The +2 is to prevent race conditions.
109
        $recordset = $searcharea->get_recordset_by_timestamp(time() + 2);
110
 
111
        // No new records.
112
        $this->assertFalse($recordset->valid());
113
        $recordset->close();
114
    }
115
 
116
    /**
117
     * Tests course indexing support for contexts.
118
     */
11 efrain 119
    public function test_courses_indexing_contexts(): void {
1 efrain 120
        global $DB, $USER, $SITE;
121
 
122
        $searcharea = \core_search\manager::get_search_area($this->coursesareaid);
123
 
124
        // Create some courses in categories, and a forum.
125
        $generator = $this->getDataGenerator();
126
        $cat1 = $generator->create_category();
127
        $course1 = $generator->create_course(['category' => $cat1->id]);
128
        $cat2 = $generator->create_category(['parent' => $cat1->id]);
129
        $course2 = $generator->create_course(['category' => $cat2->id]);
130
        $cat3 = $generator->create_category();
131
        $course3 = $generator->create_course(['category' => $cat3->id]);
132
        $forum = $generator->create_module('forum', ['course' => $course1->id]);
133
        $DB->set_field('course', 'timemodified', 0, ['id' => $SITE->id]);
134
        $DB->set_field('course', 'timemodified', 1, ['id' => $course1->id]);
135
        $DB->set_field('course', 'timemodified', 2, ['id' => $course2->id]);
136
        $DB->set_field('course', 'timemodified', 3, ['id' => $course3->id]);
137
 
138
        // Find the first block to use for a block context.
139
        $blockid = array_values($DB->get_records('block_instances', null, 'id', 'id', 0, 1))[0]->id;
140
        $blockcontext = \context_block::instance($blockid);
141
 
142
        // Check with block context - should be null.
143
        $this->assertNull($searcharea->get_document_recordset(0, $blockcontext));
144
 
145
        // Check with user context - should be null.
146
        $this->setAdminUser();
147
        $usercontext = \context_user::instance($USER->id);
148
        $this->assertNull($searcharea->get_document_recordset(0, $usercontext));
149
 
150
        // Check with module context - should be null.
151
        $modcontext = \context_module::instance($forum->cmid);
152
        $this->assertNull($searcharea->get_document_recordset(0, $modcontext));
153
 
154
        // Check with course context - should return specified course if timestamp allows.
155
        $coursecontext = \context_course::instance($course3->id);
156
        $results = self::recordset_to_ids($searcharea->get_document_recordset(3, $coursecontext));
157
        $this->assertEquals([$course3->id], $results);
158
        $results = self::recordset_to_ids($searcharea->get_document_recordset(4, $coursecontext));
159
        $this->assertEquals([], $results);
160
 
161
        // Check with category context - should return course in categories and subcategories.
162
        $catcontext = \context_coursecat::instance($cat1->id);
163
        $results = self::recordset_to_ids($searcharea->get_document_recordset(0, $catcontext));
164
        $this->assertEquals([$course1->id, $course2->id], $results);
165
        $results = self::recordset_to_ids($searcharea->get_document_recordset(2, $catcontext));
166
        $this->assertEquals([$course2->id], $results);
167
 
168
        // Check with system context and null - should return all these courses + site course.
169
        $systemcontext = \context_system::instance();
170
        $results = self::recordset_to_ids($searcharea->get_document_recordset(0, $systemcontext));
171
        $this->assertEquals([$SITE->id, $course1->id, $course2->id, $course3->id], $results);
172
        $results = self::recordset_to_ids($searcharea->get_document_recordset(0, null));
173
        $this->assertEquals([$SITE->id, $course1->id, $course2->id, $course3->id], $results);
174
        $results = self::recordset_to_ids($searcharea->get_document_recordset(3, $systemcontext));
175
        $this->assertEquals([$course3->id], $results);
176
        $results = self::recordset_to_ids($searcharea->get_document_recordset(3, null));
177
        $this->assertEquals([$course3->id], $results);
178
    }
179
 
180
    /**
181
     * Utility function to convert recordset to array of IDs for testing.
182
     *
183
     * @param moodle_recordset $rs Recordset to convert (and close)
184
     * @return array Array of IDs from records indexed by number (0, 1, 2, ...)
185
     */
186
    protected static function recordset_to_ids(\moodle_recordset $rs) {
187
        $results = [];
188
        foreach ($rs as $rec) {
189
            $results[] = $rec->id;
190
        }
191
        $rs->close();
192
        return $results;
193
    }
194
 
195
    /**
196
     * Document contents.
197
     *
198
     * @return void
199
     */
11 efrain 200
    public function test_courses_document(): void {
1 efrain 201
 
202
        // Returns the instance as long as the area is supported.
203
        $searcharea = \core_search\manager::get_search_area($this->coursesareaid);
204
        $this->assertInstanceOf('\core_course\search\course', $searcharea);
205
 
206
        $user = self::getDataGenerator()->create_user();
207
        $course = self::getDataGenerator()->create_course();
208
        $this->getDataGenerator()->enrol_user($user->id, $course->id, 'teacher');
209
 
210
        $doc = $searcharea->get_document($course);
211
        $this->assertInstanceOf('\core_search\document', $doc);
212
        $this->assertEquals($course->id, $doc->get('itemid'));
213
        $this->assertEquals($this->coursesareaid . '-' . $course->id, $doc->get('id'));
214
        $this->assertEquals($course->id, $doc->get('courseid'));
215
        $this->assertFalse($doc->is_set('userid'));
216
        $this->assertEquals(\core_search\manager::NO_OWNER_ID, $doc->get('owneruserid'));
217
        $this->assertEquals($course->fullname, $doc->get('title'));
218
 
219
        // Not nice. Applying \core_search\document::set line breaks clean up.
220
        $summary = preg_replace("/\s+/u", " ", content_to_text($course->summary, $course->summaryformat));
221
        $this->assertEquals($summary, $doc->get('content'));
222
        $this->assertEquals($course->shortname, $doc->get('description1'));
223
    }
224
 
225
    /**
226
     * Document accesses.
227
     *
228
     * @return void
229
     */
11 efrain 230
    public function test_courses_access(): void {
1 efrain 231
        $this->resetAfterTest();
232
 
233
        // Returns the instance as long as the area is supported.
234
        $searcharea = \core_search\manager::get_search_area($this->coursesareaid);
235
 
236
        $user1 = self::getDataGenerator()->create_user();
237
        $user2 = self::getDataGenerator()->create_user();
238
 
239
        $course1 = self::getDataGenerator()->create_course();
240
        $course2 = self::getDataGenerator()->create_course(array('visible' => 0));
241
        $course3 = self::getDataGenerator()->create_course();
242
 
243
        $this->getDataGenerator()->enrol_user($user1->id, $course1->id, 'teacher');
244
        $this->getDataGenerator()->enrol_user($user2->id, $course1->id, 'student');
245
        $this->getDataGenerator()->enrol_user($user1->id, $course2->id, 'teacher');
246
        $this->getDataGenerator()->enrol_user($user2->id, $course2->id, 'student');
247
 
248
        $this->setUser($user1);
249
        $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($course1->id));
250
        $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($course2->id));
251
        $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($course3->id));
252
        $this->assertEquals(\core_search\manager::ACCESS_DELETED, $searcharea->check_access(-123));
253
 
254
        $this->setUser($user2);
255
        $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($course1->id));
256
        $this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($course2->id));
257
        $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($course3->id));
258
    }
259
 
260
    /**
261
     * Indexing section contents.
262
     */
11 efrain 263
    public function test_section_indexing(): void {
1 efrain 264
        global $DB, $USER;
265
 
266
        // Returns the instance as long as the area is supported.
267
        $searcharea = \core_search\manager::get_search_area($this->sectionareaid);
268
        $this->assertInstanceOf('\core_course\search\section', $searcharea);
269
 
270
        // Create some courses in categories, and a forum.
271
        $generator = $this->getDataGenerator();
272
        $cat1 = $generator->create_category();
273
        $cat2 = $generator->create_category(['parent' => $cat1->id]);
274
        $course1 = $generator->create_course(['category' => $cat1->id]);
275
        $course2 = $generator->create_course(['category' => $cat2->id]);
276
        $forum = $generator->create_module('forum', ['course' => $course1->id]);
277
 
278
        // Edit 2 sections on course 1 and one on course 2.
279
        $existing = $DB->get_record('course_sections', ['course' => $course1->id, 'section' => 2]);
280
        $course1section2id = $existing->id;
281
        $new = clone($existing);
282
        $new->name = 'Frogs';
283
        course_update_section($course1->id, $existing, $new);
284
 
285
        $existing = $DB->get_record('course_sections', ['course' => $course1->id, 'section' => 3]);
286
        $course1section3id = $existing->id;
287
        $new = clone($existing);
288
        $new->summary = 'Frogs';
289
        $new->summaryformat = FORMAT_HTML;
290
        course_update_section($course1->id, $existing, $new);
291
 
292
        $existing = $DB->get_record('course_sections', ['course' => $course2->id, 'section' => 1]);
293
        $course2section1id = $existing->id;
294
        $new = clone($existing);
295
        $new->summary = 'Frogs';
296
        $new->summaryformat = FORMAT_HTML;
297
        course_update_section($course2->id, $existing, $new);
298
 
299
        // Bodge timemodified into a particular order.
300
        $DB->set_field('course_sections', 'timemodified', 1, ['id' => $course1section3id]);
301
        $DB->set_field('course_sections', 'timemodified', 2, ['id' => $course1section2id]);
302
        $DB->set_field('course_sections', 'timemodified', 3, ['id' => $course2section1id]);
303
 
304
        // All records.
305
        $results = self::recordset_to_ids($searcharea->get_document_recordset(0));
306
        $this->assertEquals([$course1section3id, $course1section2id, $course2section1id], $results);
307
 
308
        // Records after time 2.
309
        $results = self::recordset_to_ids($searcharea->get_document_recordset(2));
310
        $this->assertEquals([$course1section2id, $course2section1id], $results);
311
 
312
        // Records after time 10 (there aren't any).
313
        $results = self::recordset_to_ids($searcharea->get_document_recordset(10));
314
        $this->assertEquals([], $results);
315
 
316
        // Find the first block to use for a block context.
317
        $blockid = array_values($DB->get_records('block_instances', null, 'id', 'id', 0, 1))[0]->id;
318
        $blockcontext = \context_block::instance($blockid);
319
 
320
        // Check with block context - should be null.
321
        $this->assertNull($searcharea->get_document_recordset(0, $blockcontext));
322
 
323
        // Check with user context - should be null.
324
        $this->setAdminUser();
325
        $usercontext = \context_user::instance($USER->id);
326
        $this->assertNull($searcharea->get_document_recordset(0, $usercontext));
327
 
328
        // Check with module context - should be null.
329
        $modcontext = \context_module::instance($forum->cmid);
330
        $this->assertNull($searcharea->get_document_recordset(0, $modcontext));
331
 
332
        // Check with course context - should return specific course entries.
333
        $coursecontext = \context_course::instance($course1->id);
334
        $results = self::recordset_to_ids($searcharea->get_document_recordset(0, $coursecontext));
335
        $this->assertEquals([$course1section3id, $course1section2id], $results);
336
        $results = self::recordset_to_ids($searcharea->get_document_recordset(2, $coursecontext));
337
        $this->assertEquals([$course1section2id], $results);
338
 
339
        // Check with category context - should return course in categories and subcategories.
340
        $catcontext = \context_coursecat::instance($cat1->id);
341
        $results = self::recordset_to_ids($searcharea->get_document_recordset(0, $catcontext));
342
        $this->assertEquals([$course1section3id, $course1section2id, $course2section1id], $results);
343
        $catcontext = \context_coursecat::instance($cat2->id);
344
        $results = self::recordset_to_ids($searcharea->get_document_recordset(0, $catcontext));
345
        $this->assertEquals([$course2section1id], $results);
346
 
347
        // Check with system context - should return everything (same as null, tested first).
348
        $systemcontext = \context_system::instance();
349
        $results = self::recordset_to_ids($searcharea->get_document_recordset(0, $systemcontext));
350
        $this->assertEquals([$course1section3id, $course1section2id, $course2section1id], $results);
351
    }
352
 
353
    /**
354
     * Document contents for sections.
355
     */
11 efrain 356
    public function test_section_document(): void {
1 efrain 357
        global $DB;
358
 
359
        $searcharea = \core_search\manager::get_search_area($this->sectionareaid);
360
 
361
        // Create a course.
362
        $generator = $this->getDataGenerator();
363
        $course = $generator->create_course();
364
 
365
        // Test with default title.
366
        $sectionrec = (object)['id' => 123, 'course' => $course->id,
367
                'section' => 3, 'timemodified' => 456,
368
                'summary' => 'Kermit', 'summaryformat' => FORMAT_HTML];
369
        $doc = $searcharea->get_document($sectionrec);
370
        $this->assertInstanceOf('\core_search\document', $doc);
371
        $this->assertEquals(123, $doc->get('itemid'));
372
        $this->assertEquals($this->sectionareaid . '-123', $doc->get('id'));
373
        $this->assertEquals($course->id, $doc->get('courseid'));
374
        $this->assertFalse($doc->is_set('userid'));
375
        $this->assertEquals(\core_search\manager::NO_OWNER_ID, $doc->get('owneruserid'));
376
        $this->assertEquals('New section', $doc->get('title'));
377
        $this->assertEquals('Kermit', $doc->get('content'));
378
 
379
        // Test with user-set title.
380
        $DB->set_field('course_sections', 'name', 'Frogs',
381
                ['course' => $course->id, 'section' => 3]);
382
        rebuild_course_cache($course->id, true);
383
        $doc = $searcharea->get_document($sectionrec);
384
        $this->assertEquals('Frogs', $doc->get('title'));
385
    }
386
 
387
    /**
388
     * Document access for sections.
389
     */
11 efrain 390
    public function test_section_access(): void {
1 efrain 391
        global $DB;
392
 
393
        $searcharea = \core_search\manager::get_search_area($this->sectionareaid);
394
 
395
        // Create a course.
396
        $generator = $this->getDataGenerator();
397
        $course = $generator->create_course();
398
 
399
        // Create 2 users - student and manager. Initially, student is not even enrolled.
400
        $student = $generator->create_user();
401
        $manager = $generator->create_user();
402
        $generator->enrol_user($manager->id, $course->id, 'manager');
403
 
404
        // Two sections have content - one is hidden.
405
        $DB->set_field('course_sections', 'name', 'Frogs',
406
                ['course' => $course->id, 'section' => 1]);
407
        $DB->set_field('course_sections', 'name', 'Toads',
408
                ['course' => $course->id, 'section' => 2]);
409
        $DB->set_field('course_sections', 'visible', '0',
410
                ['course' => $course->id, 'section' => 2]);
411
 
412
        // Make the modified time be in order of sections.
413
        $DB->execute('UPDATE {course_sections} SET timemodified = section');
414
 
415
        // Get the two document objects.
416
        $rs = $searcharea->get_document_recordset();
417
        $documents = [];
418
        $index = 0;
419
        foreach ($rs as $rec) {
420
            $documents[$index++] = $searcharea->get_document($rec);
421
        }
422
        $this->assertCount(2, $documents);
423
 
424
        // Log in as admin and check access.
425
        $this->setAdminUser();
426
        $this->assertEquals(\core_search\manager::ACCESS_GRANTED,
427
                $searcharea->check_access($documents[0]->get('itemid')));
428
        $this->assertEquals(\core_search\manager::ACCESS_GRANTED,
429
                $searcharea->check_access($documents[1]->get('itemid')));
430
 
431
        // Log in as manager and check access.
432
        $this->setUser($manager);
433
        $this->assertEquals(\core_search\manager::ACCESS_GRANTED,
434
                $searcharea->check_access($documents[0]->get('itemid')));
435
        $this->assertEquals(\core_search\manager::ACCESS_GRANTED,
436
                $searcharea->check_access($documents[1]->get('itemid')));
437
 
438
        // Log in as student and check access - none yet.
439
        $this->setUser($student);
440
        $this->assertEquals(\core_search\manager::ACCESS_DENIED,
441
                $searcharea->check_access($documents[0]->get('itemid')));
442
        $this->assertEquals(\core_search\manager::ACCESS_DENIED,
443
                $searcharea->check_access($documents[1]->get('itemid')));
444
 
445
        // Enrol student - now they should get access but not to the hidden one.
446
        $generator->enrol_user($student->id, $course->id, 'student');
447
        $this->assertEquals(\core_search\manager::ACCESS_GRANTED,
448
                $searcharea->check_access($documents[0]->get('itemid')));
449
        $this->assertEquals(\core_search\manager::ACCESS_DENIED,
450
                $searcharea->check_access($documents[1]->get('itemid')));
451
 
452
        // Delete the course and check it returns deleted.
453
        delete_course($course, false);
454
        $this->assertEquals(\core_search\manager::ACCESS_DELETED,
455
                $searcharea->check_access($documents[0]->get('itemid')));
456
        $this->assertEquals(\core_search\manager::ACCESS_DELETED,
457
                $searcharea->check_access($documents[1]->get('itemid')));
458
    }
459
 
460
    /**
461
     * Indexing custom fields contents.
462
     *
463
     * @return void
464
     */
11 efrain 465
    public function test_customfield_indexing(): void {
1 efrain 466
        // Returns the instance as long as the area is supported.
467
        $searcharea = \core_search\manager::get_search_area($this->customfieldareaid);
468
        $this->assertInstanceOf('\core_course\search\customfield', $searcharea);
469
 
470
        // We need to be admin for custom fields creation.
471
        $this->setAdminUser();
472
 
473
        // Custom fields.
474
        $fieldcategory = self::getDataGenerator()->create_custom_field_category(['name' => 'Other fields']);
475
        $customfield = ['shortname' => 'test', 'name' => 'Customfield', 'type' => 'text',
476
            'categoryid' => $fieldcategory->get('id')];
477
        $field = self::getDataGenerator()->create_custom_field($customfield);
478
 
479
        $course1data = ['customfields' => [['shortname' => $customfield['shortname'], 'value' => 'Customvalue1']]];
480
        $course1  = self::getDataGenerator()->create_course($course1data);
481
 
482
        $course2data = ['customfields' => [['shortname' => $customfield['shortname'], 'value' => 'Customvalue2']]];
483
        $course2 = self::getDataGenerator()->create_course($course2data);
484
 
485
        // All records.
486
        $recordset = $searcharea->get_recordset_by_timestamp(0);
487
        $this->assertTrue($recordset->valid());
488
        $nrecords = 0;
489
        foreach ($recordset as $record) {
490
            $this->assertInstanceOf('stdClass', $record);
491
            $doc = $searcharea->get_document($record);
492
            $this->assertInstanceOf('\core_search\document', $doc);
493
            $nrecords++;
494
        }
495
        // If there would be an error/failure in the foreach above the recordset would be closed on shutdown.
496
        $recordset->close();
497
        $this->assertEquals(2, $nrecords);
498
 
499
        // The +2 is to prevent race conditions.
500
        $recordset = $searcharea->get_recordset_by_timestamp(time() + 2);
501
 
502
        // No new records.
503
        $this->assertFalse($recordset->valid());
504
        $recordset->close();
505
    }
506
 
507
    /**
508
     * Document contents for custom fields.
509
     *
510
     * @return void
511
     */
11 efrain 512
    public function test_customfield_document(): void {
1 efrain 513
        global $DB;
514
        // Returns the instance as long as the area is supported.
515
        $searcharea = \core_search\manager::get_search_area($this->customfieldareaid);
516
 
517
        // We need to be admin for custom fields creation.
518
        $this->setAdminUser();
519
 
520
        // Custom fields.
521
        $fieldcategory = self::getDataGenerator()->create_custom_field_category(['name' => 'Other fields']);
522
        $customfield = ['shortname' => 'test', 'name' => 'Customfield', 'type' => 'text',
523
            'categoryid' => $fieldcategory->get('id')];
524
        $field = self::getDataGenerator()->create_custom_field($customfield);
525
 
526
        $coursedata = ['customfields' => [['shortname' => $customfield['shortname'], 'value' => 'Customvalue1']]];
527
        $course  = self::getDataGenerator()->create_course($coursedata);
528
 
529
        // Retrieve data we need to compare with document instance.
530
        $record = $DB->get_record('customfield_data', ['instanceid' => $course->id]);
531
        $field = \core_customfield\field_controller::create($record->fieldid);
532
        $data = \core_customfield\data_controller::create(0, $record, $field);
533
 
534
        $doc = $searcharea->get_document($record);
535
        $this->assertInstanceOf('\core_search\document', $doc);
536
        $this->assertEquals('Customfield', $doc->get('title'));
537
        $this->assertEquals('Customvalue1', $doc->get('content'));
538
        $this->assertEquals($course->id, $doc->get('courseid'));
539
        $this->assertEquals(\core_search\manager::NO_OWNER_ID, $doc->get('owneruserid'));
540
        $this->assertEquals($course->id, $doc->get('courseid'));
541
        $this->assertFalse($doc->is_set('userid'));
542
    }
543
 
544
    /**
545
     * Document accesses for customfield area.
546
     */
11 efrain 547
    public function test_customfield_access(): void {
1 efrain 548
        global $DB;
549
 
550
        $this->resetAfterTest();
551
 
552
        // Returns the instance as long as the area is supported.
553
        $searcharea = \core_search\manager::get_search_area($this->customfieldareaid);
554
 
555
        $user1 = self::getDataGenerator()->create_user();
556
        $user2 = self::getDataGenerator()->create_user();
557
 
558
        // Create our custom field.
559
        $customfieldcategory = $this->getDataGenerator()->create_custom_field_category([]);
560
        $customfield = $this->getDataGenerator()->create_custom_field([
561
            'categoryid' => $customfieldcategory->get('id'),
562
            'type' => 'text',
563
            'shortname' => 'myfield',
564
        ]);
565
 
566
        // Create courses, each containing our custom field.
567
        $course1 = $this->getDataGenerator()->create_course(['customfield_myfield' => 'Lionel']);
568
        $course2 = $this->getDataGenerator()->create_course(['customfield_myfield' => 'Rick', 'visible' => 0]);
569
        $course3 = $this->getDataGenerator()->create_course(['customfield_myfield' => 'Jack']);
570
 
571
        $this->getDataGenerator()->enrol_user($user1->id, $course1->id, 'teacher');
572
        $this->getDataGenerator()->enrol_user($user2->id, $course1->id, 'student');
573
        $this->getDataGenerator()->enrol_user($user1->id, $course2->id, 'teacher');
574
        $this->getDataGenerator()->enrol_user($user2->id, $course2->id, 'student');
575
 
576
        // Prevent users viewing course lists.
577
        $userrole = $DB->get_field('role', 'id', ['shortname' => 'user'], MUST_EXIST);
578
        assign_capability('moodle/category:viewcourselist', CAP_PREVENT, $userrole, \context_system::instance()->id, true);
579
 
580
        // The following assertions check whether each user can view the indexed customfield data record.
581
        $course1data = \core_customfield\data::get_record([
582
            'fieldid' => $customfield->get('id'),
583
            'instanceid' => $course1->id,
584
        ]);
585
        $course2data = \core_customfield\data::get_record([
586
            'fieldid' => $customfield->get('id'),
587
            'instanceid' => $course2->id,
588
        ]);
589
        $course3data = \core_customfield\data::get_record([
590
            'fieldid' => $customfield->get('id'),
591
            'instanceid' => $course3->id,
592
        ]);
593
 
594
        // Admin user should see all present custom fields.
595
        $this->setAdminUser();
596
        $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($course1data->get('id')));
597
        $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($course2data->get('id')));
598
        $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($course3data->get('id')));
599
        $this->assertEquals(\core_search\manager::ACCESS_DELETED, $searcharea->check_access(-123));
600
 
601
        // First user (teacher) should see all those in the courses they are teaching.
602
        $this->setUser($user1);
603
        $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($course1data->get('id')));
604
        $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($course2data->get('id')));
605
        $this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($course3data->get('id')));
606
        $this->assertEquals(\core_search\manager::ACCESS_DELETED, $searcharea->check_access(-123));
607
 
608
        // Second user (student) should see all those in visible courses they are studying.
609
        $this->setUser($user2);
610
        $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($course1data->get('id')));
611
        $this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($course2data->get('id')));
612
        $this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($course3data->get('id')));
613
        $this->assertEquals(\core_search\manager::ACCESS_DELETED, $searcharea->check_access(-123));
614
    }
615
 
616
    /**
617
     * Test document icon for course area.
618
     */
11 efrain 619
    public function test_get_doc_icon_for_course_area(): void {
1 efrain 620
        $searcharea = \core_search\manager::get_search_area($this->coursesareaid);
621
 
622
        $document = $this->getMockBuilder('\core_search\document')
623
            ->disableOriginalConstructor()
624
            ->getMock();
625
 
626
        $result = $searcharea->get_doc_icon($document);
627
 
628
        $this->assertEquals('i/course', $result->get_name());
629
        $this->assertEquals('moodle', $result->get_component());
630
    }
631
 
632
    /**
633
     * Test document icon for section area.
634
     */
11 efrain 635
    public function test_get_doc_icon_for_section_area(): void {
1 efrain 636
        $searcharea = \core_search\manager::get_search_area($this->sectionareaid);
637
 
638
        $document = $this->getMockBuilder('\core_search\document')
639
            ->disableOriginalConstructor()
640
            ->getMock();
641
 
642
        $result = $searcharea->get_doc_icon($document);
643
 
644
        $this->assertEquals('i/section', $result->get_name());
645
        $this->assertEquals('moodle', $result->get_component());
646
    }
647
 
648
    /**
649
     * Test assigned search categories.
650
     */
11 efrain 651
    public function test_get_category_names(): void {
1 efrain 652
        $coursessearcharea = \core_search\manager::get_search_area($this->coursesareaid);
653
        $sectionsearcharea = \core_search\manager::get_search_area($this->sectionareaid);
654
        $customfieldssearcharea = \core_search\manager::get_search_area($this->customfieldareaid);
655
 
656
        $this->assertEquals(['core-courses'], $coursessearcharea->get_category_names());
657
        $this->assertEquals(['core-course-content'], $sectionsearcharea->get_category_names());
658
        $this->assertEquals(['core-course-content', 'core-courses'], $customfieldssearcharea->get_category_names());
659
    }
660
}