Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.3.x will end 7 October 2024 (12 months).
  • Bug fixes for security issues in 4.3.x will end 21 April 2025 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.2.x is supported too.

Differences Between: [Versions 310 and 403] [Versions 311 and 403] [Versions 39 and 403] [Versions 400 and 403] [Versions 401 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  declare(strict_types=1);
  18  
  19  namespace core\plugininfo;
  20  
  21  use testable_core_plugin_manager;
  22  use testable_plugininfo_base;
  23  
  24  /**
  25   * Unit tests for plugin base class.
  26   *
  27   * @package   core
  28   * @copyright 2019 Andrew Nicols
  29   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  30   */
  31  class base_test extends \advanced_testcase {
  32  
  33      /**
  34       * Setup to ensure that fixtures are loaded.
  35       */
  36      public static function setUpBeforeClass(): void {
  37          global $CFG;
  38  
  39          require_once($CFG->dirroot.'/lib/tests/fixtures/testable_plugin_manager.php');
  40          require_once($CFG->dirroot.'/lib/tests/fixtures/testable_plugininfo_base.php');
  41      }
  42  
  43      /**
  44       * Tear down the testable plugin manager singleton between tests.
  45       */
  46      public function tearDown(): void {
  47          // The caches of the testable singleton must be reset explicitly. It is
  48          // safer to kill the whole testable singleton at the end of every test.
  49          testable_core_plugin_manager::reset_caches();
  50      }
  51  
  52      /**
  53       * Test the load_disk_version function to check that it handles a variety of invalid supported fields.
  54       *
  55       * @dataProvider load_disk_version_invalid_supported_version_provider
  56       * @param array|null $supported Supported versions to inject
  57       * @param string|int|null $incompatible Incompatible version to inject.
  58       * @param int $version Version to test
  59       */
  60      public function test_load_disk_version_invalid_supported_version($supported, $incompatible, $version): void {
  61          $pluginman = testable_core_plugin_manager::instance();
  62  
  63          // Prepare a fake plugininfo instance.
  64          $plugininfo = new testable_plugininfo_base();
  65          $plugininfo->type = 'fake';
  66          $plugininfo->typerootdir = '/dev/null';
  67          $plugininfo->name = 'example';
  68          $plugininfo->rootdir = '/dev/null/fake';
  69          $plugininfo->pluginman = $pluginman;
  70          $plugininfo->versiondisk = 2015060600;
  71          $plugininfo->supported = $supported;
  72          $plugininfo->incompatible = $incompatible;
  73  
  74          $pluginman->add_fake_plugin_info($plugininfo);
  75  
  76          $this->expectException(\coding_exception::class);
  77          $this->expectExceptionMessage('Incorrect syntax in plugin supported declaration in example');
  78          $plugininfo->load_disk_version();
  79      }
  80  
  81      /**
  82       * Data provider for the load_disk_version tests for testing with invalid supported fields.
  83       *
  84       * @return array
  85       */
  86      public function load_disk_version_invalid_supported_version_provider(): array {
  87          return [
  88              'Invalid supported range.' => [
  89                  'supported' => [31, 29],
  90                  'incompatible' => null,
  91                  'version' => 32,
  92              ],
  93              'Explicit list, low' => [
  94                  'supported' => [29, 30, 31, 32],
  95                  'incompatible' => null,
  96                  'version' => 28,
  97              ],
  98              'Explicit list, high' => [
  99                  'supported' => [29, 30, 31, 32],
 100                  'incompatible' => null,
 101                  'version' => 33,
 102              ],
 103              'Explicit list, in list' => [
 104                  'supported' => [29, 30, 31, 32, 33],
 105                  'incompatible' => null,
 106                  'version' => 31,
 107              ],
 108              'Explicit list, missing value, unsupported' => [
 109                  'supported' => [29, 30, 32],
 110                  'incompatible' => null,
 111                  'version' => 31,
 112              ],
 113              'Explicit list, missing value, supported' => [
 114                  'supported' => [29, 30, 32],
 115                  'incompatible' => null,
 116                  'version' => 30,
 117              ],
 118          ];
 119      }
 120  
 121      /**
 122       * Test the load_disk_version function to check that it handles a variety of invalid incompatible fields.
 123       *
 124       * @dataProvider load_disk_version_invalid_incompatible_version_provider
 125       * @param mixed $incompatible
 126       */
 127      public function test_load_disk_version_invalid_incompatible_version($incompatible): void {
 128          $pluginman = testable_core_plugin_manager::instance();
 129  
 130          // Prepare a fake plugininfo instance.
 131          $plugininfo = new testable_plugininfo_base();
 132          $plugininfo->type = 'fake';
 133          $plugininfo->typerootdir = '/dev/null';
 134          $plugininfo->name = 'example';
 135          $plugininfo->rootdir = '/dev/null/fake';
 136          $plugininfo->pluginman = $pluginman;
 137          $plugininfo->versiondisk = 2015060600;
 138          $plugininfo->incompatible = $incompatible;
 139  
 140          $pluginman->add_fake_plugin_info($plugininfo);
 141  
 142          $this->expectException(\coding_exception::class);
 143          $this->expectExceptionMessage('Incorrect syntax in plugin incompatible declaration in example');
 144          $plugininfo->load_disk_version();
 145      }
 146  
 147      /**
 148       * Data provider for the load_disk_version tests for testing with invalid incompatible fields.
 149       *
 150       * @return array
 151       */
 152      public function load_disk_version_invalid_incompatible_version_provider(): array {
 153          return [
 154              [[38]],
 155              [['38']],
 156              [3.8],
 157              ['3.8'],
 158              [''],
 159              ['somestring'],
 160          ];
 161  
 162      }
 163  
 164      /**
 165       * Test the load_disk_version function to check that it handles a range of correct supported and incompatible field
 166       * definitions.
 167       *
 168       * @dataProvider load_disk_version_branch_supports_provider
 169       * @param array|null $supported Supported versions to inject
 170       * @param string|int|null $incompatible Incompatible version to inject.
 171       * @param int $version Version to test
 172       */
 173      public function test_load_disk_version_branch_supports($supported, $incompatible, $version): void {
 174          $pluginman = testable_core_plugin_manager::instance();
 175  
 176          // Prepare a fake plugininfo instance.
 177          $plugininfo = new testable_plugininfo_base();
 178          $plugininfo->type = 'fake';
 179          $plugininfo->typerootdir = '/dev/null';
 180          $plugininfo->name = 'example';
 181          $plugininfo->rootdir = '/dev/null/fake';
 182          $plugininfo->pluginman = $pluginman;
 183          $plugininfo->versiondisk = 2015060600;
 184          $plugininfo->supported = $supported;
 185          $plugininfo->incompatible = $incompatible;
 186  
 187          $pluginman->add_fake_plugin_info($plugininfo);
 188  
 189          $plugininfo->load_disk_version();
 190  
 191          $this->assertEquals($supported, $plugininfo->supported);
 192          $this->assertEquals($incompatible, $plugininfo->incompatible);
 193      }
 194  
 195      /**
 196       * Test cases for tests of load_disk_version for testing the supported/incompatible fields.
 197       *
 198       * @return array
 199       */
 200      public function load_disk_version_branch_supports_provider(): array {
 201          return [
 202              'Range, branch in support, lowest' => [
 203                  'supported' => [29, 31],
 204                  'incompatible' => null,
 205                  'version' => 29,
 206              ],
 207              'Range, branch in support, mid' => [
 208                  'supported' => [29, 31],
 209                  'incompatible' => null,
 210                  'version' => 30,
 211              ],
 212              'Range, branch in support, highest' => [
 213                  'supported' => [29, 31],
 214                  'incompatible' => null,
 215                  'version' => 31,
 216              ],
 217  
 218              'Range, branch not in support, high' => [
 219                  'supported' => [29, 31],
 220                  'incompatible' => null,
 221                  'version' => 32,
 222              ],
 223              'Range, branch not in support, low' => [
 224                  'supported' => [29, 31],
 225                  'incompatible' => null,
 226                  'version' => 28,
 227              ],
 228              'Range, incompatible, high.' => [
 229                  'supported' => [29, 31],
 230                  'incompatible' => 32,
 231                  'version' => 33,
 232              ],
 233              'Range, incompatible, low.' => [
 234                  'supported' => [29, 31],
 235                  'incompatible' => 32,
 236                  'version' => 31,
 237              ],
 238              'Range, incompatible, equal.' => [
 239                  'supported' => [29, 31],
 240                  'incompatible' => 32,
 241                  'version' => 32,
 242              ],
 243              'No supports' => [
 244                  'supported' => null,
 245                  'incompatible' => null,
 246                  'version' => 32,
 247              ],
 248              'No supports, but incompatible, older' => [
 249                  'supported' => null,
 250                  'incompatible' => 30,
 251                  'version' => 32,
 252              ],
 253              'No supports, but incompatible, equal' => [
 254                  'supported' => null,
 255                  'incompatible' => 32,
 256                  'version' => 32,
 257              ],
 258              'No supports, but incompatible, newer' => [
 259                  'supported' => null,
 260                  'incompatible' => 34,
 261                  'version' => 32,
 262              ],
 263              'String incompatible' => [
 264                  'supported' => null,
 265                  'incompatible' => '34',
 266                  'version' => 32,
 267              ],
 268              'Empty incompatible' => [
 269                  'supported' => null,
 270                  'incompatible' => null,
 271                  'version' => 32,
 272              ],
 273          ];
 274      }
 275  
 276      /**
 277       * Ensure that plugintype_supports_ordering() returns true.
 278       * @covers ::plugintype_supports_ordering
 279       */
 280      public function test_plugintype_supports_ordering(): void {
 281          $this->assertFalse(base::plugintype_supports_ordering());
 282      }
 283  
 284      /**
 285       * Ensure that the base implementation is used for plugins not supporting ordering.
 286       *
 287       * @dataProvider plugins_not_supporting_ordering
 288       * @param string $plugin
 289       * @coversNothing
 290       *
 291       * Note: This test cannot declare coverage because it covers the various plugin implementations.
 292       */
 293      public function test_get_sorted_plugins(
 294          string $plugin,
 295      ): void {
 296          [$plugintype, $pluginname] = explode('_', $plugin, 2);
 297          $classname = \core_plugin_manager::resolve_plugininfo_class($plugintype);
 298  
 299          $this->assertFalse($classname::plugintype_supports_ordering());
 300  
 301          $this->assertNull($classname::get_sorted_plugins());
 302          $this->assertNull($classname::get_sorted_plugins(true));
 303          $this->assertNull($classname::get_sorted_plugins(false));
 304  
 305          $this->assertFalse($classname::change_plugin_order($pluginname, base::MOVE_UP));
 306          $this->assertFalse($classname::change_plugin_order($pluginname, base::MOVE_DOWN));
 307      }
 308  
 309      /**
 310       * Data provider for plugins_not_supporting_ordering.
 311       *
 312       * @return string[]
 313       */
 314      public function plugins_not_supporting_ordering(): array {
 315          return [
 316              ['mod_assign'],
 317              ['block_login'],
 318          ];
 319      }
 320  }