From 882c53dc146fa75ec9b0513e4f15a3ae05f8ce62 Mon Sep 17 00:00:00 2001 From: Shamim Rezaie Date: Fri, 5 Oct 2018 04:18:37 +1000 Subject: [PATCH] MDL-63500 enrol_cohort: Support for removal of multiple context users This issue is part of the MDL-62560 Epic. --- enrol/cohort/classes/privacy/provider.php | 54 +++++++++-- enrol/cohort/tests/privacy_test.php | 149 +++++++++++++++++++++++++++++- 2 files changed, 193 insertions(+), 10 deletions(-) diff --git a/enrol/cohort/classes/privacy/provider.php b/enrol/cohort/classes/privacy/provider.php index 9380cb89b31..299fdf1ed82 100644 --- a/enrol/cohort/classes/privacy/provider.php +++ b/enrol/cohort/classes/privacy/provider.php @@ -13,18 +13,25 @@ // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . + /** * Privacy Subsystem implementation for enrol_cohort. * * @package enrol_cohort + * @category privacy * @copyright 2018 Carlos Escobedo * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ + namespace enrol_cohort\privacy; + defined('MOODLE_INTERNAL') || die(); -use \core_privacy\local\metadata\collection; -use \core_privacy\local\request\contextlist; -use \core_privacy\local\request\approved_contextlist; + +use core_privacy\local\metadata\collection; +use core_privacy\local\request\approved_userlist; +use core_privacy\local\request\contextlist; +use core_privacy\local\request\approved_contextlist; +use core_privacy\local\request\userlist; /** * Privacy provider for enrol_cohort. @@ -33,8 +40,15 @@ use \core_privacy\local\request\approved_contextlist; * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class provider implements - \core_privacy\local\metadata\provider, - \core_privacy\local\request\plugin\provider { + // This plugin stores user data. + \core_privacy\local\metadata\provider, + + // This plugin contains user's enrolments. + \core_privacy\local\request\plugin\provider, + + // This plugin is capable of determining which users have data within it. + \core_privacy\local\request\core_userlist_provider { + /** * Returns meta data about this system. * @@ -46,6 +60,7 @@ class provider implements $collection->add_subsystem_link('core_group', [], 'privacy:metadata:core_group'); return $collection; } + /** * Get the list of contexts that contain user information for the specified user. * @@ -71,6 +86,22 @@ class provider implements return $contextlist; } + + /** + * Get the list of users who have data within a context. + * + * @param userlist $userlist The userlist containing the list of users who have data in this context/plugin combination. + */ + public static function get_users_in_context(userlist $userlist) { + $context = $userlist->get_context(); + + if (!$context instanceof \context_course) { + return; + } + + \core_group\privacy\provider::get_group_members_in_context($userlist, 'enrol_cohort'); + } + /** * Export all user data for the specified user, in the specified contexts. * @@ -105,6 +136,7 @@ class provider implements \core_group\privacy\provider::delete_groups_for_all_users($context, 'enrol_cohort'); } } + /** * Delete all user data for the specified user, in the specified contexts. * @@ -116,4 +148,14 @@ class provider implements } \core_group\privacy\provider::delete_groups_for_user($contextlist, 'enrol_cohort'); } -} \ No newline at end of file + + /** + * Delete multiple users within a single context. + * + * @param approved_userlist $userlist The approved context and user information to delete information for. + */ + public static function delete_data_for_users(approved_userlist $userlist) { + \core_group\privacy\provider::delete_groups_for_users($userlist, 'enrol_cohort'); + } + +} diff --git a/enrol/cohort/tests/privacy_test.php b/enrol/cohort/tests/privacy_test.php index abb38b00ec1..eedf21e3bdd 100644 --- a/enrol/cohort/tests/privacy_test.php +++ b/enrol/cohort/tests/privacy_test.php @@ -13,6 +13,7 @@ // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . + /** * Base class for unit tests for enrol_cohort. * @@ -21,10 +22,13 @@ * @copyright 2018 Carlos Escobedo * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ + defined('MOODLE_INTERNAL') || die(); -use \core_privacy\local\request\writer; -use \core_privacy\local\request\approved_contextlist; -use \enrol_cohort\privacy\provider; + +use core_privacy\local\request\writer; +use core_privacy\local\request\approved_contextlist; +use enrol_cohort\privacy\provider; + /** * Unit tests for the enrol_cohort implementation of the privacy API. * @@ -32,6 +36,7 @@ use \enrol_cohort\privacy\provider; * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class enrol_cohort_privacy_testcase extends \core_privacy\tests\provider_testcase { + /** * Test getting the context for the user ID related to this plugin. */ @@ -123,6 +128,7 @@ class enrol_cohort_privacy_testcase extends \core_privacy\tests\provider_testcas } } } + /** * Test for provider::delete_data_for_all_users_in_context(). */ @@ -170,6 +176,7 @@ class enrol_cohort_privacy_testcase extends \core_privacy\tests\provider_testcas WHERE g.courseid = ?", [$course1->id]) ); } + /** * Test for provider::delete_data_for_user(). */ @@ -249,4 +256,138 @@ class enrol_cohort_privacy_testcase extends \core_privacy\tests\provider_testcas WHERE g.courseid = ?", [$course2->id]) ); } -} \ No newline at end of file + + /** + * Test for provider::delete_data_for_users(). + */ + public function test_delete_data_for_users() { + global $DB; + + $this->resetAfterTest(); + + $trace = new null_progress_trace(); + + $cohortplugin = enrol_get_plugin('cohort'); + + $user1 = $this->getDataGenerator()->create_user(); + $user2 = $this->getDataGenerator()->create_user(); + $user3 = $this->getDataGenerator()->create_user(); + + $cat1 = $this->getDataGenerator()->create_category(); + + $course1 = $this->getDataGenerator()->create_course(array('category' => $cat1->id)); + $course2 = $this->getDataGenerator()->create_course(array('category' => $cat1->id)); + + $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course1->id)); + $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course2->id)); + + $studentrole = $DB->get_record('role', array('shortname' => 'student')); + + $cohort1 = $this->getDataGenerator()->create_cohort( + array('contextid' => context_coursecat::instance($cat1->id)->id)); + $cohortplugin->add_instance($course1, array( + 'customint1' => $cohort1->id, + 'roleid' => $studentrole->id, + 'customint2' => $group1->id) + ); + $cohortplugin->add_instance($course2, array( + 'customint1' => $cohort1->id, + 'roleid' => $studentrole->id, + 'customint2' => $group2->id) + ); + + $this->getDataGenerator()->enrol_user($user2->id, $course1->id); + $this->getDataGenerator()->enrol_user($user3->id, $course1->id); + $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user2->id)); + $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user3->id)); + + cohort_add_member($cohort1->id, $user1->id); + enrol_cohort_sync($trace, $course1->id); + + $this->assertEquals( + 3, + $DB->count_records_sql("SELECT COUNT(gm.id) + FROM {groups_members} gm + JOIN {groups} g ON gm.groupid = g.id + WHERE g.courseid = ?", [$course1->id]) + ); + + $this->assertEquals( + 1, + $DB->count_records_sql("SELECT COUNT(gm.id) + FROM {groups_members} gm + JOIN {groups} g ON gm.groupid = g.id + WHERE g.courseid = ?", [$course2->id]) + ); + + $coursecontext1 = context_course::instance($course1->id); + + $approveduserlist = new \core_privacy\local\request\approved_userlist($coursecontext1, 'enrol_cohort', + [$user1->id, $user2->id]); + provider::delete_data_for_users($approveduserlist); + + // Check we have 2 users in groups because we have deleted user1. + // User2's membership is manual and is not as the result of a cohort enrolment. + $this->assertEquals( + 2, + $DB->count_records_sql("SELECT COUNT(gm.id) + FROM {groups_members} gm + JOIN {groups} g ON gm.groupid = g.id + WHERE g.courseid = ?", [$course1->id]) + ); + + // Check that course2 is not touched. + $this->assertEquals( + 1, + $DB->count_records_sql("SELECT COUNT(gm.id) + FROM {groups_members} gm + JOIN {groups} g ON gm.groupid = g.id + WHERE g.courseid = ?", [$course2->id]) + ); + } + + /** + * Test for provider::get_users_in_context(). + */ + public function test_get_users_in_context() { + global $DB; + + $this->resetAfterTest(); + + $trace = new null_progress_trace(); + + $cohortplugin = enrol_get_plugin('cohort'); + + $cat1 = $this->getDataGenerator()->create_category(); + $course1 = $this->getDataGenerator()->create_course(array('category' => $cat1->id)); + $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course1->id)); + $studentrole = $DB->get_record('role', array('shortname' => 'student')); + $cohort1 = $this->getDataGenerator()->create_cohort( + array('contextid' => context_coursecat::instance($cat1->id)->id)); + $cohortplugin->add_instance($course1, array( + 'customint1' => $cohort1->id, + 'roleid' => $studentrole->id, + 'customint2' => $group1->id) + ); + + $user1 = $this->getDataGenerator()->create_user(); + + cohort_add_member($cohort1->id, $user1->id); + enrol_cohort_sync($trace, $course1->id); + + // Check if user1 is enrolled into course1 in group 1. + $this->assertEquals(1, $DB->count_records('role_assignments', array())); + $this->assertTrue($DB->record_exists('groups_members', array( + 'groupid' => $group1->id, + 'userid' => $user1->id, + 'component' => 'enrol_cohort') + )); + + $context = \context_course::instance($course1->id); + + $userlist = new \core_privacy\local\request\userlist($context, 'enrol_cohort'); + \enrol_cohort\privacy\provider::get_users_in_context($userlist); + + $this->assertEquals([$user1->id], $userlist->get_userids()); + } +} -- 2.11.4.GIT