Merge branch 'MDL-68656-master' of https://github.com/catalyst/moodle
[moodle.git] / mod / quiz / accessrule / seb / tests / 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\quiz_settings;
27 use quizaccess_seb\settings_provider;
29 defined('MOODLE_INTERNAL') || die();
31 require_once(__DIR__ . '/test_helper_trait.php');
33 /**
34  * PHPUnit tests for settings_provider.
35  *
36  * @copyright  2020 Catalyst IT
37  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
38  */
39 class quizaccess_seb_settings_provider_testcase extends advanced_testcase {
40     use quizaccess_seb_test_helper_trait;
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     }
590     /**
591      * Test can check if can manage SEB settings respecting settings structure.
592      */
593     public function test_can_manage_seb_config_setting() {
594         $this->resetAfterTest();
595         $this->setAdminUser();
596         $this->course = $this->getDataGenerator()->create_course();
598         $this->quiz = $this->getDataGenerator()->create_module('quiz', ['course' => $this->course->id]);
599         $this->context = context_module::instance($this->quiz->cmid);
601         $this->set_up_user_and_role();
603         foreach (settings_provider::get_seb_settings_map()[settings_provider::USE_SEB_CONFIG_MANUALLY] as $setting => $children) {
604             // Skip not SEB setting.
605             if ($setting == 'seb_showsebdownloadlink') {
606                 continue;
607             }
609             $this->assertFalse(settings_provider::can_manage_seb_config_setting($setting, $this->context));
610             foreach ($children as $child => $empty) {
611                 $this->assertFalse(settings_provider::can_manage_seb_config_setting($child, $this->context));
613                 // Assign child capability without having parent one. Should not have access to manage child.
614                 $childcap = settings_provider::build_setting_capability_name($child);
615                 assign_capability($childcap, CAP_ALLOW, $this->roleid, $this->context->id);
616                 $this->assertFalse(settings_provider::can_manage_seb_config_setting($child, $this->context));
617             }
619             // Assign parent capability. Should be able to manage children now.
620             $parentcap = settings_provider::build_setting_capability_name($setting);
621             assign_capability($parentcap, CAP_ALLOW, $this->roleid, $this->context->id);
623             $this->assertTrue(settings_provider::can_manage_seb_config_setting($setting, $this->context));
624             foreach ($children as $child => $empty) {
625                 $this->assertTrue(settings_provider::can_manage_seb_config_setting($child, $this->context));
626             }
627         }
628     }
630     /**
631      * Test SEB usage options.
632      *
633      * @param string $settingcapability Setting capability to check manual option against.
634      *
635      * @dataProvider settings_capability_data_provider
636      */
637     public function test_get_requiresafeexambrowser_options($settingcapability) {
638         $this->resetAfterTest();
639         $this->setAdminUser();
640         $this->course = $this->getDataGenerator()->create_course();
642         $this->quiz = $this->getDataGenerator()->create_module('quiz', ['course' => $this->course->id]);
643         $this->context = context_module::instance($this->quiz->cmid);
645         $options = settings_provider::get_requiresafeexambrowser_options($this->context);
647         $this->assertCount(4, $options);
648         $this->assertTrue(array_key_exists(settings_provider::USE_SEB_NO, $options));
649         $this->assertTrue(array_key_exists(settings_provider::USE_SEB_CONFIG_MANUALLY, $options));
650         $this->assertFalse(array_key_exists(settings_provider::USE_SEB_TEMPLATE, $options));
651         $this->assertTrue(array_key_exists(settings_provider::USE_SEB_UPLOAD_CONFIG, $options));
652         $this->assertTrue(array_key_exists(settings_provider::USE_SEB_CLIENT_CONFIG, $options));
654         // Create a template.
655         $this->create_template();
657         // The template options should be visible now.
658         $options = settings_provider::get_requiresafeexambrowser_options($this->context);
659         $this->assertCount(5, $options);
660         $this->assertTrue(array_key_exists(settings_provider::USE_SEB_TEMPLATE, $options));
662         // A new user does not have the capability to use the file manager and template.
663         $this->set_up_user_and_role();
665         $options = settings_provider::get_requiresafeexambrowser_options($this->context);
667         $this->assertCount(2, $options);
668         $this->assertFalse(array_key_exists(settings_provider::USE_SEB_CONFIG_MANUALLY, $options));
669         $this->assertFalse(array_key_exists(settings_provider::USE_SEB_TEMPLATE, $options));
670         $this->assertFalse(array_key_exists(settings_provider::USE_SEB_UPLOAD_CONFIG, $options));
671         $this->assertTrue(array_key_exists(settings_provider::USE_SEB_CLIENT_CONFIG, $options));
672         $this->assertTrue(array_key_exists(settings_provider::USE_SEB_NO, $options));
674         assign_capability($settingcapability, CAP_ALLOW, $this->roleid, $this->context->id);
675         $options = settings_provider::get_requiresafeexambrowser_options($this->context);
676         $this->assertCount(3, $options);
677         $this->assertTrue(array_key_exists(settings_provider::USE_SEB_CONFIG_MANUALLY, $options));
678         $this->assertFalse(array_key_exists(settings_provider::USE_SEB_TEMPLATE, $options));
679         $this->assertFalse(array_key_exists(settings_provider::USE_SEB_UPLOAD_CONFIG, $options));
680         $this->assertTrue(array_key_exists(settings_provider::USE_SEB_CLIENT_CONFIG, $options));
681         $this->assertTrue(array_key_exists(settings_provider::USE_SEB_NO, $options));
683         assign_capability('quizaccess/seb:manage_seb_templateid', CAP_ALLOW, $this->roleid, $this->context->id);
684         $options = settings_provider::get_requiresafeexambrowser_options($this->context);
685         $this->assertCount(4, $options);
686         $this->assertTrue(array_key_exists(settings_provider::USE_SEB_CONFIG_MANUALLY, $options));
687         $this->assertTrue(array_key_exists(settings_provider::USE_SEB_TEMPLATE, $options));
688         $this->assertFalse(array_key_exists(settings_provider::USE_SEB_UPLOAD_CONFIG, $options));
689         $this->assertTrue(array_key_exists(settings_provider::USE_SEB_CLIENT_CONFIG, $options));
690         $this->assertTrue(array_key_exists(settings_provider::USE_SEB_NO, $options));
692         assign_capability('quizaccess/seb:manage_filemanager_sebconfigfile', CAP_ALLOW, $this->roleid, $this->context->id);
693         $options = settings_provider::get_requiresafeexambrowser_options($this->context);
694         $this->assertCount(5, $options);
695         $this->assertTrue(array_key_exists(settings_provider::USE_SEB_CONFIG_MANUALLY, $options));
696         $this->assertTrue(array_key_exists(settings_provider::USE_SEB_TEMPLATE, $options));
697         $this->assertTrue(array_key_exists(settings_provider::USE_SEB_UPLOAD_CONFIG, $options));
698         $this->assertTrue(array_key_exists(settings_provider::USE_SEB_CLIENT_CONFIG, $options));
699         $this->assertTrue(array_key_exists(settings_provider::USE_SEB_NO, $options));
700     }
702     /**
703      * Test SEB usage options with conflicting permissions.
704      */
705     public function test_get_requiresafeexambrowser_options_with_conflicting_permissions() {
706         $this->resetAfterTest();
707         $this->setAdminUser();
708         $this->course = $this->getDataGenerator()->create_course();
710         $this->quiz = $this->create_test_quiz($this->course, settings_provider::USE_SEB_CONFIG_MANUALLY);
711         $this->context = context_module::instance($this->quiz->cmid);
713         $template = $this->create_template();
715         $settings = quiz_settings::get_record(['quizid' => $this->quiz->id]);
716         $settings->set('templateid', $template->get('id'));
717         $settings->set('requiresafeexambrowser', settings_provider::USE_SEB_TEMPLATE);
718         $settings->save();
720         $this->set_up_user_and_role();
722         $options = settings_provider::get_requiresafeexambrowser_options($this->context);
724         // If there is nay conflict we return full list of options.
725         $this->assertCount(5, $options);
726         $this->assertTrue(array_key_exists(settings_provider::USE_SEB_TEMPLATE, $options));
727     }
729     /**
730      * Test that SEB options and templates are frozen if conflicting permissions.
731      */
732     public function test_form_elements_are_frozen_if_conflicting_permissions() {
733         $this->resetAfterTest();
734         $this->setAdminUser();
735         $this->course = $this->getDataGenerator()->create_course();
737         $this->quiz = $this->create_test_quiz($this->course, settings_provider::USE_SEB_CONFIG_MANUALLY);
738         $this->context = context_module::instance($this->quiz->cmid);
740         // Setup conflicting permissions.
741         $template = $this->create_template();
742         $settings = quiz_settings::get_record(['quizid' => $this->quiz->id]);
743         $settings->set('templateid', $template->get('id'));
744         $settings->set('requiresafeexambrowser', settings_provider::USE_SEB_TEMPLATE);
745         $settings->save();
747         $this->set_up_user_and_role();
749         assign_capability('quizaccess/seb:manage_seb_requiresafeexambrowser', CAP_ALLOW, $this->roleid, $this->context->id);
750         assign_capability('quizaccess/seb:manage_seb_showsebdownloadlink', CAP_ALLOW, $this->roleid, $this->context->id);
751         assign_capability('quizaccess/seb:manage_seb_allowedbrowserexamkeys', CAP_ALLOW, $this->roleid, $this->context->id);
753         $this->set_up_form_mocks();
755         settings_provider::add_seb_settings_fields($this->mockedquizform, $this->mockedform);
757         $this->assertTrue($this->mockedform->isElementFrozen('seb_requiresafeexambrowser'));
758         $this->assertTrue($this->mockedform->isElementFrozen('seb_templateid'));
759         $this->assertTrue($this->mockedform->isElementFrozen('seb_showsebdownloadlink'));
760         $this->assertTrue($this->mockedform->isElementFrozen('seb_allowedbrowserexamkeys'));
761     }
763     /**
764      * Test that All settings are frozen if quiz was attempted and use seb with manual settings.
765      */
766     public function test_form_elements_are_locked_when_quiz_attempted_manual() {
767         $this->resetAfterTest();
768         $this->course = $this->getDataGenerator()->create_course();
770         $this->quiz = $this->create_test_quiz($this->course, settings_provider::USE_SEB_CONFIG_MANUALLY);
771         $this->context = context_module::instance($this->quiz->cmid);
773         $user = $this->getDataGenerator()->create_user();
774         $this->attempt_quiz($this->quiz, $user);
776         $this->setAdminUser();
777         $this->set_up_form_mocks();
779         settings_provider::add_seb_settings_fields($this->mockedquizform, $this->mockedform);
781         $this->assertTrue($this->mockedform->isElementFrozen('seb_requiresafeexambrowser'));
782         $this->assertTrue($this->mockedform->elementExists('filemanager_sebconfigfile'));
783         $this->assertFalse($this->mockedform->elementExists('seb_templateid'));
784         $this->assertTrue($this->mockedform->isElementFrozen('seb_showsebdownloadlink'));
785         $this->assertTrue($this->mockedform->isElementFrozen('seb_allowedbrowserexamkeys'));
787         foreach (settings_provider::get_seb_config_elements() as $name => $type) {
788             $this->assertTrue($this->mockedform->isElementFrozen($name));
789         }
790     }
792     /**
793      * Test that All settings are frozen if a quiz was attempted and use template.
794      */
795     public function test_form_elements_are_locked_when_quiz_attempted_template() {
796         $this->resetAfterTest();
797         $this->setAdminUser();
798         $this->course = $this->getDataGenerator()->create_course();
800         $this->quiz = $this->create_test_quiz($this->course, settings_provider::USE_SEB_CONFIG_MANUALLY);
801         $this->context = context_module::instance($this->quiz->cmid);
803         $template = $this->create_template();
805         $settings = quiz_settings::get_record(['quizid' => $this->quiz->id]);
806         $settings->set('templateid', $template->get('id'));
807         $settings->set('requiresafeexambrowser', settings_provider::USE_SEB_TEMPLATE);
808         $settings->save();
810         $user = $this->getDataGenerator()->create_user();
811         $this->attempt_quiz($this->quiz, $user);
813         $this->setAdminUser();
814         $this->set_up_form_mocks();
816         settings_provider::add_seb_settings_fields($this->mockedquizform, $this->mockedform);
818         $this->assertTrue($this->mockedform->isElementFrozen('seb_requiresafeexambrowser'));
819         $this->assertTrue($this->mockedform->elementExists('filemanager_sebconfigfile'));
820         $this->assertTrue($this->mockedform->isElementFrozen('seb_templateid'));
821         $this->assertTrue($this->mockedform->isElementFrozen('seb_showsebdownloadlink'));
822         $this->assertTrue($this->mockedform->isElementFrozen('seb_allowedbrowserexamkeys'));
824         foreach (settings_provider::get_seb_config_elements() as $name => $type) {
825             $this->assertTrue($this->mockedform->isElementFrozen($name));
826         }
827     }
829     /**
830      * Test Show Safe Exam Browser download button setting in the form.
831      */
832     public function test_showsebdownloadlink_in_form() {
833         $this->resetAfterTest();
834         $this->setAdminUser();
835         $this->course = $this->getDataGenerator()->create_course();
837         $this->quiz = $this->create_test_quiz($this->course, settings_provider::USE_SEB_CONFIG_MANUALLY);
838         $this->context = context_module::instance($this->quiz->cmid);
840         $this->set_up_user_and_role();
842         assign_capability('quizaccess/seb:manage_seb_requiresafeexambrowser', CAP_ALLOW, $this->roleid, $this->context->id);
843         $this->set_up_form_mocks();
845         // Shouldn't be in the form if no permissions.
846         settings_provider::add_seb_settings_fields($this->mockedquizform, $this->mockedform);
847         $this->assertFalse($this->mockedform->elementExists('seb_showsebdownloadlink'));
849         // Should be in the form if we grant require permissions.
850         assign_capability('quizaccess/seb:manage_seb_showsebdownloadlink', CAP_ALLOW, $this->roleid, $this->context->id);
852         settings_provider::add_seb_settings_fields($this->mockedquizform, $this->mockedform);
853         $this->assertTrue($this->mockedform->elementExists('seb_showsebdownloadlink'));
854     }
856     /**
857      * Test Allowed Browser Exam Keys setting in the form.
858      */
859     public function test_allowedbrowserexamkeys_in_form() {
860         $this->resetAfterTest();
861         $this->setAdminUser();
862         $this->course = $this->getDataGenerator()->create_course();
864         $this->quiz = $this->create_test_quiz($this->course, settings_provider::USE_SEB_CLIENT_CONFIG);
865         $this->context = context_module::instance($this->quiz->cmid);
867         $this->set_up_user_and_role();
869         assign_capability('quizaccess/seb:manage_seb_requiresafeexambrowser', CAP_ALLOW, $this->roleid, $this->context->id);
870         $this->set_up_form_mocks();
872         // Shouldn't be in the form if no permissions.
873         settings_provider::add_seb_settings_fields($this->mockedquizform, $this->mockedform);
874         $this->assertFalse($this->mockedform->elementExists('seb_allowedbrowserexamkeys'));
876         // Should be in the form if we grant require permissions.
877         assign_capability('quizaccess/seb:manage_seb_allowedbrowserexamkeys', CAP_ALLOW, $this->roleid, $this->context->id);
878         settings_provider::add_seb_settings_fields($this->mockedquizform, $this->mockedform);
879         $this->assertTrue($this->mockedform->elementExists('seb_allowedbrowserexamkeys'));
880     }
882     /**
883      * Test the validation of a seb config file.
884      */
885     public function test_validate_draftarea_configfile_success() {
886         $this->resetAfterTest();
888         $user = $this->getDataGenerator()->create_user();
889         $this->setUser($user);
890         $xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
891             . "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
892             . "<plist version=\"1.0\"><dict><key>hashedQuitPassword</key><string>hashedpassword</string>"
893             . "<key>allowWlan</key><false/></dict></plist>\n";
894         $itemid = $this->create_test_draftarea_file($xml);
895         $errors = settings_provider::validate_draftarea_configfile($itemid);
896         $this->assertEmpty($errors);
897     }
899     /**
900      * Test the validation of a missing seb config file.
901      */
902     public function test_validate_draftarea_configfile_failure() {
903         $this->resetAfterTest();
905         $user = $this->getDataGenerator()->create_user();
906         $this->setUser($user);
907         $xml = "This is not a config file.";
908         $itemid = $this->create_test_draftarea_file($xml);
909         $errors = settings_provider::validate_draftarea_configfile($itemid);
910         $this->assertEquals($errors, new lang_string('fileparsefailed', 'quizaccess_seb'));
911     }
913     /**
914      * Test obtaining the draftarea content.
915      */
916     public function test_get_current_user_draft_file() {
917         $this->resetAfterTest();
919         $user = $this->getDataGenerator()->create_user();
920         $this->setUser($user);
922         $xml = file_get_contents(__DIR__ . '/fixtures/unencrypted.seb');
923         $itemid = $this->create_test_draftarea_file($xml);
924         $file = settings_provider::get_current_user_draft_file($itemid);
925         $content = $file->get_content();
927         $this->assertEquals($xml, $content);
928     }
930     /**
931      * Test saving files from the user draft area into the quiz context area storage.
932      */
933     public function test_save_filemanager_sebconfigfile_draftarea() {
934         $this->resetAfterTest();
935         $this->course = $this->getDataGenerator()->create_course();
936         $this->quiz = $this->getDataGenerator()->create_module('quiz', ['course' => $this->course->id]);
937         $this->context = context_module::instance($this->quiz->cmid);
938         $this->set_up_user_and_role();
940         $xml = file_get_contents(__DIR__ . '/fixtures/unencrypted.seb');
942         $draftitemid = $this->create_test_draftarea_file($xml);
944         settings_provider::save_filemanager_sebconfigfile_draftarea($draftitemid, $this->quiz->cmid);
946         $fs = get_file_storage();
947         $files = $fs->get_area_files($this->context->id, 'quizaccess_seb', 'filemanager_sebconfigfile');
949         $this->assertCount(2, $files);
950     }
952     /**
953      * Test deleting the $this->quiz->cmid itemid from the file area.
954      */
955     public function test_delete_uploaded_config_file() {
956         $this->resetAfterTest();
957         $this->course = $this->getDataGenerator()->create_course();
958         $this->quiz = $this->getDataGenerator()->create_module('quiz', ['course' => $this->course->id]);
959         $this->context = context_module::instance($this->quiz->cmid);
960         $this->set_up_user_and_role();
962         $xml = file_get_contents(__DIR__ . '/fixtures/unencrypted.seb');
963         $draftitemid = $this->create_test_draftarea_file($xml);
965         settings_provider::save_filemanager_sebconfigfile_draftarea($draftitemid, $this->quiz->cmid);
967         $fs = get_file_storage();
968         $files = $fs->get_area_files($this->context->id, 'quizaccess_seb', 'filemanager_sebconfigfile');
969         $this->assertCount(2, $files);
971         settings_provider::delete_uploaded_config_file($this->quiz->cmid);
973         $files = $fs->get_area_files($this->context->id, 'quizaccess_seb', 'filemanager_sebconfigfile');
974         // The '.' directory.
975         $this->assertCount(1, $files);
976     }
978     /**
979      * Test getting the file from the context module id file area.
980      */
981     public function test_get_module_context_sebconfig_file() {
982         $this->resetAfterTest();
983         $this->setAdminUser();
985         $this->course = $this->getDataGenerator()->create_course();
986         $this->quiz = $this->create_test_quiz($this->course, settings_provider::USE_SEB_CONFIG_MANUALLY);
987         $this->context = context_module::instance($this->quiz->cmid);
989         $this->set_up_user_and_role();
991         $xml = file_get_contents(__DIR__ . '/fixtures/unencrypted.seb');
992         $draftitemid = $this->create_test_draftarea_file($xml);
994         $fs = get_file_storage();
995         $files = $fs->get_area_files($this->context->id, 'quizaccess_seb', 'filemanager_sebconfigfile');
996         $this->assertCount(0, $files);
998         settings_provider::save_filemanager_sebconfigfile_draftarea($draftitemid, $this->quiz->cmid);
1000         $settings = quiz_settings::get_record(['quizid' => $this->quiz->id]);
1001         $settings->set('requiresafeexambrowser', settings_provider::USE_SEB_UPLOAD_CONFIG);
1002         $settings->save();
1004         $file = settings_provider::get_module_context_sebconfig_file($this->quiz->cmid);
1006         $this->assertSame($file->get_content(), $xml);
1007     }
1009     /**
1010      * Test file manager options.
1011      */
1012     public function test_get_filemanager_options() {
1013         $expected = [
1014             'subdirs' => 0,
1015             'maxfiles' => 1,
1016             'accepted_types' => ['.seb']
1017         ];
1018         $this->assertSame($expected, settings_provider::get_filemanager_options());
1019     }
1021     /**
1022      * Test that users can or can not configure seb settings.
1023      */
1024     public function test_can_configure_seb() {
1025         $this->resetAfterTest();
1027         $this->course = $this->getDataGenerator()->create_course();
1028         $this->quiz = $this->getDataGenerator()->create_module('quiz', ['course' => $this->course->id]);
1029         $this->context = context_module::instance($this->quiz->cmid);
1030         $this->setAdminUser();
1032         $this->assertTrue(settings_provider::can_configure_seb($this->context));
1034         $this->set_up_user_and_role();
1036         $this->assertFalse(settings_provider::can_configure_seb($this->context));
1038         assign_capability('quizaccess/seb:manage_seb_requiresafeexambrowser', CAP_ALLOW, $this->roleid, $this->context->id);
1039         $this->assertTrue(settings_provider::can_configure_seb($this->context));
1040     }
1042     /**
1043      * Test that users can or can not use seb template.
1044      */
1045     public function test_can_use_seb_template() {
1046         $this->resetAfterTest();
1048         $this->course = $this->getDataGenerator()->create_course();
1049         $this->quiz = $this->getDataGenerator()->create_module('quiz', ['course' => $this->course->id]);
1050         $this->context = context_module::instance($this->quiz->cmid);
1051         $this->setAdminUser();
1053         $this->assertTrue(settings_provider::can_use_seb_template($this->context));
1055         $this->set_up_user_and_role();
1057         $this->assertFalse(settings_provider::can_use_seb_template($this->context));
1059         assign_capability('quizaccess/seb:manage_seb_templateid', CAP_ALLOW, $this->roleid, $this->context->id);
1060         $this->assertTrue(settings_provider::can_use_seb_template($this->context));
1061     }
1063     /**
1064      * Test that users can or can not upload seb config file.
1065      */
1066     public function test_can_upload_seb_file() {
1067         $this->resetAfterTest();
1069         $this->course = $this->getDataGenerator()->create_course();
1070         $this->quiz = $this->getDataGenerator()->create_module('quiz', ['course' => $this->course->id]);
1071         $this->context = context_module::instance($this->quiz->cmid);
1072         $this->setAdminUser();
1074         $this->assertTrue(settings_provider::can_upload_seb_file($this->context));
1076         $this->set_up_user_and_role();
1078         $this->assertFalse(settings_provider::can_upload_seb_file($this->context));
1080         assign_capability('quizaccess/seb:manage_filemanager_sebconfigfile', CAP_ALLOW, $this->roleid, $this->context->id);
1081         $this->assertTrue(settings_provider::can_upload_seb_file($this->context));
1082     }
1084     /**
1085      * Test that users can or can not change Show Safe Exam Browser download button setting.
1086      */
1087     public function test_can_change_seb_showsebdownloadlink() {
1088         $this->resetAfterTest();
1090         $this->course = $this->getDataGenerator()->create_course();
1091         $this->quiz = $this->getDataGenerator()->create_module('quiz', ['course' => $this->course->id]);
1092         $this->context = context_module::instance($this->quiz->cmid);
1093         $this->setAdminUser();
1094         $this->assertTrue(settings_provider::can_change_seb_showsebdownloadlink($this->context));
1096         $this->set_up_user_and_role();
1098         $this->assertFalse(settings_provider::can_change_seb_showsebdownloadlink($this->context));
1100         assign_capability('quizaccess/seb:manage_seb_showsebdownloadlink', CAP_ALLOW, $this->roleid, $this->context->id);
1101         $this->assertTrue(settings_provider::can_change_seb_showsebdownloadlink($this->context));
1102     }
1104     /**
1105      * Test that users can or can not change Allowed Browser Exam Keys setting.
1106      */
1107     public function test_can_change_seb_allowedbrowserexamkeys() {
1108         $this->resetAfterTest();
1109         $this->course = $this->getDataGenerator()->create_course();
1111         $this->quiz = $this->getDataGenerator()->create_module('quiz', ['course' => $this->course->id]);
1112         $this->context = context_module::instance($this->quiz->cmid);
1113         $this->setAdminUser();
1114         $this->assertTrue(settings_provider::can_change_seb_allowedbrowserexamkeys($this->context));
1116         $this->set_up_user_and_role();
1118         $this->assertFalse(settings_provider::can_change_seb_allowedbrowserexamkeys($this->context));
1120         assign_capability('quizaccess/seb:manage_seb_allowedbrowserexamkeys', CAP_ALLOW, $this->roleid, $this->context->id);
1121         $this->assertTrue(settings_provider::can_change_seb_allowedbrowserexamkeys($this->context));
1122     }
1124     /**
1125      * Test that users can or can not Configure SEb manually
1126      *
1127      * @param string $settingcapability Setting capability to check manual option against.
1128      *
1129      * @dataProvider settings_capability_data_provider
1130      */
1131     public function test_can_configure_manually($settingcapability) {
1132         $this->resetAfterTest();
1133         $this->course = $this->getDataGenerator()->create_course();
1135         $this->quiz = $this->getDataGenerator()->create_module('quiz', ['course' => $this->course->id]);
1136         $this->context = context_module::instance($this->quiz->cmid);
1137         $this->setAdminUser();
1139         $this->assertTrue(settings_provider::can_configure_manually($this->context));
1141         $this->set_up_user_and_role();
1143         $this->assertFalse(settings_provider::can_configure_manually($this->context));
1145         assign_capability($settingcapability, CAP_ALLOW, $this->roleid, $this->context->id);
1146         $this->assertTrue(settings_provider::can_configure_manually($this->context));
1147     }
1149     /**
1150      * Test that we can check if the seb settings are locked.
1151      */
1152     public function test_is_seb_settings_locked() {
1153         $this->resetAfterTest();
1155         $this->course = $this->getDataGenerator()->create_course();
1156         $this->quiz = $this->create_test_quiz($this->course);
1157         $user = $this->getDataGenerator()->create_user();
1159         $this->assertFalse(settings_provider::is_seb_settings_locked($this->quiz->id));
1161         $this->attempt_quiz($this->quiz, $user);
1162         $this->assertTrue(settings_provider::is_seb_settings_locked($this->quiz->id));
1163     }
1165     /**
1166      * Test that we can check identify conflicting permissions if set to use template.
1167      */
1168     public function test_is_conflicting_permissions_for_manage_templates() {
1169         $this->resetAfterTest();
1170         $this->setAdminUser();
1172         $this->course = $this->getDataGenerator()->create_course();
1173         $this->quiz = $this->create_test_quiz($this->course, settings_provider::USE_SEB_CONFIG_MANUALLY);
1174         $this->context = context_module::instance($this->quiz->cmid);
1176         // Create a template.
1177         $template = $this->create_template();
1178         $settings = quiz_settings::get_record(['quizid' => $this->quiz->id]);
1179         $settings->set('templateid', $template->get('id'));
1180         $settings->set('requiresafeexambrowser', settings_provider::USE_SEB_TEMPLATE);
1181         $settings->save();
1183         $this->assertFalse(settings_provider::is_conflicting_permissions($this->context));
1185         $this->set_up_user_and_role();
1187         $this->assertTrue(settings_provider::is_conflicting_permissions($this->context));
1189         assign_capability('quizaccess/seb:manage_seb_templateid', CAP_ALLOW, $this->roleid, $this->context->id);
1190         $this->assertFalse(settings_provider::is_conflicting_permissions($this->context));
1191     }
1193     /**
1194      * Test that we can check identify conflicting permissions if set to use own seb file.
1195      */
1196     public function test_is_conflicting_permissions_for_upload_seb_file() {
1197         $this->resetAfterTest();
1198         $this->setAdminUser();
1200         $this->course = $this->getDataGenerator()->create_course();
1201         $this->quiz = $this->create_test_quiz($this->course, settings_provider::USE_SEB_CONFIG_MANUALLY);
1202         $this->context = context_module::instance($this->quiz->cmid);
1204         // Save file.
1205         $xml = file_get_contents(__DIR__ . '/fixtures/unencrypted.seb');
1206         $draftitemid = $this->create_test_draftarea_file($xml);
1207         settings_provider::save_filemanager_sebconfigfile_draftarea($draftitemid, $this->quiz->cmid);
1208         $settings = quiz_settings::get_record(['quizid' => $this->quiz->id]);
1209         $settings->set('requiresafeexambrowser', settings_provider::USE_SEB_UPLOAD_CONFIG);
1210         $settings->save();
1212         $this->assertFalse(settings_provider::is_conflicting_permissions($this->context));
1214         $this->set_up_user_and_role();
1216         assign_capability('quizaccess/seb:manage_filemanager_sebconfigfile', CAP_ALLOW, $this->roleid, $this->context->id);
1217         $this->assertFalse(settings_provider::is_conflicting_permissions($this->context));
1218     }
1220     /**
1221      * Test that we can check identify conflicting permissions if set to use own configure manually.
1222      *
1223      * @param string $settingcapability Setting capability to check manual option against.
1224      *
1225      * @dataProvider settings_capability_data_provider
1226      */
1227     public function test_is_conflicting_permissions_for_configure_manually($settingcapability) {
1228         $this->resetAfterTest();
1229         $this->setAdminUser();
1231         $this->course = $this->getDataGenerator()->create_course();
1232         $this->quiz = $this->create_test_quiz($this->course, settings_provider::USE_SEB_CONFIG_MANUALLY);
1233         $this->context = context_module::instance($this->quiz->cmid);
1235         $this->assertFalse(settings_provider::is_conflicting_permissions($this->context));
1237         $this->set_up_user_and_role();
1239         assign_capability($settingcapability, CAP_ALLOW, $this->roleid, $this->context->id);
1240         $this->assertFalse(settings_provider::is_conflicting_permissions($this->context));
1241     }
1243     /**
1244      * Test add_prefix helper method.
1245      */
1246     public function test_add_prefix() {
1247         $this->assertEquals('seb_one', settings_provider::add_prefix('one'));
1248         $this->assertEquals('seb_two', settings_provider::add_prefix('seb_two'));
1249         $this->assertEquals('seb_seb_three', settings_provider::add_prefix('seb_seb_three'));
1250         $this->assertEquals('seb_', settings_provider::add_prefix('seb_'));
1251         $this->assertEquals('seb_', settings_provider::add_prefix(''));
1252         $this->assertEquals('seb_one_seb', settings_provider::add_prefix('one_seb'));
1253     }
1255     /**
1256      * Test filter_plugin_settings helper method.
1257      */
1258     public function test_filter_plugin_settings() {
1259         $test = new stdClass();
1260         $test->one = 'one';
1261         $test->seb_two = 'two';
1262         $test->seb_seb_three = 'three';
1263         $test->four = 'four';
1265         $newsettings = (array)settings_provider::filter_plugin_settings($test);
1267         $this->assertFalse(key_exists('one', $newsettings));
1268         $this->assertFalse(key_exists('four', $newsettings));
1270         $this->assertCount(2, $newsettings);
1271         $this->assertEquals('two', $newsettings['two']);
1272         $this->assertEquals('three', $newsettings['seb_three']);
1273     }
1275     /**
1276      * Helper method to get a list of settings.
1277      *
1278      * @return \stdClass
1279      */
1280     protected function get_settings() {
1281         $allsettings = new stdClass();
1282         $allsettings->seb_showsebdownloadlink = 0;
1283         $allsettings->seb_linkquitseb = 2;
1284         $allsettings->seb_userconfirmquit = 3;
1285         $allsettings->seb_allowuserquitseb = 4;
1286         $allsettings->seb_quitpassword = 5;
1287         $allsettings->seb_allowreloadinexam = 6;
1288         $allsettings->seb_showsebtaskbar = 7;
1289         $allsettings->seb_showreloadbutton = 8;
1290         $allsettings->seb_showtime = 9;
1291         $allsettings->seb_showkeyboardlayout = 10;
1292         $allsettings->seb_showwificontrol = 11;
1293         $allsettings->seb_enableaudiocontrol = 12;
1294         $allsettings->seb_muteonstartup = 13;
1295         $allsettings->seb_allowspellchecking = 14;
1296         $allsettings->seb_activateurlfiltering = 15;
1297         $allsettings->seb_filterembeddedcontent = 16;
1298         $allsettings->seb_expressionsallowed = 17;
1299         $allsettings->seb_regexallowed = 18;
1300         $allsettings->seb_expressionsblocked = 19;
1301         $allsettings->seb_regexblocked = 20;
1302         $allsettings->seb_templateid = 21;
1303         $allsettings->seb_allowedbrowserexamkeys = 22;
1305         return $allsettings;
1306     }
1308     /**
1309      * Helper method to assert results of filter_plugin_settings
1310      *
1311      * @param int $type Type of SEB usage.
1312      * @param array $notnulls A list of expected not null settings.
1313      */
1314     protected function assert_filter_plugin_settings(int $type, array $notnulls) {
1315         $allsettings = $this->get_settings();
1316         $allsettings->seb_requiresafeexambrowser = $type;
1317         $actual = settings_provider::filter_plugin_settings($allsettings);
1319         $expected = (array)$allsettings;
1320         foreach ($actual as $name => $value) {
1321             if (in_array($name, $notnulls)) {
1322                 $this->assertEquals($expected['seb_' . $name], $value);
1323             } else {
1324                 $this->assertNull($value);
1325             }
1326         }
1327     }
1329     /**
1330      * Test filter_plugin_settings method for no SEB case.
1331      */
1332     public function test_filter_plugin_settings_for_no_seb() {
1333         $notnulls = ['requiresafeexambrowser'];
1334         $this->assert_filter_plugin_settings(settings_provider::USE_SEB_NO, $notnulls);
1335     }
1337     /**
1338      * Test filter_plugin_settings method for using uploaded config.
1339      */
1340     public function test_filter_plugin_settings_for_uploaded_config() {
1341         $notnulls = ['requiresafeexambrowser', 'showsebdownloadlink', 'allowedbrowserexamkeys'];
1342         $this->assert_filter_plugin_settings(settings_provider::USE_SEB_UPLOAD_CONFIG, $notnulls);
1343     }
1345     /**
1346      * Test filter_plugin_settings method for using template.
1347      */
1348     public function test_filter_plugin_settings_for_template() {
1349         $notnulls = ['requiresafeexambrowser', 'showsebdownloadlink', 'allowuserquitseb', 'quitpassword', 'templateid'];
1350         $this->assert_filter_plugin_settings(settings_provider::USE_SEB_TEMPLATE, $notnulls);
1351     }
1353     /**
1354      * Test filter_plugin_settings method for using client config.
1355      */
1356     public function test_filter_plugin_settings_for_client_config() {
1357         $notnulls = ['requiresafeexambrowser', 'showsebdownloadlink', 'allowedbrowserexamkeys'];
1358         $this->assert_filter_plugin_settings(settings_provider::USE_SEB_CLIENT_CONFIG, $notnulls);
1359     }
1361     /**
1362      * Test filter_plugin_settings method for manually configured SEB.
1363      */
1364     public function test_filter_plugin_settings_for_configure_manually() {
1365         $allsettings = $this->get_settings();
1366         $allsettings->seb_requiresafeexambrowser = settings_provider::USE_SEB_CONFIG_MANUALLY;
1367         $actual = settings_provider::filter_plugin_settings($allsettings);
1369         // For manual it's easier to check nulls, as most of the settings are not null.
1370         $nulls = ['templateid', 'allowedbrowserexamkeys'];
1372         $expected = (array)$allsettings;
1373         foreach ($actual as $name => $value) {
1374             if (in_array($name, $nulls)) {
1375                 $this->assertNull($value);
1376             } else {
1377                 $this->assertEquals($expected['seb_' . $name], $value);
1378             }
1379         }
1380     }
1382     /**
1383      * Test settings map.
1384      */
1385     public function test_get_seb_settings_map() {
1386         $expected = [
1387             settings_provider::USE_SEB_NO => [
1389             ],
1390             settings_provider::USE_SEB_CONFIG_MANUALLY => [
1391                 'seb_showsebdownloadlink' => [],
1392                 'seb_linkquitseb' => [],
1393                 'seb_userconfirmquit' => [],
1394                 'seb_allowuserquitseb' => [
1395                     'seb_quitpassword' => []
1396                 ],
1397                 'seb_allowreloadinexam' => [],
1398                 'seb_showsebtaskbar' => [
1399                     'seb_showreloadbutton' => [],
1400                     'seb_showtime' => [],
1401                     'seb_showkeyboardlayout' => [],
1402                     'seb_showwificontrol' => [],
1403                 ],
1404                 'seb_enableaudiocontrol' => [
1405                     'seb_muteonstartup' => [],
1406                 ],
1407                 'seb_allowspellchecking' => [],
1408                 'seb_activateurlfiltering' => [
1409                     'seb_filterembeddedcontent' => [],
1410                     'seb_expressionsallowed' => [],
1411                     'seb_regexallowed' => [],
1412                     'seb_expressionsblocked' => [],
1413                     'seb_regexblocked' => [],
1414                 ],
1415             ],
1416             settings_provider::USE_SEB_TEMPLATE => [
1417                 'seb_templateid' => [],
1418                 'seb_showsebdownloadlink' => [],
1419                 'seb_allowuserquitseb' => [
1420                     'seb_quitpassword' => [],
1421                 ],
1422             ],
1423             settings_provider::USE_SEB_UPLOAD_CONFIG => [
1424                 'filemanager_sebconfigfile' => [],
1425                 'seb_showsebdownloadlink' => [],
1426                 'seb_allowedbrowserexamkeys' => [],
1427             ],
1428             settings_provider::USE_SEB_CLIENT_CONFIG => [
1429                 'seb_showsebdownloadlink' => [],
1430                 'seb_allowedbrowserexamkeys' => [],
1431             ],
1432         ];
1434         $this->assertEquals($expected, settings_provider::get_seb_settings_map());
1435     }