| Línea 14... | Línea 14... | 
          
            | 14 | // You should have received a copy of the GNU General Public License
 | 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/>.
 | 15 | // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 | 
          
            | Línea 16... | Línea 16... | 
          
            | 16 |  
 | 16 |  
 | 
          
            | Línea -... | Línea 17... | 
          
            | - |   | 17 | namespace core;
 | 
          
            | - |   | 18 |  
 | 
          
            | 17 | namespace core;
 | 19 | use core\plugininfo\base;
 | 
          
            | 18 |  
 | 20 | use core\tests\fake_plugins_test_trait;
 | 
          
            | 19 | use core_plugin_manager;
 | 21 | use core_plugin_manager;
 | 
          
            | Línea 20... | Línea 22... | 
          
            | 20 | use testable_core_plugin_manager;
 | 22 | use testable_core_plugin_manager;
 | 
          
            | Línea 28... | Línea 30... | 
          
            | 28 |  * @copyright 2013 Petr Skoda {@link http://skodak.org}
 | 30 |  * @copyright 2013 Petr Skoda {@link http://skodak.org}
 | 
          
            | 29 |  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 | 31 |  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 | 
          
            | 30 |  * @covers \core_plugin_manager
 | 32 |  * @covers \core_plugin_manager
 | 
          
            | 31 |  */
 | 33 |  */
 | 
          
            | 32 | final class plugin_manager_test extends \advanced_testcase {
 | 34 | final class plugin_manager_test extends \advanced_testcase {
 | 
          
            | - |   | 35 |  
 | 
          
            | - |   | 36 |     use fake_plugins_test_trait;
 | 
          
            | - |   | 37 |  
 | 
          
            | 33 |     public static function setUpBeforeClass(): void {
 | 38 |     public static function setUpBeforeClass(): void {
 | 
          
            | 34 |         global $CFG;
 | 39 |         global $CFG;
 | 
          
            | 35 |         require_once($CFG->dirroot . '/lib/tests/fixtures/testable_plugin_manager.php');
 | 40 |         require_once($CFG->dirroot . '/lib/tests/fixtures/testable_plugin_manager.php');
 | 
          
            | 36 |         require_once($CFG->dirroot . '/lib/tests/fixtures/testable_plugininfo_base.php');
 | 41 |         require_once($CFG->dirroot . '/lib/tests/fixtures/testable_plugininfo_base.php');
 | 
          
            | - |   | 42 |         parent::setUpBeforeClass();
 | 
          
            | 37 |     }
 | 43 |     }
 | 
          
            | Línea 38... | Línea 44... | 
          
            | 38 |  
 | 44 |  
 | 
          
            | 39 |     public function tearDown(): void {
 | 45 |     public function tearDown(): void {
 | 
          
            | 40 |         // The caches of the testable singleton must be reset explicitly. It is
 | 46 |         // The caches of the testable singleton must be reset explicitly. It is
 | 
          
            | 41 |         // safer to kill the whole testable singleton at the end of every test.
 | 47 |         // safer to kill the whole testable singleton at the end of every test.
 | 
          
            | - |   | 48 |         testable_core_plugin_manager::reset_caches();
 | 
          
            | 42 |         testable_core_plugin_manager::reset_caches();
 | 49 |         parent::tearDown();
 | 
          
            | Línea 43... | Línea 50... | 
          
            | 43 |     }
 | 50 |     }
 | 
          
            | 44 |  
 | 51 |  
 | 
          
            | 45 |     public function test_instance(): void {
 | 52 |     public function test_instance(): void {
 | 
          
            | Línea 782... | Línea 789... | 
          
            | 782 |  
 | 789 |  
 | 
          
            | 783 |         $this->assertContains('mod_forum', $plugins);
 | 790 |         $this->assertContains('mod_forum', $plugins);
 | 
          
            | 784 |         $this->assertContains('block_badges', $plugins);
 | 791 |         $this->assertContains('block_badges', $plugins);
 | 
          
            | 785 |         $this->assertNotContains('marmelade_paddington', $plugins);
 | 792 |         $this->assertNotContains('marmelade_paddington', $plugins);
 | 
          
            | - |   | 793 |     }
 | 
          
            | - |   | 794 |  
 | 
          
            | - |   | 795 |     /**
 | 
          
            | - |   | 796 |      * Test core_plugin_manager when dealing with deprecated plugin (not subplugin) types.
 | 
          
            | - |   | 797 |      *
 | 
          
            | - |   | 798 |      * @runInSeparateProcess
 | 
          
            | - |   | 799 |      * @return void
 | 
          
            | - |   | 800 |      */
 | 
          
            | - |   | 801 |     public function test_plugin_manager_deprecated_plugintype(): void {
 | 
          
            | - |   | 802 |         $this->resetAfterTest();
 | 
          
            | - |   | 803 |  
 | 
          
            | - |   | 804 |         // Inject the mock plugin 'fake_fullfeatured' and deprecate it.
 | 
          
            | - |   | 805 |         $this->add_full_mocked_plugintype(
 | 
          
            | - |   | 806 |             plugintype: 'fake',
 | 
          
            | - |   | 807 |             path: 'lib/tests/fixtures/fakeplugins/fake',
 | 
          
            | - |   | 808 |         );
 | 
          
            | - |   | 809 |         $this->deprecate_full_mocked_plugintype('fake');
 | 
          
            | - |   | 810 |  
 | 
          
            | - |   | 811 |         // Use testable_plugin_manager, as this properly loads the mocked fake_plugininfo class, meaning the fake plugins are
 | 
          
            | - |   | 812 |         // recognised by the plugin manager. See testable_plugin_manager::resolve_plugininfo_class().
 | 
          
            | - |   | 813 |         $pluginman = testable_core_plugin_manager::instance();
 | 
          
            | - |   | 814 |  
 | 
          
            | - |   | 815 |         // Deprecated plugin type are excluded from the following for B/C.
 | 
          
            | - |   | 816 |         $this->assertArrayNotHasKey('fake', $pluginman->get_plugin_types());
 | 
          
            | - |   | 817 |         $this->assertNull($pluginman->get_enabled_plugins('fake'));
 | 
          
            | - |   | 818 |  
 | 
          
            | - |   | 819 |         // Deprecated plugins excluded by default for B/C, but can be included by request.
 | 
          
            | - |   | 820 |         $this->assertArrayNotHasKey('fake', $pluginman->get_plugins());
 | 
          
            | - |   | 821 |         $plugins = $pluginman->get_plugins(true);
 | 
          
            | - |   | 822 |         $this->assertArrayHasKey('fake', $plugins);
 | 
          
            | - |   | 823 |  
 | 
          
            | - |   | 824 |         /** @var base $plugininfo */
 | 
          
            | - |   | 825 |         $plugininfo = $plugins['fake']['fullfeatured'];
 | 
          
            | - |   | 826 |         $this->assertNull($plugininfo->is_enabled());
 | 
          
            | - |   | 827 |         $this->assertTrue($plugininfo->is_deprecated());
 | 
          
            | - |   | 828 |         $this->assertFalse($plugininfo->is_deleted());
 | 
          
            | - |   | 829 |         $this->assertTrue($plugininfo->is_uninstall_allowed());
 | 
          
            | - |   | 830 |         $this->assertIsString($plugininfo->full_path('version.php'));
 | 
          
            | - |   | 831 |         $this->assertEquals(\core_plugin_manager::PLUGIN_STATUS_UPTODATE, $plugininfo->get_status());
 | 
          
            | - |   | 832 |         $this->assertFalse($plugininfo->get_parent_plugin());
 | 
          
            | - |   | 833 |         $this->assertNotEmpty($plugininfo->versiondisk);
 | 
          
            | - |   | 834 |         $this->assertStringContainsString('/fake/', $plugininfo->get_dir());
 | 
          
            | - |   | 835 |  
 | 
          
            | - |   | 836 |         $this->assertArrayNotHasKey('fullfeatured', $pluginman->get_plugins_of_type('fake'));
 | 
          
            | - |   | 837 |         $this->assertArrayHasKey('fullfeatured', $pluginman->get_plugins_of_type('fake', true));
 | 
          
            | - |   | 838 |  
 | 
          
            | - |   | 839 |         // Deprecated plugins included in the following.
 | 
          
            | - |   | 840 |         $this->assertArrayHasKey('fullfeatured', $pluginman->get_present_plugins('fake')); // Plugins on disk.
 | 
          
            | - |   | 841 |         $this->assertArrayHasKey('fullfeatured', $pluginman->get_installed_plugins('fake')); // Plugins with DB config.
 | 
          
            | - |   | 842 |         $this->assertInstanceOf(\fake_plugininfo::class, $pluginman->get_plugin_info('fake_fullfeatured'));
 | 
          
            | - |   | 843 |         $this->assertIsString($pluginman->get_plugintype_root('fake'));
 | 
          
            | - |   | 844 |         $this->assertTrue($pluginman->can_uninstall_plugin('fake_fullfeatured'));
 | 
          
            | - |   | 845 |         $uninstallurl = $pluginman->get_uninstall_url('fake_fullfeatured');
 | 
          
            | - |   | 846 |         $this->assertInstanceOf(\moodle_url::class, $uninstallurl);
 | 
          
            | - |   | 847 |         $this->assertEquals('fake_fullfeatured', $uninstallurl->param('uninstall'));
 | 
          
            | - |   | 848 |  
 | 
          
            | - |   | 849 |         // Strings are supported for deprecated plugins.
 | 
          
            | - |   | 850 |         $this->assertEquals('Fake full featured plugin', $pluginman->plugin_name('fake_fullfeatured'));
 | 
          
            | - |   | 851 |         $this->assertEquals('fake', $pluginman->plugintype_name('fake'));
 | 
          
            | - |   | 852 |         $this->assertEquals('fake', $pluginman->plugintype_name_plural('fake'));
 | 
          
            | - |   | 853 |     }
 | 
          
            | - |   | 854 |  
 | 
          
            | - |   | 855 |     /**
 | 
          
            | - |   | 856 |      * Test core_plugin_manager when dealing with deprecated subplugin types.
 | 
          
            | - |   | 857 |      *
 | 
          
            | - |   | 858 |      * @runInSeparateProcess
 | 
          
            | - |   | 859 |      * @return void
 | 
          
            | - |   | 860 |      */
 | 
          
            | - |   | 861 |     public function test_plugin_manager_deprecated_subplugintype(): void {
 | 
          
            | - |   | 862 |         $this->resetAfterTest();
 | 
          
            | - |   | 863 |  
 | 
          
            | - |   | 864 |         // Inject the 'fake' plugin type. This includes three mock subplugins:
 | 
          
            | - |   | 865 |         // 1. fullsubtype_example: a regular plugin type, not deprecated, nor deleted.
 | 
          
            | - |   | 866 |         // 2. fulldeprecatedsubtype_test: a deprecated subplugin type.
 | 
          
            | - |   | 867 |         // 3. fulldeletedsubtype_demo: a deleted subplugin type.
 | 
          
            | - |   | 868 |         $this->add_full_mocked_plugintype(
 | 
          
            | - |   | 869 |             plugintype: 'fake',
 | 
          
            | - |   | 870 |             path: 'lib/tests/fixtures/fakeplugins/fake',
 | 
          
            | - |   | 871 |             subpluginsupport: true
 | 
          
            | - |   | 872 |         );
 | 
          
            | - |   | 873 |  
 | 
          
            | - |   | 874 |         // Use testable_plugin_manager, as this properly loads the mocked fake_plugininfo class, meaning the fake plugins are
 | 
          
            | - |   | 875 |         // recognised by the plugin manager. See testable_plugin_manager::resolve_plugininfo_class().
 | 
          
            | - |   | 876 |         $pluginman = testable_core_plugin_manager::instance();
 | 
          
            | - |   | 877 |  
 | 
          
            | - |   | 878 |         // Deprecated plugin type are excluded from the following for B/C.
 | 
          
            | - |   | 879 |         $this->assertArrayNotHasKey('fulldeprecatedsubtype', $pluginman->get_plugin_types());
 | 
          
            | - |   | 880 |         $this->assertNull($pluginman->get_enabled_plugins('fulldeprecatedsubtype'));
 | 
          
            | - |   | 881 |         $subplugins = $pluginman->get_subplugins();
 | 
          
            | - |   | 882 |         $this->assertArrayHasKey('fake_fullfeatured', $subplugins);
 | 
          
            | - |   | 883 |         $fullfeaturedplug = $subplugins['fake_fullfeatured'];
 | 
          
            | - |   | 884 |         $this->assertArrayHasKey('fullsubtype', $fullfeaturedplug);
 | 
          
            | - |   | 885 |         $this->assertArrayNotHasKey('fulldeprecatedsubtype', $fullfeaturedplug);
 | 
          
            | - |   | 886 |         $this->assertArrayHasKey('fullsubtype_example', $pluginman->get_subplugins_of_plugin('fake_fullfeatured'));
 | 
          
            | - |   | 887 |         $this->assertArrayNotHasKey('fulldeprecatedsubtype_test', $pluginman->get_subplugins_of_plugin('fake_fullfeatured'));
 | 
          
            | - |   | 888 |  
 | 
          
            | - |   | 889 |         // Deprecated plugins excluded by default for B/C, but can be included by request.
 | 
          
            | - |   | 890 |         $this->assertArrayNotHasKey('fulldeprecatedsubtype', $pluginman->get_plugins());
 | 
          
            | - |   | 891 |         $plugins = $pluginman->get_plugins(true);
 | 
          
            | - |   | 892 |         $this->assertArrayHasKey('fulldeprecatedsubtype', $plugins);
 | 
          
            | - |   | 893 |  
 | 
          
            | - |   | 894 |         /** @var base $plugininfo */
 | 
          
            | - |   | 895 |         $plugininfo = $plugins['fulldeprecatedsubtype']['test'];
 | 
          
            | - |   | 896 |         $this->assertNull($plugininfo->is_enabled());
 | 
          
            | - |   | 897 |         $this->assertTrue($plugininfo->is_deprecated());
 | 
          
            | - |   | 898 |         $this->assertFalse($plugininfo->is_deleted());
 | 
          
            | - |   | 899 |         $this->assertTrue($plugininfo->is_uninstall_allowed());
 | 
          
            | - |   | 900 |         $this->assertIsString($plugininfo->full_path('version.php'));
 | 
          
            | - |   | 901 |         $this->assertEquals(\core_plugin_manager::PLUGIN_STATUS_UPTODATE, $plugininfo->get_status());
 | 
          
            | - |   | 902 |         $this->assertEquals('fake_fullfeatured', $plugininfo->get_parent_plugin());
 | 
          
            | - |   | 903 |         $this->assertNotEmpty($plugininfo->versiondisk);
 | 
          
            | - |   | 904 |         $this->assertStringContainsString('/fulldeprecatedsubtype/', $plugininfo->get_dir());
 | 
          
            | - |   | 905 |  
 | 
          
            | - |   | 906 |         $this->assertArrayNotHasKey('test', $pluginman->get_plugins_of_type('fulldeprecatedsubtype'));
 | 
          
            | - |   | 907 |         $this->assertArrayHasKey('test', $pluginman->get_plugins_of_type('fulldeprecatedsubtype', true));
 | 
          
            | - |   | 908 |  
 | 
          
            | - |   | 909 |         $this->assertFalse($pluginman->get_parent_of_subplugin('fulldeprecatedsubtype'));
 | 
          
            | - |   | 910 |         $this->assertEquals('fake_fullfeatured', $pluginman->get_parent_of_subplugin('fulldeprecatedsubtype', true));
 | 
          
            | - |   | 911 |  
 | 
          
            | - |   | 912 |         // Deprecated plugins included in the following.
 | 
          
            | - |   | 913 |         $this->assertArrayHasKey('test', $pluginman->get_present_plugins('fulldeprecatedsubtype')); // Plugins on disk.
 | 
          
            | - |   | 914 |         $this->assertArrayHasKey('test', $pluginman->get_installed_plugins('fulldeprecatedsubtype')); // Plugins with DB config.
 | 
          
            | - |   | 915 |         $this->assertInstanceOf(\fake_fullfeatured\plugininfo\fulldeprecatedsubtype::class,
 | 
          
            | - |   | 916 |             $pluginman->get_plugin_info('fulldeprecatedsubtype_test'));
 | 
          
            | - |   | 917 |         $this->assertEquals('Full deprecated subtype test', $pluginman->plugin_name('fulldeprecatedsubtype_test'));
 | 
          
            | - |   | 918 |         $this->assertIsString($pluginman->get_plugintype_root('fulldeprecatedsubtype'));
 | 
          
            | - |   | 919 |         $this->assertTrue($pluginman->can_uninstall_plugin('fulldeprecatedsubtype_test'));
 | 
          
            | - |   | 920 |         $uninstallurl = $pluginman->get_uninstall_url('fulldeprecatedsubtype_test');
 | 
          
            | - |   | 921 |         $this->assertInstanceOf(\moodle_url::class, $uninstallurl);
 | 
          
            | - |   | 922 |         $this->assertEquals('fulldeprecatedsubtype_test', $uninstallurl->param('uninstall'));
 | 
          
            | - |   | 923 |     }
 | 
          
            | - |   | 924 |  
 | 
          
            | - |   | 925 |     /**
 | 
          
            | - |   | 926 |      * Test core_plugin_manager when dealing with deleted plugin (not subplugin) types.
 | 
          
            | - |   | 927 |      *
 | 
          
            | - |   | 928 |      * @runInSeparateProcess
 | 
          
            | - |   | 929 |      * @return void
 | 
          
            | - |   | 930 |      */
 | 
          
            | - |   | 931 |     public function test_plugin_manager_deleted_plugintype(): void {
 | 
          
            | - |   | 932 |         $this->resetAfterTest();
 | 
          
            | - |   | 933 |  
 | 
          
            | - |   | 934 |         // Inject the mock plugin 'fake_fullfeatured', and deprecate it.
 | 
          
            | - |   | 935 |         $this->add_full_mocked_plugintype(
 | 
          
            | - |   | 936 |             plugintype: 'fake',
 | 
          
            | - |   | 937 |             path: 'lib/tests/fixtures/fakeplugins/fake',
 | 
          
            | - |   | 938 |         );
 | 
          
            | - |   | 939 |         $this->delete_full_mocked_plugintype('fake');
 | 
          
            | - |   | 940 |  
 | 
          
            | - |   | 941 |         // Use testable_plugin_manager, as this properly loads the mocked fake_plugininfo class, meaning the fake plugins are
 | 
          
            | - |   | 942 |         // recognised by the plugin manager. See testable_plugin_manager::resolve_plugininfo_class().
 | 
          
            | - |   | 943 |         $pluginman = testable_core_plugin_manager::instance();
 | 
          
            | - |   | 944 |  
 | 
          
            | - |   | 945 |         // Deleted plugins are excluded from the following for B/C.
 | 
          
            | - |   | 946 |         $this->assertArrayNotHasKey('fake', $pluginman->get_plugin_types());
 | 
          
            | - |   | 947 |         $this->assertNull($pluginman->get_enabled_plugins('fake'));
 | 
          
            | - |   | 948 |  
 | 
          
            | - |   | 949 |         // Deleted plugins excluded by default for B/C, but can be included by request.
 | 
          
            | - |   | 950 |         $this->assertArrayNotHasKey('fake', $pluginman->get_plugins());
 | 
          
            | - |   | 951 |         $plugins = $pluginman->get_plugins(true);
 | 
          
            | - |   | 952 |         $this->assertArrayHasKey('fake', $plugins);
 | 
          
            | - |   | 953 |  
 | 
          
            | - |   | 954 |         /** @var base $plugininfo */
 | 
          
            | - |   | 955 |         $plugininfo = $plugins['fake']['fullfeatured'];
 | 
          
            | - |   | 956 |         $this->assertNull($plugininfo->is_enabled());
 | 
          
            | - |   | 957 |         $this->assertFalse($plugininfo->is_deprecated());
 | 
          
            | - |   | 958 |         $this->assertTrue($plugininfo->is_deleted());
 | 
          
            | - |   | 959 |         $this->assertTrue($plugininfo->is_uninstall_allowed());
 | 
          
            | - |   | 960 |         $this->assertIsString($plugininfo->full_path('version.php'));
 | 
          
            | - |   | 961 |         $this->assertEquals(\core_plugin_manager::PLUGIN_STATUS_UPTODATE, $plugininfo->get_status());
 | 
          
            | - |   | 962 |         $this->assertFalse($plugininfo->get_parent_plugin());
 | 
          
            | - |   | 963 |         $this->assertNotEmpty($plugininfo->versiondisk);
 | 
          
            | - |   | 964 |         $this->assertStringContainsString('/fake/', $plugininfo->get_dir());
 | 
          
            | - |   | 965 |  
 | 
          
            | - |   | 966 |         $this->assertArrayNotHasKey('fullfeatured', $pluginman->get_plugins_of_type('fake'));
 | 
          
            | - |   | 967 |         $this->assertArrayHasKey('fullfeatured', $pluginman->get_plugins_of_type('fake', true));
 | 
          
            | - |   | 968 |  
 | 
          
            | - |   | 969 |         // Deleted plugins included in the following.
 | 
          
            | - |   | 970 |         $this->assertArrayHasKey('fullfeatured', $pluginman->get_present_plugins('fake')); // Plugins on disk.
 | 
          
            | - |   | 971 |         $this->assertArrayHasKey('fullfeatured', $pluginman->get_installed_plugins('fake')); // Plugins with DB config.
 | 
          
            | - |   | 972 |         $this->assertInstanceOf(\fake_plugininfo::class, $pluginman->get_plugin_info('fake_fullfeatured'));
 | 
          
            | - |   | 973 |         $this->assertIsString($pluginman->get_plugintype_root('fake'));
 | 
          
            | - |   | 974 |         $this->assertTrue($pluginman->can_uninstall_plugin('fake_fullfeatured'));
 | 
          
            | - |   | 975 |         $uninstallurl = $pluginman->get_uninstall_url('fake_fullfeatured');
 | 
          
            | - |   | 976 |         $this->assertInstanceOf(\moodle_url::class, $uninstallurl);
 | 
          
            | - |   | 977 |         $this->assertEquals('fake_fullfeatured', $uninstallurl->param('uninstall'));
 | 
          
            | - |   | 978 |  
 | 
          
            | - |   | 979 |         // Included, but there is no string support for deleted plugin types.
 | 
          
            | - |   | 980 |         // Without string support, the type name defaults to the plugin type,
 | 
          
            | - |   | 981 |         // while plugin name is set in \core\plugininfo\base::init_is_deprecated().
 | 
          
            | - |   | 982 |         $this->assertEquals('fullfeatured', $pluginman->plugin_name('fake_fullfeatured'));
 | 
          
            | - |   | 983 |         $this->assertEquals('fake', $pluginman->plugintype_name('fake'));
 | 
          
            | - |   | 984 |         $this->assertEquals('fake', $pluginman->plugintype_name_plural('fake'));
 | 
          
            | - |   | 985 |     }
 | 
          
            | - |   | 986 |  
 | 
          
            | - |   | 987 |     /**
 | 
          
            | - |   | 988 |      * Test core_plugin_manager when dealing with deleted subplugin types.
 | 
          
            | - |   | 989 |      *
 | 
          
            | - |   | 990 |      * @runInSeparateProcess
 | 
          
            | - |   | 991 |      * @return void
 | 
          
            | - |   | 992 |      */
 | 
          
            | - |   | 993 |     public function test_plugin_manager_deleted_subplugintype(): void {
 | 
          
            | - |   | 994 |         $this->resetAfterTest();
 | 
          
            | - |   | 995 |  
 | 
          
            | - |   | 996 |         // Inject the 'fake' plugin type. This includes three mock subplugins:
 | 
          
            | - |   | 997 |         // 1. fullsubtype_example: a regular plugin type, not deprecated, nor deleted.
 | 
          
            | - |   | 998 |         // 2. fulldeprecatedsubtype_test: a deprecated subplugin type.
 | 
          
            | - |   | 999 |         // 3. fulldeletedsubtype_demo: a deleted subplugin type.
 | 
          
            | - |   | 1000 |         $this->add_full_mocked_plugintype(
 | 
          
            | - |   | 1001 |             plugintype: 'fake',
 | 
          
            | - |   | 1002 |             path: 'lib/tests/fixtures/fakeplugins/fake',
 | 
          
            | - |   | 1003 |             subpluginsupport: true
 | 
          
            | - |   | 1004 |         );
 | 
          
            | - |   | 1005 |  
 | 
          
            | - |   | 1006 |         // Use testable_plugin_manager, as this properly loads the mocked fake_plugininfo class, meaning the fake plugins are
 | 
          
            | - |   | 1007 |         // recognised by the plugin manager. See testable_plugin_manager::resolve_plugininfo_class().
 | 
          
            | - |   | 1008 |         $pluginman = testable_core_plugin_manager::instance();
 | 
          
            | - |   | 1009 |  
 | 
          
            | - |   | 1010 |         // Deleted plugin type are excluded from the following for B/C.
 | 
          
            | - |   | 1011 |         $this->assertArrayNotHasKey('fulldeletedsubtype', $pluginman->get_plugin_types());
 | 
          
            | - |   | 1012 |         $this->assertNull($pluginman->get_enabled_plugins('fulldeletedsubtype'));
 | 
          
            | - |   | 1013 |         $subplugins = $pluginman->get_subplugins();
 | 
          
            | - |   | 1014 |         $this->assertArrayHasKey('fake_fullfeatured', $subplugins);
 | 
          
            | - |   | 1015 |         $fullfeaturedplug = $subplugins['fake_fullfeatured'];
 | 
          
            | - |   | 1016 |         $this->assertArrayHasKey('fullsubtype', $fullfeaturedplug);
 | 
          
            | - |   | 1017 |         $this->assertArrayNotHasKey('fulldeletedsubtype', $fullfeaturedplug);
 | 
          
            | - |   | 1018 |         $this->assertArrayHasKey('fullsubtype_example', $pluginman->get_subplugins_of_plugin('fake_fullfeatured'));
 | 
          
            | - |   | 1019 |         $this->assertArrayNotHasKey('fulldeletedsubtype_demo', $pluginman->get_subplugins_of_plugin('fake_fullfeatured'));
 | 
          
            | - |   | 1020 |  
 | 
          
            | - |   | 1021 |         // Deleted plugins excluded by default for B/C, but can be included by request.
 | 
          
            | - |   | 1022 |         $this->assertArrayNotHasKey('fulldeletedsubtype', $pluginman->get_plugins());
 | 
          
            | - |   | 1023 |         $plugins = $pluginman->get_plugins(true);
 | 
          
            | - |   | 1024 |         $this->assertArrayHasKey('fulldeletedsubtype', $plugins);
 | 
          
            | - |   | 1025 |  
 | 
          
            | - |   | 1026 |         /** @var base $plugininfo */
 | 
          
            | - |   | 1027 |         $plugininfo = $plugins['fulldeletedsubtype']['demo'];
 | 
          
            | - |   | 1028 |         $this->assertNull($plugininfo->is_enabled());
 | 
          
            | - |   | 1029 |         $this->assertFalse($plugininfo->is_deprecated());
 | 
          
            | - |   | 1030 |         $this->assertTrue($plugininfo->is_deleted());
 | 
          
            | - |   | 1031 |         $this->assertTrue($plugininfo->is_uninstall_allowed());
 | 
          
            | - |   | 1032 |         $this->assertIsString($plugininfo->full_path('version.php'));
 | 
          
            | - |   | 1033 |         $this->assertEquals(\core_plugin_manager::PLUGIN_STATUS_UPTODATE, $plugininfo->get_status());
 | 
          
            | - |   | 1034 |         $this->assertEquals('fake_fullfeatured', $plugininfo->get_parent_plugin());
 | 
          
            | - |   | 1035 |         $this->assertNotEmpty($plugininfo->versiondisk);
 | 
          
            | - |   | 1036 |         $this->assertStringContainsString('/fulldeletedsubtype/', $plugininfo->get_dir());
 | 
          
            | - |   | 1037 |  
 | 
          
            | - |   | 1038 |         $this->assertArrayNotHasKey('demo', $pluginman->get_plugins_of_type('fulldeletedsubtype'));
 | 
          
            | - |   | 1039 |         $this->assertArrayHasKey('demo', $pluginman->get_plugins_of_type('fulldeletedsubtype', true));
 | 
          
            | - |   | 1040 |  
 | 
          
            | - |   | 1041 |         $this->assertFalse($pluginman->get_parent_of_subplugin('fulldeletedsubtype'));
 | 
          
            | - |   | 1042 |         $this->assertEquals('fake_fullfeatured', $pluginman->get_parent_of_subplugin('fulldeletedsubtype', true));
 | 
          
            | - |   | 1043 |  
 | 
          
            | - |   | 1044 |         // Deprecated plugins included in the following.
 | 
          
            | - |   | 1045 |         $this->assertArrayHasKey('demo', $pluginman->get_present_plugins('fulldeletedsubtype')); // Plugins on disk.
 | 
          
            | - |   | 1046 |         $this->assertArrayHasKey('demo', $pluginman->get_installed_plugins('fulldeletedsubtype')); // Plugins with DB config.
 | 
          
            | - |   | 1047 |         $this->assertInstanceOf(\fake_fullfeatured\plugininfo\fulldeletedsubtype::class,
 | 
          
            | - |   | 1048 |             $pluginman->get_plugin_info('fulldeletedsubtype_demo'));
 | 
          
            | - |   | 1049 |         $this->assertIsString($pluginman->get_plugintype_root('fulldeletedsubtype'));
 | 
          
            | - |   | 1050 |         $this->assertTrue($pluginman->can_uninstall_plugin('fulldeletedsubtype_demo'));
 | 
          
            | - |   | 1051 |         $uninstallurl = $pluginman->get_uninstall_url('fulldeletedsubtype_demo');
 | 
          
            | - |   | 1052 |         $this->assertInstanceOf(\moodle_url::class, $uninstallurl);
 | 
          
            | - |   | 1053 |         $this->assertEquals('fulldeletedsubtype_demo', $uninstallurl->param('uninstall'));
 | 
          
            | - |   | 1054 |  
 | 
          
            | - |   | 1055 |         // Included, but there is no string support for deleted plugin types.
 | 
          
            | - |   | 1056 |         // Without string support, the type name defaults to the plugin type,
 | 
          
            | - |   | 1057 |         // while plugin name is set in \core\plugininfo\base::init_is_deprecated().
 | 
          
            | - |   | 1058 |         $this->assertEquals('demo', $pluginman->plugin_name('fulldeletedsubtype_demo'));
 | 
          
            | - |   | 1059 |         $this->assertEquals('fulldeletedsubtype', $pluginman->plugintype_name('fulldeletedsubtype'));
 | 
          
            | - |   | 1060 |         $this->assertEquals('fulldeletedsubtype', $pluginman->plugintype_name_plural('fulldeletedsubtype'));
 | 
          
            | 786 |     }
 | 1061 |     }
 |