Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.10.x will end 8 November 2021 (12 months).
  • Bug fixes for security issues in 3.10.x will end 9 May 2022 (18 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

Differences Between: [Versions 310 and 311] [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403]

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  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   */
  25  
  26  use quizaccess_seb\quiz_settings;
  27  use quizaccess_seb\settings_provider;
  28  
  29  defined('MOODLE_INTERNAL') || die();
  30  
  31  require_once (__DIR__ . '/test_helper_trait.php');
  32  
  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;
  41  
  42      /**
  43       * Mocked quiz form instance.
  44       * @var \mod_quiz_mod_form
  45       */
  46      protected $mockedquizform;
  47  
  48      /**
  49       * Test moodle form.
  50       * @var \MoodleQuickForm
  51       */
  52      protected $mockedform;
  53  
  54      /**
  55       * Context for testing.
  56       * @var \context
  57       */
  58      protected $context;
  59  
  60      /**
  61       * Test user.
  62       * @var \stdClass
  63       */
  64      protected $user;
  65  
  66      /**
  67       * Test role ID.
  68       * @var int
  69       */
  70      protected $roleid;
  71  
  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          }
  79  
  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      }
  86  
  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();
  92  
  93          $this->setUser($this->user);
  94          $this->roleid = $this->getDataGenerator()->create_role();
  95  
  96          $this->getDataGenerator()->role_assign($this->roleid, $this->user->id, $this->context->id);
  97      }
  98  
  99      /**
 100       * Capability data for testing.
 101       *
 102       * @return array
 103       */
 104      public function settings_capability_data_provider() {
 105          $data = [];
 106  
 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          }
 114  
 115          return $data;
 116      }
 117  
 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);
 125  
 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);
 128  
 129          $this->assertEmpty($diffelements);
 130      }
 131  
 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      }
 140  
 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();
 147  
 148          // Get all defaults that have no matching element in settings types.
 149          $diffelements = array_diff_key($settingdefaults, $settingelements);
 150  
 151          $this->assertEmpty($diffelements);
 152      }
 153  
 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();
 160  
 161          // Get all defaults that have no matching element in settings types.
 162          $diffelements = array_diff_key($settingtypes, $settingelements);
 163  
 164          $this->assertEmpty($diffelements);
 165      }
 166  
 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      }
 181  
 182      /**
 183       * Test hideif rules.
 184       */
 185      public function test_hideifs() {
 186          $settinghideifs = settings_provider::get_quiz_hideifs();
 187  
 188          $this->assertCount(23, $settinghideifs);
 189  
 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          );
 199  
 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          );
 209  
 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          );
 219  
 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          );
 236  
 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          );
 253  
 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          );
 270  
 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          );
 287  
 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          );
 311  
 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          );
 342  
 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          );
 352  
 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          );
 362  
 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          );
 372  
 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          );
 389  
 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          );
 399  
 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          );
 409  
 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          );
 419  
 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          );
 436  
 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          );
 453  
 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          );
 470  
 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          );
 487  
 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          );
 504  
 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          );
 514  
 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      }
 539  
 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();
 546  
 547          // Add known additional elements.
 548          $settingelements['seb_templateid'] = '';
 549          $settingelements['filemanager_sebconfigfile'] = '';
 550          $settingelements['seb_showsebdownloadlink'] = '';
 551          $settingelements['seb_allowedbrowserexamkeys'] = '';
 552  
 553          // Get all defaults that have no matching element in settings types.
 554          $diffelements = array_diff_key($settinghideifs, $settingelements);
 555  
 556          // Check no diff for elements to hide.
 557          $this->assertEmpty($diffelements);
 558  
 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      }
 566  
 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');
 573  
 574          $broken = settings_provider::build_setting_capability_name('broken');
 575      }
 576  
 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);
 584  
 585              $this->assertSame($expected, $actual);
 586          }
 587      }
 588  
 589  
 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();
 597  
 598          $this->quiz = $this->getDataGenerator()->create_module('quiz', ['course' => $this->course->id]);
 599          $this->context = context_module::instance($this->quiz->cmid);
 600  
 601          $this->set_up_user_and_role();
 602  
 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              }
 608  
 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));
 612  
 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              }
 618  
 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);
 622  
 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      }
 629  
 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();
 641  
 642          $this->quiz = $this->getDataGenerator()->create_module('quiz', ['course' => $this->course->id]);
 643          $this->context = context_module::instance($this->quiz->cmid);
 644  
 645          $options = settings_provider::get_requiresafeexambrowser_options($this->context);
 646  
 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));
 653  
 654          // Create a template.
 655          $this->create_template();
 656  
 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));
 661  
 662          // A new user does not have the capability to use the file manager and template.
 663          $this->set_up_user_and_role();
 664  
 665          $options = settings_provider::get_requiresafeexambrowser_options($this->context);
 666  
 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));
 673  
 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));
 682  
 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));
 691  
 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      }
 701  
 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();
 709  
 710          $this->quiz = $this->create_test_quiz($this->course, settings_provider::USE_SEB_CONFIG_MANUALLY);
 711          $this->context = context_module::instance($this->quiz->cmid);
 712  
 713          $template = $this->create_template();
 714  
 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();
 719  
 720          $this->set_up_user_and_role();
 721  
 722          $options = settings_provider::get_requiresafeexambrowser_options($this->context);
 723  
 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      }
 728  
 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();
 736  
 737          $this->quiz = $this->create_test_quiz($this->course, settings_provider::USE_SEB_CONFIG_MANUALLY);
 738          $this->context = context_module::instance($this->quiz->cmid);
 739  
 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();
 746  
 747          $this->set_up_user_and_role();
 748  
 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);
 752  
 753          $this->set_up_form_mocks();
 754  
 755          settings_provider::add_seb_settings_fields($this->mockedquizform, $this->mockedform);
 756  
 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      }
 762  
 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();
 769  
 770          $this->quiz = $this->create_test_quiz($this->course, settings_provider::USE_SEB_CONFIG_MANUALLY);
 771          $this->context = context_module::instance($this->quiz->cmid);
 772  
 773          $user = $this->getDataGenerator()->create_user();
 774          $this->attempt_quiz($this->quiz, $user);
 775  
 776          $this->setAdminUser();
 777          $this->set_up_form_mocks();
 778  
 779          settings_provider::add_seb_settings_fields($this->mockedquizform, $this->mockedform);
 780  
 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'));
 786  
 787          foreach (settings_provider::get_seb_config_elements() as $name => $type) {
 788              $this->assertTrue($this->mockedform->isElementFrozen($name));
 789          }
 790      }
 791  
 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();
 799  
 800          $this->quiz = $this->create_test_quiz($this->course, settings_provider::USE_SEB_CONFIG_MANUALLY);
 801          $this->context = context_module::instance($this->quiz->cmid);
 802  
 803          $template = $this->create_template();
 804  
 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();
 809  
 810          $user = $this->getDataGenerator()->create_user();
 811          $this->attempt_quiz($this->quiz, $user);
 812  
 813          $this->setAdminUser();
 814          $this->set_up_form_mocks();
 815  
 816          settings_provider::add_seb_settings_fields($this->mockedquizform, $this->mockedform);
 817  
 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'));
 823  
 824          foreach (settings_provider::get_seb_config_elements() as $name => $type) {
 825              $this->assertTrue($this->mockedform->isElementFrozen($name));
 826          }
 827      }
 828  
 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();
 836  
 837          $this->quiz = $this->create_test_quiz($this->course, settings_provider::USE_SEB_CONFIG_MANUALLY);
 838          $this->context = context_module::instance($this->quiz->cmid);
 839  
 840          $this->set_up_user_and_role();
 841  
 842          assign_capability('quizaccess/seb:manage_seb_requiresafeexambrowser', CAP_ALLOW, $this->roleid, $this->context->id);
 843          $this->set_up_form_mocks();
 844  
 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'));
 848  
 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);
 851  
 852          settings_provider::add_seb_settings_fields($this->mockedquizform, $this->mockedform);
 853          $this->assertTrue($this->mockedform->elementExists('seb_showsebdownloadlink'));
 854      }
 855  
 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();
 863  
 864          $this->quiz = $this->create_test_quiz($this->course, settings_provider::USE_SEB_CLIENT_CONFIG);
 865          $this->context = context_module::instance($this->quiz->cmid);
 866  
 867          $this->set_up_user_and_role();
 868  
 869          assign_capability('quizaccess/seb:manage_seb_requiresafeexambrowser', CAP_ALLOW, $this->roleid, $this->context->id);
 870          $this->set_up_form_mocks();
 871  
 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'));
 875  
 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      }
 881  
 882      /**
 883       * Test the validation of a seb config file.
 884       */
 885      public function test_validate_draftarea_configfile_success() {
 886          $this->resetAfterTest();
 887  
 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      }
 898  
 899      /**
 900       * Test the validation of a missing seb config file.
 901       */
 902      public function test_validate_draftarea_configfile_failure() {
 903          $this->resetAfterTest();
 904  
 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      }
 912  
 913      /**
 914       * Test obtaining the draftarea content.
 915       */
 916      public function test_get_current_user_draft_file() {
 917          $this->resetAfterTest();
 918  
 919          $user = $this->getDataGenerator()->create_user();
 920          $this->setUser($user);
 921  
 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();
 926  
 927          $this->assertEquals($xml, $content);
 928      }
 929  
 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();
 939  
 940          $xml = file_get_contents(__DIR__ . '/fixtures/unencrypted.seb');
 941  
 942          $draftitemid = $this->create_test_draftarea_file($xml);
 943  
 944          settings_provider::save_filemanager_sebconfigfile_draftarea($draftitemid, $this->quiz->cmid);
 945  
 946          $fs = get_file_storage();
 947          $files = $fs->get_area_files($this->context->id, 'quizaccess_seb', 'filemanager_sebconfigfile');
 948  
 949          $this->assertCount(2, $files);
 950      }
 951  
 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();
 961  
 962          $xml = file_get_contents(__DIR__ . '/fixtures/unencrypted.seb');
 963          $draftitemid = $this->create_test_draftarea_file($xml);
 964  
 965          settings_provider::save_filemanager_sebconfigfile_draftarea($draftitemid, $this->quiz->cmid);
 966  
 967          $fs = get_file_storage();
 968          $files = $fs->get_area_files($this->context->id, 'quizaccess_seb', 'filemanager_sebconfigfile');
 969          $this->assertCount(2, $files);
 970  
 971          settings_provider::delete_uploaded_config_file($this->quiz->cmid);
 972  
 973          $files = $fs->get_area_files($this->context->id, 'quizaccess_seb', 'filemanager_sebconfigfile');
 974          // The '.' directory.
 975          $this->assertCount(1, $files);
 976      }
 977  
 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();
 984  
 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);
 988  
 989          $this->set_up_user_and_role();
 990  
 991          $xml = file_get_contents(__DIR__ . '/fixtures/unencrypted.seb');
 992          $draftitemid = $this->create_test_draftarea_file($xml);
 993  
 994          $fs = get_file_storage();
 995          $files = $fs->get_area_files($this->context->id, 'quizaccess_seb', 'filemanager_sebconfigfile');
 996          $this->assertCount(0, $files);
 997  
 998          settings_provider::save_filemanager_sebconfigfile_draftarea($draftitemid, $this->quiz->cmid);
 999  
1000          $settings = quiz_settings::get_record(['quizid' => $this->quiz->id]);
1001          $settings->set('requiresafeexambrowser', settings_provider::USE_SEB_UPLOAD_CONFIG);
1002          $settings->save();
1003  
1004          $file = settings_provider::get_module_context_sebconfig_file($this->quiz->cmid);
1005  
1006          $this->assertSame($file->get_content(), $xml);
1007      }
1008  
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      }
1020  
1021      /**
1022       * Test that users can or can not configure seb settings.
1023       */
1024      public function test_can_configure_seb() {
1025          $this->resetAfterTest();
1026  
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();
1031  
1032          $this->assertTrue(settings_provider::can_configure_seb($this->context));
1033  
1034          $this->set_up_user_and_role();
1035  
1036          $this->assertFalse(settings_provider::can_configure_seb($this->context));
1037  
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      }
1041  
1042      /**
1043       * Test that users can or can not use seb template.
1044       */
1045      public function test_can_use_seb_template() {
1046          $this->resetAfterTest();
1047  
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();
1052  
1053          $this->assertTrue(settings_provider::can_use_seb_template($this->context));
1054  
1055          $this->set_up_user_and_role();
1056  
1057          $this->assertFalse(settings_provider::can_use_seb_template($this->context));
1058  
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      }
1062  
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();
1068  
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();
1073  
1074          $this->assertTrue(settings_provider::can_upload_seb_file($this->context));
1075  
1076          $this->set_up_user_and_role();
1077  
1078          $this->assertFalse(settings_provider::can_upload_seb_file($this->context));
1079  
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      }
1083  
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();
1089  
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));
1095  
1096          $this->set_up_user_and_role();
1097  
1098          $this->assertFalse(settings_provider::can_change_seb_showsebdownloadlink($this->context));
1099  
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      }
1103  
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();
1110  
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));
1115  
1116          $this->set_up_user_and_role();
1117  
1118          $this->assertFalse(settings_provider::can_change_seb_allowedbrowserexamkeys($this->context));
1119  
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      }
1123  
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();
1134  
1135          $this->quiz = $this->getDataGenerator()->create_module('quiz', ['course' => $this->course->id]);
1136          $this->context = context_module::instance($this->quiz->cmid);
1137          $this->setAdminUser();
1138  
1139          $this->assertTrue(settings_provider::can_configure_manually($this->context));
1140  
1141          $this->set_up_user_and_role();
1142  
1143          $this->assertFalse(settings_provider::can_configure_manually($this->context));
1144  
1145          assign_capability($settingcapability, CAP_ALLOW, $this->roleid, $this->context->id);
1146          $this->assertTrue(settings_provider::can_configure_manually($this->context));
1147      }
1148  
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();
1154  
1155          $this->course = $this->getDataGenerator()->create_course();
1156          $this->quiz = $this->create_test_quiz($this->course);
1157          $user = $this->getDataGenerator()->create_user();
1158  
1159          $this->assertFalse(settings_provider::is_seb_settings_locked($this->quiz->id));
1160  
1161          $this->attempt_quiz($this->quiz, $user);
1162          $this->assertTrue(settings_provider::is_seb_settings_locked($this->quiz->id));
1163      }
1164  
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();
1171  
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);
1175  
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();
1182  
1183          $this->assertFalse(settings_provider::is_conflicting_permissions($this->context));
1184  
1185          $this->set_up_user_and_role();
1186  
1187          $this->assertTrue(settings_provider::is_conflicting_permissions($this->context));
1188  
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      }
1192  
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();
1199  
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);
1203  
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();
1211  
1212          $this->assertFalse(settings_provider::is_conflicting_permissions($this->context));
1213  
1214          $this->set_up_user_and_role();
1215  
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      }
1219  
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();
1230  
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);
1234  
1235          $this->assertFalse(settings_provider::is_conflicting_permissions($this->context));
1236  
1237          $this->set_up_user_and_role();
1238  
1239          assign_capability($settingcapability, CAP_ALLOW, $this->roleid, $this->context->id);
1240          $this->assertFalse(settings_provider::is_conflicting_permissions($this->context));
1241      }
1242  
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      }
1254  
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';
1264  
1265          $newsettings = (array)settings_provider::filter_plugin_settings($test);
1266  
1267          $this->assertFalse(key_exists('one', $newsettings));
1268          $this->assertFalse(key_exists('four', $newsettings));
1269  
1270          $this->assertCount(2, $newsettings);
1271          $this->assertEquals('two', $newsettings['two']);
1272          $this->assertEquals('three', $newsettings['seb_three']);
1273      }
1274  
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;
1304  
1305          return $allsettings;
1306      }
1307  
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);
1318  
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      }
1328  
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      }
1336  
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      }
1344  
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      }
1352  
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      }
1360  
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);
1368  
1369          // For manual it's easier to check nulls, as most of the settings are not null.
1370          $nulls = ['templateid', 'allowedbrowserexamkeys'];
1371  
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      }
1381  
1382      /**
1383       * Test settings map.
1384       */
1385      public function test_get_seb_settings_map() {
1386          $expected = [
1387              settings_provider::USE_SEB_NO => [
1388  
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          ];
1433  
1434          $this->assertEquals($expected, settings_provider::get_seb_settings_map());
1435      }
1436  
1437  }