Proyectos de Subversion Moodle

Rev

Ir a la última revisión | | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - https://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 <https://www.gnu.org/licenses/>.
16
 
17
namespace core;
18
 
19
/**
20
 * Unit tests for context helper class.
21
 *
22
 * NOTE: more tests are in lib/tests/accesslib_test.php
23
 *
24
 * @package   core
25
 * @copyright Petr Skoda
26
 * @license   https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
27
 * @coversDefaultClass \core\context_helper
28
 */
29
class context_helper_test extends \advanced_testcase {
30
    /**
31
     * Tests covered method.
32
     * @covers ::parse_external_level
33
     */
34
    public function test_parse_external_level() {
35
        $this->assertSame(context\system::class, context_helper::parse_external_level('system'));
36
        $this->assertSame(context\system::class, context_helper::parse_external_level(CONTEXT_SYSTEM));
37
        $this->assertSame(context\system::class, context_helper::parse_external_level((string)CONTEXT_SYSTEM));
38
 
39
        $this->assertSame(context\user::class, context_helper::parse_external_level('user'));
40
        $this->assertSame(context\user::class, context_helper::parse_external_level(CONTEXT_USER));
41
        $this->assertSame(context\user::class, context_helper::parse_external_level((string)CONTEXT_USER));
42
 
43
        $this->assertSame(context\coursecat::class, context_helper::parse_external_level('coursecat'));
44
        $this->assertSame(context\coursecat::class, context_helper::parse_external_level(CONTEXT_COURSECAT));
45
        $this->assertSame(context\coursecat::class, context_helper::parse_external_level((string)CONTEXT_COURSECAT));
46
 
47
        $this->assertSame(context\course::class, context_helper::parse_external_level('course'));
48
        $this->assertSame(context\course::class, context_helper::parse_external_level(CONTEXT_COURSE));
49
        $this->assertSame(context\course::class, context_helper::parse_external_level((string)CONTEXT_COURSE));
50
 
51
        $this->assertSame(context\module::class, context_helper::parse_external_level('module'));
52
        $this->assertSame(context\module::class, context_helper::parse_external_level(CONTEXT_MODULE));
53
        $this->assertSame(context\module::class, context_helper::parse_external_level((string)CONTEXT_MODULE));
54
 
55
        $this->assertSame(context\block::class, context_helper::parse_external_level('block'));
56
        $this->assertSame(context\block::class, context_helper::parse_external_level(CONTEXT_BLOCK));
57
        $this->assertSame(context\block::class, context_helper::parse_external_level((string)CONTEXT_BLOCK));
58
 
59
        $this->assertNull(context_helper::parse_external_level('core_system'));
60
        $this->assertNull(context_helper::parse_external_level('xsystem'));
61
        $this->assertNull(context_helper::parse_external_level(1));
62
        $this->assertNull(context_helper::parse_external_level(''));
63
    }
64
 
65
    /**
66
     * Tests covered method.
67
     * @covers ::resolve_behat_reference
68
     */
69
    public function test_resolve_behat_reference() {
70
        $this->assertNull(context_helper::resolve_behat_reference('blahbla', 'blahbla'));
71
        $this->assertNull(context_helper::resolve_behat_reference('', ''));
72
        $this->assertNull(context_helper::resolve_behat_reference('0', ''));
73
 
74
        $syscontext = context\system::instance();
75
        $result = context_helper::resolve_behat_reference('System', '');
76
        $this->assertSame($syscontext->id, $result->id);
77
 
78
        $syscontext = context\system::instance();
79
        $result = context_helper::resolve_behat_reference('10', '');
80
        $this->assertSame($syscontext->id, $result->id);
81
 
82
        // The rest is tested in each context class test.
83
    }
84
 
85
    /**
86
     * Tests covered method.
87
     * @covers ::get_class_for_level
88
     */
89
    public function test_get_class_for_level() {
90
        $this->assertSame(context\system::class, context_helper::get_class_for_level(CONTEXT_SYSTEM));
91
        $this->assertSame(context\system::class, context_helper::get_class_for_level((string)CONTEXT_SYSTEM));
92
 
93
        $this->assertSame(context\user::class, context_helper::get_class_for_level(CONTEXT_USER));
94
        $this->assertSame(context\user::class, context_helper::get_class_for_level((string)CONTEXT_USER));
95
 
96
        $this->assertSame(context\coursecat::class, context_helper::get_class_for_level(CONTEXT_COURSECAT));
97
        $this->assertSame(context\coursecat::class, context_helper::get_class_for_level((string)CONTEXT_COURSECAT));
98
 
99
        $this->assertSame(context\course::class, context_helper::get_class_for_level(CONTEXT_COURSE));
100
        $this->assertSame(context\course::class, context_helper::get_class_for_level((string)CONTEXT_COURSE));
101
 
102
        $this->assertSame(context\module::class, context_helper::get_class_for_level(CONTEXT_MODULE));
103
        $this->assertSame(context\module::class, context_helper::get_class_for_level((string)CONTEXT_MODULE));
104
 
105
        $this->assertSame(context\block::class, context_helper::get_class_for_level(CONTEXT_BLOCK));
106
        $this->assertSame(context\block::class, context_helper::get_class_for_level((string)CONTEXT_BLOCK));
107
 
108
        try {
109
            context_helper::get_class_for_level(1);
110
            $this->fail('Exception expected if level does not exist');
111
        } catch (\moodle_exception $e) {
112
            $this->assertInstanceOf(\coding_exception::class, $e);
113
            $this->assertSame('Coding error detected, it must be fixed by a programmer: Invalid context level specified',
114
                $e->getMessage());
115
        }
116
    }
117
 
118
    /**
119
     * Tests covered method.
120
     * @covers ::get_all_levels
121
     */
122
    public function test_get_all_levels() {
123
        $levels = context_helper::get_all_levels();
124
 
125
        $this->assertArrayHasKey(CONTEXT_SYSTEM, $levels);
126
        $this->assertSame(context\system::class, $levels[CONTEXT_SYSTEM]);
127
 
128
        $this->assertArrayHasKey(CONTEXT_USER, $levels);
129
        $this->assertSame(context\user::class, $levels[CONTEXT_USER]);
130
 
131
        $this->assertArrayHasKey(CONTEXT_COURSECAT, $levels);
132
        $this->assertSame(context\coursecat::class, $levels[CONTEXT_COURSECAT]);
133
 
134
        $this->assertArrayHasKey(CONTEXT_COURSE, $levels);
135
        $this->assertSame(context\course::class, $levels[CONTEXT_COURSE]);
136
 
137
        $this->assertArrayHasKey(CONTEXT_MODULE, $levels);
138
        $this->assertSame(context\module::class, $levels[CONTEXT_MODULE]);
139
 
140
        $this->assertArrayHasKey(CONTEXT_BLOCK, $levels);
141
        $this->assertSame(context\block::class, $levels[CONTEXT_BLOCK]);
142
 
143
        $sorted = $levels;
144
        ksort($sorted, SORT_NUMERIC);
145
        $block = $sorted[CONTEXT_BLOCK];
146
        unset($sorted[CONTEXT_BLOCK]);
147
        $sorted[CONTEXT_BLOCK] = $block;
148
        $this->assertSame(array_keys($sorted), array_keys($levels));
149
 
150
        // Make sure level is set properly.
151
        foreach ($levels as $level => $classname) {
152
            $this->assertEquals($level, $classname::LEVEL);
153
            if ($level != CONTEXT_SYSTEM) {
154
                $this->assertGreaterThan(CONTEXT_SYSTEM, $level);
155
            }
156
        }
157
    }
158
 
159
    /**
160
     * Tests covered method.
161
     * @covers ::get_child_levels
162
     */
163
    public function test_get_child_levels() {
164
        $alllevels = context_helper::get_all_levels();
165
 
166
        $childlevels = context_helper::get_child_levels(CONTEXT_SYSTEM);
167
        $this->assertSame(count($alllevels) - 1, count($childlevels));
168
 
169
        $childlevels = context_helper::get_child_levels(CONTEXT_USER);
170
        $this->assertNotContains(CONTEXT_SYSTEM, $childlevels);
171
        $this->assertNotContains(CONTEXT_USER, $childlevels);
172
        $this->assertNotContains(CONTEXT_COURSECAT, $childlevels);
173
        $this->assertNotContains(CONTEXT_COURSE, $childlevels);
174
        $this->assertNotContains(CONTEXT_MODULE, $childlevels);
175
        $this->assertContains(CONTEXT_BLOCK, $childlevels);
176
 
177
        $childlevels = context_helper::get_child_levels(CONTEXT_COURSECAT);
178
        $this->assertNotContains(CONTEXT_SYSTEM, $childlevels);
179
        $this->assertNotContains(CONTEXT_USER, $childlevels);
180
        $this->assertContains(CONTEXT_COURSECAT, $childlevels);
181
        $this->assertContains(CONTEXT_COURSE, $childlevels);
182
        $this->assertContains(CONTEXT_MODULE, $childlevels);
183
        $this->assertContains(CONTEXT_BLOCK, $childlevels);
184
 
185
        $childlevels = context_helper::get_child_levels(CONTEXT_COURSE);
186
        $this->assertNotContains(CONTEXT_SYSTEM, $childlevels);
187
        $this->assertNotContains(CONTEXT_USER, $childlevels);
188
        $this->assertNotContains(CONTEXT_COURSECAT, $childlevels);
189
        $this->assertNotContains(CONTEXT_COURSE, $childlevels);
190
        $this->assertContains(CONTEXT_MODULE, $childlevels);
191
        $this->assertContains(CONTEXT_BLOCK, $childlevels);
192
 
193
        $childlevels = context_helper::get_child_levels(CONTEXT_MODULE);
194
        $this->assertNotContains(CONTEXT_SYSTEM, $childlevels);
195
        $this->assertNotContains(CONTEXT_USER, $childlevels);
196
        $this->assertNotContains(CONTEXT_COURSECAT, $childlevels);
197
        $this->assertNotContains(CONTEXT_COURSE, $childlevels);
198
        $this->assertNotContains(CONTEXT_MODULE, $childlevels);
199
        $this->assertContains(CONTEXT_BLOCK, $childlevels);
200
 
201
        $childlevels = context_helper::get_child_levels(CONTEXT_BLOCK);
202
        $this->assertCount(0, $childlevels);
203
    }
204
 
205
    /**
206
     * Tests covered method.
207
     * @covers ::get_compatible_levels
208
     */
209
    public function test_get_compatible_levels() {
210
        $levels = context_helper::get_compatible_levels('manager');
211
        $this->assertContains(CONTEXT_SYSTEM, $levels);
212
        $this->assertNotContains(CONTEXT_USER, $levels);
213
        $this->assertContains(CONTEXT_COURSECAT, $levels);
214
        $this->assertContains(CONTEXT_COURSE, $levels);
215
        $this->assertNotContains(CONTEXT_MODULE, $levels);
216
        $this->assertNotContains(CONTEXT_BLOCK, $levels);
217
 
218
        $levels = context_helper::get_compatible_levels('coursecreator');
219
        $this->assertContains(CONTEXT_SYSTEM, $levels);
220
        $this->assertNotContains(CONTEXT_USER, $levels);
221
        $this->assertContains(CONTEXT_COURSECAT, $levels);
222
        $this->assertNotContains(CONTEXT_COURSE, $levels);
223
        $this->assertNotContains(CONTEXT_MODULE, $levels);
224
        $this->assertNotContains(CONTEXT_BLOCK, $levels);
225
 
226
        $levels = context_helper::get_compatible_levels('editingteacher');
227
        $this->assertNotContains(CONTEXT_SYSTEM, $levels);
228
        $this->assertNotContains(CONTEXT_USER, $levels);
229
        $this->assertNotContains(CONTEXT_COURSECAT, $levels);
230
        $this->assertContains(CONTEXT_COURSE, $levels);
231
        $this->assertContains(CONTEXT_MODULE, $levels);
232
        $this->assertNotContains(CONTEXT_BLOCK, $levels);
233
 
234
        $levels = context_helper::get_compatible_levels('teacher');
235
        $this->assertNotContains(CONTEXT_SYSTEM, $levels);
236
        $this->assertNotContains(CONTEXT_USER, $levels);
237
        $this->assertNotContains(CONTEXT_COURSECAT, $levels);
238
        $this->assertContains(CONTEXT_COURSE, $levels);
239
        $this->assertContains(CONTEXT_MODULE, $levels);
240
        $this->assertNotContains(CONTEXT_BLOCK, $levels);
241
 
242
        $levels = context_helper::get_compatible_levels('student');
243
        $this->assertNotContains(CONTEXT_SYSTEM, $levels);
244
        $this->assertNotContains(CONTEXT_USER, $levels);
245
        $this->assertNotContains(CONTEXT_COURSECAT, $levels);
246
        $this->assertContains(CONTEXT_COURSE, $levels);
247
        $this->assertContains(CONTEXT_MODULE, $levels);
248
        $this->assertNotContains(CONTEXT_BLOCK, $levels);
249
 
250
        $levels = context_helper::get_compatible_levels('user');
251
        $this->assertCount(0, $levels);
252
 
253
        $levels = context_helper::get_compatible_levels('guest');
254
        $this->assertCount(0, $levels);
255
 
256
        $levels = context_helper::get_compatible_levels('frontpage');
257
        $this->assertCount(0, $levels);
258
    }
259
 
260
    /**
261
     * Tests covered method.
262
     * @covers ::cleanup_instances
263
     */
264
    public function test_cleanup_instances() {
265
        global $DB;
266
 
267
        $this->resetAfterTest();
268
        $this->preventResetByRollback();
269
 
270
        $prevcount = $DB->count_records('context', []);
271
        context_helper::cleanup_instances();
272
        $count = $DB->count_records('context', []);
273
        $this->assertSame($prevcount, $count);
274
 
275
        // Insert bogus records for each level and see if they get removed,
276
        // more test should be in tests for each context level.
277
        $alllevels = context_helper::get_all_levels();
278
        foreach ($alllevels as $classname) {
279
            if ($classname::LEVEL == CONTEXT_SYSTEM) {
280
                continue;
281
            }
282
            $record = new \stdClass();
283
            $record->contextlevel = $classname::LEVEL;
284
            $record->instanceid = 9999999999;
285
            $record->path = null;
286
            $record->depth = '2';
287
            $record->id = $DB->insert_record('context', $record);
288
            $DB->set_field('context', 'path', SYSCONTEXTID . '/' . $record->id, ['id' => $record->id]);
289
        }
290
        context_helper::cleanup_instances();
291
        $count = $DB->count_records('context', []);
292
        $this->assertSame($prevcount, $count);
293
    }
294
 
295
    /**
296
     * Tests covered method.
297
     * @covers ::create_instances
298
     */
299
    public function test_create_instances() {
300
        global $DB;
301
 
302
        $this->resetAfterTest();
303
        $this->preventResetByRollback();
304
 
305
        $user = $this->getDataGenerator()->create_user();
306
        $usercontext = context\user::instance($user->id);
307
        $category = $this->getDataGenerator()->create_category();
308
        $categorycontext = context\coursecat::instance($category->id);
309
        $course = $this->getDataGenerator()->create_course();
310
        $coursecontext = context\course::instance($course->id);
311
        $page = $this->getDataGenerator()->create_module('page', ['course' => $course->id]);
312
        $pagecontext = context\module::instance($page->cmid);
313
 
314
        $prevcount = $DB->count_records('context', []);
315
        $DB->delete_records('context', ['id' => $usercontext->id]);
316
        $DB->delete_records('context', ['id' => $categorycontext->id]);
317
        $DB->delete_records('context', ['id' => $coursecontext->id]);
318
        $DB->delete_records('context', ['id' => $pagecontext->id]);
319
 
320
        context_helper::create_instances();
321
        $count = $DB->count_records('context', []);
322
        $this->assertSame($prevcount, $count);
323
    }
324
 
325
    /**
326
     * Tests covered method.
327
     * @covers ::build_all_paths
328
     */
329
    public function test_build_all_paths() {
330
        $this->resetAfterTest();
331
        $this->preventResetByRollback();
332
 
333
        // Just make sure there are no fatal errors for now.
334
        context_helper::build_all_paths(true);
335
        context_helper::build_all_paths();
336
    }
337
 
338
    /**
339
     * Tests covered method.
340
     * @covers ::reset_caches
341
     */
342
    public function test_reset_caches() {
343
        $this->resetAfterTest();
344
        $this->preventResetByRollback();
345
 
346
        // Just make sure there are no fatal errors for now.
347
        context_helper::reset_caches();
348
    }
349
 
350
    /**
351
     * Tests covered method.
352
     * @covers ::get_preload_record_columns
353
     */
354
    public function test_get_preload_record_columns() {
355
        $expected = array (
356
            'testalias.id' => 'ctxid',
357
            'testalias.path' => 'ctxpath',
358
            'testalias.depth' => 'ctxdepth',
359
            'testalias.contextlevel' => 'ctxlevel',
360
            'testalias.instanceid' => 'ctxinstance',
361
            'testalias.locked' => 'ctxlocked',
362
        );
363
        $result = context_helper::get_preload_record_columns('testalias');
364
        $this->assertSame($expected, $result);
365
    }
366
 
367
    /**
368
     * Tests covered method.
369
     * @covers ::get_preload_record_columns_sql
370
     */
371
    public function test_get_preload_record_columns_sql() {
372
        global $DB;
373
 
374
        $result = context_helper::get_preload_record_columns_sql('testalias');
375
        $expected = 'testalias.id AS ctxid, testalias.path AS ctxpath, testalias.depth AS ctxdepth,'
376
            .' testalias.contextlevel AS ctxlevel, testalias.instanceid AS ctxinstance, testalias.locked AS ctxlocked';
377
        $this->assertSame($expected, $result);
378
 
379
        $sql = "SELECT id, $result
380
                  FROM {context} testalias";
381
        $DB->get_records_sql($sql, []);
382
    }
383
 
384
    /**
385
     * Tests covered method.
386
     * @covers ::preload_from_record
387
     */
388
    public function test_preload_from_record() {
389
        global $DB;
390
 
391
        $select = context_helper::get_preload_record_columns_sql('testalias');
392
        $sql = "SELECT id, $select
393
                  FROM {context} testalias";
394
        $records = $DB->get_records_sql($sql, []);
395
        foreach ($records as $record) {
396
            $this->assertNull(context_helper::preload_from_record($record));
397
        }
398
 
399
        $this->assertDebuggingNotCalled();
400
        $record = reset($records);
401
        unset($record->ctxlevel);
402
        $this->assertNull(context_helper::preload_from_record($record));
403
    }
404
 
405
    /**
406
     * Tests covered method.
407
     * @covers ::preload_contexts_by_id
408
     */
409
    public function test_preload_contexts_by_id() {
410
        global $DB;
411
 
412
        $contextids = $DB->get_fieldset_sql("SELECT id FROM {context}", []);
413
        context_helper::preload_contexts_by_id($contextids);
414
        context_helper::preload_contexts_by_id($contextids);
415
 
416
        context_helper::reset_caches();
417
        context_helper::preload_contexts_by_id($contextids);
418
    }
419
 
420
    /**
421
     * Tests covered method.
422
     * @covers ::preload_course
423
     */
424
    public function test_preload_course() {
425
        global $SITE;
426
        context_helper::preload_course($SITE->id);
427
    }
428
 
429
    /**
430
     * Tests covered method.
431
     * @covers ::delete_instance
432
     */
433
    public function test_delete_instance() {
434
        $this->resetAfterTest();
435
 
436
        $user = $this->getDataGenerator()->create_user();
437
        $category = $this->getDataGenerator()->create_category();
438
        $course = $this->getDataGenerator()->create_course();
439
        $page = $this->getDataGenerator()->create_module('page', array('course' => $course->id));
440
 
441
        // This is a bit silly test, it might start failing in the future
442
        // because the instances are not deleted before deleting the contexts.
443
        context_helper::delete_instance(CONTEXT_USER, $user->id);
444
        context_helper::delete_instance(CONTEXT_COURSECAT, $category->id);
445
        context_helper::delete_instance(CONTEXT_COURSE, $course->id);
446
        context_helper::delete_instance(CONTEXT_MODULE, $page->cmid);
447
    }
448
 
449
    /**
450
     * Tests covered method.
451
     * @covers ::get_level_name
452
     */
453
    public function test_get_level_name() {
454
        $allevels = context_helper::get_all_levels();
455
        foreach ($allevels as $level => $classname) {
456
            $name = context_helper::get_level_name($level);
457
            $this->assertIsString($name);
458
        }
459
 
460
        $this->assertSame('System', context_helper::get_level_name(CONTEXT_SYSTEM));
461
        $this->assertSame('User', context_helper::get_level_name(CONTEXT_USER));
462
        $this->assertSame('Category', context_helper::get_level_name(CONTEXT_COURSECAT));
463
        $this->assertSame('Course', context_helper::get_level_name(CONTEXT_COURSE));
464
        $this->assertSame('Activity module', context_helper::get_level_name(CONTEXT_MODULE));
465
        $this->assertSame('Block', context_helper::get_level_name(CONTEXT_BLOCK));
466
    }
467
 
468
    /**
469
     * Tests covered method.
470
     * @covers ::get_navigation_filter_context
471
     */
472
    public function test_get_navigation_filter_context() {
473
        global $CFG;
474
        $this->resetAfterTest();
475
 
476
        $user = $this->getDataGenerator()->create_user();
477
        $usercontext = context\user::instance($user->id);
478
        $category = $this->getDataGenerator()->create_category();
479
        $categorycontext = context\coursecat::instance($category->id);
480
        $course = $this->getDataGenerator()->create_course();
481
        $coursecontext = context\course::instance($course->id);
482
        $page = $this->getDataGenerator()->create_module('page', array('course' => $course->id));
483
        $pagecontext = context\module::instance($page->cmid);
484
        $systemcontext = context\system::instance();
485
 
486
        // Default is OFF.
487
        $this->assertSame('0', $CFG->filternavigationwithsystemcontext);
488
 
489
        // First test passed values are returned if disabled.
490
        set_config('filternavigationwithsystemcontext', '0');
491
 
492
        $this->assertNull(context_helper::get_navigation_filter_context(null));
493
 
494
        $filtercontext = context_helper::get_navigation_filter_context($systemcontext);
495
        $this->assertSame($systemcontext, $filtercontext);
496
 
497
        $filtercontext = context_helper::get_navigation_filter_context($usercontext);
498
        $this->assertSame($usercontext, $filtercontext);
499
 
500
        $filtercontext = context_helper::get_navigation_filter_context($categorycontext);
501
        $this->assertSame($categorycontext, $filtercontext);
502
 
503
        $filtercontext = context_helper::get_navigation_filter_context($coursecontext);
504
        $this->assertSame($coursecontext, $filtercontext);
505
 
506
        $filtercontext = context_helper::get_navigation_filter_context($pagecontext);
507
        $this->assertSame($pagecontext, $filtercontext);
508
 
509
        // Now test that any input returns system context if enabled.
510
        set_config('filternavigationwithsystemcontext', '1');
511
 
512
        $filtercontext = context_helper::get_navigation_filter_context(null);
513
        $this->assertSame($systemcontext->id, $filtercontext->id);
514
 
515
        $filtercontext = context_helper::get_navigation_filter_context($systemcontext);
516
        $this->assertSame($systemcontext->id, $filtercontext->id);
517
 
518
        $filtercontext = context_helper::get_navigation_filter_context($usercontext);
519
        $this->assertSame($systemcontext->id, $filtercontext->id);
520
 
521
        $filtercontext = context_helper::get_navigation_filter_context($categorycontext);
522
        $this->assertSame($systemcontext->id, $filtercontext->id);
523
 
524
        $filtercontext = context_helper::get_navigation_filter_context($coursecontext);
525
        $this->assertSame($systemcontext->id, $filtercontext->id);
526
 
527
        $filtercontext = context_helper::get_navigation_filter_context($pagecontext);
528
        $this->assertSame($systemcontext->id, $filtercontext->id);
529
    }
530
}