From cf672397546533e88abc056d6a1945253f499fb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9line=20Perv=C3=A8s?= Date: Mon, 11 Jan 2021 09:31:19 +0100 Subject: [PATCH] [#85]multiple role enrolments --- classes/observers.php | 5 +- classes/task/enrol_role_unassign.php | 2 +- locallib.php | 44 +++++++++++++-- tests/observer_test.php | 80 +++++++++++++++++++++++++++- 4 files changed, 121 insertions(+), 10 deletions(-) diff --git a/classes/observers.php b/classes/observers.php index 0f2c30a..aca8946 100644 --- a/classes/observers.php +++ b/classes/observers.php @@ -97,12 +97,13 @@ public static function role_unassigned(\core\event\role_unassigned $event) { array( 'courseid' => $coursecontext->instanceid, 'roleid' => $roleid, - 'moodleuser' => $moodleuser + 'moodleuser' => $moodleuser, + 'contextid' => $context->id ) ); \core\task\manager::queue_adhoc_task($taskunenrolment); } else { - \mod_rocketchat_tools::role_unassign($coursecontext->instanceid, $roleid, $moodleuser); + \mod_rocketchat_tools::role_unassign($coursecontext->instanceid, $roleid, $moodleuser, $context->id); } } } diff --git a/classes/task/enrol_role_unassign.php b/classes/task/enrol_role_unassign.php index 5ea434a..b20e410 100644 --- a/classes/task/enrol_role_unassign.php +++ b/classes/task/enrol_role_unassign.php @@ -31,7 +31,7 @@ class enrol_role_unassign extends \core\task\adhoc_task { public function execute() { $data = $this->get_custom_data(); - \mod_rocketchat_tools::role_unassign($data->courseid, $data->roleid, $data->moodleuser); + \mod_rocketchat_tools::role_unassign($data->courseid, $data->roleid, $data->moodleuser, $data->contextid); } } \ No newline at end of file diff --git a/locallib.php b/locallib.php index 24a3400..47b81cd 100644 --- a/locallib.php +++ b/locallib.php @@ -356,17 +356,51 @@ public static function role_assign($courseid, int $roleid, $moodleuser): void { * @param int $roleid * @param $moodleuser */ - public static function role_unassign($courseid, int $roleid, $moodleuser): void { + public static function role_unassign($courseid, int $roleid, $moodleuser, $contextid) { $rocketchatmoduleinstances = self::get_rocketchat_module_instances($courseid); if (!empty($rocketchatmoduleinstances)) { $rocketchatapimanager = new rocket_chat_api_manager(); } foreach ($rocketchatmoduleinstances as $rocketchatmoduleinstance) { - if (in_array($roleid, array_filter(explode(',', $rocketchatmoduleinstance->moderatorroles)))) { - $rocketchatapimanager->unenrol_moderator_from_group($rocketchatmoduleinstance->rocketchatid, $moodleuser); + $moderaorroles = explode(',', $rocketchatmoduleinstance->moderatorroles); + $userroles = explode(',', $rocketchatmoduleinstance->userroles); + $hasothermoderatorrole = false; + $hasotheruserrole = false; + $wasmoderator = false; + // Has other moderator moodle roles? + foreach ($moderaorroles as $moderatorrole) { + if ($moderatorrole != $roleid) { + if (user_has_role_assignment($moodleuser->id, $moderatorrole, $contextid)) { + $hasothermoderatorrole = true; + break; + } + } + } + // Has other user moodle roles? + foreach ($userroles as $userrole) { + if ($userrole != $roleid) { + if (user_has_role_assignment($moodleuser->id, $userrole, $contextid)) { + $hasotheruserrole = true; + break; + } + } + } + if (in_array($roleid, array_filter($moderaorroles))) { + $wasmoderator = true; + if (!$hasothermoderatorrole) { + $rocketchatapimanager->revoke_moderator_in_group($rocketchatmoduleinstance->rocketchatid, $moodleuser); + } } - if (in_array($roleid, array_filter(explode(',', $rocketchatmoduleinstance->userroles)))) { - $rocketchatapimanager->unenrol_user_from_group($rocketchatmoduleinstance->rocketchatid, $moodleuser); + $wasuser = false; + if (!$hasothermoderatorrole) { + if (in_array($roleid, array_filter($userroles))) { + $wasuser = true; + if (!$hasotheruserrole) { + $rocketchatapimanager->unenrol_user_from_group($rocketchatmoduleinstance->rocketchatid, $moodleuser); + } + } else if($wasmoderator) { + $rocketchatapimanager->unenrol_user_from_group($rocketchatmoduleinstance->rocketchatid, $moodleuser); + } } } } diff --git a/tests/observer_test.php b/tests/observer_test.php index 385e784..939a20a 100644 --- a/tests/observer_test.php +++ b/tests/observer_test.php @@ -41,9 +41,9 @@ class observer_testcase extends advanced_testcase{ protected function setUp() { global $CFG, $DB; parent::setUp(); - set_config('recyclebin_patch', 1, 'mod_rocketchat'); $this->resetAfterTest(); + $this->preventResetByRollback(); $this->setAdminUser(); // Enable rocketchat module. $modulerecord = $DB->get_record('modules', ['name' => 'rocketchat']); @@ -134,7 +134,7 @@ public function test_module_visibility() { $this->assertTrue($this->rocketchatmanager->group_archived($this->rocketchat->rocketchatid)); } - public function test_user_role_changes() { + public function test_user_role_changes_unenrol() { global $DB; $members = $this->rocketchatmanager->get_group_members($this->rocketchat->rocketchatid); $this->assertCount(3, $members); @@ -169,6 +169,82 @@ public function test_user_role_changes() { $enrol->unenrol_user($instance, $this->usereditingteacher->id); } + public function test_user_role_changes() { + global $DB; + $members = $this->rocketchatmanager->get_group_members($this->rocketchat->rocketchatid); + $this->assertCount(3, $members); + $moderators = $this->rocketchatmanager->get_group_moderators($this->rocketchat->rocketchatid); + $this->assertCount(1, $moderators); + $moderator = $moderators[0]; + $this->assertEquals($this->usereditingteacher->username, $moderator->username); + $coursecontext = context_course::instance($this->course->id); + $student = $DB->get_record('role', array('shortname' => 'student')); + $editingteacher = $DB->get_record('role', array('shortname' => 'editingteacher')); + // Change role for usereditingteacher. + $enrol = enrol_get_plugin('manual'); + $enrolinstances = enrol_get_instances($this->course->id, true); + foreach ($enrolinstances as $courseenrolinstance) { + if ($courseenrolinstance->enrol == "manual") { + $instance = $courseenrolinstance; + break; + } + } + role_unassign($editingteacher->id, $this->usereditingteacher->id, $coursecontext->id); + // Enrol as student. + $this->getDataGenerator()->enrol_user($this->usereditingteacher->id, $this->course->id, $student->id); + $moderators = $this->rocketchatmanager->get_group_moderators($this->rocketchat->rocketchatid); + $members = $this->rocketchatmanager->get_group_members($this->rocketchat->rocketchatid); + $this->assertCount(3, $members); + $this->assertCount(0, $moderators); + role_unassign($editingteacher->id, $this->usereditingteacher->id, $coursecontext->id); + $this->getDataGenerator()->enrol_user($this->usereditingteacher->id, $this->course->id, $editingteacher->id); + $moderators = $this->rocketchatmanager->get_group_moderators($this->rocketchat->rocketchatid); + $members = $this->rocketchatmanager->get_group_members($this->rocketchat->rocketchatid); + $this->assertCount(3, $members); + $this->assertCount(1, $moderators); + role_unassign($editingteacher->id, $this->usereditingteacher->id, $coursecontext->id); + } + + public function test_double_user_role_changes() { + global $DB; + $members = $this->rocketchatmanager->get_group_members($this->rocketchat->rocketchatid); + $this->assertCount(3, $members); + $moderators = $this->rocketchatmanager->get_group_moderators($this->rocketchat->rocketchatid); + $this->assertCount(1, $moderators); + $moderator = $moderators[0]; + $this->assertEquals($this->usereditingteacher->username, $moderator->username); + $enrol = enrol_get_plugin('manual'); + $enrolinstances = enrol_get_instances($this->course->id, true); + foreach ($enrolinstances as $courseenrolinstance) { + if ($courseenrolinstance->enrol == "manual") { + $instance = $courseenrolinstance; + break; + } + } + // add editingteacher to student -> 2 roles + $editingteacher = $DB->get_record('role', array('shortname' => 'editingteacher')); + $student = $DB->get_record('role', array('shortname' => 'student')); + $this->getDataGenerator()->enrol_user($this->userstudent->id, $this->course->id, $editingteacher->id); + $moderators = $this->rocketchatmanager->get_group_moderators($this->rocketchat->rocketchatid); + $members = $this->rocketchatmanager->get_group_members($this->rocketchat->rocketchatid); + $this->assertCount(3, $members); + $this->assertCount(2, $moderators); + + // Unassign as student. + $coursecontext = context_course::instance($this->course->id); + role_unassign($student->id, $this->userstudent->id, $coursecontext->id ); + $moderators = $this->rocketchatmanager->get_group_moderators($this->rocketchat->rocketchatid); + $members = $this->rocketchatmanager->get_group_members($this->rocketchat->rocketchatid); + $this->assertCount(3, $members); + $this->assertCount(2, $moderators); + // Unassign as moderator , since last role will be removed from Rocket.Chat group. + role_unassign($editingteacher->id, $this->userstudent->id, $coursecontext->id ); + $moderators = $this->rocketchatmanager->get_group_moderators($this->rocketchat->rocketchatid); + $members = $this->rocketchatmanager->get_group_members($this->rocketchat->rocketchatid); + $this->assertCount(2, $members); + $this->assertCount(1, $moderators); + } + public function test_user_updated() { set_config('background_user_update', 0, 'mod_rocketchat'); $members = $this->rocketchatmanager->get_enriched_group_members($this->rocketchat->rocketchatid);