Search moodle.org's
Developer Documentation


  • Bug fixes for general core bugs in 2.8.x ended 9 November 2015 (12 months).
  • Bug fixes for security issues in 2.8.x ended 9 May 2016 (18 months).
  • minimum PHP 5.4.4 (always use latest PHP 5.4.x or 5.5.x on Windows - http://windows.php.net/download/), PHP 7 is NOT supported
  • Differences Between: [Versions 28 and 29] [Versions 28 and 30] [Versions 28 and 31] [Versions 28 and 32] [Versions 28 and 33] [Versions 28 and 34] [Versions 28 and 35] [Versions 28 and 36] [Versions 28 and 37]

       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   * core_component related tests.
      19   *
      20   * @package    core
      21   * @category   phpunit
      22   * @copyright  2013 Petr Skoda {@link http://skodak.org}
      23   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
      24   */
      25  
      26  defined('MOODLE_INTERNAL') || die();
      27  
      28  
      29  /**
      30   * Class core_component_testcase.
      31   */
      32  class core_component_testcase extends advanced_testcase {
      33  
      34      // To be changed if number of subsystems increases/decreases,
      35      // this is defined here to annoy devs that try to add more without any thinking,
      36      // always verify that it does not collide with any existing add-on modules and subplugins!!!
      37      const SUBSYSTEMCOUNT = 62;
      38  
      39      public function test_get_core_subsystems() {
      40          global $CFG;
      41  
      42          $subsystems = core_component::get_core_subsystems();
      43  
      44          $this->assertCount(self::SUBSYSTEMCOUNT, $subsystems, 'Oh, somebody added or removed a core subsystem, think twice before doing that!');
      45  
      46          // Make sure all paths are full/null, exist and are inside dirroot.
      47          foreach ($subsystems as $subsystem => $fulldir) {
      48              $this->assertFalse(strpos($subsystem, '_'), 'Core subsystems must be one work without underscores');
      49              if ($fulldir === null) {
      50                  if ($subsystem === 'filepicker' or $subsystem === 'help') {
      51                      // Arrgghh, let's not introduce more subsystems for no real reason...
      52                  } else {
      53                      // Lang strings.
      54                      $this->assertFileExists("$CFG->dirroot/lang/en/$subsystem.php", 'Core subsystems without fulldir are usually used for lang strings.');
      55                  }
      56                  continue;
      57              }
      58              $this->assertFileExists($fulldir);
      59              // Check that base uses realpath() separators and "/" in the subdirs.
      60              $this->assertStringStartsWith($CFG->dirroot.'/', $fulldir);
      61              $reldir = substr($fulldir, strlen($CFG->dirroot)+1);
      62              $this->assertFalse(strpos($reldir, '\\'));
      63          }
      64  
      65          // Make sure all core language files are also subsystems!
      66          $items = new DirectoryIterator("$CFG->dirroot/lang/en");
      67          foreach ($items as $item) {
      68              if ($item->isDot() or $item->isDir()) {
      69                  continue;
      70              }
      71              $file = $item->getFilename();
      72              if ($file === 'moodle.php') {
      73                  // Do not add new lang strings unless really necessary!!!
      74                  continue;
      75              }
      76  
      77              if (substr($file, -4) !== '.php') {
      78                  continue;
      79              }
      80              $file = substr($file, 0, strlen($file)-4);
      81              $this->assertArrayHasKey($file, $subsystems, 'All core lang files should be subsystems, think twice before adding anything!');
      82          }
      83          unset($item);
      84          unset($items);
      85  
      86      }
      87  
      88      public function test_deprecated_get_core_subsystems() {
      89          global $CFG;
      90  
      91          $subsystems = core_component::get_core_subsystems();
      92  
      93          $this->assertSame($subsystems, get_core_subsystems(true));
      94  
      95          $realsubsystems = get_core_subsystems();
      96          $this->assertDebuggingCalled();
      97          $this->assertSame($realsubsystems, get_core_subsystems(false));
      98          $this->assertDebuggingCalled();
      99  
     100          $this->assertEquals(count($subsystems), count($realsubsystems));
     101  
     102          foreach ($subsystems as $subsystem => $fulldir) {
     103              $this->assertArrayHasKey($subsystem, $realsubsystems);
     104              if ($fulldir === null) {
     105                  $this->assertNull($realsubsystems[$subsystem]);
     106                  continue;
     107              }
     108              $this->assertSame($fulldir, $CFG->dirroot.'/'.$realsubsystems[$subsystem]);
     109          }
     110      }
     111  
     112      public function test_get_plugin_types() {
     113          global $CFG;
     114  
     115          $this->assertTrue(empty($CFG->themedir), 'Non-empty $CFG->themedir is not covered by any tests yet, you need to disable it.');
     116  
     117          $plugintypes = core_component::get_plugin_types();
     118  
     119          foreach ($plugintypes as $plugintype => $fulldir) {
     120              $this->assertStringStartsWith("$CFG->dirroot/", $fulldir);
     121          }
     122      }
     123  
     124      public function test_deprecated_get_plugin_types() {
     125          global $CFG;
     126  
     127          $plugintypes = core_component::get_plugin_types();
     128  
     129          $this->assertSame($plugintypes, get_plugin_types());
     130          $this->assertSame($plugintypes, get_plugin_types(true));
     131  
     132          $realplugintypes = get_plugin_types(false);
     133          $this->assertDebuggingCalled();
     134  
     135          foreach ($plugintypes as $plugintype => $fulldir) {
     136              $this->assertSame($fulldir, $CFG->dirroot.'/'.$realplugintypes[$plugintype]);
     137          }
     138      }
     139  
     140      public function test_get_plugin_list() {
     141          global $CFG;
     142  
     143          $plugintypes = core_component::get_plugin_types();
     144  
     145          foreach ($plugintypes as $plugintype => $fulldir) {
     146              $plugins = core_component::get_plugin_list($plugintype);
     147              foreach ($plugins as $pluginname => $plugindir) {
     148                  $this->assertStringStartsWith("$CFG->dirroot/", $plugindir);
     149              }
     150              if ($plugintype !== 'auth') {
     151                  // Let's crosscheck it with independent implementation (auth/db is an exception).
     152                  $reldir = substr($fulldir, strlen($CFG->dirroot)+1);
     153                  $dirs = get_list_of_plugins($reldir);
     154                  $dirs = array_values($dirs);
     155                  $this->assertDebuggingCalled();
     156                  $this->assertSame($dirs, array_keys($plugins));
     157              }
     158          }
     159      }
     160  
     161      public function test_deprecated_get_plugin_list() {
     162          $plugintypes = core_component::get_plugin_types();
     163  
     164          foreach ($plugintypes as $plugintype => $fulldir) {
     165              $plugins = core_component::get_plugin_list($plugintype);
     166              $this->assertSame($plugins, get_plugin_list($plugintype));
     167          }
     168      }
     169  
     170      public function test_get_plugin_directory() {
     171          $plugintypes = core_component::get_plugin_types();
     172  
     173          foreach ($plugintypes as $plugintype => $fulldir) {
     174              $plugins = core_component::get_plugin_list($plugintype);
     175              foreach ($plugins as $pluginname => $plugindir) {
     176                  $this->assertSame($plugindir, core_component::get_plugin_directory($plugintype, $pluginname));
     177              }
     178          }
     179      }
     180  
     181      public function test_deprecated_get_plugin_directory() {
     182          $plugintypes = core_component::get_plugin_types();
     183  
     184          foreach ($plugintypes as $plugintype => $fulldir) {
     185              $plugins = core_component::get_plugin_list($plugintype);
     186              foreach ($plugins as $pluginname => $plugindir) {
     187                  $this->assertSame(core_component::get_plugin_directory($plugintype, $pluginname), get_plugin_directory($plugintype, $pluginname));
     188              }
     189          }
     190      }
     191  
     192      public function test_get_subsystem_directory() {
     193          $subsystems = core_component::get_core_subsystems();
     194          foreach ($subsystems as $subsystem => $fulldir) {
     195              $this->assertSame($fulldir, core_component::get_subsystem_directory($subsystem));
     196          }
     197      }
     198  
     199      public function test_is_valid_plugin_name() {
     200          $this->assertTrue(core_component::is_valid_plugin_name('mod', 'example1'));
     201          $this->assertTrue(core_component::is_valid_plugin_name('mod', 'feedback360'));
     202          $this->assertFalse(core_component::is_valid_plugin_name('mod', 'feedback_360'));
     203          $this->assertFalse(core_component::is_valid_plugin_name('mod', '2feedback'));
     204          $this->assertFalse(core_component::is_valid_plugin_name('mod', '1example'));
     205          $this->assertFalse(core_component::is_valid_plugin_name('mod', 'example.xx'));
     206          $this->assertFalse(core_component::is_valid_plugin_name('mod', '.example'));
     207          $this->assertFalse(core_component::is_valid_plugin_name('mod', '_example'));
     208          $this->assertFalse(core_component::is_valid_plugin_name('mod', 'example_'));
     209          $this->assertFalse(core_component::is_valid_plugin_name('mod', 'example_x1'));
     210          $this->assertFalse(core_component::is_valid_plugin_name('mod', 'example-x1'));
     211          $this->assertFalse(core_component::is_valid_plugin_name('mod', 'role'));
     212  
     213          $this->assertTrue(core_component::is_valid_plugin_name('tool', 'example1'));
     214          $this->assertTrue(core_component::is_valid_plugin_name('tool', 'example_x1'));
     215          $this->assertTrue(core_component::is_valid_plugin_name('tool', 'example_x1_xxx'));
     216          $this->assertTrue(core_component::is_valid_plugin_name('tool', 'feedback360'));
     217          $this->assertTrue(core_component::is_valid_plugin_name('tool', 'feed_back360'));
     218          $this->assertTrue(core_component::is_valid_plugin_name('tool', 'role'));
     219          $this->assertFalse(core_component::is_valid_plugin_name('tool', '1example'));
     220          $this->assertFalse(core_component::is_valid_plugin_name('tool', 'example.xx'));
     221          $this->assertFalse(core_component::is_valid_plugin_name('tool', 'example-xx'));
     222          $this->assertFalse(core_component::is_valid_plugin_name('tool', '.example'));
     223          $this->assertFalse(core_component::is_valid_plugin_name('tool', '_example'));
     224          $this->assertFalse(core_component::is_valid_plugin_name('tool', 'example_'));
     225          $this->assertFalse(core_component::is_valid_plugin_name('tool', 'example__x1'));
     226      }
     227  
     228      public function test_normalize_componentname() {
     229          // Moodle core.
     230          $this->assertSame('core', core_component::normalize_componentname('core'));
     231          $this->assertSame('core', core_component::normalize_componentname('moodle'));
     232          $this->assertSame('core', core_component::normalize_componentname(''));
     233  
     234          // Moodle core subsystems.
     235          $this->assertSame('core_admin', core_component::normalize_componentname('admin'));
     236          $this->assertSame('core_admin', core_component::normalize_componentname('core_admin'));
     237          $this->assertSame('core_admin', core_component::normalize_componentname('moodle_admin'));
     238  
     239          // Activity modules and their subplugins.
     240          $this->assertSame('mod_workshop', core_component::normalize_componentname('workshop'));
     241          $this->assertSame('mod_workshop', core_component::normalize_componentname('mod_workshop'));
     242          $this->assertSame('workshopform_accumulative', core_component::normalize_componentname('workshopform_accumulative'));
     243          $this->assertSame('mod_quiz', core_component::normalize_componentname('quiz'));
     244          $this->assertSame('quiz_grading', core_component::normalize_componentname('quiz_grading'));
     245          $this->assertSame('mod_data', core_component::normalize_componentname('data'));
     246          $this->assertSame('datafield_checkbox', core_component::normalize_componentname('datafield_checkbox'));
     247  
     248          // Other plugin types.
     249          $this->assertSame('auth_mnet', core_component::normalize_componentname('auth_mnet'));
     250          $this->assertSame('enrol_self', core_component::normalize_componentname('enrol_self'));
     251          $this->assertSame('block_html', core_component::normalize_componentname('block_html'));
     252          $this->assertSame('block_mnet_hosts', core_component::normalize_componentname('block_mnet_hosts'));
     253          $this->assertSame('local_amos', core_component::normalize_componentname('local_amos'));
     254          $this->assertSame('local_admin', core_component::normalize_componentname('local_admin'));
     255  
     256          // Unknown words without underscore are supposed to be activity modules.
     257          $this->assertSame('mod_whoonearthwouldcomewithsuchastupidnameofcomponent',
     258              core_component::normalize_componentname('whoonearthwouldcomewithsuchastupidnameofcomponent'));
     259          // Module names can not contain underscores, this must be a subplugin.
     260          $this->assertSame('whoonearth_wouldcomewithsuchastupidnameofcomponent',
     261              core_component::normalize_componentname('whoonearth_wouldcomewithsuchastupidnameofcomponent'));
     262          $this->assertSame('whoonearth_would_come_withsuchastupidnameofcomponent',
     263              core_component::normalize_componentname('whoonearth_would_come_withsuchastupidnameofcomponent'));
     264      }
     265  
     266      public function test_normalize_component() {
     267          // Moodle core.
     268          $this->assertSame(array('core', null), core_component::normalize_component('core'));
     269          $this->assertSame(array('core', null), core_component::normalize_component('moodle'));
     270          $this->assertSame(array('core', null), core_component::normalize_component(''));
     271  
     272          // Moodle core subsystems.
     273          $this->assertSame(array('core', 'admin'), core_component::normalize_component('admin'));
     274          $this->assertSame(array('core', 'admin'), core_component::normalize_component('core_admin'));
     275          $this->assertSame(array('core', 'admin'), core_component::normalize_component('moodle_admin'));
     276  
     277          // Activity modules and their subplugins.
     278          $this->assertSame(array('mod', 'workshop'), core_component::normalize_component('workshop'));
     279          $this->assertSame(array('mod', 'workshop'), core_component::normalize_component('mod_workshop'));
     280          $this->assertSame(array('workshopform', 'accumulative'), core_component::normalize_component('workshopform_accumulative'));
     281          $this->assertSame(array('mod', 'quiz'), core_component::normalize_component('quiz'));
     282          $this->assertSame(array('quiz', 'grading'), core_component::normalize_component('quiz_grading'));
     283          $this->assertSame(array('mod', 'data'), core_component::normalize_component('data'));
     284          $this->assertSame(array('datafield', 'checkbox'), core_component::normalize_component('datafield_checkbox'));
     285  
     286          // Other plugin types.
     287          $this->assertSame(array('auth', 'mnet'), core_component::normalize_component('auth_mnet'));
     288          $this->assertSame(array('enrol', 'self'), core_component::normalize_component('enrol_self'));
     289          $this->assertSame(array('block', 'html'), core_component::normalize_component('block_html'));
     290          $this->assertSame(array('block', 'mnet_hosts'), core_component::normalize_component('block_mnet_hosts'));
     291          $this->assertSame(array('local', 'amos'), core_component::normalize_component('local_amos'));
     292          $this->assertSame(array('local', 'admin'), core_component::normalize_component('local_admin'));
     293  
     294          // Unknown words without underscore are supposed to be activity modules.
     295          $this->assertSame(array('mod', 'whoonearthwouldcomewithsuchastupidnameofcomponent'),
     296              core_component::normalize_component('whoonearthwouldcomewithsuchastupidnameofcomponent'));
     297          // Module names can not contain underscores, this must be a subplugin.
     298          $this->assertSame(array('whoonearth', 'wouldcomewithsuchastupidnameofcomponent'),
     299              core_component::normalize_component('whoonearth_wouldcomewithsuchastupidnameofcomponent'));
     300          $this->assertSame(array('whoonearth', 'would_come_withsuchastupidnameofcomponent'),
     301              core_component::normalize_component('whoonearth_would_come_withsuchastupidnameofcomponent'));
     302      }
     303  
     304      public function test_deprecated_normalize_component() {
     305          // Moodle core.
     306          $this->assertSame(array('core', null), normalize_component('core'));
     307          $this->assertSame(array('core', null), normalize_component(''));
     308          $this->assertSame(array('core', null), normalize_component('moodle'));
     309  
     310          // Moodle core subsystems.
     311          $this->assertSame(array('core', 'admin'), normalize_component('admin'));
     312          $this->assertSame(array('core', 'admin'), normalize_component('core_admin'));
     313          $this->assertSame(array('core', 'admin'), normalize_component('moodle_admin'));
     314  
     315          // Activity modules and their subplugins.
     316          $this->assertSame(array('mod', 'workshop'), normalize_component('workshop'));
     317          $this->assertSame(array('mod', 'workshop'), normalize_component('mod_workshop'));
     318          $this->assertSame(array('workshopform', 'accumulative'), normalize_component('workshopform_accumulative'));
     319          $this->assertSame(array('mod', 'quiz'), normalize_component('quiz'));
     320          $this->assertSame(array('quiz', 'grading'), normalize_component('quiz_grading'));
     321          $this->assertSame(array('mod', 'data'), normalize_component('data'));
     322          $this->assertSame(array('datafield', 'checkbox'), normalize_component('datafield_checkbox'));
     323  
     324          // Other plugin types.
     325          $this->assertSame(array('auth', 'mnet'), normalize_component('auth_mnet'));
     326          $this->assertSame(array('enrol', 'self'), normalize_component('enrol_self'));
     327          $this->assertSame(array('block', 'html'), normalize_component('block_html'));
     328          $this->assertSame(array('block', 'mnet_hosts'), normalize_component('block_mnet_hosts'));
     329          $this->assertSame(array('local', 'amos'), normalize_component('local_amos'));
     330          $this->assertSame(array('local', 'admin'), normalize_component('local_admin'));
     331  
     332          // Unknown words without underscore are supposed to be activity modules.
     333          $this->assertSame(array('mod', 'whoonearthwouldcomewithsuchastupidnameofcomponent'),
     334              normalize_component('whoonearthwouldcomewithsuchastupidnameofcomponent'));
     335          // Module names can not contain underscores, this must be a subplugin.
     336          $this->assertSame(array('whoonearth', 'wouldcomewithsuchastupidnameofcomponent'),
     337              normalize_component('whoonearth_wouldcomewithsuchastupidnameofcomponent'));
     338          $this->assertSame(array('whoonearth', 'would_come_withsuchastupidnameofcomponent'),
     339              normalize_component('whoonearth_would_come_withsuchastupidnameofcomponent'));
     340      }
     341  
     342      public function test_get_component_directory() {
     343          $plugintypes = core_component::get_plugin_types();
     344          foreach ($plugintypes as $plugintype => $fulldir) {
     345              $plugins = core_component::get_plugin_list($plugintype);
     346              foreach ($plugins as $pluginname => $plugindir) {
     347                  $this->assertSame($plugindir, core_component::get_component_directory(($plugintype.'_'.$pluginname)));
     348              }
     349          }
     350  
     351          $subsystems = core_component::get_core_subsystems();
     352          foreach ($subsystems as $subsystem => $fulldir) {
     353              $this->assertSame($fulldir, core_component::get_component_directory(('core_'.$subsystem)));
     354          }
     355      }
     356  
     357      public function test_deprecated_get_component_directory() {
     358          $plugintypes = core_component::get_plugin_types();
     359          foreach ($plugintypes as $plugintype => $fulldir) {
     360              $plugins = core_component::get_plugin_list($plugintype);
     361              foreach ($plugins as $pluginname => $plugindir) {
     362                  $this->assertSame($plugindir, get_component_directory(($plugintype.'_'.$pluginname)));
     363              }
     364          }
     365  
     366          $subsystems = core_component::get_core_subsystems();
     367          foreach ($subsystems as $subsystem => $fulldir) {
     368              $this->assertSame($fulldir, get_component_directory(('core_'.$subsystem)));
     369          }
     370      }
     371  
     372      public function test_get_subtype_parent() {
     373          global $CFG;
     374  
     375          $this->assertNull(core_component::get_subtype_parent('mod'));
     376  
     377          // Any plugin with more subtypes is ok here.
     378          $this->assertFileExists("$CFG->dirroot/mod/assign/db/subplugins.php");
     379          $this->assertSame('mod_assign', core_component::get_subtype_parent('assignsubmission'));
     380          $this->assertSame('mod_assign', core_component::get_subtype_parent('assignfeedback'));
     381          $this->assertNull(core_component::get_subtype_parent('assignxxxxx'));
     382      }
     383  
     384      public function test_get_subplugins() {
     385          global $CFG;
     386  
     387          // Any plugin with more subtypes is ok here.
     388          $this->assertFileExists("$CFG->dirroot/mod/assign/db/subplugins.php");
     389  
     390          $subplugins = core_component::get_subplugins('mod_assign');
     391          $this->assertSame(array('assignsubmission', 'assignfeedback'), array_keys($subplugins));
     392  
     393          $subs = core_component::get_plugin_list('assignsubmission');
     394          $feeds = core_component::get_plugin_list('assignfeedback');
     395  
     396          $this->assertSame(array_keys($subs), $subplugins['assignsubmission']);
     397          $this->assertSame(array_keys($feeds), $subplugins['assignfeedback']);
     398  
     399          // Any plugin without subtypes is ok here.
     400          $this->assertFileExists("$CFG->dirroot/mod/choice");
     401          $this->assertFileNotExists("$CFG->dirroot/mod/choice/db/subplugins.php");
     402  
     403          $this->assertNull(core_component::get_subplugins('mod_choice'));
     404  
     405          $this->assertNull(core_component::get_subplugins('xxxx_yyyy'));
     406      }
     407  
     408      public function test_get_plugin_types_with_subplugins() {
     409          global $CFG;
     410  
     411          $types = core_component::get_plugin_types_with_subplugins();
     412  
     413          // Hardcode it here to detect if anybody hacks the code to include more subplugin types.
     414          $expected = array(
     415              'mod' => "$CFG->dirroot/mod",
     416              'editor' => "$CFG->dirroot/lib/editor",
     417              'tool' => "$CFG->dirroot/$CFG->admin/tool",
     418              'local' => "$CFG->dirroot/local",
     419          );
     420  
     421          $this->assertSame($expected, $types);
     422  
     423      }
     424  
     425      public function test_get_plugin_list_with_file() {
     426          $this->resetAfterTest(true);
     427  
     428          // No extra reset here because core_component reset automatically.
     429  
     430          $expected = array();
     431          $reports = core_component::get_plugin_list('report');
     432          foreach ($reports as $name => $fulldir) {
     433              if (file_exists("$fulldir/lib.php")) {
     434                  $expected[] = $name;
     435              }
     436          }
     437  
     438          // Test cold.
     439          $list = core_component::get_plugin_list_with_file('report', 'lib.php', false);
     440          $this->assertEquals($expected, array_keys($list));
     441  
     442          // Test hot.
     443          $list = core_component::get_plugin_list_with_file('report', 'lib.php', false);
     444          $this->assertEquals($expected, array_keys($list));
     445  
     446          // Test with include.
     447          $list = core_component::get_plugin_list_with_file('report', 'lib.php', true);
     448          $this->assertEquals($expected, array_keys($list));
     449  
     450          // Test missing.
     451          $list = core_component::get_plugin_list_with_file('report', 'idontexist.php', true);
     452          $this->assertEquals(array(), array_keys($list));
     453      }
     454  }
    

    Search This Site: