| 1 | efrain | 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 |  * Provides testable_core_plugin_manager class.
 | 
        
           |  |  | 19 |  *
 | 
        
           |  |  | 20 |  * @package     core
 | 
        
           |  |  | 21 |  * @category    test
 | 
        
           |  |  | 22 |  * @copyright   2015 David Mudrak <david@moodle.com>
 | 
        
           |  |  | 23 |  * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 | 
        
           |  |  | 24 |  */
 | 
        
           |  |  | 25 |   | 
        
           |  |  | 26 | defined('MOODLE_INTERNAL') || die();
 | 
        
           |  |  | 27 |   | 
        
           |  |  | 28 | require_once(__DIR__.'/testable_update_api.php');
 | 
        
           |  |  | 29 |   | 
        
           |  |  | 30 | /**
 | 
        
           |  |  | 31 |  * Testable variant of the core_plugin_manager
 | 
        
           |  |  | 32 |  *
 | 
        
           |  |  | 33 |  * @copyright 2015 David Mudrak <david@moodle.com>
 | 
        
           |  |  | 34 |  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 | 
        
           |  |  | 35 |  */
 | 
        
           |  |  | 36 | class testable_core_plugin_manager extends core_plugin_manager {
 | 
        
           |  |  | 37 |   | 
        
           |  |  | 38 |     /** @var testable_core_plugin_manager holds the singleton instance */
 | 
        
           |  |  | 39 |     protected static $singletoninstance;
 | 
        
           |  |  | 40 |   | 
        
           |  |  | 41 |     /**
 | 
        
           |  |  | 42 |      * Allows us to inject items directly into the plugins info tree.
 | 
        
           |  |  | 43 |      *
 | 
        
           |  |  | 44 |      * Do not forget to call our reset_caches() after using this method to force a new
 | 
        
           |  |  | 45 |      * singleton instance.
 | 
        
           |  |  | 46 |      *
 | 
        
           |  |  | 47 |      * @param string $type plugin type
 | 
        
           |  |  | 48 |      * @param string $name plugin name
 | 
        
           |  |  | 49 |      * @param \core\plugininfo\base $plugininfo plugin info class
 | 
        
           |  |  | 50 |      */
 | 
        
           |  |  | 51 |     public function inject_testable_plugininfo($type, $name, \core\plugininfo\base $plugininfo) {
 | 
        
           |  |  | 52 |   | 
        
           |  |  | 53 |         // Let the parent initialize the ->pluginsinfo tree.
 | 
        
           |  |  | 54 |         parent::get_plugins();
 | 
        
           |  |  | 55 |   | 
        
           |  |  | 56 |         // Inject the additional plugin info.
 | 
        
           |  |  | 57 |         $this->pluginsinfo[$type][$name] = $plugininfo;
 | 
        
           |  |  | 58 |     }
 | 
        
           |  |  | 59 |   | 
        
           |  |  | 60 |     /**
 | 
        
           |  |  | 61 |      * Returns testable subclass of the client.
 | 
        
           |  |  | 62 |      *
 | 
        
           |  |  | 63 |      * @return \core\update\testable_api
 | 
        
           |  |  | 64 |      */
 | 
        
           |  |  | 65 |     protected function get_update_api_client() {
 | 
        
           |  |  | 66 |         return \core\update\testable_api::client();
 | 
        
           |  |  | 67 |     }
 | 
        
           |  |  | 68 |   | 
        
           |  |  | 69 |     /**
 | 
        
           |  |  | 70 |      * Mockup implementation of loading available updates info.
 | 
        
           |  |  | 71 |      *
 | 
        
           |  |  | 72 |      * This testable implementation does not actually use
 | 
        
           |  |  | 73 |      * {@link \core\update\checker}. Instead, it provides hard-coded list of
 | 
        
           |  |  | 74 |      * fictional available updates for our foo_bar plugin.
 | 
        
           |  |  | 75 |      *
 | 
        
           |  |  | 76 |      * Note there is a difference in the behaviour as the actual update API
 | 
        
           |  |  | 77 |      * does not return info of lower version than requested. To mock up well,
 | 
        
           |  |  | 78 |      * make sure the injected foo_bar testable plugin info has version lower
 | 
        
           |  |  | 79 |      * than the lowest one returned here.
 | 
        
           |  |  | 80 |      *
 | 
        
           |  |  | 81 |      * @param string $component
 | 
        
           |  |  | 82 |      * @return array|null array of \core\update\info objects or null
 | 
        
           |  |  | 83 |      */
 | 
        
           |  |  | 84 |     public function load_available_updates_for_plugin($component) {
 | 
        
           |  |  | 85 |   | 
        
           |  |  | 86 |         if ($component === 'foo_bar') {
 | 
        
           |  |  | 87 |             $updates = array();
 | 
        
           |  |  | 88 |   | 
        
           |  |  | 89 |             $updates[] = new \core\update\info($component, array(
 | 
        
           |  |  | 90 |                 'version' => '2015093000',
 | 
        
           |  |  | 91 |                 'release' => 'Foo bar 15.09.30 beta',
 | 
        
           |  |  | 92 |                 'maturity' => MATURITY_BETA,
 | 
        
           |  |  | 93 |             ));
 | 
        
           |  |  | 94 |   | 
        
           |  |  | 95 |             $updates[] = new \core\update\info($component, array(
 | 
        
           |  |  | 96 |                 'version' => '2015100400',
 | 
        
           |  |  | 97 |                 'release' => 'Foo bar 15.10.04',
 | 
        
           |  |  | 98 |                 'maturity' => MATURITY_STABLE,
 | 
        
           |  |  | 99 |             ));
 | 
        
           |  |  | 100 |   | 
        
           |  |  | 101 |             $updates[] = new \core\update\info($component, array(
 | 
        
           |  |  | 102 |                 'version' => '2015100500',
 | 
        
           |  |  | 103 |                 'release' => 'Foo bar 15.10.05 beta',
 | 
        
           |  |  | 104 |                 'maturity' => MATURITY_BETA,
 | 
        
           |  |  | 105 |             ));
 | 
        
           |  |  | 106 |   | 
        
           |  |  | 107 |             return $updates;
 | 
        
           |  |  | 108 |         }
 | 
        
           |  |  | 109 |   | 
        
           |  |  | 110 |         return null;
 | 
        
           |  |  | 111 |     }
 | 
        
           |  |  | 112 |   | 
        
           |  |  | 113 |     /**
 | 
        
           |  |  | 114 |      * Adds fake plugin information from record.
 | 
        
           |  |  | 115 |      *
 | 
        
           |  |  | 116 |      * @param testable_plugininfo_base $record
 | 
        
           |  |  | 117 |      * @return void
 | 
        
           |  |  | 118 |      */
 | 
        
           |  |  | 119 |     public function add_fake_plugin_info($record): void {
 | 
        
           |  |  | 120 |         $this->load_present_plugins();
 | 
        
           |  |  | 121 |   | 
        
           |  |  | 122 |         $this->presentplugins[$record->type][$record->name] = $record;
 | 
        
           |  |  | 123 |     }
 | 
        
           | 1441 | ariadna | 124 |   | 
        
           |  |  | 125 |     /**
 | 
        
           |  |  | 126 |      * Test-specific override allowing mock plugin types to provide their plugininfo at PATH/TYPE_plugininfo.php instead of the
 | 
        
           |  |  | 127 |      * usual core location lib/classes/plugininfo.
 | 
        
           |  |  | 128 |      *
 | 
        
           |  |  | 129 |      * This is required to:
 | 
        
           |  |  | 130 |      * a) prevent debugging calls during tests using deep mocked plugintypes, as their plugininfo can't be located without this
 | 
        
           |  |  | 131 |      * override.
 | 
        
           |  |  | 132 |      * b) ensure plugin_manager returns an instance of the fixture plugininfo class, during tests using deep mocked plugintypes.
 | 
        
           |  |  | 133 |      * If no fixture plugininfo is found, plugin_manager will default to \core\pluginfo\general.
 | 
        
           |  |  | 134 |      *
 | 
        
           |  |  | 135 |      * @param string $type the plugintype.
 | 
        
           |  |  | 136 |      * @return string the name of the plugininfo class.
 | 
        
           |  |  | 137 |      */
 | 
        
           |  |  | 138 |     public static function resolve_plugininfo_class($type): string {
 | 
        
           |  |  | 139 |         $allplugintypes = array_merge(
 | 
        
           |  |  | 140 |             \core_component::get_plugin_types(),
 | 
        
           |  |  | 141 |             \core_component::get_deprecated_plugin_types(),
 | 
        
           |  |  | 142 |             \core_component::get_deleted_plugin_types()
 | 
        
           |  |  | 143 |         );
 | 
        
           |  |  | 144 |   | 
        
           |  |  | 145 |         // This is not a problem for mock plugins supporting subtypes, since subtype plugininfo class can be loaded, as expected,
 | 
        
           |  |  | 146 |         // from the subtype root directory.
 | 
        
           |  |  | 147 |         $issubtype = !is_null(\core_component::get_subtype_parent($type));
 | 
        
           |  |  | 148 |   | 
        
           |  |  | 149 |         $path = $allplugintypes[$type];
 | 
        
           |  |  | 150 |         if (!$issubtype && preg_match('/lib\/tests\/fixtures/', $path)) {
 | 
        
           |  |  | 151 |             require_once("$path/{$type}_plugininfo.php");
 | 
        
           |  |  | 152 |             return "{$type}_plugininfo";
 | 
        
           |  |  | 153 |         }
 | 
        
           |  |  | 154 |   | 
        
           |  |  | 155 |         return parent::resolve_plugininfo_class($type);
 | 
        
           |  |  | 156 |     }
 | 
        
           | 1 | efrain | 157 | }
 |