Merge branch 'patch/MDL-85666-404' of https://github.com/skodak/moodle into MOODLE_404_STABLE

This commit is contained in:
Mihail Geshoski
2025-07-03 09:53:37 +08:00
13 changed files with 633 additions and 50 deletions
@@ -0,0 +1,70 @@
<?php
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
namespace tool_capability;
// phpcs:disable moodle.PHPUnit.TestCaseProvider.dataProviderSyntaxMethodNotFound
/**
* Detect common problems in capability definitions of plugins.
*
* @group plugin_checks
* @package tool_capability
* @copyright 2025 Petr Skoda
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
final class plugin_checks_test extends \core\tests\plugin_checks_testcase {
/**
* Verify contents of plugin db/access.php file.
*
* @dataProvider all_plugins_provider
* @coversNothing
*
* @param string $component
* @param string $plugintype
* @param string $pluginname
* @param string $dir
*/
public function test_db_access_file(string $component, string $plugintype, string $pluginname, string $dir): void {
global $CFG;
$stringmanager = get_string_manager();
$corerolefile = "$CFG->dirroot/lang/en/role.php";
$langfile = "$dir/lang/en/$component.php";
$file = "$dir/db/access.php";
$capabilities = $this->fetch_array_from_file($file, 'capabilities');
if (!$capabilities) {
$this->expectNotToPerformAssertions();
return;
}
foreach ($capabilities as $capname => $capability) {
if ($plugintype === 'qbank' && str_starts_with($capname, 'moodle/question:')) {
// Question bank capabilities are irregular.
$strname = explode('/', $capname, 2)[1];
$this->assertTrue($stringmanager->string_exists($strname, 'core_role'),
"Missing capability name string '$strname' in $corerolefile");
continue;
}
$this->assertMatchesRegularExpression("|^$plugintype/$pluginname:[a-z0-9_]+$|", $capname);
$strname = substr($capname, strlen($plugintype) + 1);
$this->assertTrue($stringmanager->string_exists($strname, $component),
"Missing capability name string '$strname' in $langfile");
$this->assertSame($capname, clean_param($capname, PARAM_CAPABILITY));
}
}
}
+1
View File
@@ -391,6 +391,7 @@ final class external_api_test extends \advanced_testcase {
/**
* Test \core_external\external_api::external_function_info.
*
* @group plugin_checks
* @runInSeparateProcess
* @dataProvider all_external_info_provider
* @covers \core_external\external_api::external_function_info
+53
View File
@@ -0,0 +1,53 @@
<?php
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
namespace core_external;
// phpcs:disable moodle.PHPUnit.TestCaseProvider.dataProviderSyntaxMethodNotFound
/**
* Detect common problems in plugin external API.
*
* @group plugin_checks
* @package core_external
* @copyright 2025 Petr Skoda
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
final class plugin_checks_test extends \core\tests\plugin_checks_testcase {
/**
* Verify plugin external API definition files.
*
* @dataProvider all_plugins_provider
* @coversNothing
*
* @param string $component
* @param string $plugintype
* @param string $pluginname
* @param string $dir
*/
public function test_db_services_file(string $component, string $plugintype, string $pluginname, string $dir): void {
$file = "$dir/db/services.php";
$functions = $this->fetch_array_from_file($file, 'functions');
if (!$functions) {
$this->expectNotToPerformAssertions();
return;
}
foreach ($functions as $wsname => $definition) {
$this->assertStringStartsWith($component . '_', $wsname);
}
}
}
@@ -0,0 +1,65 @@
<?php
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
namespace core\tests;
// phpcs:disable moodle.PHPUnit.TestCaseProvider.dataProviderSyntaxMethodNotFound
/**
* Base class for general testing of plugin features and APIs.
* The test must not modify database or any global state.
*
* Following is required to allow filtering of test by Frankenstyle plugin name:
* - all providers used in the tests must use components as keys of provider data
* - all tests must include group "plugin_checks"
*
* @package core
* @copyright 2025 Petr Skoda
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class plugin_checks_testcase extends \basic_testcase {
/**
* Data provider for testing of all available plugins.
*
* @return array as array of [component, plugintype, pluginname, dir]
*/
public static function all_plugins_provider(): array {
$result = [];
foreach (\core_component::get_plugin_types() as $plugintype => $unused) {
foreach (\core_component::get_plugin_list($plugintype) as $pluginname => $dir) {
$component = $plugintype . '_' . $pluginname;
$result[$component] = [$component, $plugintype, $pluginname, $dir];
}
}
return $result;
}
/**
* Include file and return an array variable defined in its global scope.
* This is intended primarily for files inside plugin /db/ subdirectory.
*
* @param string $phpfile
* @param string $variablename
* @return array|null NULL means file does not exist
*/
protected function fetch_array_from_file(string $phpfile, string $variablename): ?array {
if (!file_exists($phpfile)) {
return null;
}
require($phpfile);
return $$variablename;
}
}
+58
View File
@@ -0,0 +1,58 @@
<?php
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
namespace core\db;
// phpcs:disable moodle.PHPUnit.TestCaseProvider.dataProviderSyntaxMethodNotFound
/**
* Detect common problems in plugin database structures.
*
* @group plugin_checks
* @package core
* @copyright 2025 Petr Skoda
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
final class plugin_checks_test extends \core\tests\plugin_checks_testcase {
/**
* Verify plugin db/install.xml file.
*
* @dataProvider all_plugins_provider
* @coversNothing
*
* @param string $component
* @param string $plugintype
* @param string $pluginname
* @param string $dir
*/
public function test_db_install_file(string $component, string $plugintype, string $pluginname, string $dir): void {
global $DB;
$DB->get_manager(); // Preload XMLDB classes.
$file = "$dir/db/install.xml";
if (!file_exists($file)) {
$this->expectNotToPerformAssertions();
return;
}
$rawcontents = file_get_contents($file);
$xmldb = new \xmldb_file($file);
$xmldb->loadXMLStructure();
$xmlcontents = $xmldb->getStructure()->xmlOutput();
$this->assertSame($xmlcontents, $rawcontents,
"Unexpected install.xml format detected, reconciliation needed in $file");
}
}
+60
View File
@@ -0,0 +1,60 @@
<?php
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
namespace core\event;
// phpcs:disable moodle.PHPUnit.TestCaseProvider.dataProviderSyntaxMethodNotFound
/**
* Detect common problems in plugin events.
*
* @group plugin_checks
* @package core
* @copyright 2025 Petr Skoda
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
final class plugin_checks_test extends \core\tests\plugin_checks_testcase {
/**
* Verify all plugin events.
*
* @dataProvider all_plugins_provider
* @coversNothing
*
* @param string $component
* @param string $plugintype
* @param string $pluginname
* @param string $dir
*/
public function test_event_classes(string $component, string $plugintype, string $pluginname, string $dir): void {
$events = \core_component::get_component_classes_in_namespace($component, 'event');
if (!$events) {
$this->expectNotToPerformAssertions();
return;
}
foreach ($events as $eventclassname => $unused) {
$rc = new \ReflectionClass($eventclassname);
if ($rc->isAbstract()) {
continue;
}
if (!is_subclass_of($eventclassname, \core\event\base::class)) {
// Most likely an observer in irregular location, ignore for now.
continue;
}
$this->assertIsString($eventclassname::get_name());
}
}
}
+56
View File
@@ -0,0 +1,56 @@
<?php
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
namespace core\output;
// phpcs:disable moodle.PHPUnit.TestCaseProvider.dataProviderSyntaxMethodNotFound
/**
* Detect common problems in plugin output and them related code.
*
* @group plugin_checks
* @package core
* @copyright 2025 Petr Skoda
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
final class plugin_checks_test extends \core\tests\plugin_checks_testcase {
/**
* Verify plugin defines FA icon fallbacks.
*
* @dataProvider all_plugins_provider
* @coversNothing
*
* @param string $component
* @param string $plugintype
* @param string $pluginname
* @param string $dir
*/
public function test_get_fontawesome_icon_map(string $component, string $plugintype, string $pluginname, string $dir): void {
$iconmap = component_callback($component, 'get_fontawesome_icon_map');
if (!$iconmap) {
$this->expectNotToPerformAssertions();
return;
}
foreach ($iconmap as $componenticon => $fa) {
list($iconcomponent, $iconname) = explode(':', $componenticon, 2);
$svgfile = "$dir/pix/$iconname.svg";
$this->assertFileExists($svgfile, "No SVG equivalent found for icon '$componenticon'");
$this->assertSame($component, $iconcomponent,
"Unexpected icon component found in {$component}_get_fontawesome_icon_map() function");
}
}
}
+56
View File
@@ -0,0 +1,56 @@
<?php
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
namespace core\task;
// phpcs:disable moodle.PHPUnit.TestCaseProvider.dataProviderSyntaxMethodNotFound
/**
* Detect common problems in plugin tasks.
*
* @group plugin_checks
* @package core
* @copyright 2025 Petr Skoda
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
final class plugin_checks_test extends \core\tests\plugin_checks_testcase {
/**
* Verify plugin all plugin tasks.
*
* @dataProvider all_plugins_provider
* @coversNothing
*
* @param string $component
* @param string $plugintype
* @param string $pluginname
* @param string $dir
*/
public function test_db_tasks_file(string $component, string $plugintype, string $pluginname, string $dir): void {
$file = "$dir/db/tasks.php";
$tasks = $this->fetch_array_from_file($file, 'tasks');
if (!$tasks) {
$this->expectNotToPerformAssertions();
return;
}
foreach ($tasks as $task) {
/** @var class-string<\core\task\task_base> $taskclassname */
$taskclassname = $task['classname'];
$t = new $taskclassname();
$this->assertIsString($t->get_name());
}
}
}
+58
View File
@@ -0,0 +1,58 @@
<?php
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
namespace core_message;
// phpcs:disable moodle.PHPUnit.TestCaseProvider.dataProviderSyntaxMethodNotFound
/**
* Detect common problems in message provider definitions of plugins.
*
* @group plugin_checks
* @package core_message
* @copyright 2025 Petr Skoda
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
final class plugin_checks_test extends \core\tests\plugin_checks_testcase {
/**
* Verify contents of plugin db/message.php file.
*
* @dataProvider all_plugins_provider
* @coversNothing
*
* @param string $component
* @param string $plugintype
* @param string $pluginname
* @param string $dir
*/
public function test_db_messages_file(string $component, string $plugintype, string $pluginname, string $dir): void {
$stringmanager = get_string_manager();
$langfile = "$dir/lang/en/$component.php";
$file = "$dir/db/messages.php";
$messageproviders = $this->fetch_array_from_file($file, 'messageproviders');
if (!$messageproviders) {
$this->expectNotToPerformAssertions();
return;
}
foreach ($messageproviders as $providername => $provider) {
$strname = 'messageprovider:' . $providername;
$this->assertTrue($stringmanager->string_exists($strname, $component),
"Missing capability name string '$strname' in $langfile");
}
}
}
+4 -2
View File
@@ -27,8 +27,6 @@ namespace mod_lesson\event;
defined('MOODLE_INTERNAL') || die();
debugging('mod_lesson\event\highscore_added has been deprecated. Since the functionality no longer resides in the lesson module.',
DEBUG_DEVELOPER);
/**
* The mod_lesson highscore added event class.
*
@@ -51,6 +49,10 @@ class highscore_added extends \core\event\base {
* Set basic properties for the event.
*/
protected function init() {
// phpcs:ignore moodle.Files.LineLength.TooLong
debugging('mod_lesson\event\highscore_added has been deprecated. Since the functionality no longer resides in the lesson module.',
DEBUG_DEVELOPER);
$this->data['objecttable'] = 'lesson_high_scores';
$this->data['crud'] = 'c';
$this->data['edulevel'] = self::LEVEL_PARTICIPATING;
@@ -27,8 +27,6 @@ namespace mod_lesson\event;
defined('MOODLE_INTERNAL') || die();
debugging('mod_lesson\event\highscores_viewed has been deprecated. Since the functionality no longer resides in the lesson module.',
DEBUG_DEVELOPER);
/**
* The mod_lesson highscores viewed class.
*
@@ -43,6 +41,10 @@ class highscores_viewed extends \core\event\base {
* Set basic properties for the event.
*/
protected function init() {
// phpcs:ignore moodle.Files.LineLength.TooLong
debugging('mod_lesson\event\highscores_viewed has been deprecated. Since the functionality no longer resides in the lesson module.',
DEBUG_DEVELOPER);
$this->data['objecttable'] = 'lesson';
$this->data['crud'] = 'r';
$this->data['edulevel'] = self::LEVEL_PARTICIPATING;
@@ -0,0 +1,119 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_privacy\privacy;
use core_privacy\manager;
/**
* Slow unit tests for all Privacy Providers that require database modifications.
*
* @package core_privacy
* @copyright 2018 Andrew Nicols <[email protected]>
* @copyright 2025 Petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
final class provider_advanced_test extends \advanced_testcase {
/**
* Returns a list of frankenstyle names of core components (plugins and subsystems).
*
* @return array the array of frankenstyle component names with the relevant class name.
*/
public static function get_component_list(): array {
$components = ['core' => [
'component' => 'core',
'classname' => manager::get_provider_classname_for_component('core'),
]];
// Get all plugins.
$plugintypes = \core_component::get_plugin_types();
foreach ($plugintypes as $plugintype => $typedir) {
$plugins = \core_component::get_plugin_list($plugintype);
foreach ($plugins as $pluginname => $plugindir) {
$frankenstyle = $plugintype . '_' . $pluginname;
$components[$frankenstyle] = [
'component' => $frankenstyle,
'classname' => manager::get_provider_classname_for_component($frankenstyle),
];
}
}
// Get all subsystems.
foreach (\core_component::get_core_subsystems() as $name => $path) {
if (isset($path)) {
$frankenstyle = 'core_' . $name;
$components[$frankenstyle] = [
'component' => $frankenstyle,
'classname' => manager::get_provider_classname_for_component($frankenstyle),
];
}
}
return $components;
}
/**
* Ensure that providers do not throw an error when processing a deleted user.
*
* @group plugin_checks
* @dataProvider is_user_data_provider
* @coversNothing
* @param string $component
*/
public function test_component_understands_deleted_users($component): void {
$this->resetAfterTest();
// Create a user.
$user = $this->getDataGenerator()->create_user();
// Delete the user and their context.
delete_user($user);
$usercontext = \context_user::instance($user->id);
$usercontext->delete();
$contextlist = manager::component_class_callback($component, \core_privacy\local\request\core_user_data_provider::class,
'get_contexts_for_userid', [$user->id]);
$this->assertInstanceOf(\core_privacy\local\request\contextlist::class, $contextlist);
}
/**
* List of providers which implement the core_user_data_provider.
*
* @return array
*/
public static function is_user_data_provider(): array {
return array_filter(self::get_component_list(), function($component): bool {
return static::component_implements(
$component['classname'],
\core_privacy\local\request\core_user_data_provider::class
);
});
}
/**
* Checks whether the component's provider class implements the specified interface, either directly or as a grandchild.
*
* @param string $providerclass The name of the class to test.
* @param string $interface the name of the interface we want to check.
* @return bool Whether the class implements the interface.
*/
protected static function component_implements($providerclass, $interface) {
if (class_exists($providerclass) && interface_exists($interface)) {
return is_subclass_of($providerclass, $interface);
}
return false;
}
}
+29 -46
View File
@@ -23,16 +23,13 @@
*/
namespace core_privacy\privacy;
defined('MOODLE_INTERNAL') || die();
use core_privacy\manager;
use core_privacy\local\metadata\collection;
use core_privacy\local\metadata\types\type;
use core_privacy\local\metadata\types\database_table;
use core_privacy\local\metadata\types\external_location;
use core_privacy\local\metadata\types\plugin_type_link;
use core_privacy\local\metadata\types\subsystem_link;
use core_privacy\local\metadata\types\user_preference;
// phpcs:disable moodle.PHPUnit.TestCaseProvider.dataProviderSyntaxMethodNotFound
/**
* Unit tests for all Privacy Providers.
@@ -40,7 +37,7 @@ use core_privacy\local\metadata\types\user_preference;
* @copyright 2018 Andrew Nicols <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
final class provider_test extends \advanced_testcase {
final class provider_test extends \core\tests\plugin_checks_testcase {
/**
* Returns a list of frankenstyle names of core components (plugins and subsystems).
*
@@ -49,7 +46,7 @@ final class provider_test extends \advanced_testcase {
public static function get_component_list(): array {
$components = ['core' => [
'component' => 'core',
'classname' => manager::get_provider_classname_for_component('core')
'classname' => manager::get_provider_classname_for_component('core'),
]];
// Get all plugins.
$plugintypes = \core_component::get_plugin_types();
@@ -80,6 +77,7 @@ final class provider_test extends \advanced_testcase {
/**
* Test that the specified null_provider works as expected.
*
* @group plugin_checks
* @dataProvider null_provider_provider
* @param string $component The name of the component.
* @param string $classname The name of the class for privacy
@@ -89,7 +87,6 @@ final class provider_test extends \advanced_testcase {
$this->assertIsString($reason);
$this->assertIsString(get_string($reason, $component));
$this->assertDebuggingNotCalled();
}
/**
@@ -109,6 +106,7 @@ final class provider_test extends \advanced_testcase {
/**
* Test that the specified metadata_provider works as expected.
*
* @group plugin_checks
* @dataProvider metadata_provider_provider
* @param string $component The name of the component.
* @param string $classname The name of the class for privacy
@@ -150,7 +148,6 @@ final class provider_test extends \advanced_testcase {
// Check that the string is also correctly defined.
$this->assertIsString(get_string($summary, $component));
$this->assertDebuggingNotCalled();
}
if ($fields = $item->get_privacy_fields()) {
@@ -161,7 +158,6 @@ final class provider_test extends \advanced_testcase {
// Check that the string is also correctly defined.
$this->assertIsString(get_string($identifier, $component));
$this->assertDebuggingNotCalled();
}
}
}
@@ -170,6 +166,7 @@ final class provider_test extends \advanced_testcase {
/**
* Test that all providers implement some form of compliant provider.
*
* @group plugin_checks
* @dataProvider get_component_list
* @param string $component frankenstyle component name, e.g. 'mod_assign'
* @param string $classname the fully qualified provider classname
@@ -182,29 +179,7 @@ final class provider_test extends \advanced_testcase {
/**
* Ensure that providers do not throw an error when processing a deleted user.
*
* @dataProvider is_user_data_provider
* @param string $component
*/
public function test_component_understands_deleted_users($component): void {
$this->resetAfterTest();
// Create a user.
$user = $this->getDataGenerator()->create_user();
// Delete the user and their context.
delete_user($user);
$usercontext = \context_user::instance($user->id);
$usercontext->delete();
$contextlist = manager::component_class_callback($component, \core_privacy\local\request\core_user_data_provider::class,
'get_contexts_for_userid', [$user->id]);
$this->assertInstanceOf(\core_privacy\local\request\contextlist::class, $contextlist);
}
/**
* Ensure that providers do not throw an error when processing a deleted user.
*
* @group plugin_checks
* @dataProvider is_user_data_provider
* @param string $component
*/
@@ -289,24 +264,32 @@ final class provider_test extends \advanced_testcase {
/**
* Test that all tables with user fields are covered by metadata providers
*
* @group plugin_checks
* @dataProvider get_component_list
* @coversNothing
* @param string $component frankenstyle component name, e.g. 'mod_assign'
* @param string $classname the fully qualified provider classname
*/
public function test_table_coverage(): void {
public function test_table_coverage(string $component, string $classname): void {
global $DB;
$dbman = $DB->get_manager();
$dbman = $DB->get_manager(); // Load DDL classes.
$tables = [];
foreach ($dbman->get_install_xml_files() as $filename) {
$xmldbfile = new \xmldb_file($filename);
if (!$xmldbfile->loadXMLStructure()) {
continue;
}
$structure = $xmldbfile->getStructure();
$tablelist = $structure->getTables();
$filename = \core_component::get_component_directory($component) . '/db/install.xml';
if (!file_exists($filename)) {
$this->expectNotToPerformAssertions();
return;
}
$xmldbfile = new \xmldb_file($filename);
$this->assertTrue($xmldbfile->loadXMLStructure());;
foreach ($tablelist as $table) {
if ($fields = $this->get_userid_fields($table)) {
$tables[$table->getName()] = ' - ' . $table->getName() . ' (' . join(', ', $fields) . ')';
}
$structure = $xmldbfile->getStructure();
$tablelist = $structure->getTables();
foreach ($tablelist as $table) {
if ($fields = $this->get_userid_fields($table)) {
$tables[$table->getName()] = ' - ' . $table->getName() . ' (' . join(', ', $fields) . ')';
}
}