From 8a07684e69e30434686d797a0561fc77a0ba78f1 Mon Sep 17 00:00:00 2001 From: Jake Dallimore Date: Thu, 25 Jul 2024 12:33:32 +0800 Subject: [PATCH] MDL-79843 core: test covering hook events for deprecated plugins Verifies that listeners are excluded if they are from a deprecated plugin type. --- lib/tests/event/manager_test.php | 2 +- lib/tests/hook/manager_test.php | 43 ++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/lib/tests/event/manager_test.php b/lib/tests/event/manager_test.php index 6a965d85b2627..109fdd040288b 100644 --- a/lib/tests/event/manager_test.php +++ b/lib/tests/event/manager_test.php @@ -25,7 +25,7 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @covers \core\event\manager */ -class manager_test extends \advanced_testcase { +final class manager_test extends \advanced_testcase { /** * Test verifying that observers are not returned for deprecated plugin types. diff --git a/lib/tests/hook/manager_test.php b/lib/tests/hook/manager_test.php index a91c8bcc52a31..043c94adcb7e2 100644 --- a/lib/tests/hook/manager_test.php +++ b/lib/tests/hook/manager_test.php @@ -464,6 +464,49 @@ public function test_migrated_class_callback_with_replacement(): void { $this->assertDebuggingNotCalled(); } + /** + * Test verifying that callbacks for deprecated plugins are not returned and hook dispatching won't call into these plugins. + * + * @runInSeparateProcess + * @return void + */ + public function test_get_callbacks_for_hook_deprecated_plugintype(): void { + $this->resetAfterTest(); + + // Inject the fixture 'fake' plugin type into component sources, which includes a single 'fake_fullfeatured' plugin. + // This 'fake_fullfeatured' plugin is an available plugin at this stage (not yet deprecated). + $this->add_full_mocked_plugintype( + plugintype: 'fake', + path: 'lib/tests/fixtures/fakeplugins/fake', + ); + + // Force reset the static instance cache \core\hook\manager::$instance so that a fresh instance is instantiated, ensuring + // the component lists are re-run and the hook manager can see the injected mock plugin and it's callbacks. + // Note: we can't use \core\hook\manager::phpunit_get_instance() because that doesn't load in component callbacks from disk. + $hookmanrc = new \ReflectionClass(\core\hook\manager::class); + $hookmanrc->setStaticPropertyValue('instance', null); + $manager = \core\hook\manager::get_instance(); + + // Get all registered callbacks for the hook listened to by the mock plugin (after_course_created). + $listeners = $manager->get_callbacks_for_hook(\core_course\hook\after_course_created::class); + $componentswithcallbacks = array_column($listeners, 'component'); + + // Verify the available mock plugin is returned as a listener. + $this->assertContains('fake_fullfeatured', $componentswithcallbacks); + + // Deprecate the 'fake' plugin type. + $this->deprecate_full_mocked_plugintype('fake'); + + // Force a fresh plugin manager instance, again to ensure the up-to-date component lists are used. + $hookmanrc->setStaticPropertyValue('instance', null); + $manager = \core\hook\manager::get_instance(); + + // And verify the plugin is now not returned as a listener, since it's deprecated. + $listeners = $manager->get_callbacks_for_hook(\core_course\hook\after_course_created::class); + $componentswithcallbacks = array_column($listeners, 'component'); + $this->assertNotContains('fake_fullfeatured', $componentswithcallbacks); + } + /** * Normalise the sort order of callbacks to help with asserts. *