Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.
   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  namespace tool_admin_presets\local\action;
  18  
  19  use core_adminpresets\manager;
  20  
  21  /**
  22   * Tests for the import class.
  23   *
  24   * @package    tool_admin_presets
  25   * @category   test
  26   * @copyright  2021 Sara Arjona (sara@moodle.com)
  27   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  28   * @coversDefaultClass \tool_admin_presets\local\action\import
  29   */
  30  class import_test extends \advanced_testcase {
  31  
  32      /**
  33       * Test the behaviour of execute() method.
  34       *
  35       * @dataProvider import_execute_provider
  36       * @covers ::execute
  37       *
  38       * @param string $filecontents File content to import.
  39       * @param bool $expectedpreset Whether the preset should be created or not.
  40       * @param bool $expectedsettings Whether settings will be created or not.
  41       * @param bool $expectedplugins Whether plugins will be created or not.
  42       * @param bool $expecteddebugging Whether debugging message will be thrown or not.
  43       * @param string|null $expectedexception Expected exception class (if that's the case).
  44       * @param string|null $expectedpresetname Expected preset name.
  45       */
  46      public function test_import_execute(string $filecontents, bool $expectedpreset, bool $expectedsettings = false,
  47              bool $expectedplugins = false, bool $expecteddebugging = false, string $expectedexception = null,
  48              string $expectedpresetname = 'Imported preset'): void {
  49          global $DB, $USER;
  50  
  51          $this->resetAfterTest();
  52          $this->setAdminUser();
  53  
  54          $currentpresets = $DB->count_records('adminpresets');
  55          $currentitems = $DB->count_records('adminpresets_it');
  56          $currentadvitems = $DB->count_records('adminpresets_it_a');
  57  
  58          // Create draft file to import.
  59          $draftid = file_get_unused_draft_itemid();
  60          $filerecord = [
  61              'component' => 'user',
  62              'filearea' => 'draft',
  63              'contextid' => \context_user::instance($USER->id)->id, 'itemid' => $draftid,
  64              'filename' => 'export.xml', 'filepath' => '/'
  65          ];
  66          $fs = get_file_storage();
  67          $fs->create_file_from_string($filerecord, $filecontents);
  68          // Get the data we are submitting for the form and mock submitting it.
  69          $formdata = [
  70              'xmlfile' => $draftid,
  71              'name' => '',
  72              'admin_presets_submit' => 'Save changes',
  73              'sesskey' => sesskey(),
  74          ];
  75          \tool_admin_presets\form\import_form::mock_submit($formdata);
  76  
  77          // Initialise the parameters and create the import class.
  78          $_POST['action'] = 'import';
  79          $_POST['mode'] = 'execute';
  80  
  81          $action = new import();
  82          $sink = $this->redirectEvents();
  83          try {
  84              $action->execute();
  85          } catch (\exception $e) {
  86              // If import action was successfull, redirect should be called so we will encounter an
  87              // 'unsupported redirect error' moodle_exception.
  88              if ($expectedexception) {
  89                  $this->assertInstanceOf($expectedexception, $e);
  90              } else {
  91                  $this->assertInstanceOf(\moodle_exception::class, $e);
  92              }
  93          } finally {
  94              if ($expecteddebugging) {
  95                  $this->assertDebuggingCalled();
  96              }
  97  
  98              if ($expectedpreset) {
  99                  // Check the preset record has been created.
 100                  $presets = $DB->get_records('adminpresets');
 101                  $this->assertCount($currentpresets + 1, $presets);
 102                  $generator = $this->getDataGenerator()->get_plugin_generator('core_adminpresets');
 103                  $presetid = $generator->access_protected($action, 'id');
 104                  $this->assertArrayHasKey($presetid, $presets);
 105                  $preset = $presets[$presetid];
 106                  $this->assertEquals($expectedpresetname, $preset->name);
 107                  $this->assertEquals('http://demo.moodle', $preset->site);
 108                  $this->assertEquals('Ada Lovelace', $preset->author);
 109                  $this->assertEquals(manager::NONCORE_PRESET, $preset->iscore);
 110  
 111                  if ($expectedsettings) {
 112                      // Check the items have been created.
 113                      $items = $DB->get_records('adminpresets_it', ['adminpresetid' => $presetid]);
 114                      $this->assertCount(4, $items);
 115                      $presetitems = [
 116                          'none' => [
 117                              'enablebadges' => 0,
 118                              'enableportfolios' => 1,
 119                              'allowemojipicker' => 1,
 120                          ],
 121                          'mod_lesson' => [
 122                              'mediawidth' => 900,
 123                              'maxanswers' => 2,
 124                          ],
 125                      ];
 126                      foreach ($items as $item) {
 127                          $this->assertArrayHasKey($item->name, $presetitems[$item->plugin]);
 128                          $this->assertEquals($presetitems[$item->plugin][$item->name], $item->value);
 129                      }
 130  
 131                      // Check the advanced attributes have been created.
 132                      $advitems = $DB->get_records('adminpresets_it_a');
 133                      $this->assertCount($currentadvitems + 1, $advitems);
 134                      $advitemfound = false;
 135                      foreach ($advitems as $advitem) {
 136                          if ($advitem->name == 'maxanswers_adv') {
 137                              $this->assertEmpty($advitem->value);
 138                              $advitemfound = true;
 139                          }
 140                      }
 141                      $this->assertTrue($advitemfound);
 142                  }
 143  
 144                  if ($expectedplugins) {
 145                      // Check the plugins have been created.
 146                      $plugins = $DB->get_records('adminpresets_plug', ['adminpresetid' => $presetid]);
 147                      $this->assertCount(6, $plugins);
 148                      $presetplugins = [
 149                          'atto' => [
 150                              'html' => 1,
 151                          ],
 152                          'block' => [
 153                              'html' => 0,
 154                              'activity_modules' => 1,
 155                          ],
 156                          'mod' => [
 157                              'chat' => 0,
 158                              'data' => 0,
 159                              'lesson' => 1,
 160                          ],
 161                      ];
 162                      foreach ($plugins as $plugin) {
 163                          $this->assertArrayHasKey($plugin->name, $presetplugins[$plugin->plugin]);
 164                          $this->assertEquals($presetplugins[$plugin->plugin][$plugin->name], $plugin->enabled);
 165                      }
 166  
 167                  }
 168              } else {
 169                  // Check the preset nor the items are not created.
 170                  $this->assertCount($currentpresets, $DB->get_records('adminpresets'));
 171                  $this->assertCount($currentitems, $DB->get_records('adminpresets_it'));
 172                  $this->assertCount($currentadvitems, $DB->get_records('adminpresets_it_a'));
 173              }
 174  
 175              // Check the export event has been raised.
 176              $events = $sink->get_events();
 177              $sink->close();
 178              $event = reset($events);
 179              if ($expectedpreset) {
 180                  // If preset has been created, an event should be raised.
 181                  $this->assertInstanceOf('\\tool_admin_presets\\event\\preset_imported', $event);
 182              } else {
 183                  $this->assertFalse($event);
 184              }
 185          }
 186      }
 187  
 188      /**
 189       * Data provider for test_import_execute().
 190       *
 191       * @return array
 192       */
 193      public function import_execute_provider(): array {
 194          $fixturesfolder = __DIR__ . '/../../../../../presets/tests/fixtures/';
 195  
 196          return [
 197              'Import settings from an empty file' => [
 198                  'filecontents' => '',
 199                  'expectedpreset' => false,
 200              ],
 201              'Import settings and plugins from a valid XML file' => [
 202                  'filecontents' => file_get_contents($fixturesfolder . 'import_settings_plugins.xml'),
 203                  'expectedpreset' => true,
 204                  'expectedsettings' => true,
 205                  'expectedplugins' => true,
 206              ],
 207              'Import only settings from a valid XML file' => [
 208                  'filecontents' => file_get_contents($fixturesfolder . 'import_settings.xml'),
 209                  'expectedpreset' => true,
 210                  'expectedsettings' => true,
 211                  'expectedplugins' => false,
 212              ],
 213              'Import settings and plugins from a valid XML file with Starter name, which will be marked as non-core' => [
 214                  'filecontents' => file_get_contents($fixturesfolder . 'import_starter_name.xml'),
 215                  'expectedpreset' => true,
 216                  'expectedsettings' => true,
 217                  'expectedplugins' => true,
 218                  'expecteddebugging' => false,
 219                  'expectedexception' => null,
 220                  'expectedpresetname' => 'Starter',
 221              ],
 222              'Import settings from an invalid XML file' => [
 223                  'filecontents' => file_get_contents($fixturesfolder . 'invalid_xml_file.xml'),
 224                  'expectedpreset' => false,
 225                  'expectedsettings' => false,
 226                  'expectedplugins' => false,
 227                  'expecteddebugging' => false,
 228                  'expectedexception' => \Exception::class,
 229              ],
 230              'Import unexisting settings category' => [
 231                  'filecontents' => file_get_contents($fixturesfolder . 'unexisting_category.xml'),
 232                  'expectedpreset' => false,
 233                  'expectedsettings' => false,
 234                  'expectedplugins' => false,
 235              ],
 236              'Import unexisting setting' => [
 237                  'filecontents' => file_get_contents($fixturesfolder . 'unexisting_setting.xml'),
 238                  'expectedpreset' => false,
 239                  'expectedsettings' => false,
 240                  'expectedplugins' => false,
 241                  'expecteddebugging' => true,
 242              ],
 243              'Import valid settings with one unexisting setting too' => [
 244                  'filecontents' => file_get_contents($fixturesfolder . 'import_settings_with_unexisting_setting.xml'),
 245                  'expectedpreset' => true,
 246                  'expectedsettings' => false,
 247                  'expectedplugins' => false,
 248                  'expecteddebugging' => true,
 249              ],
 250          ];
 251      }
 252  }