Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.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 core\output;
  18  
  19  /**
  20   * Unit tests for lib/classes/output/mustache_template_finder.php
  21   *
  22   * Unit tests for the Mustache template finder class (contains logic about
  23   * resolving mustache template locations.
  24   *
  25   * @package   core
  26   * @category  test
  27   * @copyright 2015 Damyon Wiese
  28   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  29   */
  30  class mustache_template_finder_test extends \advanced_testcase {
  31  
  32      /**
  33       * Data provider which reutrns a set of valid template directories to be used when testing
  34       * get_template_directories_for_component.
  35       *
  36       * @return array
  37       */
  38      public function valid_template_directories_provider(): array {
  39          return [
  40              'plugin: mod_assign' => [
  41                  'component' => 'mod_assign',
  42                  'theme' => '',
  43                  'paths' => [
  44                      'theme/boost/templates/mod_assign/',
  45                      'mod/assign/templates/'
  46                  ],
  47              ],
  48              'plugin: mod_assign with classic' => [
  49                  'component' => 'mod_assign',
  50                  'theme' => 'classic',
  51                  'paths' => [
  52                      'theme/classic/templates/mod_assign/',
  53                      'theme/boost/templates/mod_assign/',
  54                      'mod/assign/templates/'
  55                  ],
  56              ],
  57              'subsystem: core_user' => [
  58                  'component' => 'core_user',
  59                  'theme' => 'classic',
  60                  'paths' => [
  61                      'theme/classic/templates/core_user/',
  62                      'theme/boost/templates/core_user/',
  63                      'user/templates/'
  64                  ],
  65              ],
  66              'core' => [
  67                  'component' => 'core',
  68                  'theme' => 'classic',
  69                  'paths' => [
  70                      'theme/classic/templates/core/',
  71                      'theme/boost/templates/core/',
  72                      'lib/templates/'
  73                  ],
  74              ],
  75          ];
  76      }
  77  
  78      /**
  79       * Tests for get_template_directories_for_component.
  80       *
  81       * @dataProvider valid_template_directories_provider
  82       * @param   string $component
  83       * @param   string $theme
  84       * @param   array $paths
  85       */
  86      public function test_get_template_directories_for_component(string $component, string $theme, array $paths): void {
  87          global $CFG;
  88  
  89          // Test a plugin.
  90          $dirs = mustache_template_finder::get_template_directories_for_component($component, $theme, $paths);
  91  
  92          $correct = array_map(function($path) use ($CFG) {
  93              return implode('/', [$CFG->dirroot, $path]);
  94          }, $paths);
  95  
  96          $this->assertEquals($correct, $dirs);
  97      }
  98  
  99      /**
 100       * Tests for get_template_directories_for_component when dealing with an invalid component.
 101       */
 102      public function test_invalid_component_get_template_directories_for_component() {
 103          // Test something invalid.
 104          $this->expectException(\coding_exception::class);
 105          mustache_template_finder::get_template_directories_for_component('octopus', 'classic');
 106      }
 107  
 108      /**
 109       * Data provider which reutrns a set of valid template directories to be used when testing
 110       * get_template_directories_for_component.
 111       *
 112       * @return array
 113       */
 114      public function valid_template_filepath_provider(): array {
 115          return [
 116              'Standard core template' => [
 117                  'template' => 'core/modal',
 118                  'theme' => '',
 119                  'location' => 'lib/templates/modal.mustache',
 120              ],
 121              'Template overridden by theme' => [
 122                  'template' => 'core_form/element-float-inline',
 123                  'theme' => '',
 124                  'location' => 'theme/boost/templates/core_form/element-float-inline.mustache',
 125              ],
 126              'Template overridden by theme but child theme selected' => [
 127                  'template' => 'core_form/element-float-inline',
 128                  'theme' => 'classic',
 129                  'location' => 'theme/boost/templates/core_form/element-float-inline.mustache',
 130              ],
 131              'Template overridden by child theme' => [
 132                  'template' => 'core/full_header',
 133                  'theme' => 'classic',
 134                  'location' => 'theme/classic/templates/core/full_header.mustache',
 135              ],
 136              'Template overridden by child theme but tested against defualt theme' => [
 137                  'template' => 'core/full_header',
 138                  'theme' => '',
 139                  'location' => 'lib/templates/full_header.mustache',
 140              ],
 141              'Standard plugin template' => [
 142                  'template' => 'mod_assign/grading_panel',
 143                  'theme' => '',
 144                  'location' => 'mod/assign/templates/grading_panel.mustache',
 145              ],
 146              'Subsystem template' => [
 147                  'template' => 'core_user/status_details',
 148                  'theme' => '',
 149                  'location' => 'user/templates/status_details.mustache',
 150              ],
 151              'Theme own template' => [
 152                  'template' => 'theme_classic/columns',
 153                  'theme' => '',
 154                  'location' => 'theme/classic/templates/columns.mustache',
 155              ],
 156              'Theme overridden template against that theme' => [
 157                  'template' => 'theme_classic/navbar',
 158                  'theme' => 'classic',
 159                  'location' => 'theme/classic/templates/navbar.mustache',
 160              ],
 161              // Note: This one looks strange but is correct. It is legitimate to request theme's component template in
 162              // the context of another theme. For example, this is used by child themes making use of parent theme
 163              // templates.
 164              'Theme overridden template against the default theme' => [
 165                  'template' => 'theme_classic/navbar',
 166                  'theme' => '',
 167                  'location' => 'theme/classic/templates/navbar.mustache',
 168              ],
 169          ];
 170      }
 171  
 172      /**
 173       * Tests for get_template_filepath.
 174       *
 175       * @dataProvider valid_template_filepath_provider
 176       * @param   string $template
 177       * @param   string $theme
 178       * @param   string $location
 179       */
 180      public function test_get_template_filepath(string $template, string $theme, string $location) {
 181          global $CFG;
 182  
 183          $filename = mustache_template_finder::get_template_filepath($template, $theme);
 184          $this->assertEquals("{$CFG->dirroot}/{$location}", $filename);
 185      }
 186  
 187      /**
 188       * Tests for get_template_filepath when dealing with an invalid component.
 189       */
 190      public function test_invalid_component_get_template_filepath() {
 191          $this->expectException(\moodle_exception::class);
 192          mustache_template_finder::get_template_filepath('core/octopus', 'classic');
 193      }
 194  }