From 65774d72b1838e26b19f9c5b6b976fbdb9ae5c86 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Thu, 1 Mar 2018 09:29:01 +0800 Subject: [PATCH] MDL-61307 core_privacy: Add legacy polyfill for contrib plugins This legacy polyfill allows plugin developers who release a single branch to work with multiple versions of Moodle to support the API in both Moodle 3.3 with PHP 5.6, and later versions. --- privacy/classes/local/legacy_polyfill.php | 106 +++++++++ privacy/tests/legacy_polyfill_test.php | 268 ++++++++++++++++++++++ 2 files changed, 374 insertions(+) create mode 100644 privacy/classes/local/legacy_polyfill.php create mode 100644 privacy/tests/legacy_polyfill_test.php diff --git a/privacy/classes/local/legacy_polyfill.php b/privacy/classes/local/legacy_polyfill.php new file mode 100644 index 00000000000..5c8ce6ed240 --- /dev/null +++ b/privacy/classes/local/legacy_polyfill.php @@ -0,0 +1,106 @@ +. + +/** + * This file contains the polyfill to allow a plugin to operate with Moodle 3.3 up. + * + * @package core_privacy + * @copyright 2018 Andrew Nicols + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +namespace core_privacy\local; + +use \core_privacy\local\metadata\collection; +use \core_privacy\local\request\contextlist; +use \core_privacy\local\request\approved_contextlist; +use \core_privacy\local\request\deletion_criteria; + +defined('MOODLE_INTERNAL') || die(); + +/** + * The trait used to provide a backwards compatability for third-party plugins. + * + * @copyright 2018 Andrew Nicols + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +trait legacy_polyfill { + + /** + * Get the language string identifier with the component's language + * file to explain why this plugin stores no data. + * + * @return string + */ + public static function get_reason() : string { + return static::_get_reason(); + } + + /** + * Get the list of items. + * + * @param collection $collection The initialised collection to add items to. + * @return collection A listing of user data stored through this system. + */ + public static function get_metadata(collection $collection) : collection { + return static::_get_metadata($collection); + } + + /** + * Export all user preferences for the plugin. + * + * @param int $userid The userid of the user whose data is to be exported. + */ + public static function export_user_preferences(int $userid) { + return static::_export_user_preferences($userid); + } + + /** + * Get the list of contexts that contain user information for the specified user. + * + * @param int $userid The user to search. + * @return contextlist $contextlist The contextlist containing the list of contexts used in this plugin. + */ + public static function get_contexts_for_userid(int $userid) : contextlist { + return static::_get_contexts_for_userid($userid); + } + + /** + * Export all user data for the specified user, in the specified contexts. + * + * @param approved_contextlist $contextlist The approved contexts to export information for. + */ + public static function export_user_data(approved_contextlist $contextlist) { + return static::_export_user_data($contextlist); + } + + /** + * Delete all use data which matches the specified deletion_criteria. + * + * @param deletion_criteria $criteria An object containing specific deletion criteria to delete for. + */ + public static function delete_for_context(deletion_criteria $criteria) { + return static::_delete_for_context($criteria); + } + + /** + * Delete all user data for the specified user, in the specified contexts. + * + * @param approved_contextlist $contextlist The approved contexts and user information to delete information for. + */ + public static function delete_user_data(approved_contextlist $contextlist) { + return static::_delete_user_data($contextlist); + } +} diff --git a/privacy/tests/legacy_polyfill_test.php b/privacy/tests/legacy_polyfill_test.php new file mode 100644 index 00000000000..2e44702aae7 --- /dev/null +++ b/privacy/tests/legacy_polyfill_test.php @@ -0,0 +1,268 @@ +. + +/** + * Unit tests for the privacy legacy polyfill. + * + * @package core_privacy + * @category test + * @copyright 2018 Andrew Nicols + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +global $CFG; + +use \core_privacy\local\metadata\collection; +use \core_privacy\local\request\contextlist; +use \core_privacy\local\request\deletion_criteria; +use \core_privacy\local\request\approved_contextlist; + +/** + * Tests for the \core_privacy API's types\user_preference functionality. + * Unit tests for the Privacy API's legacy_polyfill. + * + * @copyright 2018 Andrew Nicols + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class core_privacy_legacy_polyfill_test extends advanced_testcase { + /** + * Test that the null_provider polyfill works and that the static _get_reason can be + * successfully called. + */ + public function test_null_provider() { + $this->assertEquals('thisisareason', test_legacy_polyfill_null_provider::get_reason()); + } + + /** + * Test that the metdata\provider polyfill works and that the static _get_metadata can be + * successfully called. + */ + public function test_metadata_provider() { + $collection = new collection('core_privacy'); + $this->assertSame($collection, test_legacy_polyfill_metadata_provider::get_metadata($collection)); + } + + /** + * Test that the local\request\user_preference_provider polyfill works and that the static + * _export_user_preferences can be successfully called. + */ + public function test_user_preference_provider() { + $userid = 417; + + $mock = $this->createMock(test_legacy_polyfill_mock_wrapper::class); + $mock->expects($this->once()) + ->method('get_return_value') + ->with('_export_user_preferences', [$userid]) + ->willReturn(null); + + test_legacy_polyfill_user_preference_provider::$mock = $mock; + test_legacy_polyfill_user_preference_provider::export_user_preferences($userid); + } + + /** + * Test that the local\request\core_user_preference_provider polyfill works and that the static + * _get_contexts_for_userid can be successfully called. + */ + public function test_get_contexts_for_userid() { + $userid = 417; + $contextlist = new contextlist('core_privacy'); + + $mock = $this->createMock(test_legacy_polyfill_mock_wrapper::class); + $mock->expects($this->once()) + ->method('get_return_value') + ->with('_get_contexts_for_userid', [$userid]) + ->willReturn($contextlist); + + test_legacy_polyfill_request_provider::$mock = $mock; + $result = test_legacy_polyfill_request_provider::get_contexts_for_userid($userid); + $this->assertSame($contextlist, $result); + } + + /** + * Test that the local\request\core_user_preference_provider polyfill works and that the static + * _export_user_data can be successfully called. + */ + public function test_export_user_data() { + $contextlist = new approved_contextlist(\core_user::get_user_by_username('admin'), 'core_privacy', [98]); + + $mock = $this->createMock(test_legacy_polyfill_mock_wrapper::class); + $mock->expects($this->once()) + ->method('get_return_value') + ->with('_export_user_data', [$contextlist]); + + test_legacy_polyfill_request_provider::$mock = $mock; + test_legacy_polyfill_request_provider::export_user_data($contextlist); + } + + /** + * Test that the local\request\core_user_preference_provider polyfill works and that the static + * _delete_for_context can be successfully called. + */ + public function test_delete_for_context() { + $criteria = new deletion_criteria(\context_system::instance()); + + $mock = $this->createMock(test_legacy_polyfill_mock_wrapper::class); + $mock->expects($this->once()) + ->method('get_return_value') + ->with('_delete_for_context', [$criteria]); + + test_legacy_polyfill_request_provider::$mock = $mock; + test_legacy_polyfill_request_provider::delete_for_context($criteria); + } + + /** + * Test that the local\request\core_user_preference_provider polyfill works and that the static + * _delete_user_data can be successfully called. + */ + public function test_delete_user_data() { + $contextlist = new approved_contextlist(\core_user::get_user_by_username('admin'), 'core_privacy', [98]); + + $mock = $this->createMock(test_legacy_polyfill_mock_wrapper::class); + $mock->expects($this->once()) + ->method('get_return_value') + ->with('_delete_user_data', [$contextlist]); + + test_legacy_polyfill_request_provider::$mock = $mock; + test_legacy_polyfill_request_provider::delete_user_data($contextlist); + } +} + +/** + * Legacy polyfill test for the null provider. + * + * @copyright 2018 Andrew Nicols + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class test_legacy_polyfill_null_provider implements \core_privacy\local\metadata\null_provider { + + use \core_privacy\local\legacy_polyfill; + + /** + * Test for get_reason + */ + protected static function _get_reason() { + return 'thisisareason'; + } +} + +/** + * Legacy polyfill test for the metadata provider. + * + * @copyright 2018 Andrew Nicols + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class test_legacy_polyfill_metadata_provider implements \core_privacy\local\metadata\provider { + + use \core_privacy\local\legacy_polyfill; + + /** + * Test for get_metadata. + * + * @param collection $collection The initialised collection to add items to. + * @return collection A listing of user data stored through this system. + */ + protected static function _get_metadata(collection $collection) { + return $collection; + } +} + +/** + * Legacy polyfill test for the metadata provider. + * + * @copyright 2018 Andrew Nicols + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class test_legacy_polyfill_user_preference_provider implements \core_privacy\local\request\user_preference_provider { + + use \core_privacy\local\legacy_polyfill; + + /** + * @var test_legacy_polyfill_request_provider $mock + */ + public static $mock = null; + + /** + * Export all user preferences for the plugin. + * + * @param int $userid The userid of the user whose data is to be exported. + */ + protected static function _export_user_preferences($userid) { + return static::$mock->get_return_value(__FUNCTION__, func_get_args()); + } +} + +/** + * Legacy polyfill test for the request provider. + * + * @copyright 2018 Andrew Nicols + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class test_legacy_polyfill_request_provider implements \core_privacy\local\request\core_user_data_provider { + + use \core_privacy\local\legacy_polyfill; + + /** + * @var test_legacy_polyfill_request_provider $mock + */ + public static $mock = null; + + /** + * Test for get_contexts_for_userid. + * + * @param int $userid The user to search. + * @return contextlist $contextlist The contextlist containing the list of contexts used in this plugin. + */ + protected static function _get_contexts_for_userid($userid) { + return static::$mock->get_return_value(__FUNCTION__, func_get_args()); + } + + /** + * Test for export_user_data. + * + * @param approved_contextlist $contextlist The approved contexts to export information for. + */ + protected static function _export_user_data(approved_contextlist $contextlist) { + return static::$mock->get_return_value(__FUNCTION__, func_get_args()); + } + + + /** + * Delete all use data which matches the specified deletion_criteria. + * + * @param deletion_criteria $criteria An object containing specific deletion criteria to delete for. + */ + public static function _delete_for_context(deletion_criteria $criteria) { + return static::$mock->get_return_value(__FUNCTION__, func_get_args()); + } + + /** + * Delete all user data for the specified user, in the specified contexts. + * + * @param approved_contextlist $contextlist The approved contexts and user information to delete information for. + */ + public static function _delete_user_data(approved_contextlist $contextlist) { + return static::$mock->get_return_value(__FUNCTION__, func_get_args()); + } +} + +class test_legacy_polyfill_mock_wrapper { + /** + * Get the return value for the specified item. + */ + public function get_return_value() {} +} -- 2.39.2