Merge branch 'MDL-80233-main' of https://github.com/aanabit/moodle
[moodle.git] / lib / tests / filterlib_test.php
blob29bd34c74efd6f532bc9c7caa701d24779cd50e5
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17 namespace core;
19 use filter_manager;
21 defined('MOODLE_INTERNAL') || die();
23 global $CFG;
24 require_once($CFG->libdir . '/filterlib.php');
26 /**
27 * Test filters.
29 * Tests for the parts of ../filterlib.php that involve loading the configuration
30 * from, and saving the configuration to, the database.
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
37 class filterlib_test extends \advanced_testcase {
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);
53 private function assert_global_sort_order($filters) {
54 global $DB;
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;
63 $this->assertEquals($testarray, $sortedfilters);
66 public function test_set_filter_globally_on() {
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);
76 public function test_set_filter_globally_off() {
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);
86 public function test_set_filter_globally_disabled() {
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);
96 public function test_global_config_exception_on_invalid_state() {
97 $this->resetAfterTest();
98 $this->expectException(\coding_exception::class);
99 filter_set_global_state('name', 0);
102 public function test_auto_sort_order() {
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'));
113 public function test_auto_sort_order_enabled() {
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'));
124 public function test_update_existing_dont_duplicate() {
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);
135 public function test_update_reorder_down() {
136 global $DB;
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'));
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);
158 public function test_update_reorder_up() {
159 global $DB;
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'));
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);
182 public function test_auto_sort_order_change_to_enabled() {
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'));
195 public function test_auto_sort_order_change_to_disabled() {
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'));
208 public function test_filter_get_global_states() {
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);
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);
239 private function assert_no_local_setting() {
240 global $DB;
241 $this->assertEquals(0, $DB->count_records('filter_active'));
244 public function test_local_on() {
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);
253 public function test_local_off() {
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);
262 public function test_local_inherit() {
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();
271 public function test_local_invalid_state_throws_exception() {
272 $this->resetAfterTest();
273 // Exercise SUT.
274 $this->expectException(\coding_exception::class);
275 filter_set_local_state('name', 123, -9999);
278 public function test_throws_exception_when_setting_global() {
279 $this->resetAfterTest();
280 // Exercise SUT.
281 $this->expectException(\coding_exception::class);
282 filter_set_local_state('name', \context_system::instance()->id, TEXTFILTER_INHERIT);
285 public function test_local_inherit_deletes_existing() {
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();
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);
310 public function test_set_new_config() {
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');
319 public function test_update_existing_config() {
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');
330 public function test_filter_get_local_config() {
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);
343 protected function setup_available_in_context_tests() {
344 $course = $this->getDataGenerator()->create_course(array('category' => 1));
346 $childcontext = \context_coursecat::instance(1);
347 $childcontext2 = \context_course::instance($course->id);
348 $syscontext = \context_system::instance();
350 return [
351 'syscontext' => $syscontext,
352 'childcontext' => $childcontext,
353 'childcontext2' => $childcontext2
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());
363 private function assert_filter_list($expectedfilters, $filters) {
364 $this->assertEqualsCanonicalizing($expectedfilters, array_keys($filters));
367 public function test_globally_on_is_returned() {
368 $this->resetAfterTest();
369 $this->remove_all_filters_from_config(); // Remove all filters.
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']);
383 public function test_globally_off_not_returned() {
384 $this->resetAfterTest();
385 $this->remove_all_filters_from_config(); // Remove all filters.
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);
397 public function test_globally_off_overridden() {
398 $this->resetAfterTest();
399 $this->remove_all_filters_from_config(); // Remove all filters.
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);
413 public function test_globally_on_overridden() {
414 $this->resetAfterTest();
415 $this->remove_all_filters_from_config(); // Remove all filters.
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);
429 public function test_globally_disabled_not_overridden() {
430 $this->resetAfterTest();
431 $this->remove_all_filters_from_config(); // Remove all filters.
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);
445 public function test_single_config_returned() {
446 $this->resetAfterTest();
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']);
459 public function test_multi_config_returned() {
460 $this->resetAfterTest();
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']);
474 public function test_config_from_other_context_not_returned() {
475 $this->resetAfterTest();
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']);
490 public function test_config_from_other_filter_not_returned() {
491 $this->resetAfterTest();
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']);
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);
516 public function test_available_in_context_localoverride() {
517 $this->resetAfterTest();
518 $this->remove_all_filters_from_config(); // Remove all filters.
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);
531 public function test_available_in_context_nolocaloverride() {
532 $this->resetAfterTest();
533 $this->remove_all_filters_from_config(); // Remove all filters.
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);
547 public function test_available_in_context_disabled_not_returned() {
548 $this->resetAfterTest();
549 $this->remove_all_filters_from_config(); // Remove all filters.
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);
562 public function test_available_in_context_exception_with_syscontext() {
563 $this->resetAfterTest();
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);
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
591 private function assert_matches($modinfo, $activity1context, $activity2context) {
592 global $FILTERLIB_PRIVATE, $DB;
594 // Use preload cache...
595 $FILTERLIB_PRIVATE = new \stdClass();
596 filter_preload_activities($modinfo);
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);
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);
613 // Check they match.
614 $this->assertEquals($plfilters1, $filters1);
615 $this->assertEquals($plfilters2, $filters2);
618 public function test_preload() {
619 $this->resetAfterTest();
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);
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.
634 // Initially, check with no filters enabled.
635 $this->assert_matches($modinfo, $activity1context, $activity2context);
637 // Enable filter globally, check.
638 filter_set_global_state('name', TEXTFILTER_ON);
639 $this->assert_matches($modinfo, $activity1context, $activity2context);
641 // Disable for activity 2.
642 filter_set_local_state('name', $activity2context->id, TEXTFILTER_OFF);
643 $this->assert_matches($modinfo, $activity1context, $activity2context);
645 // Disable at category.
646 filter_set_local_state('name', $catcontext->id, TEXTFILTER_OFF);
647 $this->assert_matches($modinfo, $activity1context, $activity2context);
649 // Enable for activity 1.
650 filter_set_local_state('name', $activity1context->id, TEXTFILTER_ON);
651 $this->assert_matches($modinfo, $activity1context, $activity2context);
653 // Disable globally.
654 filter_set_global_state('name', TEXTFILTER_DISABLED);
655 $this->assert_matches($modinfo, $activity1context, $activity2context);
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);
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);
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);
678 public function test_filter_delete_all_for_filter() {
679 global $DB;
680 $this->resetAfterTest();
681 $this->remove_all_filters_from_config(); // Remove all filters.
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());
703 public function test_filter_delete_all_for_context() {
704 global $DB;
705 $this->resetAfterTest();
706 $this->remove_all_filters_from_config(); // Remove all filters.
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')));
723 public function test_set() {
724 global $CFG;
725 $this->resetAfterTest();
727 $this->assertFileExists("$CFG->dirroot/filter/emailprotect"); // Any standard filter.
728 $this->assertFileExists("$CFG->dirroot/filter/tidy"); // Any standard filter.
729 $this->assertFileDoesNotExist("$CFG->dirroot/filter/grgrggr"); // Any non-existent filter.
731 // Setup fixture.
732 set_config('filterall', 0);
733 set_config('stringfilters', '');
734 // Exercise SUT.
735 filter_set_applies_to_strings('tidy', true);
736 // Validate.
737 $this->assertEquals('tidy', $CFG->stringfilters);
738 $this->assertEquals(1, $CFG->filterall);
740 filter_set_applies_to_strings('grgrggr', true);
741 $this->assertEquals('tidy', $CFG->stringfilters);
742 $this->assertEquals(1, $CFG->filterall);
744 filter_set_applies_to_strings('emailprotect', true);
745 $this->assertEquals('tidy,emailprotect', $CFG->stringfilters);
746 $this->assertEquals(1, $CFG->filterall);
749 public function test_unset_to_empty() {
750 global $CFG;
751 $this->resetAfterTest();
753 $this->assertFileExists("$CFG->dirroot/filter/tidy"); // Any standard filter.
755 // Setup fixture.
756 set_config('filterall', 1);
757 set_config('stringfilters', 'tidy');
758 // Exercise SUT.
759 filter_set_applies_to_strings('tidy', false);
760 // Validate.
761 $this->assertEquals('', $CFG->stringfilters);
762 $this->assertEquals('', $CFG->filterall);
765 public function test_unset_multi() {
766 global $CFG;
767 $this->resetAfterTest();
769 $this->assertFileExists("$CFG->dirroot/filter/emailprotect"); // Any standard filter.
770 $this->assertFileExists("$CFG->dirroot/filter/tidy"); // Any standard filter.
771 $this->assertFileExists("$CFG->dirroot/filter/multilang"); // Any standard filter.
773 // Setup fixture.
774 set_config('filterall', 1);
775 set_config('stringfilters', 'emailprotect,tidy,multilang');
776 // Exercise SUT.
777 filter_set_applies_to_strings('tidy', false);
778 // Validate.
779 $this->assertEquals('emailprotect,multilang', $CFG->stringfilters);
780 $this->assertEquals(1, $CFG->filterall);
783 public function test_filter_manager_instance() {
784 $this->resetAfterTest();
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);
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);
799 public function test_filter_get_active_state_contextid_parameter() {
800 $this->resetAfterTest();
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);
807 $systemcontext = \context_system::instance();
808 // Passing $systemcontext object.
809 $active = filter_get_active_state('glossary', $systemcontext);
810 $this->assertEquals($active, TEXTFILTER_ON);
812 // Passing $systemcontext id.
813 $active = filter_get_active_state('glossary', $systemcontext->id);
814 $this->assertEquals($active, TEXTFILTER_ON);
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);
822 public function test_filter_get_active_state_filtername_parameter() {
823 $this->resetAfterTest();
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);
830 // Wrong filtername.
831 $this->expectException('coding_exception');
832 $active = filter_get_active_state('mod/glossary');
835 public function test_filter_get_active_state_after_change() {
836 $this->resetAfterTest();
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);
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);
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);
854 public function test_filter_get_globally_enabled_default() {
855 $this->resetAfterTest();
856 $enabledfilters = filter_get_globally_enabled();
857 $this->assertArrayNotHasKey('glossary', $enabledfilters);
860 public function test_filter_get_globally_enabled_after_change() {
861 $this->resetAfterTest();
862 filter_set_global_state('glossary', TEXTFILTER_ON);
863 $enabledfilters = filter_get_globally_enabled();
864 $this->assertArrayHasKey('glossary', $enabledfilters);
867 public function test_filter_get_globally_enabled_filters_with_config() {
868 $this->resetAfterTest();
869 $this->remove_all_filters_from_config(); // Remove all filters.
871 'syscontext' => $syscontext,
872 'childcontext' => $childcontext
873 ] = $this->setup_available_in_context_tests();
874 $this->remove_all_filters_from_config(); // Remove all filters.
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);
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');
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');
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']);