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
namespace core;
18
 
19
use filter_manager;
20
 
21
defined('MOODLE_INTERNAL') || die();
22
 
23
global $CFG;
24
require_once($CFG->libdir . '/filterlib.php');
25
 
26
/**
27
 * Test filters.
28
 *
29
 * Tests for the parts of ../filterlib.php that involve loading the configuration
30
 * from, and saving the configuration to, the database.
31
 *
32
 * @package   core
33
 * @category  test
34
 * @copyright 2009 Tim Hunt
35
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
36
 */
1441 ariadna 37
final class filterlib_test extends \advanced_testcase {
1 efrain 38
 
39
    private function assert_only_one_filter_globally($filter, $state) {
40
        global $DB;
41
        $recs = $DB->get_records('filter_active');
42
        $this->assertCount(1, $recs);
43
        $rec = reset($recs);
44
        unset($rec->id);
45
        $expectedrec = new \stdClass();
46
        $expectedrec->filter = $filter;
47
        $expectedrec->contextid = \context_system::instance()->id;
48
        $expectedrec->active = $state;
49
        $expectedrec->sortorder = 1;
50
        $this->assertEquals($expectedrec, $rec);
51
    }
52
 
53
    private function assert_global_sort_order($filters) {
54
        global $DB;
55
 
56
        $sortedfilters = $DB->get_records_menu('filter_active',
57
            array('contextid' => \context_system::instance()->id), 'sortorder', 'sortorder,filter');
58
        $testarray = array();
59
        $index = 1;
60
        foreach ($filters as $filter) {
61
            $testarray[$index++] = $filter;
62
        }
63
        $this->assertEquals($testarray, $sortedfilters);
64
    }
65
 
11 efrain 66
    public function test_set_filter_globally_on(): void {
1 efrain 67
        $this->resetAfterTest();
68
        $this->remove_all_filters_from_config(); // Remove all filters.
69
        // Setup fixture.
70
        // Exercise SUT.
71
        filter_set_global_state('name', TEXTFILTER_ON);
72
        // Validate.
73
        $this->assert_only_one_filter_globally('name', TEXTFILTER_ON);
74
    }
75
 
11 efrain 76
    public function test_set_filter_globally_off(): void {
1 efrain 77
        $this->resetAfterTest();
78
        $this->remove_all_filters_from_config(); // Remove all filters.
79
        // Setup fixture.
80
        // Exercise SUT.
81
        filter_set_global_state('name', TEXTFILTER_OFF);
82
        // Validate.
83
        $this->assert_only_one_filter_globally('name', TEXTFILTER_OFF);
84
    }
85
 
11 efrain 86
    public function test_set_filter_globally_disabled(): void {
1 efrain 87
        $this->resetAfterTest();
88
        $this->remove_all_filters_from_config(); // Remove all filters.
89
        // Setup fixture.
90
        // Exercise SUT.
91
        filter_set_global_state('name', TEXTFILTER_DISABLED);
92
        // Validate.
93
        $this->assert_only_one_filter_globally('name', TEXTFILTER_DISABLED);
94
    }
95
 
11 efrain 96
    public function test_global_config_exception_on_invalid_state(): void {
1 efrain 97
        $this->resetAfterTest();
98
        $this->expectException(\coding_exception::class);
99
        filter_set_global_state('name', 0);
100
    }
101
 
11 efrain 102
    public function test_auto_sort_order(): void {
1 efrain 103
        $this->resetAfterTest();
104
        $this->remove_all_filters_from_config(); // Remove all filters.
105
        // Setup fixture.
106
        // Exercise SUT.
107
        filter_set_global_state('one', TEXTFILTER_DISABLED);
108
        filter_set_global_state('two', TEXTFILTER_DISABLED);
109
        // Validate.
110
        $this->assert_global_sort_order(array('one', 'two'));
111
    }
112
 
11 efrain 113
    public function test_auto_sort_order_enabled(): void {
1 efrain 114
        $this->resetAfterTest();
115
        $this->remove_all_filters_from_config(); // Remove all filters.
116
        // Setup fixture.
117
        // Exercise SUT.
118
        filter_set_global_state('one', TEXTFILTER_ON);
119
        filter_set_global_state('two', TEXTFILTER_OFF);
120
        // Validate.
121
        $this->assert_global_sort_order(array('one', 'two'));
122
    }
123
 
11 efrain 124
    public function test_update_existing_dont_duplicate(): void {
1 efrain 125
        $this->resetAfterTest();
126
        $this->remove_all_filters_from_config(); // Remove all filters.
127
        // Setup fixture.
128
        // Exercise SUT.
129
        filter_set_global_state('name', TEXTFILTER_ON);
130
        filter_set_global_state('name', TEXTFILTER_OFF);
131
        // Validate.
132
        $this->assert_only_one_filter_globally('name', TEXTFILTER_OFF);
133
    }
134
 
11 efrain 135
    public function test_update_reorder_down(): void {
1 efrain 136
        global $DB;
137
 
138
        $this->resetAfterTest();
139
        $this->remove_all_filters_from_config(); // Remove all filters.
140
        // Setup fixture.
141
        filter_set_global_state('one', TEXTFILTER_ON);
142
        filter_set_global_state('two', TEXTFILTER_ON);
143
        filter_set_global_state('three', TEXTFILTER_ON);
144
        // Exercise SUT.
145
        filter_set_global_state('two', TEXTFILTER_ON, -1);
146
        // Validate.
147
        $this->assert_global_sort_order(array('two', 'one', 'three'));
148
 
149
        // Check this was logged in config log.
150
        $logs = $DB->get_records('config_log', null, 'id DESC', '*', 0, 1);
151
        $log = reset($logs);
152
        $this->assertEquals('core_filter', $log->plugin);
153
        $this->assertEquals('order', $log->name);
154
        $this->assertEquals('two, one, three', $log->value);
155
        $this->assertEquals('one, two, three', $log->oldvalue);
156
    }
157
 
11 efrain 158
    public function test_update_reorder_up(): void {
1 efrain 159
        global $DB;
160
 
161
        $this->resetAfterTest();
162
        $this->remove_all_filters_from_config(); // Remove all filters.
163
        // Setup fixture.
164
        filter_set_global_state('one', TEXTFILTER_ON);
165
        filter_set_global_state('two', TEXTFILTER_ON);
166
        filter_set_global_state('three', TEXTFILTER_ON);
167
        filter_set_global_state('four', TEXTFILTER_ON);
168
        // Exercise SUT.
169
        filter_set_global_state('two', TEXTFILTER_ON, 1);
170
        // Validate.
171
        $this->assert_global_sort_order(array('one', 'three', 'two', 'four'));
172
 
173
        // Check this was logged in config log.
174
        $logs = $DB->get_records('config_log', null, 'id DESC', '*', 0, 1);
175
        $log = reset($logs);
176
        $this->assertEquals('core_filter', $log->plugin);
177
        $this->assertEquals('order', $log->name);
178
        $this->assertEquals('one, three, two, four', $log->value);
179
        $this->assertEquals('one, two, three, four', $log->oldvalue);
180
    }
181
 
11 efrain 182
    public function test_auto_sort_order_change_to_enabled(): void {
1 efrain 183
        $this->resetAfterTest();
184
        $this->remove_all_filters_from_config(); // Remove all filters.
185
        // Setup fixture.
186
        filter_set_global_state('one', TEXTFILTER_ON);
187
        filter_set_global_state('two', TEXTFILTER_DISABLED);
188
        filter_set_global_state('three', TEXTFILTER_DISABLED);
189
        // Exercise SUT.
190
        filter_set_global_state('three', TEXTFILTER_ON);
191
        // Validate.
192
        $this->assert_global_sort_order(array('one', 'three', 'two'));
193
    }
194
 
11 efrain 195
    public function test_auto_sort_order_change_to_disabled(): void {
1 efrain 196
        $this->resetAfterTest();
197
        $this->remove_all_filters_from_config(); // Remove all filters.
198
        // Setup fixture.
199
        filter_set_global_state('one', TEXTFILTER_ON);
200
        filter_set_global_state('two', TEXTFILTER_ON);
201
        filter_set_global_state('three', TEXTFILTER_DISABLED);
202
        // Exercise SUT.
203
        filter_set_global_state('one', TEXTFILTER_DISABLED);
204
        // Validate.
205
        $this->assert_global_sort_order(array('two', 'one', 'three'));
206
    }
207
 
11 efrain 208
    public function test_filter_get_global_states(): void {
1 efrain 209
        $this->resetAfterTest();
210
        $this->remove_all_filters_from_config(); // Remove all filters.
211
        // Setup fixture.
212
        filter_set_global_state('one', TEXTFILTER_ON);
213
        filter_set_global_state('two', TEXTFILTER_OFF);
214
        filter_set_global_state('three', TEXTFILTER_DISABLED);
215
        // Exercise SUT.
216
        $filters = filter_get_global_states();
217
        // Validate.
218
        $this->assertEquals(array(
219
            'one' => (object) array('filter' => 'one', 'active' => TEXTFILTER_ON, 'sortorder' => 1),
220
            'two' => (object) array('filter' => 'two', 'active' => TEXTFILTER_OFF, 'sortorder' => 2),
221
            'three' => (object) array('filter' => 'three', 'active' => TEXTFILTER_DISABLED, 'sortorder' => 3)
222
        ), $filters);
223
    }
224
 
225
    private function assert_only_one_local_setting($filter, $contextid, $state) {
226
        global $DB;
227
        $recs = $DB->get_records('filter_active');
228
        $this->assertEquals(1, count($recs), 'More than one record returned %s.');
229
        $rec = reset($recs);
230
        unset($rec->id);
231
        unset($rec->sortorder);
232
        $expectedrec = new \stdClass();
233
        $expectedrec->filter = $filter;
234
        $expectedrec->contextid = $contextid;
235
        $expectedrec->active = $state;
236
        $this->assertEquals($expectedrec, $rec);
237
    }
238
 
239
    private function assert_no_local_setting() {
240
        global $DB;
241
        $this->assertEquals(0, $DB->count_records('filter_active'));
242
    }
243
 
11 efrain 244
    public function test_local_on(): void {
1 efrain 245
        $this->resetAfterTest();
246
        $this->remove_all_filters_from_config(); // Remove all filters.
247
        // Exercise SUT.
248
        filter_set_local_state('name', 123, TEXTFILTER_ON);
249
        // Validate.
250
        $this->assert_only_one_local_setting('name', 123, TEXTFILTER_ON);
251
    }
252
 
11 efrain 253
    public function test_local_off(): void {
1 efrain 254
        $this->resetAfterTest();
255
        $this->remove_all_filters_from_config(); // Remove all filters.
256
        // Exercise SUT.
257
        filter_set_local_state('name', 123, TEXTFILTER_OFF);
258
        // Validate.
259
        $this->assert_only_one_local_setting('name', 123, TEXTFILTER_OFF);
260
    }
261
 
11 efrain 262
    public function test_local_inherit(): void {
1 efrain 263
        $this->resetAfterTest();
264
        $this->remove_all_filters_from_config(); // Remove all filters.
265
        // Exercise SUT.
266
        filter_set_local_state('name', 123, TEXTFILTER_INHERIT);
267
        // Validate.
268
        $this->assert_no_local_setting();
269
    }
270
 
11 efrain 271
    public function test_local_invalid_state_throws_exception(): void {
1 efrain 272
        $this->resetAfterTest();
273
        // Exercise SUT.
274
        $this->expectException(\coding_exception::class);
275
        filter_set_local_state('name', 123, -9999);
276
    }
277
 
11 efrain 278
    public function test_throws_exception_when_setting_global(): void {
1 efrain 279
        $this->resetAfterTest();
280
        // Exercise SUT.
281
        $this->expectException(\coding_exception::class);
282
        filter_set_local_state('name', \context_system::instance()->id, TEXTFILTER_INHERIT);
283
    }
284
 
11 efrain 285
    public function test_local_inherit_deletes_existing(): void {
1 efrain 286
        $this->resetAfterTest();
287
        $this->remove_all_filters_from_config(); // Remove all filters.
288
        // Setup fixture.
289
        filter_set_local_state('name', 123, TEXTFILTER_INHERIT);
290
        // Exercise SUT.
291
        filter_set_local_state('name', 123, TEXTFILTER_INHERIT);
292
        // Validate.
293
        $this->assert_no_local_setting();
294
    }
295
 
296
    private function assert_only_one_config($filter, $context, $name, $value) {
297
        global $DB;
298
        $recs = $DB->get_records('filter_config');
299
        $this->assertEquals(1, count($recs), 'More than one record returned %s.');
300
        $rec = reset($recs);
301
        unset($rec->id);
302
        $expectedrec = new \stdClass();
303
        $expectedrec->filter = $filter;
304
        $expectedrec->contextid = $context;
305
        $expectedrec->name = $name;
306
        $expectedrec->value = $value;
307
        $this->assertEquals($expectedrec, $rec);
308
    }
309
 
11 efrain 310
    public function test_set_new_config(): void {
1 efrain 311
        $this->resetAfterTest();
312
        $this->remove_all_filters_from_config(); // Remove all filters.
313
        // Exercise SUT.
314
        filter_set_local_config('name', 123, 'settingname', 'An arbitrary value');
315
        // Validate.
316
        $this->assert_only_one_config('name', 123, 'settingname', 'An arbitrary value');
317
    }
318
 
11 efrain 319
    public function test_update_existing_config(): void {
1 efrain 320
        $this->resetAfterTest();
321
        $this->remove_all_filters_from_config(); // Remove all filters.
322
        // Setup fixture.
323
        filter_set_local_config('name', 123, 'settingname', 'An arbitrary value');
324
        // Exercise SUT.
325
        filter_set_local_config('name', 123, 'settingname', 'A changed value');
326
        // Validate.
327
        $this->assert_only_one_config('name', 123, 'settingname', 'A changed value');
328
    }
329
 
11 efrain 330
    public function test_filter_get_local_config(): void {
1 efrain 331
        $this->resetAfterTest();
332
        // Setup fixture.
333
        filter_set_local_config('name', 123, 'setting1', 'An arbitrary value');
334
        filter_set_local_config('name', 123, 'setting2', 'Another arbitrary value');
335
        filter_set_local_config('name', 122, 'settingname', 'Value from another context');
336
        filter_set_local_config('other', 123, 'settingname', 'Someone else\'s value');
337
        // Exercise SUT.
338
        $config = filter_get_local_config('name', 123);
339
        // Validate.
340
        $this->assertEquals(array('setting1' => 'An arbitrary value', 'setting2' => 'Another arbitrary value'), $config);
341
    }
342
 
343
    protected function setup_available_in_context_tests() {
344
        $course = $this->getDataGenerator()->create_course(array('category' => 1));
345
 
346
        $childcontext = \context_coursecat::instance(1);
347
        $childcontext2 = \context_course::instance($course->id);
348
        $syscontext = \context_system::instance();
349
 
350
        return [
351
            'syscontext' => $syscontext,
352
            'childcontext' => $childcontext,
353
            'childcontext2' => $childcontext2
354
        ];
355
    }
356
 
357
    protected function remove_all_filters_from_config() {
358
        global $DB;
359
        $DB->delete_records('filter_active', array());
360
        $DB->delete_records('filter_config', array());
361
    }
362
 
363
    private function assert_filter_list($expectedfilters, $filters) {
364
        $this->assertEqualsCanonicalizing($expectedfilters, array_keys($filters));
365
    }
366
 
11 efrain 367
    public function test_globally_on_is_returned(): void {
1 efrain 368
        $this->resetAfterTest();
369
        $this->remove_all_filters_from_config(); // Remove all filters.
370
        [
371
            'syscontext' => $syscontext
372
        ] = $this->setup_available_in_context_tests();
373
        // Setup fixture.
374
        filter_set_global_state('name', TEXTFILTER_ON);
375
        // Exercise SUT.
376
        $filters = filter_get_active_in_context($syscontext);
377
        // Validate.
378
        $this->assert_filter_list(array('name'), $filters);
379
        // Check no config returned correctly.
380
        $this->assertEquals(array(), $filters['name']);
381
    }
382
 
11 efrain 383
    public function test_globally_off_not_returned(): void {
1 efrain 384
        $this->resetAfterTest();
385
        $this->remove_all_filters_from_config(); // Remove all filters.
386
        [
387
            'childcontext2' => $childcontext2
388
        ] = $this->setup_available_in_context_tests();
389
        // Setup fixture.
390
        filter_set_global_state('name', TEXTFILTER_OFF);
391
        // Exercise SUT.
392
        $filters = filter_get_active_in_context($childcontext2);
393
        // Validate.
394
        $this->assert_filter_list(array(), $filters);
395
    }
396
 
11 efrain 397
    public function test_globally_off_overridden(): void {
1 efrain 398
        $this->resetAfterTest();
399
        $this->remove_all_filters_from_config(); // Remove all filters.
400
        [
401
            'childcontext' => $childcontext,
402
            'childcontext2' => $childcontext2
403
        ] = $this->setup_available_in_context_tests();
404
        // Setup fixture.
405
        filter_set_global_state('name', TEXTFILTER_OFF);
406
        filter_set_local_state('name', $childcontext->id, TEXTFILTER_ON);
407
        // Exercise SUT.
408
        $filters = filter_get_active_in_context($childcontext2);
409
        // Validate.
410
        $this->assert_filter_list(array('name'), $filters);
411
    }
412
 
11 efrain 413
    public function test_globally_on_overridden(): void {
1 efrain 414
        $this->resetAfterTest();
415
        $this->remove_all_filters_from_config(); // Remove all filters.
416
        [
417
            'childcontext' => $childcontext,
418
            'childcontext2' => $childcontext2
419
        ] = $this->setup_available_in_context_tests();
420
        // Setup fixture.
421
        filter_set_global_state('name', TEXTFILTER_ON);
422
        filter_set_local_state('name', $childcontext->id, TEXTFILTER_OFF);
423
        // Exercise SUT.
424
        $filters = filter_get_active_in_context($childcontext2);
425
        // Validate.
426
        $this->assert_filter_list(array(), $filters);
427
    }
428
 
11 efrain 429
    public function test_globally_disabled_not_overridden(): void {
1 efrain 430
        $this->resetAfterTest();
431
        $this->remove_all_filters_from_config(); // Remove all filters.
432
        [
433
            'syscontext' => $syscontext,
434
            'childcontext' => $childcontext
435
        ] = $this->setup_available_in_context_tests();
436
        // Setup fixture.
437
        filter_set_global_state('name', TEXTFILTER_DISABLED);
438
        filter_set_local_state('name', $childcontext->id, TEXTFILTER_ON);
439
        // Exercise SUT.
440
        $filters = filter_get_active_in_context($syscontext);
441
        // Validate.
442
        $this->assert_filter_list(array(), $filters);
443
    }
444
 
11 efrain 445
    public function test_single_config_returned(): void {
1 efrain 446
        $this->resetAfterTest();
447
        [
448
            'childcontext' => $childcontext
449
        ] = $this->setup_available_in_context_tests();
450
        // Setup fixture.
451
        filter_set_global_state('name', TEXTFILTER_ON);
452
        filter_set_local_config('name', $childcontext->id, 'settingname', 'A value');
453
        // Exercise SUT.
454
        $filters = filter_get_active_in_context($childcontext);
455
        // Validate.
456
        $this->assertEquals(array('settingname' => 'A value'), $filters['name']);
457
    }
458
 
11 efrain 459
    public function test_multi_config_returned(): void {
1 efrain 460
        $this->resetAfterTest();
461
        [
462
            'childcontext' => $childcontext
463
        ] = $this->setup_available_in_context_tests();
464
        // Setup fixture.
465
        filter_set_global_state('name', TEXTFILTER_ON);
466
        filter_set_local_config('name', $childcontext->id, 'settingname', 'A value');
467
        filter_set_local_config('name', $childcontext->id, 'anothersettingname', 'Another value');
468
        // Exercise SUT.
469
        $filters = filter_get_active_in_context($childcontext);
470
        // Validate.
471
        $this->assertEquals(array('settingname' => 'A value', 'anothersettingname' => 'Another value'), $filters['name']);
472
    }
473
 
11 efrain 474
    public function test_config_from_other_context_not_returned(): void {
1 efrain 475
        $this->resetAfterTest();
476
        [
477
            'childcontext' => $childcontext,
478
            'childcontext2' => $childcontext2
479
        ] = $this->setup_available_in_context_tests();
480
        // Setup fixture.
481
        filter_set_global_state('name', TEXTFILTER_ON);
482
        filter_set_local_config('name', $childcontext->id, 'settingname', 'A value');
483
        filter_set_local_config('name', $childcontext2->id, 'anothersettingname', 'Another value');
484
        // Exercise SUT.
485
        $filters = filter_get_active_in_context($childcontext2);
486
        // Validate.
487
        $this->assertEquals(array('anothersettingname' => 'Another value'), $filters['name']);
488
    }
489
 
11 efrain 490
    public function test_config_from_other_filter_not_returned(): void {
1 efrain 491
        $this->resetAfterTest();
492
        [
493
            'childcontext' => $childcontext
494
        ] = $this->setup_available_in_context_tests();
495
        // Setup fixture.
496
        filter_set_global_state('name', TEXTFILTER_ON);
497
        filter_set_local_config('name', $childcontext->id, 'settingname', 'A value');
498
        filter_set_local_config('other', $childcontext->id, 'anothersettingname', 'Another value');
499
        // Exercise SUT.
500
        $filters = filter_get_active_in_context($childcontext);
501
        // Validate.
502
        $this->assertEquals(array('settingname' => 'A value'), $filters['name']);
503
    }
504
 
505
    protected function assert_one_available_filter($filter, $localstate, $inheritedstate, $filters) {
506
        $this->assertEquals(1, count($filters), 'More than one record returned %s.');
507
        $rec = $filters[$filter];
508
        unset($rec->id);
509
        $expectedrec = new \stdClass();
510
        $expectedrec->filter = $filter;
511
        $expectedrec->localstate = $localstate;
512
        $expectedrec->inheritedstate = $inheritedstate;
513
        $this->assertEquals($expectedrec, $rec);
514
    }
515
 
11 efrain 516
    public function test_available_in_context_localoverride(): void {
1 efrain 517
        $this->resetAfterTest();
518
        $this->remove_all_filters_from_config(); // Remove all filters.
519
        [
520
            'childcontext' => $childcontext
521
        ] = $this->setup_available_in_context_tests();
522
        // Setup fixture.
523
        filter_set_global_state('name', TEXTFILTER_ON);
524
        filter_set_local_state('name', $childcontext->id, TEXTFILTER_OFF);
525
        // Exercise SUT.
526
        $filters = filter_get_available_in_context($childcontext);
527
        // Validate.
528
        $this->assert_one_available_filter('name', TEXTFILTER_OFF, TEXTFILTER_ON, $filters);
529
    }
530
 
11 efrain 531
    public function test_available_in_context_nolocaloverride(): void {
1 efrain 532
        $this->resetAfterTest();
533
        $this->remove_all_filters_from_config(); // Remove all filters.
534
        [
535
            'childcontext' => $childcontext,
536
            'childcontext2' => $childcontext2
537
        ] = $this->setup_available_in_context_tests();
538
        // Setup fixture.
539
        filter_set_global_state('name', TEXTFILTER_ON);
540
        filter_set_local_state('name', $childcontext->id, TEXTFILTER_OFF);
541
        // Exercise SUT.
542
        $filters = filter_get_available_in_context($childcontext2);
543
        // Validate.
544
        $this->assert_one_available_filter('name', TEXTFILTER_INHERIT, TEXTFILTER_OFF, $filters);
545
    }
546
 
11 efrain 547
    public function test_available_in_context_disabled_not_returned(): void {
1 efrain 548
        $this->resetAfterTest();
549
        $this->remove_all_filters_from_config(); // Remove all filters.
550
        [
551
            'childcontext' => $childcontext
552
        ] = $this->setup_available_in_context_tests();
553
        // Setup fixture.
554
        filter_set_global_state('name', TEXTFILTER_DISABLED);
555
        filter_set_local_state('name', $childcontext->id, TEXTFILTER_ON);
556
        // Exercise SUT.
557
        $filters = filter_get_available_in_context($childcontext);
558
        // Validate.
559
        $this->assertEquals(array(), $filters);
560
    }
561
 
11 efrain 562
    public function test_available_in_context_exception_with_syscontext(): void {
1 efrain 563
        $this->resetAfterTest();
564
        [
565
            'syscontext' => $syscontext
566
        ] = $this->setup_available_in_context_tests();
567
        // Exercise SUT.
568
        $this->expectException(\coding_exception::class);
569
        filter_get_available_in_context($syscontext);
570
    }
571
 
572
    protected function setup_preload_activities_test() {
573
        $syscontext = \context_system::instance();
574
        $catcontext = \context_coursecat::instance(1);
575
        $course = $this->getDataGenerator()->create_course(array('category' => 1));
576
        $coursecontext = \context_course::instance($course->id);
577
        $page1 = $this->getDataGenerator()->create_module('page', array('course' => $course->id));
578
        $activity1context = \context_module::instance($page1->cmid);
579
        $page2 = $this->getDataGenerator()->create_module('page', array('course' => $course->id));
580
        $activity2context = \context_module::instance($page2->cmid);
581
        return [
582
            'syscontext' => $syscontext,
583
            'catcontext' => $catcontext,
584
            'course' => $course,
585
            'coursecontext' => $coursecontext,
586
            'activity1context' => $activity1context,
587
            'activity2context' => $activity2context
588
         ];
589
    }
590
 
591
    private function assert_matches($modinfo, $activity1context, $activity2context) {
592
        global $FILTERLIB_PRIVATE, $DB;
593
 
594
        // Use preload cache...
595
        $FILTERLIB_PRIVATE = new \stdClass();
596
        filter_preload_activities($modinfo);
597
 
598
        // Get data and check no queries are made.
599
        $before = $DB->perf_get_reads();
600
        $plfilters1 = filter_get_active_in_context($activity1context);
601
        $plfilters2 = filter_get_active_in_context($activity2context);
602
        $after = $DB->perf_get_reads();
603
        $this->assertEquals($before, $after);
604
 
605
        // Repeat without cache and check it makes queries now.
606
        $FILTERLIB_PRIVATE = new \stdClass;
607
        $before = $DB->perf_get_reads();
608
        $filters1 = filter_get_active_in_context($activity1context);
609
        $filters2 = filter_get_active_in_context($activity2context);
610
        $after = $DB->perf_get_reads();
611
        $this->assertTrue($after > $before);
612
 
613
        // Check they match.
614
        $this->assertEquals($plfilters1, $filters1);
615
        $this->assertEquals($plfilters2, $filters2);
616
    }
617
 
11 efrain 618
    public function test_preload(): void {
1 efrain 619
        $this->resetAfterTest();
620
        [
621
            'catcontext' => $catcontext,
622
            'course' => $course,
623
            'coursecontext' => $coursecontext,
624
            'activity1context' => $activity1context,
625
            'activity2context' => $activity2context
626
         ] = $this->setup_preload_activities_test();
627
        // Get course and modinfo.
628
        $modinfo = new \course_modinfo($course, 2);
629
 
630
        // Note: All the tests in this function check that the result from the
631
        // preloaded cache is the same as the result from calling the standard
632
        // function without preloading.
633
 
634
        // Initially, check with no filters enabled.
635
        $this->assert_matches($modinfo, $activity1context, $activity2context);
636
 
637
        // Enable filter globally, check.
638
        filter_set_global_state('name', TEXTFILTER_ON);
639
        $this->assert_matches($modinfo, $activity1context, $activity2context);
640
 
641
        // Disable for activity 2.
642
        filter_set_local_state('name', $activity2context->id, TEXTFILTER_OFF);
643
        $this->assert_matches($modinfo, $activity1context, $activity2context);
644
 
645
        // Disable at category.
646
        filter_set_local_state('name', $catcontext->id, TEXTFILTER_OFF);
647
        $this->assert_matches($modinfo, $activity1context, $activity2context);
648
 
649
        // Enable for activity 1.
650
        filter_set_local_state('name', $activity1context->id, TEXTFILTER_ON);
651
        $this->assert_matches($modinfo, $activity1context, $activity2context);
652
 
653
        // Disable globally.
654
        filter_set_global_state('name', TEXTFILTER_DISABLED);
655
        $this->assert_matches($modinfo, $activity1context, $activity2context);
656
 
657
        // Add another 2 filters.
658
        filter_set_global_state('frog', TEXTFILTER_ON);
659
        filter_set_global_state('zombie', TEXTFILTER_ON);
660
        $this->assert_matches($modinfo, $activity1context, $activity2context);
661
 
662
        // Disable random one of these in each context.
663
        filter_set_local_state('zombie', $activity1context->id, TEXTFILTER_OFF);
664
        filter_set_local_state('frog', $activity2context->id, TEXTFILTER_OFF);
665
        $this->assert_matches($modinfo, $activity1context, $activity2context);
666
 
667
        // Now do some filter options.
668
        filter_set_local_config('name', $activity1context->id, 'a', 'x');
669
        filter_set_local_config('zombie', $activity1context->id, 'a', 'y');
670
        filter_set_local_config('frog', $activity1context->id, 'a', 'z');
671
        // These last two don't do anything as they are not at final level but I
672
        // thought it would be good to have that verified in test.
673
        filter_set_local_config('frog', $coursecontext->id, 'q', 'x');
674
        filter_set_local_config('frog', $catcontext->id, 'q', 'z');
675
        $this->assert_matches($modinfo, $activity1context, $activity2context);
676
    }
677
 
11 efrain 678
    public function test_filter_delete_all_for_filter(): void {
1 efrain 679
        global $DB;
680
        $this->resetAfterTest();
681
        $this->remove_all_filters_from_config(); // Remove all filters.
682
 
683
        // Setup fixture.
684
        filter_set_global_state('name', TEXTFILTER_ON);
685
        filter_set_global_state('other', TEXTFILTER_ON);
686
        filter_set_local_config('name', \context_system::instance()->id, 'settingname', 'A value');
687
        filter_set_local_config('other', \context_system::instance()->id, 'settingname', 'Other value');
688
        set_config('configname', 'A config value', 'filter_name');
689
        set_config('configname', 'Other config value', 'filter_other');
690
        // Exercise SUT.
691
        filter_delete_all_for_filter('name');
692
        // Validate.
693
        $this->assertEquals(1, $DB->count_records('filter_active'));
694
        $this->assertTrue($DB->record_exists('filter_active', array('filter' => 'other')));
695
        $this->assertEquals(1, $DB->count_records('filter_config'));
696
        $this->assertTrue($DB->record_exists('filter_config', array('filter' => 'other')));
697
        $expectedconfig = new \stdClass;
698
        $expectedconfig->configname = 'Other config value';
699
        $this->assertEquals($expectedconfig, get_config('filter_other'));
700
        $this->assertEquals(get_config('filter_name'), new \stdClass());
701
    }
702
 
11 efrain 703
    public function test_filter_delete_all_for_context(): void {
1 efrain 704
        global $DB;
705
        $this->resetAfterTest();
706
        $this->remove_all_filters_from_config(); // Remove all filters.
707
 
708
        // Setup fixture.
709
        filter_set_global_state('name', TEXTFILTER_ON);
710
        filter_set_local_state('name', 123, TEXTFILTER_OFF);
711
        filter_set_local_config('name', 123, 'settingname', 'A value');
712
        filter_set_local_config('other', 123, 'settingname', 'Other value');
713
        filter_set_local_config('other', 122, 'settingname', 'Other value');
714
        // Exercise SUT.
715
        filter_delete_all_for_context(123);
716
        // Validate.
717
        $this->assertEquals(1, $DB->count_records('filter_active'));
718
        $this->assertTrue($DB->record_exists('filter_active', array('contextid' => \context_system::instance()->id)));
719
        $this->assertEquals(1, $DB->count_records('filter_config'));
720
        $this->assertTrue($DB->record_exists('filter_config', array('filter' => 'other')));
721
    }
722
 
11 efrain 723
    public function test_set(): void {
1 efrain 724
        global $CFG;
725
        $this->resetAfterTest();
726
 
727
        $this->assertFileExists("$CFG->dirroot/filter/emailprotect"); // Any standard filter.
1441 ariadna 728
        $this->assertFileExists("$CFG->dirroot/filter/glossary");         // Any standard filter.
1 efrain 729
        $this->assertFileDoesNotExist("$CFG->dirroot/filter/grgrggr");   // Any non-existent filter.
730
 
731
        // Setup fixture.
732
        set_config('filterall', 0);
733
        set_config('stringfilters', '');
734
        // Exercise SUT.
1441 ariadna 735
        filter_set_applies_to_strings('glossary', true);
1 efrain 736
        // Validate.
1441 ariadna 737
        $this->assertEquals('glossary', $CFG->stringfilters);
1 efrain 738
        $this->assertEquals(1, $CFG->filterall);
739
 
740
        filter_set_applies_to_strings('grgrggr', true);
1441 ariadna 741
        $this->assertEquals('glossary', $CFG->stringfilters);
1 efrain 742
        $this->assertEquals(1, $CFG->filterall);
743
 
744
        filter_set_applies_to_strings('emailprotect', true);
1441 ariadna 745
        $this->assertEquals('glossary,emailprotect', $CFG->stringfilters);
1 efrain 746
        $this->assertEquals(1, $CFG->filterall);
747
    }
748
 
11 efrain 749
    public function test_unset_to_empty(): void {
1 efrain 750
        global $CFG;
751
        $this->resetAfterTest();
752
 
1441 ariadna 753
        $this->assertFileExists("$CFG->dirroot/filter/glossary"); // Any standard filter.
1 efrain 754
 
755
        // Setup fixture.
756
        set_config('filterall', 1);
1441 ariadna 757
        set_config('stringfilters', 'glossary');
1 efrain 758
        // Exercise SUT.
1441 ariadna 759
        filter_set_applies_to_strings('glossary', false);
1 efrain 760
        // Validate.
761
        $this->assertEquals('', $CFG->stringfilters);
762
        $this->assertEquals('', $CFG->filterall);
763
    }
764
 
11 efrain 765
    public function test_unset_multi(): void {
1 efrain 766
        global $CFG;
767
        $this->resetAfterTest();
768
 
769
        $this->assertFileExists("$CFG->dirroot/filter/emailprotect"); // Any standard filter.
1441 ariadna 770
        $this->assertFileExists("$CFG->dirroot/filter/glossary");         // Any standard filter.
1 efrain 771
        $this->assertFileExists("$CFG->dirroot/filter/multilang");    // Any standard filter.
772
 
773
        // Setup fixture.
774
        set_config('filterall', 1);
1441 ariadna 775
        set_config('stringfilters', 'emailprotect,glossary,multilang');
1 efrain 776
        // Exercise SUT.
1441 ariadna 777
        filter_set_applies_to_strings('glossary', false);
1 efrain 778
        // Validate.
779
        $this->assertEquals('emailprotect,multilang', $CFG->stringfilters);
780
        $this->assertEquals(1, $CFG->filterall);
781
    }
782
 
11 efrain 783
    public function test_filter_manager_instance(): void {
1 efrain 784
        $this->resetAfterTest();
785
 
786
        set_config('perfdebug', 7);
787
        filter_manager::reset_caches();
788
        $filterman = filter_manager::instance();
789
        $this->assertInstanceOf('filter_manager', $filterman);
790
        $this->assertNotInstanceOf('performance_measuring_filter_manager', $filterman);
791
 
792
        set_config('perfdebug', 15);
793
        filter_manager::reset_caches();
794
        $filterman = filter_manager::instance();
795
        $this->assertInstanceOf('filter_manager', $filterman);
796
        $this->assertInstanceOf('performance_measuring_filter_manager', $filterman);
797
    }
798
 
11 efrain 799
    public function test_filter_get_active_state_contextid_parameter(): void {
1 efrain 800
        $this->resetAfterTest();
801
 
802
        filter_set_global_state('glossary', TEXTFILTER_ON);
803
        // Using system context by default.
804
        $active = filter_get_active_state('glossary');
805
        $this->assertEquals($active, TEXTFILTER_ON);
806
 
807
        $systemcontext = \context_system::instance();
808
        // Passing $systemcontext object.
809
        $active = filter_get_active_state('glossary', $systemcontext);
810
        $this->assertEquals($active, TEXTFILTER_ON);
811
 
812
        // Passing $systemcontext id.
813
        $active = filter_get_active_state('glossary', $systemcontext->id);
814
        $this->assertEquals($active, TEXTFILTER_ON);
815
 
816
        // Not system context.
817
        filter_set_local_state('glossary', '123', TEXTFILTER_ON);
818
        $active = filter_get_active_state('glossary', '123');
819
        $this->assertEquals($active, TEXTFILTER_ON);
820
    }
821
 
11 efrain 822
    public function test_filter_get_active_state_filtername_parameter(): void {
1 efrain 823
        $this->resetAfterTest();
824
 
825
        filter_set_global_state('glossary', TEXTFILTER_ON);
826
        // Using full filtername.
827
        $active = filter_get_active_state('filter/glossary');
828
        $this->assertEquals($active, TEXTFILTER_ON);
829
 
830
        // Wrong filtername.
831
        $this->expectException('coding_exception');
832
        $active = filter_get_active_state('mod/glossary');
833
    }
834
 
11 efrain 835
    public function test_filter_get_active_state_after_change(): void {
1 efrain 836
        $this->resetAfterTest();
837
 
838
        filter_set_global_state('glossary', TEXTFILTER_ON);
839
        $systemcontextid = \context_system::instance()->id;
840
        $active = filter_get_active_state('glossary', $systemcontextid);
841
        $this->assertEquals($active, TEXTFILTER_ON);
842
 
843
        filter_set_global_state('glossary', TEXTFILTER_OFF);
844
        $systemcontextid = \context_system::instance()->id;
845
        $active = filter_get_active_state('glossary', $systemcontextid);
846
        $this->assertEquals($active, TEXTFILTER_OFF);
847
 
848
        filter_set_global_state('glossary', TEXTFILTER_DISABLED);
849
        $systemcontextid = \context_system::instance()->id;
850
        $active = filter_get_active_state('glossary', $systemcontextid);
851
        $this->assertEquals($active, TEXTFILTER_DISABLED);
852
    }
853
 
11 efrain 854
    public function test_filter_get_globally_enabled_default(): void {
1 efrain 855
        $this->resetAfterTest();
856
        $enabledfilters = filter_get_globally_enabled();
857
        $this->assertArrayNotHasKey('glossary', $enabledfilters);
858
    }
859
 
11 efrain 860
    public function test_filter_get_globally_enabled_after_change(): void {
1 efrain 861
        $this->resetAfterTest();
862
        filter_set_global_state('glossary', TEXTFILTER_ON);
863
        $enabledfilters = filter_get_globally_enabled();
864
        $this->assertArrayHasKey('glossary', $enabledfilters);
865
    }
866
 
11 efrain 867
    public function test_filter_get_globally_enabled_filters_with_config(): void {
1 efrain 868
        $this->resetAfterTest();
869
        $this->remove_all_filters_from_config(); // Remove all filters.
870
        [
871
            'syscontext' => $syscontext,
872
            'childcontext' => $childcontext
873
        ] = $this->setup_available_in_context_tests();
874
        $this->remove_all_filters_from_config(); // Remove all filters.
875
 
876
        // Set few filters.
877
        filter_set_global_state('one', TEXTFILTER_ON);
878
        filter_set_global_state('three', TEXTFILTER_OFF, -1);
879
        filter_set_global_state('two', TEXTFILTER_DISABLED);
880
 
881
        // Set global config.
882
        filter_set_local_config('one', $syscontext->id, 'test1a', 'In root');
883
        filter_set_local_config('one', $syscontext->id, 'test1b', 'In root');
884
        filter_set_local_config('two', $syscontext->id, 'test2a', 'In root');
885
        filter_set_local_config('two', $syscontext->id, 'test2b', 'In root');
886
 
887
        // Set child config.
888
        filter_set_local_config('one', $childcontext->id, 'test1a', 'In child');
889
        filter_set_local_config('one', $childcontext->id, 'test1b', 'In child');
890
        filter_set_local_config('two', $childcontext->id, 'test2a', 'In child');
891
        filter_set_local_config('two', $childcontext->id, 'test2b', 'In child');
892
        filter_set_local_config('three', $childcontext->id, 'test3a', 'In child');
893
        filter_set_local_config('three', $childcontext->id, 'test3b', 'In child');
894
 
895
        // Check.
896
        $actual = filter_get_globally_enabled_filters_with_config();
897
        $this->assertCount(2, $actual);
898
        $this->assertEquals(['three', 'one'], array_keys($actual));     // Checks sortorder.
899
        $this->assertArrayHasKey('one', $actual);
900
        $this->assertArrayNotHasKey('two', $actual);
901
        $this->assertArrayHasKey('three', $actual);
902
        $this->assertEquals(['test1a' => 'In root', 'test1b' => 'In root'], $actual['one']);
903
        $this->assertEquals([], $actual['three']);
904
    }
905
}