Merge branch 'MDL-68760' of https://github.com/timhunt/moodle
[moodle.git] / mod / quiz / accessrule / seb / tests / phpunit / settings_provider_test.php
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/>.
17 /**
18  * PHPUnit tests for settings_provider.
19  *
20  * @package    quizaccess_seb
21  * @author     Andrew Madden <andrewmadden@catalyst-au.net>
22  * @copyright  2019 Catalyst IT
23  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24  */
26 use quizaccess_seb\tests\phpunit\quizaccess_seb_testcase;
27 use quizaccess_seb\quiz_settings;
28 use quizaccess_seb\settings_provider;
30 defined('MOODLE_INTERNAL') || die();
32 require_once(__DIR__ . '/base.php');
34 /**
35  * PHPUnit tests for settings_provider.
36  *
37  * @copyright  2020 Catalyst IT
38  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
39  */
40 class quizaccess_seb_settings_provider_testcase extends quizaccess_seb_testcase {
42     /**
43      * Mocked quiz form instance.
44      * @var \mod_quiz_mod_form
45      */
46     protected $mockedquizform;
48     /**
49      * Test moodle form.
50      * @var \MoodleQuickForm
51      */
52     protected $mockedform;
54     /**
55      * Context for testing.
56      * @var \context
57      */
58     protected $context;
60     /**
61      * Test user.
62      * @var \stdClass
63      */
64     protected $user;
66     /**
67      * Test role ID.
68      * @var int
69      */
70     protected $roleid;
72     /**
73      * Helper method to set up form mocks.
74      */
75     protected function set_up_form_mocks() {
76         if (empty($this->context)) {
77             $this->context = context_module::instance($this->quiz->cmid);
78         }
80         $this->mockedquizform = $this->createMock('mod_quiz_mod_form');
81         $this->mockedquizform->method('get_context')->willReturn($this->context);
82         $this->mockedquizform->method('get_instance')->willReturn($this->quiz->id);
83         $this->mockedform = new \MoodleQuickForm('test', 'post', '');
84         $this->mockedform->addElement('static', 'security');
85     }
87     /**
88      * Helper method to set up user and role for testing.
89      */
90     protected function set_up_user_and_role() {
91         $this->user = $this->getDataGenerator()->create_user();
93         $this->setUser($this->user);
94         $this->roleid = $this->getDataGenerator()->create_role();
96         $this->getDataGenerator()->role_assign($this->roleid, $this->user->id, $this->context->id);
97     }
99     /**
100      * Capability data for testing.
101      *
102      * @return array
103      */
104     public function settings_capability_data_provider() {
105         $data = [];
107         // Build first level SEB config settings. Any of this setting let us use SEB manual config.
108         foreach (settings_provider::get_seb_settings_map()[settings_provider::USE_SEB_CONFIG_MANUALLY] as $name => $children) {
109             if (key_exists($name, settings_provider::get_seb_config_elements())) {
110                 $cap = settings_provider::build_setting_capability_name($name);
111                 $data[] = [$cap];
112             }
113         }
115         return $data;
116     }
118     /**
119      * Test that settings types to be added to quiz settings, are part of quiz_settings persistent class.
120      */
121     public function test_setting_elements_are_part_of_quiz_settings_table() {
122         $dbsettings = (array) (new quiz_settings())->to_record();
123         $settingelements = settings_provider::get_seb_config_elements();
124         $settingelements = (array) $this->strip_all_prefixes((object) $settingelements);
126         // Get all elements to be added to form, that are not in the persistent quiz_settings class.
127         $diffelements = array_diff_key($settingelements, $dbsettings);
129         $this->assertEmpty($diffelements);
130     }
132     /**
133      * Make sure that all SEB settings have related capabilities.
134      */
135     public function test_that_all_seb_settings_have_capabilities() {
136         foreach (settings_provider::get_seb_config_elements() as $name => $notused) {
137             $this->assertNotEmpty(get_capability_info(settings_provider::build_setting_capability_name($name)));
138         }
139     }
141     /**
142      * Test that setting defaults only refer to settings defined in setting types.
143      */
144     public function test_setting_defaults_are_part_of_file_types() {
145         $settingelements = settings_provider::get_seb_config_elements();
146         $settingdefaults = settings_provider::get_seb_config_element_defaults();
148         // Get all defaults that have no matching element in settings types.
149         $diffelements = array_diff_key($settingdefaults, $settingelements);
151         $this->assertEmpty($diffelements);
152     }
154     /**
155      * Test that setting types only refer to settings defined in setting types.
156      */
157     public function test_setting_types_are_part_of_file_types() {
158         $settingelements = settings_provider::get_seb_config_elements();
159         $settingtypes = settings_provider::get_seb_config_element_types();
161         // Get all defaults that have no matching element in settings types.
162         $diffelements = array_diff_key($settingtypes, $settingelements);
164         $this->assertEmpty($diffelements);
165     }
167     /**
168      * Helper method to assert hide if element.
169      * @param \quizaccess_seb\hideif_rule $hideif Rule to check.
170      * @param string $element Expected element.
171      * @param string $dependantname Expected dependant element name.
172      * @param string $condition Expected condition.
173      * @param mixed $value Expected value.
174      */
175     protected function assert_hide_if(\quizaccess_seb\hideif_rule $hideif, $element, $dependantname, $condition, $value) {
176         $this->assertEquals($element, $hideif->get_element());
177         $this->assertEquals($dependantname, $hideif->get_dependantname());
178         $this->assertEquals($condition, $hideif->get_condition());
179         $this->assertEquals($value, $hideif->get_dependantvalue());
180     }
182     /**
183      * Test hideif rules.
184      */
185     public function test_hideifs() {
186         $settinghideifs = settings_provider::get_quiz_hideifs();
188         $this->assertCount(23, $settinghideifs);
190         $this->assertArrayHasKey('seb_templateid', $settinghideifs);
191         $this->assertCount(1, $settinghideifs['seb_templateid']);
192         $this->assert_hide_if(
193             $settinghideifs['seb_templateid'][0],
194             'seb_templateid',
195             'seb_requiresafeexambrowser',
196             'noteq',
197             settings_provider::USE_SEB_TEMPLATE
198         );
200         $this->assertArrayHasKey('filemanager_sebconfigfile', $settinghideifs);
201         $this->assertCount(1, $settinghideifs['filemanager_sebconfigfile']);
202         $this->assert_hide_if(
203             $settinghideifs['filemanager_sebconfigfile'][0],
204             'filemanager_sebconfigfile',
205             'seb_requiresafeexambrowser',
206             'noteq',
207             settings_provider::USE_SEB_UPLOAD_CONFIG
208         );
210         $this->assertArrayHasKey('seb_showsebtaskbar', $settinghideifs);
211         $this->assertCount(1, $settinghideifs['seb_showsebtaskbar']);
212         $this->assert_hide_if(
213             $settinghideifs['seb_showsebtaskbar'][0],
214             'seb_showsebtaskbar',
215             'seb_requiresafeexambrowser',
216             'noteq',
217             settings_provider::USE_SEB_CONFIG_MANUALLY
218         );
220         $this->assertArrayHasKey('seb_showwificontrol', $settinghideifs);
221         $this->assertCount(2, $settinghideifs['seb_showwificontrol']);
222         $this->assert_hide_if(
223             $settinghideifs['seb_showwificontrol'][0],
224             'seb_showwificontrol',
225             'seb_requiresafeexambrowser',
226             'noteq',
227             settings_provider::USE_SEB_CONFIG_MANUALLY
228         );
229         $this->assert_hide_if(
230             $settinghideifs['seb_showwificontrol'][1],
231             'seb_showwificontrol',
232             'seb_showsebtaskbar',
233             'eq',
234             0
235         );
237         $this->assertArrayHasKey('seb_showreloadbutton', $settinghideifs);
238         $this->assertCount(2, $settinghideifs['seb_showreloadbutton']);
239         $this->assert_hide_if(
240             $settinghideifs['seb_showreloadbutton'][0],
241             'seb_showreloadbutton',
242             'seb_requiresafeexambrowser',
243             'noteq',
244             settings_provider::USE_SEB_CONFIG_MANUALLY
245         );
246         $this->assert_hide_if(
247             $settinghideifs['seb_showreloadbutton'][1],
248             'seb_showreloadbutton',
249             'seb_showsebtaskbar',
250             'eq',
251             0
252         );
254         $this->assertArrayHasKey('seb_showtime', $settinghideifs);
255         $this->assertCount(2, $settinghideifs['seb_showtime']);
256         $this->assert_hide_if(
257             $settinghideifs['seb_showtime'][0],
258             'seb_showtime',
259             'seb_requiresafeexambrowser',
260             'noteq',
261             settings_provider::USE_SEB_CONFIG_MANUALLY
262         );
263         $this->assert_hide_if(
264             $settinghideifs['seb_showtime'][1],
265             'seb_showtime',
266             'seb_showsebtaskbar',
267             'eq',
268             0
269         );
271         $this->assertArrayHasKey('seb_showkeyboardlayout', $settinghideifs);
272         $this->assertCount(2, $settinghideifs['seb_showkeyboardlayout']);
273         $this->assert_hide_if(
274             $settinghideifs['seb_showkeyboardlayout'][0],
275             'seb_showkeyboardlayout',
276             'seb_requiresafeexambrowser',
277             'noteq',
278             settings_provider::USE_SEB_CONFIG_MANUALLY
279         );
280         $this->assert_hide_if(
281             $settinghideifs['seb_showkeyboardlayout'][1],
282             'seb_showkeyboardlayout',
283             'seb_showsebtaskbar',
284             'eq',
285             0
286         );
288         $this->assertArrayHasKey('seb_allowuserquitseb', $settinghideifs);
289         $this->assertCount(3, $settinghideifs['seb_allowuserquitseb']);
290         $this->assert_hide_if(
291             $settinghideifs['seb_allowuserquitseb'][0],
292             'seb_allowuserquitseb',
293             'seb_requiresafeexambrowser',
294             'eq',
295             settings_provider::USE_SEB_NO
296         );
297         $this->assert_hide_if(
298             $settinghideifs['seb_allowuserquitseb'][1],
299             'seb_allowuserquitseb',
300             'seb_requiresafeexambrowser',
301             'eq',
302             settings_provider::USE_SEB_CLIENT_CONFIG
303         );
304         $this->assert_hide_if(
305             $settinghideifs['seb_allowuserquitseb'][2],
306             'seb_allowuserquitseb',
307             'seb_requiresafeexambrowser',
308             'eq',
309             settings_provider::USE_SEB_UPLOAD_CONFIG
310         );
312         $this->assertArrayHasKey('seb_quitpassword', $settinghideifs);
313         $this->assertCount(4, $settinghideifs['seb_quitpassword']);
314         $this->assert_hide_if(
315             $settinghideifs['seb_quitpassword'][0],
316             'seb_quitpassword',
317             'seb_requiresafeexambrowser',
318             'eq',
319             settings_provider::USE_SEB_NO
320         );
321         $this->assert_hide_if(
322             $settinghideifs['seb_quitpassword'][1],
323             'seb_quitpassword',
324             'seb_requiresafeexambrowser',
325             'eq',
326             settings_provider::USE_SEB_CLIENT_CONFIG
327         );
328         $this->assert_hide_if(
329             $settinghideifs['seb_quitpassword'][2],
330             'seb_quitpassword',
331             'seb_requiresafeexambrowser',
332             'eq',
333             settings_provider::USE_SEB_UPLOAD_CONFIG
334         );
335         $this->assert_hide_if(
336             $settinghideifs['seb_quitpassword'][3],
337             'seb_quitpassword',
338             'seb_allowuserquitseb',
339             'eq',
340             0
341         );
343         $this->assertArrayHasKey('seb_linkquitseb', $settinghideifs);
344         $this->assertCount(1, $settinghideifs['seb_linkquitseb']);
345         $this->assert_hide_if(
346             $settinghideifs['seb_linkquitseb'][0],
347             'seb_linkquitseb',
348             'seb_requiresafeexambrowser',
349             'noteq',
350             settings_provider::USE_SEB_CONFIG_MANUALLY
351         );
353         $this->assertArrayHasKey('seb_userconfirmquit', $settinghideifs);
354         $this->assertCount(1, $settinghideifs['seb_userconfirmquit']);
355         $this->assert_hide_if(
356             $settinghideifs['seb_userconfirmquit'][0],
357             'seb_userconfirmquit',
358             'seb_requiresafeexambrowser',
359             'noteq',
360             settings_provider::USE_SEB_CONFIG_MANUALLY
361         );
363         $this->assertArrayHasKey('seb_enableaudiocontrol', $settinghideifs);
364         $this->assertCount(1, $settinghideifs['seb_enableaudiocontrol']);
365         $this->assert_hide_if(
366             $settinghideifs['seb_enableaudiocontrol'][0],
367             'seb_enableaudiocontrol',
368             'seb_requiresafeexambrowser',
369             'noteq',
370             settings_provider::USE_SEB_CONFIG_MANUALLY
371         );
373         $this->assertArrayHasKey('seb_muteonstartup', $settinghideifs);
374         $this->assertCount(2, $settinghideifs['seb_muteonstartup']);
375         $this->assert_hide_if(
376             $settinghideifs['seb_muteonstartup'][0],
377             'seb_muteonstartup',
378             'seb_requiresafeexambrowser',
379             'noteq',
380             settings_provider::USE_SEB_CONFIG_MANUALLY
381         );
382         $this->assert_hide_if(
383             $settinghideifs['seb_muteonstartup'][1],
384             'seb_muteonstartup',
385             'seb_enableaudiocontrol',
386             'eq',
387             0
388         );
390         $this->assertArrayHasKey('seb_allowspellchecking', $settinghideifs);
391         $this->assertCount(1, $settinghideifs['seb_allowspellchecking']);
392         $this->assert_hide_if(
393             $settinghideifs['seb_allowspellchecking'][0],
394             'seb_allowspellchecking',
395             'seb_requiresafeexambrowser',
396             'noteq',
397             settings_provider::USE_SEB_CONFIG_MANUALLY
398         );
400         $this->assertArrayHasKey('seb_allowreloadinexam', $settinghideifs);
401         $this->assertCount(1, $settinghideifs['seb_allowreloadinexam']);
402         $this->assert_hide_if(
403             $settinghideifs['seb_allowreloadinexam'][0],
404             'seb_allowreloadinexam',
405             'seb_requiresafeexambrowser',
406             'noteq',
407             settings_provider::USE_SEB_CONFIG_MANUALLY
408         );
410         $this->assertArrayHasKey('seb_activateurlfiltering', $settinghideifs);
411         $this->assertCount(1, $settinghideifs['seb_activateurlfiltering']);
412         $this->assert_hide_if(
413             $settinghideifs['seb_activateurlfiltering'][0],
414             'seb_activateurlfiltering',
415             'seb_requiresafeexambrowser',
416             'noteq',
417             settings_provider::USE_SEB_CONFIG_MANUALLY
418         );
420         $this->assertArrayHasKey('seb_filterembeddedcontent', $settinghideifs);
421         $this->assertCount(2, $settinghideifs['seb_filterembeddedcontent']);
422         $this->assert_hide_if(
423             $settinghideifs['seb_filterembeddedcontent'][0],
424             'seb_filterembeddedcontent',
425             'seb_requiresafeexambrowser',
426             'noteq',
427             settings_provider::USE_SEB_CONFIG_MANUALLY
428         );
429         $this->assert_hide_if(
430             $settinghideifs['seb_filterembeddedcontent'][1],
431             'seb_filterembeddedcontent',
432             'seb_activateurlfiltering',
433             'eq',
434             0
435         );
437         $this->assertArrayHasKey('seb_expressionsallowed', $settinghideifs);
438         $this->assertCount(2, $settinghideifs['seb_expressionsallowed']);
439         $this->assert_hide_if(
440             $settinghideifs['seb_expressionsallowed'][0],
441             'seb_expressionsallowed',
442             'seb_requiresafeexambrowser',
443             'noteq',
444             settings_provider::USE_SEB_CONFIG_MANUALLY
445         );
446         $this->assert_hide_if(
447             $settinghideifs['seb_expressionsallowed'][1],
448             'seb_expressionsallowed',
449             'seb_activateurlfiltering',
450             'eq',
451             0
452         );
454         $this->assertArrayHasKey('seb_regexallowed', $settinghideifs);
455         $this->assertCount(2, $settinghideifs['seb_regexallowed']);
456         $this->assert_hide_if(
457             $settinghideifs['seb_regexallowed'][0],
458             'seb_regexallowed',
459             'seb_requiresafeexambrowser',
460             'noteq',
461             settings_provider::USE_SEB_CONFIG_MANUALLY
462         );
463         $this->assert_hide_if(
464             $settinghideifs['seb_regexallowed'][1],
465             'seb_regexallowed',
466             'seb_activateurlfiltering',
467             'eq',
468             0
469         );
471         $this->assertArrayHasKey('seb_expressionsblocked', $settinghideifs);
472         $this->assertCount(2, $settinghideifs['seb_expressionsblocked']);
473         $this->assert_hide_if(
474             $settinghideifs['seb_expressionsblocked'][0],
475             'seb_expressionsblocked',
476             'seb_requiresafeexambrowser',
477             'noteq',
478             settings_provider::USE_SEB_CONFIG_MANUALLY
479         );
480         $this->assert_hide_if(
481             $settinghideifs['seb_expressionsblocked'][1],
482             'seb_expressionsblocked',
483             'seb_activateurlfiltering',
484             'eq',
485             0
486         );
488         $this->assertArrayHasKey('seb_regexblocked', $settinghideifs);
489         $this->assertCount(2, $settinghideifs['seb_regexblocked']);
490         $this->assert_hide_if(
491             $settinghideifs['seb_regexblocked'][0],
492             'seb_regexblocked',
493             'seb_requiresafeexambrowser',
494             'noteq',
495             settings_provider::USE_SEB_CONFIG_MANUALLY
496         );
497         $this->assert_hide_if(
498             $settinghideifs['seb_regexblocked'][1],
499             'seb_regexblocked',
500             'seb_activateurlfiltering',
501             'eq',
502             0
503         );
505         $this->assertArrayHasKey('seb_showsebdownloadlink', $settinghideifs);
506         $this->assertCount(1, $settinghideifs['seb_showsebdownloadlink']);
507         $this->assert_hide_if(
508             $settinghideifs['seb_showsebdownloadlink'][0],
509             'seb_showsebdownloadlink',
510             'seb_requiresafeexambrowser',
511             'eq',
512             settings_provider::USE_SEB_NO
513         );
515         $this->assertArrayHasKey('seb_allowedbrowserexamkeys', $settinghideifs);
516         $this->assertCount(3, $settinghideifs['seb_allowedbrowserexamkeys']);
517         $this->assert_hide_if(
518             $settinghideifs['seb_allowedbrowserexamkeys'][0],
519             'seb_allowedbrowserexamkeys',
520             'seb_requiresafeexambrowser',
521             'eq',
522             settings_provider::USE_SEB_NO
523         );
524         $this->assert_hide_if(
525             $settinghideifs['seb_allowedbrowserexamkeys'][1],
526             'seb_allowedbrowserexamkeys',
527             'seb_requiresafeexambrowser',
528             'eq',
529             settings_provider::USE_SEB_CONFIG_MANUALLY
530         );
531         $this->assert_hide_if(
532             $settinghideifs['seb_allowedbrowserexamkeys'][2],
533             'seb_allowedbrowserexamkeys',
534             'seb_requiresafeexambrowser',
535             'eq',
536             settings_provider::USE_SEB_TEMPLATE
537         );
538     }
540     /**
541      * Test that setting hideif rules only refer to settings defined in setting types, including the conditions.
542      */
543     public function test_setting_hideifs_are_part_of_file_types() {
544         $settingelements = settings_provider::get_seb_config_elements();
545         $settinghideifs = settings_provider::get_quiz_hideifs();
547         // Add known additional elements.
548         $settingelements['seb_templateid'] = '';
549         $settingelements['filemanager_sebconfigfile'] = '';
550         $settingelements['seb_showsebdownloadlink'] = '';
551         $settingelements['seb_allowedbrowserexamkeys'] = '';
553         // Get all defaults that have no matching element in settings types.
554         $diffelements = array_diff_key($settinghideifs, $settingelements);
556         // Check no diff for elements to hide.
557         $this->assertEmpty($diffelements);
559         // Check each element's to hide conditions that each condition refers to element in settings types.
560         foreach ($settinghideifs as $conditions) {
561             foreach ($conditions as $condition) {
562                 $this->assertTrue(array_key_exists($condition->get_element(), $settingelements));
563             }
564         }
565     }
567     /**
568      * Test that exception thrown if we try to build capability name from the incorrect setting name.
569      */
570     public function test_build_setting_capability_name_incorrect_setting() {
571         $this->expectException(coding_exception::class);
572         $this->expectExceptionMessage('Incorrect SEB quiz setting broken');
574         $broken = settings_provider::build_setting_capability_name('broken');
575     }
577     /**
578      * Test we can build capability name from the the setting name.
579      */
580     public function test_build_setting_capability_name_correct_setting() {
581         foreach (settings_provider::get_seb_config_elements() as $name => $type) {
582             $expected = 'quizaccess/seb:manage_' . $name;
583             $actual = settings_provider::build_setting_capability_name($name);
585             $this->assertSame($expected, $actual);
586         }
587     }
589     /**
590      * Test can check if can manage SEB settings respecting settings structure.
591      */
592     public function test_can_manage_seb_config_setting() {
593         $this->setAdminUser();
595         $this->quiz = $this->getDataGenerator()->create_module('quiz', ['course' => $this->course->id]);
596         $this->context = context_module::instance($this->quiz->cmid);
598         $this->set_up_user_and_role();
600         foreach (settings_provider::get_seb_settings_map()[settings_provider::USE_SEB_CONFIG_MANUALLY] as $setting => $children) {
601             // Skip not SEB setting.
602             if ($setting == 'seb_showsebdownloadlink') {
603                 continue;
604             }
606             $this->assertFalse(settings_provider::can_manage_seb_config_setting($setting, $this->context));
607             foreach ($children as $child => $empty) {
608                 $this->assertFalse(settings_provider::can_manage_seb_config_setting($child, $this->context));
610                 // Assign child capability without having parent one. Should not have access to manage child.
611                 $childcap = settings_provider::build_setting_capability_name($child);
612                 assign_capability($childcap, CAP_ALLOW, $this->roleid, $this->context->id);
613                 $this->assertFalse(settings_provider::can_manage_seb_config_setting($child, $this->context));
614             }
616             // Assign parent capability. Should be able to manage children now.
617             $parentcap = settings_provider::build_setting_capability_name($setting);
618             assign_capability($parentcap, CAP_ALLOW, $this->roleid, $this->context->id);
620             $this->assertTrue(settings_provider::can_manage_seb_config_setting($setting, $this->context));
621             foreach ($children as $child => $empty) {
622                 $this->assertTrue(settings_provider::can_manage_seb_config_setting($child, $this->context));
623             }
624         }
625     }
627     /**
628      * Test SEB usage options.
629      *
630      * @param string $settingcapability Setting capability to check manual option against.
631      *
632      * @dataProvider settings_capability_data_provider
633      */
634     public function test_get_requiresafeexambrowser_options($settingcapability) {
635         $this->setAdminUser();
637         $this->quiz = $this->getDataGenerator()->create_module('quiz', ['course' => $this->course->id]);
638         $this->context = context_module::instance($this->quiz->cmid);
640         $options = settings_provider::get_requiresafeexambrowser_options($this->context);
642         $this->assertCount(4, $options);
643         $this->assertTrue(array_key_exists(settings_provider::USE_SEB_NO, $options));
644         $this->assertTrue(array_key_exists(settings_provider::USE_SEB_CONFIG_MANUALLY, $options));
645         $this->assertFalse(array_key_exists(settings_provider::USE_SEB_TEMPLATE, $options));
646         $this->assertTrue(array_key_exists(settings_provider::USE_SEB_UPLOAD_CONFIG, $options));
647         $this->assertTrue(array_key_exists(settings_provider::USE_SEB_CLIENT_CONFIG, $options));
649         // Create a template.
650         $this->create_template();
652         // The template options should be visible now.
653         $options = settings_provider::get_requiresafeexambrowser_options($this->context);
654         $this->assertCount(5, $options);
655         $this->assertTrue(array_key_exists(settings_provider::USE_SEB_TEMPLATE, $options));
657         // A new user does not have the capability to use the file manager and template.
658         $this->set_up_user_and_role();
660         $options = settings_provider::get_requiresafeexambrowser_options($this->context);
662         $this->assertCount(2, $options);
663         $this->assertFalse(array_key_exists(settings_provider::USE_SEB_CONFIG_MANUALLY, $options));
664         $this->assertFalse(array_key_exists(settings_provider::USE_SEB_TEMPLATE, $options));
665         $this->assertFalse(array_key_exists(settings_provider::USE_SEB_UPLOAD_CONFIG, $options));
666         $this->assertTrue(array_key_exists(settings_provider::USE_SEB_CLIENT_CONFIG, $options));
667         $this->assertTrue(array_key_exists(settings_provider::USE_SEB_NO, $options));
669         assign_capability($settingcapability, CAP_ALLOW, $this->roleid, $this->context->id);
670         $options = settings_provider::get_requiresafeexambrowser_options($this->context);
671         $this->assertCount(3, $options);
672         $this->assertTrue(array_key_exists(settings_provider::USE_SEB_CONFIG_MANUALLY, $options));
673         $this->assertFalse(array_key_exists(settings_provider::USE_SEB_TEMPLATE, $options));
674         $this->assertFalse(array_key_exists(settings_provider::USE_SEB_UPLOAD_CONFIG, $options));
675         $this->assertTrue(array_key_exists(settings_provider::USE_SEB_CLIENT_CONFIG, $options));
676         $this->assertTrue(array_key_exists(settings_provider::USE_SEB_NO, $options));
678         assign_capability('quizaccess/seb:manage_seb_templateid', CAP_ALLOW, $this->roleid, $this->context->id);
679         $options = settings_provider::get_requiresafeexambrowser_options($this->context);
680         $this->assertCount(4, $options);
681         $this->assertTrue(array_key_exists(settings_provider::USE_SEB_CONFIG_MANUALLY, $options));
682         $this->assertTrue(array_key_exists(settings_provider::USE_SEB_TEMPLATE, $options));
683         $this->assertFalse(array_key_exists(settings_provider::USE_SEB_UPLOAD_CONFIG, $options));
684         $this->assertTrue(array_key_exists(settings_provider::USE_SEB_CLIENT_CONFIG, $options));
685         $this->assertTrue(array_key_exists(settings_provider::USE_SEB_NO, $options));
687         assign_capability('quizaccess/seb:manage_filemanager_sebconfigfile', CAP_ALLOW, $this->roleid, $this->context->id);
688         $options = settings_provider::get_requiresafeexambrowser_options($this->context);
689         $this->assertCount(5, $options);
690         $this->assertTrue(array_key_exists(settings_provider::USE_SEB_CONFIG_MANUALLY, $options));
691         $this->assertTrue(array_key_exists(settings_provider::USE_SEB_TEMPLATE, $options));
692         $this->assertTrue(array_key_exists(settings_provider::USE_SEB_UPLOAD_CONFIG, $options));
693         $this->assertTrue(array_key_exists(settings_provider::USE_SEB_CLIENT_CONFIG, $options));
694         $this->assertTrue(array_key_exists(settings_provider::USE_SEB_NO, $options));
695     }
697     /**
698      * Test SEB usage options with conflicting permissions.
699      */
700     public function test_get_requiresafeexambrowser_options_with_conflicting_permissions() {
701         $this->setAdminUser();
703         $this->quiz = $this->create_test_quiz($this->course, settings_provider::USE_SEB_CONFIG_MANUALLY);
704         $this->context = context_module::instance($this->quiz->cmid);
706         $template = $this->create_template();
708         $settings = quiz_settings::get_record(['quizid' => $this->quiz->id]);
709         $settings->set('templateid', $template->get('id'));
710         $settings->set('requiresafeexambrowser', settings_provider::USE_SEB_TEMPLATE);
711         $settings->save();
713         $this->set_up_user_and_role();
715         $options = settings_provider::get_requiresafeexambrowser_options($this->context);
717         // If there is nay conflict we return full list of options.
718         $this->assertCount(5, $options);
719         $this->assertTrue(array_key_exists(settings_provider::USE_SEB_TEMPLATE, $options));
720     }
722     /**
723      * Test that SEB options and templates are frozen if conflicting permissions.
724      */
725     public function test_form_elements_are_frozen_if_conflicting_permissions() {
726         $this->setAdminUser();
728         $this->quiz = $this->create_test_quiz($this->course, settings_provider::USE_SEB_CONFIG_MANUALLY);
729         $this->context = context_module::instance($this->quiz->cmid);
731         // Setup conflicting permissions.
732         $template = $this->create_template();
733         $settings = quiz_settings::get_record(['quizid' => $this->quiz->id]);
734         $settings->set('templateid', $template->get('id'));
735         $settings->set('requiresafeexambrowser', settings_provider::USE_SEB_TEMPLATE);
736         $settings->save();
738         $this->set_up_user_and_role();
740         assign_capability('quizaccess/seb:manage_seb_requiresafeexambrowser', CAP_ALLOW, $this->roleid, $this->context->id);
741         assign_capability('quizaccess/seb:manage_seb_showsebdownloadlink', CAP_ALLOW, $this->roleid, $this->context->id);
742         assign_capability('quizaccess/seb:manage_seb_allowedbrowserexamkeys', CAP_ALLOW, $this->roleid, $this->context->id);
744         $this->set_up_form_mocks();
746         settings_provider::add_seb_settings_fields($this->mockedquizform, $this->mockedform);
748         $this->assertTrue($this->mockedform->isElementFrozen('seb_requiresafeexambrowser'));
749         $this->assertTrue($this->mockedform->isElementFrozen('seb_templateid'));
750         $this->assertTrue($this->mockedform->isElementFrozen('seb_showsebdownloadlink'));
751         $this->assertTrue($this->mockedform->isElementFrozen('seb_allowedbrowserexamkeys'));
752     }
754     /**
755      * Test that All settings are frozen if quiz was attempted and use seb with manual settings.
756      */
757     public function test_form_elements_are_locked_when_quiz_attempted_manual() {
758         $this->quiz = $this->create_test_quiz($this->course, settings_provider::USE_SEB_CONFIG_MANUALLY);
759         $this->context = context_module::instance($this->quiz->cmid);
761         $user = $this->getDataGenerator()->create_user();
762         $this->attempt_quiz($this->quiz, $user);
764         $this->setAdminUser();
765         $this->set_up_form_mocks();
767         settings_provider::add_seb_settings_fields($this->mockedquizform, $this->mockedform);
769         $this->assertTrue($this->mockedform->isElementFrozen('seb_requiresafeexambrowser'));
770         $this->assertTrue($this->mockedform->elementExists('filemanager_sebconfigfile'));
771         $this->assertFalse($this->mockedform->elementExists('seb_templateid'));
772         $this->assertTrue($this->mockedform->isElementFrozen('seb_showsebdownloadlink'));
773         $this->assertTrue($this->mockedform->isElementFrozen('seb_allowedbrowserexamkeys'));
775         foreach (settings_provider::get_seb_config_elements() as $name => $type) {
776             $this->assertTrue($this->mockedform->isElementFrozen($name));
777         }
778     }
780     /**
781      * Test that All settings are frozen if a quiz was attempted and use template.
782      */
783     public function test_form_elements_are_locked_when_quiz_attempted_template() {
784         $this->setAdminUser();
786         $this->quiz = $this->create_test_quiz($this->course, settings_provider::USE_SEB_CONFIG_MANUALLY);
787         $this->context = context_module::instance($this->quiz->cmid);
789         $template = $this->create_template();
791         $settings = quiz_settings::get_record(['quizid' => $this->quiz->id]);
792         $settings->set('templateid', $template->get('id'));
793         $settings->set('requiresafeexambrowser', settings_provider::USE_SEB_TEMPLATE);
794         $settings->save();
796         $user = $this->getDataGenerator()->create_user();
797         $this->attempt_quiz($this->quiz, $user);
799         $this->setAdminUser();
800         $this->set_up_form_mocks();
802         settings_provider::add_seb_settings_fields($this->mockedquizform, $this->mockedform);
804         $this->assertTrue($this->mockedform->isElementFrozen('seb_requiresafeexambrowser'));
805         $this->assertTrue($this->mockedform->elementExists('filemanager_sebconfigfile'));
806         $this->assertTrue($this->mockedform->isElementFrozen('seb_templateid'));
807         $this->assertTrue($this->mockedform->isElementFrozen('seb_showsebdownloadlink'));
808         $this->assertTrue($this->mockedform->isElementFrozen('seb_allowedbrowserexamkeys'));
810         foreach (settings_provider::get_seb_config_elements() as $name => $type) {
811             $this->assertTrue($this->mockedform->isElementFrozen($name));
812         }
813     }
815     /**
816      * Test Show Safe Exam Browser download button setting in the form.
817      */
818     public function test_showsebdownloadlink_in_form() {
819         $this->setAdminUser();
821         $this->quiz = $this->create_test_quiz($this->course, settings_provider::USE_SEB_CONFIG_MANUALLY);
822         $this->context = context_module::instance($this->quiz->cmid);
824         $this->set_up_user_and_role();
826         assign_capability('quizaccess/seb:manage_seb_requiresafeexambrowser', CAP_ALLOW, $this->roleid, $this->context->id);
827         $this->set_up_form_mocks();
829         // Shouldn't be in the form if no permissions.
830         settings_provider::add_seb_settings_fields($this->mockedquizform, $this->mockedform);
831         $this->assertFalse($this->mockedform->elementExists('seb_showsebdownloadlink'));
833         // Should be in the form if we grant require permissions.
834         assign_capability('quizaccess/seb:manage_seb_showsebdownloadlink', CAP_ALLOW, $this->roleid, $this->context->id);
836         settings_provider::add_seb_settings_fields($this->mockedquizform, $this->mockedform);
837         $this->assertTrue($this->mockedform->elementExists('seb_showsebdownloadlink'));
838     }
840     /**
841      * Test Allowed Browser Exam Keys setting in the form.
842      */
843     public function test_allowedbrowserexamkeys_in_form() {
844         $this->setAdminUser();
846         $this->quiz = $this->create_test_quiz($this->course, settings_provider::USE_SEB_CLIENT_CONFIG);
847         $this->context = context_module::instance($this->quiz->cmid);
849         $this->set_up_user_and_role();
851         assign_capability('quizaccess/seb:manage_seb_requiresafeexambrowser', CAP_ALLOW, $this->roleid, $this->context->id);
852         $this->set_up_form_mocks();
854         // Shouldn't be in the form if no permissions.
855         settings_provider::add_seb_settings_fields($this->mockedquizform, $this->mockedform);
856         $this->assertFalse($this->mockedform->elementExists('seb_allowedbrowserexamkeys'));
858         // Should be in the form if we grant require permissions.
859         assign_capability('quizaccess/seb:manage_seb_allowedbrowserexamkeys', CAP_ALLOW, $this->roleid, $this->context->id);
860         settings_provider::add_seb_settings_fields($this->mockedquizform, $this->mockedform);
861         $this->assertTrue($this->mockedform->elementExists('seb_allowedbrowserexamkeys'));
862     }
864     /**
865      * Test the validation of a seb config file.
866      */
867     public function test_validate_draftarea_configfile_success() {
868         $user = $this->getDataGenerator()->create_user();
869         $this->setUser($user);
870         $xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
871             . "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
872             . "<plist version=\"1.0\"><dict><key>hashedQuitPassword</key><string>hashedpassword</string>"
873             . "<key>allowWlan</key><false/></dict></plist>\n";
874         $itemid = $this->create_test_draftarea_file($xml);
875         $errors = settings_provider::validate_draftarea_configfile($itemid);
876         $this->assertEmpty($errors);
877     }
879     /**
880      * Test the validation of a missing seb config file.
881      */
882     public function test_validate_draftarea_configfile_failure() {
883         $user = $this->getDataGenerator()->create_user();
884         $this->setUser($user);
885         $xml = "This is not a config file.";
886         $itemid = $this->create_test_draftarea_file($xml);
887         $errors = settings_provider::validate_draftarea_configfile($itemid);
888         $this->assertEquals($errors, new lang_string('fileparsefailed', 'quizaccess_seb'));
889     }
891     /**
892      * Test obtaining the draftarea content.
893      */
894     public function test_get_current_user_draft_file() {
895         $user = $this->getDataGenerator()->create_user();
896         $this->setUser($user);
898         $xml = file_get_contents(__DIR__ . '/sample_data/unencrypted.seb');
899         $itemid = $this->create_test_draftarea_file($xml);
900         $file = settings_provider::get_current_user_draft_file($itemid);
901         $content = $file->get_content();
903         $this->assertEquals($xml, $content);
904     }
906     /**
907      * Test saving files from the user draft area into the quiz context area storage.
908      */
909     public function test_save_filemanager_sebconfigfile_draftarea() {
910         $this->quiz = $this->getDataGenerator()->create_module('quiz', ['course' => $this->course->id]);
911         $this->context = context_module::instance($this->quiz->cmid);
912         $this->set_up_user_and_role();
914         $xml = file_get_contents(__DIR__ . '/sample_data/unencrypted.seb');
916         $draftitemid = $this->create_test_draftarea_file($xml);
918         settings_provider::save_filemanager_sebconfigfile_draftarea($draftitemid, $this->quiz->cmid);
920         $fs = get_file_storage();
921         $files = $fs->get_area_files($this->context->id, 'quizaccess_seb', 'filemanager_sebconfigfile');
923         $this->assertCount(2, $files);
924     }
926     /**
927      * Test deleting the $this->quiz->cmid itemid from the file area.
928      */
929     public function test_delete_uploaded_config_file() {
930         $this->quiz = $this->getDataGenerator()->create_module('quiz', ['course' => $this->course->id]);
931         $this->context = context_module::instance($this->quiz->cmid);
932         $this->set_up_user_and_role();
934         $xml = file_get_contents(__DIR__ . '/sample_data/unencrypted.seb');
935         $draftitemid = $this->create_test_draftarea_file($xml);
937         settings_provider::save_filemanager_sebconfigfile_draftarea($draftitemid, $this->quiz->cmid);
939         $fs = get_file_storage();
940         $files = $fs->get_area_files($this->context->id, 'quizaccess_seb', 'filemanager_sebconfigfile');
941         $this->assertCount(2, $files);
943         settings_provider::delete_uploaded_config_file($this->quiz->cmid);
945         $files = $fs->get_area_files($this->context->id, 'quizaccess_seb', 'filemanager_sebconfigfile');
946         // The '.' directory.
947         $this->assertCount(1, $files);
948     }
950     /**
951      * Test getting the file from the context module id file area.
952      */
953     public function test_get_module_context_sebconfig_file() {
954         $this->setAdminUser();
956         $this->quiz = $this->create_test_quiz($this->course, settings_provider::USE_SEB_CONFIG_MANUALLY);
957         $this->context = context_module::instance($this->quiz->cmid);
959         $this->set_up_user_and_role();
961         $xml = file_get_contents(__DIR__ . '/sample_data/unencrypted.seb');
962         $draftitemid = $this->create_test_draftarea_file($xml);
964         $fs = get_file_storage();
965         $files = $fs->get_area_files($this->context->id, 'quizaccess_seb', 'filemanager_sebconfigfile');
966         $this->assertCount(0, $files);
968         settings_provider::save_filemanager_sebconfigfile_draftarea($draftitemid, $this->quiz->cmid);
970         $settings = quiz_settings::get_record(['quizid' => $this->quiz->id]);
971         $settings->set('requiresafeexambrowser', settings_provider::USE_SEB_UPLOAD_CONFIG);
972         $settings->save();
974         $file = settings_provider::get_module_context_sebconfig_file($this->quiz->cmid);
976         $this->assertSame($file->get_content(), $xml);
977     }
979     /**
980      * Test file manager options.
981      */
982     public function test_get_filemanager_options() {
983         $expected = [
984             'subdirs' => 0,
985             'maxfiles' => 1,
986             'accepted_types' => ['.seb']
987         ];
988         $this->assertSame($expected, settings_provider::get_filemanager_options());
989     }
991     /**
992      * Test that users can or can not configure seb settings.
993      */
994     public function test_can_configure_seb() {
995         $this->quiz = $this->getDataGenerator()->create_module('quiz', ['course' => $this->course->id]);
996         $this->context = context_module::instance($this->quiz->cmid);
997         $this->setAdminUser();
999         $this->assertTrue(settings_provider::can_configure_seb($this->context));
1001         $this->set_up_user_and_role();
1003         $this->assertFalse(settings_provider::can_configure_seb($this->context));
1005         assign_capability('quizaccess/seb:manage_seb_requiresafeexambrowser', CAP_ALLOW, $this->roleid, $this->context->id);
1006         $this->assertTrue(settings_provider::can_configure_seb($this->context));
1007     }
1009     /**
1010      * Test that users can or can not use seb template.
1011      */
1012     public function test_can_use_seb_template() {
1013         $this->quiz = $this->getDataGenerator()->create_module('quiz', ['course' => $this->course->id]);
1014         $this->context = context_module::instance($this->quiz->cmid);
1015         $this->setAdminUser();
1017         $this->assertTrue(settings_provider::can_use_seb_template($this->context));
1019         $this->set_up_user_and_role();
1021         $this->assertFalse(settings_provider::can_use_seb_template($this->context));
1023         assign_capability('quizaccess/seb:manage_seb_templateid', CAP_ALLOW, $this->roleid, $this->context->id);
1024         $this->assertTrue(settings_provider::can_use_seb_template($this->context));
1025     }
1027     /**
1028      * Test that users can or can not upload seb config file.
1029      */
1030     public function test_can_upload_seb_file() {
1031         $this->quiz = $this->getDataGenerator()->create_module('quiz', ['course' => $this->course->id]);
1032         $this->context = context_module::instance($this->quiz->cmid);
1033         $this->setAdminUser();
1035         $this->assertTrue(settings_provider::can_upload_seb_file($this->context));
1037         $this->set_up_user_and_role();
1039         $this->assertFalse(settings_provider::can_upload_seb_file($this->context));
1041         assign_capability('quizaccess/seb:manage_filemanager_sebconfigfile', CAP_ALLOW, $this->roleid, $this->context->id);
1042         $this->assertTrue(settings_provider::can_upload_seb_file($this->context));
1043     }
1045     /**
1046      * Test that users can or can not change Show Safe Exam Browser download button setting.
1047      */
1048     public function test_can_change_seb_showsebdownloadlink() {
1049         $this->quiz = $this->getDataGenerator()->create_module('quiz', ['course' => $this->course->id]);
1050         $this->context = context_module::instance($this->quiz->cmid);
1051         $this->setAdminUser();
1052         $this->assertTrue(settings_provider::can_change_seb_showsebdownloadlink($this->context));
1054         $this->set_up_user_and_role();
1056         $this->assertFalse(settings_provider::can_change_seb_showsebdownloadlink($this->context));
1058         assign_capability('quizaccess/seb:manage_seb_showsebdownloadlink', CAP_ALLOW, $this->roleid, $this->context->id);
1059         $this->assertTrue(settings_provider::can_change_seb_showsebdownloadlink($this->context));
1060     }
1062     /**
1063      * Test that users can or can not change Allowed Browser Exam Keys setting.
1064      */
1065     public function test_can_change_seb_allowedbrowserexamkeys() {
1066         $this->quiz = $this->getDataGenerator()->create_module('quiz', ['course' => $this->course->id]);
1067         $this->context = context_module::instance($this->quiz->cmid);
1068         $this->setAdminUser();
1069         $this->assertTrue(settings_provider::can_change_seb_allowedbrowserexamkeys($this->context));
1071         $this->set_up_user_and_role();
1073         $this->assertFalse(settings_provider::can_change_seb_allowedbrowserexamkeys($this->context));
1075         assign_capability('quizaccess/seb:manage_seb_allowedbrowserexamkeys', CAP_ALLOW, $this->roleid, $this->context->id);
1076         $this->assertTrue(settings_provider::can_change_seb_allowedbrowserexamkeys($this->context));
1077     }
1079     /**
1080      * Test that users can or can not Configure SEb manually
1081      *
1082      * @param string $settingcapability Setting capability to check manual option against.
1083      *
1084      * @dataProvider settings_capability_data_provider
1085      */
1086     public function test_can_configure_manually($settingcapability) {
1087         $this->quiz = $this->getDataGenerator()->create_module('quiz', ['course' => $this->course->id]);
1088         $this->context = context_module::instance($this->quiz->cmid);
1089         $this->setAdminUser();
1091         $this->assertTrue(settings_provider::can_configure_manually($this->context));
1093         $this->set_up_user_and_role();
1095         $this->assertFalse(settings_provider::can_configure_manually($this->context));
1097         assign_capability($settingcapability, CAP_ALLOW, $this->roleid, $this->context->id);
1098         $this->assertTrue(settings_provider::can_configure_manually($this->context));
1099     }
1101     /**
1102      * Test that we can check if the seb settings are locked.
1103      */
1104     public function test_is_seb_settings_locked() {
1105         $this->quiz = $this->create_test_quiz($this->course);
1106         $user = $this->getDataGenerator()->create_user();
1108         $this->assertFalse(settings_provider::is_seb_settings_locked($this->quiz->id));
1110         $this->attempt_quiz($this->quiz, $user);
1111         $this->assertTrue(settings_provider::is_seb_settings_locked($this->quiz->id));
1112     }
1114     /**
1115      * Test that we can check identify conflicting permissions if set to use template.
1116      */
1117     public function test_is_conflicting_permissions_for_manage_templates() {
1118         $this->setAdminUser();
1120         $this->quiz = $this->create_test_quiz($this->course, settings_provider::USE_SEB_CONFIG_MANUALLY);
1121         $this->context = context_module::instance($this->quiz->cmid);
1123         // Create a template.
1124         $template = $this->create_template();
1125         $settings = quiz_settings::get_record(['quizid' => $this->quiz->id]);
1126         $settings->set('templateid', $template->get('id'));
1127         $settings->set('requiresafeexambrowser', settings_provider::USE_SEB_TEMPLATE);
1128         $settings->save();
1130         $this->assertFalse(settings_provider::is_conflicting_permissions($this->context));
1132         $this->set_up_user_and_role();
1134         $this->assertTrue(settings_provider::is_conflicting_permissions($this->context));
1136         assign_capability('quizaccess/seb:manage_seb_templateid', CAP_ALLOW, $this->roleid, $this->context->id);
1137         $this->assertFalse(settings_provider::is_conflicting_permissions($this->context));
1138     }
1140     /**
1141      * Test that we can check identify conflicting permissions if set to use own seb file.
1142      */
1143     public function test_is_conflicting_permissions_for_upload_seb_file() {
1144         $this->setAdminUser();
1146         $this->quiz = $this->create_test_quiz($this->course, settings_provider::USE_SEB_CONFIG_MANUALLY);
1147         $this->context = context_module::instance($this->quiz->cmid);
1149         // Save file.
1150         $xml = file_get_contents(__DIR__ . '/sample_data/unencrypted.seb');
1151         $draftitemid = $this->create_test_draftarea_file($xml);
1152         settings_provider::save_filemanager_sebconfigfile_draftarea($draftitemid, $this->quiz->cmid);
1153         $settings = quiz_settings::get_record(['quizid' => $this->quiz->id]);
1154         $settings->set('requiresafeexambrowser', settings_provider::USE_SEB_UPLOAD_CONFIG);
1155         $settings->save();
1157         $this->assertFalse(settings_provider::is_conflicting_permissions($this->context));
1159         $this->set_up_user_and_role();
1161         assign_capability('quizaccess/seb:manage_filemanager_sebconfigfile', CAP_ALLOW, $this->roleid, $this->context->id);
1162         $this->assertFalse(settings_provider::is_conflicting_permissions($this->context));
1163     }
1165     /**
1166      * Test that we can check identify conflicting permissions if set to use own configure manually.
1167      *
1168      * @param string $settingcapability Setting capability to check manual option against.
1169      *
1170      * @dataProvider settings_capability_data_provider
1171      */
1172     public function test_is_conflicting_permissions_for_configure_manually($settingcapability) {
1173         $this->setAdminUser();
1175         $this->quiz = $this->create_test_quiz($this->course, settings_provider::USE_SEB_CONFIG_MANUALLY);
1176         $this->context = context_module::instance($this->quiz->cmid);
1178         $this->assertFalse(settings_provider::is_conflicting_permissions($this->context));
1180         $this->set_up_user_and_role();
1182         assign_capability($settingcapability, CAP_ALLOW, $this->roleid, $this->context->id);
1183         $this->assertFalse(settings_provider::is_conflicting_permissions($this->context));
1184     }
1186     /**
1187      * Test add_prefix helper method.
1188      */
1189     public function test_add_prefix() {
1190         $this->assertEquals('seb_one', settings_provider::add_prefix('one'));
1191         $this->assertEquals('seb_two', settings_provider::add_prefix('seb_two'));
1192         $this->assertEquals('seb_seb_three', settings_provider::add_prefix('seb_seb_three'));
1193         $this->assertEquals('seb_', settings_provider::add_prefix('seb_'));
1194         $this->assertEquals('seb_', settings_provider::add_prefix(''));
1195         $this->assertEquals('seb_one_seb', settings_provider::add_prefix('one_seb'));
1196     }
1198     /**
1199      * Test filter_plugin_settings helper method.
1200      */
1201     public function test_filter_plugin_settings() {
1202         $test = new stdClass();
1203         $test->one = 'one';
1204         $test->seb_two = 'two';
1205         $test->seb_seb_three = 'three';
1206         $test->four = 'four';
1208         $newsettings = (array)settings_provider::filter_plugin_settings($test);
1210         $this->assertFalse(key_exists('one', $newsettings));
1211         $this->assertFalse(key_exists('four', $newsettings));
1213         $this->assertCount(2, $newsettings);
1214         $this->assertEquals('two', $newsettings['two']);
1215         $this->assertEquals('three', $newsettings['seb_three']);
1216     }
1218     /**
1219      * Helper method to get a list of settings.
1220      *
1221      * @return \stdClass
1222      */
1223     protected function get_settings() {
1224         $allsettings = new stdClass();
1225         $allsettings->seb_showsebdownloadlink = 0;
1226         $allsettings->seb_linkquitseb = 2;
1227         $allsettings->seb_userconfirmquit = 3;
1228         $allsettings->seb_allowuserquitseb = 4;
1229         $allsettings->seb_quitpassword = 5;
1230         $allsettings->seb_allowreloadinexam = 6;
1231         $allsettings->seb_showsebtaskbar = 7;
1232         $allsettings->seb_showreloadbutton = 8;
1233         $allsettings->seb_showtime = 9;
1234         $allsettings->seb_showkeyboardlayout = 10;
1235         $allsettings->seb_showwificontrol = 11;
1236         $allsettings->seb_enableaudiocontrol = 12;
1237         $allsettings->seb_muteonstartup = 13;
1238         $allsettings->seb_allowspellchecking = 14;
1239         $allsettings->seb_activateurlfiltering = 15;
1240         $allsettings->seb_filterembeddedcontent = 16;
1241         $allsettings->seb_expressionsallowed = 17;
1242         $allsettings->seb_regexallowed = 18;
1243         $allsettings->seb_expressionsblocked = 19;
1244         $allsettings->seb_regexblocked = 20;
1245         $allsettings->seb_templateid = 21;
1246         $allsettings->seb_allowedbrowserexamkeys = 22;
1248         return $allsettings;
1249     }
1251     /**
1252      * Helper method to assert results of filter_plugin_settings
1253      *
1254      * @param int $type Type of SEB usage.
1255      * @param array $notnulls A list of expected not null settings.
1256      */
1257     protected function assert_filter_plugin_settings(int $type, array $notnulls) {
1258         $allsettings = $this->get_settings();
1259         $allsettings->seb_requiresafeexambrowser = $type;
1260         $actual = settings_provider::filter_plugin_settings($allsettings);
1262         $expected = (array)$allsettings;
1263         foreach ($actual as $name => $value) {
1264             if (in_array($name, $notnulls)) {
1265                 $this->assertEquals($expected['seb_' . $name], $value);
1266             } else {
1267                 $this->assertNull($value);
1268             }
1269         }
1270     }
1272     /**
1273      * Test filter_plugin_settings method for no SEB case.
1274      */
1275     public function test_filter_plugin_settings_for_no_seb() {
1276         $notnulls = ['requiresafeexambrowser'];
1277         $this->assert_filter_plugin_settings(settings_provider::USE_SEB_NO, $notnulls);
1278     }
1280     /**
1281      * Test filter_plugin_settings method for using uploaded config.
1282      */
1283     public function test_filter_plugin_settings_for_uploaded_config() {
1284         $notnulls = ['requiresafeexambrowser', 'showsebdownloadlink', 'allowedbrowserexamkeys'];
1285         $this->assert_filter_plugin_settings(settings_provider::USE_SEB_UPLOAD_CONFIG, $notnulls);
1286     }
1288     /**
1289      * Test filter_plugin_settings method for using template.
1290      */
1291     public function test_filter_plugin_settings_for_template() {
1292         $notnulls = ['requiresafeexambrowser', 'showsebdownloadlink', 'allowuserquitseb', 'quitpassword', 'templateid'];
1293         $this->assert_filter_plugin_settings(settings_provider::USE_SEB_TEMPLATE, $notnulls);
1294     }
1296     /**
1297      * Test filter_plugin_settings method for using client config.
1298      */
1299     public function test_filter_plugin_settings_for_client_config() {
1300         $notnulls = ['requiresafeexambrowser', 'showsebdownloadlink', 'allowedbrowserexamkeys'];
1301         $this->assert_filter_plugin_settings(settings_provider::USE_SEB_CLIENT_CONFIG, $notnulls);
1302     }
1304     /**
1305      * Test filter_plugin_settings method for manually configured SEB.
1306      */
1307     public function test_filter_plugin_settings_for_configure_manually() {
1308         $allsettings = $this->get_settings();
1309         $allsettings->seb_requiresafeexambrowser = settings_provider::USE_SEB_CONFIG_MANUALLY;
1310         $actual = settings_provider::filter_plugin_settings($allsettings);
1312         // For manual it's easier to check nulls, as most of the settings are not null.
1313         $nulls = ['templateid', 'allowedbrowserexamkeys'];
1315         $expected = (array)$allsettings;
1316         foreach ($actual as $name => $value) {
1317             if (in_array($name, $nulls)) {
1318                 $this->assertNull($value);
1319             } else {
1320                 $this->assertEquals($expected['seb_' . $name], $value);
1321             }
1322         }
1323     }
1325     /**
1326      * Test settings map.
1327      */
1328     public function test_get_seb_settings_map() {
1329         $expected = [
1330             settings_provider::USE_SEB_NO => [
1332             ],
1333             settings_provider::USE_SEB_CONFIG_MANUALLY => [
1334                 'seb_showsebdownloadlink' => [],
1335                 'seb_linkquitseb' => [],
1336                 'seb_userconfirmquit' => [],
1337                 'seb_allowuserquitseb' => [
1338                     'seb_quitpassword' => []
1339                 ],
1340                 'seb_allowreloadinexam' => [],
1341                 'seb_showsebtaskbar' => [
1342                     'seb_showreloadbutton' => [],
1343                     'seb_showtime' => [],
1344                     'seb_showkeyboardlayout' => [],
1345                     'seb_showwificontrol' => [],
1346                 ],
1347                 'seb_enableaudiocontrol' => [
1348                     'seb_muteonstartup' => [],
1349                 ],
1350                 'seb_allowspellchecking' => [],
1351                 'seb_activateurlfiltering' => [
1352                     'seb_filterembeddedcontent' => [],
1353                     'seb_expressionsallowed' => [],
1354                     'seb_regexallowed' => [],
1355                     'seb_expressionsblocked' => [],
1356                     'seb_regexblocked' => [],
1357                 ],
1358             ],
1359             settings_provider::USE_SEB_TEMPLATE => [
1360                 'seb_templateid' => [],
1361                 'seb_showsebdownloadlink' => [],
1362                 'seb_allowuserquitseb' => [
1363                     'seb_quitpassword' => [],
1364                 ],
1365             ],
1366             settings_provider::USE_SEB_UPLOAD_CONFIG => [
1367                 'filemanager_sebconfigfile' => [],
1368                 'seb_showsebdownloadlink' => [],
1369                 'seb_allowedbrowserexamkeys' => [],
1370             ],
1371             settings_provider::USE_SEB_CLIENT_CONFIG => [
1372                 'seb_showsebdownloadlink' => [],
1373                 'seb_allowedbrowserexamkeys' => [],
1374             ],
1375         ];
1377         $this->assertEquals($expected, settings_provider::get_seb_settings_map());
1378     }