From f076ce283465a9868a23a63c095ae0091965a7d2 Mon Sep 17 00:00:00 2001 From: "Eloy Lafuente (stronk7)" Date: Fri, 6 Nov 2015 01:03:02 +0100 Subject: [PATCH] MDL-51861 enrol: new unit test to verify all conditions and filters This unit test does not verify contents, details, but only that the returned users for every group mode, for every filtering (active, groupid and withcapability) together with permissions are correct. --- enrol/tests/externallib_test.php | 320 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 320 insertions(+) diff --git a/enrol/tests/externallib_test.php b/enrol/tests/externallib_test.php index 170d064c7e0..9f0ee98d5a7 100644 --- a/enrol/tests/externallib_test.php +++ b/enrol/tests/externallib_test.php @@ -33,6 +33,326 @@ require_once($CFG->dirroot . '/enrol/externallib.php'); class core_enrol_externallib_testcase extends externallib_advanced_testcase { /** + * dataProvider for test_get_enrolled_users_visibility(). + */ + public function get_enrolled_users_visibility_provider() { + return array( + 'Course without groups, default behavior (not filtering by cap, group, active)' => + array( + 'settings' => array( + 'coursegroupmode' => NOGROUPS, + 'withcapability' => null, + 'groupid' => null, + 'onlyactive' => false, + 'allowedcaps' => array(), + ), + 'results' => array( // Everybody can view everybody. + 'user0' => array('canview' => array('user0', 'user1', 'user2', 'user2su', 'user31', 'user32', 'userall')), + 'user1' => array('canview' => array('user0', 'user1', 'user2', 'user2su', 'user31', 'user32', 'userall')), + 'user2' => array('canview' => array('user0', 'user1', 'user2', 'user2su', 'user31', 'user32', 'userall')), + 'user31' => array('canview' => array('user0', 'user1', 'user2', 'user2su', 'user31', 'user32', 'userall')), + 'userall' => array('canview' => array('user0', 'user1', 'user2', 'user2su', 'user31', 'user32', 'userall')), + ), + ), + + 'Course with visible groups, default behavior (not filtering by cap, group, active)' => + array( + 'settings' => array( + 'coursegroupmode' => VISIBLEGROUPS, + 'withcapability' => null, + 'groupid' => null, + 'onlyactive' => false, + 'allowedcaps' => array(), + ), + 'results' => array( // Everybody can view everybody. + 'user0' => array('canview' => array('user0', 'user1', 'user2', 'user2su', 'user31', 'user32', 'userall')), + 'user1' => array('canview' => array('user0', 'user1', 'user2', 'user2su', 'user31', 'user32', 'userall')), + 'user2' => array('canview' => array('user0', 'user1', 'user2', 'user2su', 'user31', 'user32', 'userall')), + 'user31' => array('canview' => array('user0', 'user1', 'user2', 'user2su', 'user31', 'user32', 'userall')), + 'userall' => array('canview' => array('user0', 'user1', 'user2', 'user2su', 'user31', 'user32', 'userall')), + ), + ), + + 'Course with separate groups, default behavior (not filtering by cap, group, active)' => + array( + 'settings' => array( + 'coursegroupmode' => SEPARATEGROUPS, + 'withcapability' => null, + 'groupid' => null, + 'onlyactive' => false, + 'allowedcaps' => array(), + ), + 'results' => array( // Only users from own groups are visible. + 'user0' => array('canview' => array()), // Poor guy, cannot see anybody, himself included. + 'user1' => array('canview' => array('user1', 'userall')), + 'user2' => array('canview' => array('user2', 'user2su', 'userall')), + 'user31' => array('canview' => array('user31', 'user32', 'userall')), + 'userall' => array('canview' => array('user1', 'user2', 'user2su', 'user31', 'user32', 'userall')), + ), + ), + + 'Course with separate groups, default behavior (not filtering but having moodle/site:accessallgroups)' => + array( + 'settings' => array( + 'coursegroupmode' => VISIBLEGROUPS, + 'withcapability' => null, + 'groupid' => null, + 'onlyactive' => false, + 'allowedcaps' => array('moodle/site:accessallgroups'), + ), + 'results' => array( // Everybody can view everybody. + 'user0' => array('canview' => array('user0', 'user1', 'user2', 'user2su', 'user31', 'user32', 'userall')), + 'user1' => array('canview' => array('user0', 'user1', 'user2', 'user2su', 'user31', 'user32', 'userall')), + 'user2' => array('canview' => array('user0', 'user1', 'user2', 'user2su', 'user31', 'user32', 'userall')), + 'user31' => array('canview' => array('user0', 'user1', 'user2', 'user2su', 'user31', 'user32', 'userall')), + 'userall' => array('canview' => array('user0', 'user1', 'user2', 'user2su', 'user31', 'user32', 'userall')), + ), + ), + + 'Course with separate groups, filtering onlyactive (missing moodle/course:enrolreview)' => + array( + 'settings' => array( + 'coursegroupmode' => SEPARATEGROUPS, + 'withcapability' => null, + 'groupid' => null, + 'onlyactive' => true, + 'allowedcaps' => array(), + ), + 'results' => array( // returns exception, cannot view anybody without the cap. + 'user2' => array('exception' => array( + 'type' => 'required_capability_exception', + 'message' => 'Review course enrolments')), + 'userall' => array('exception' => array( + 'type' => 'required_capability_exception', + 'message' => 'Review course enrolments')), + ), + ), + + 'Course with separate groups, filtering onlyactive (having moodle/course:enrolreview)' => + array( + 'settings' => array( + 'coursegroupmode' => SEPARATEGROUPS, + 'withcapability' => null, + 'groupid' => null, + 'onlyactive' => true, + 'allowedcaps' => array('moodle/course:enrolreview'), + ), + 'results' => array( // Suspended are not returned. + 'user2' => array('canview' => array('user2', 'userall')), + 'user31' => array('canview' => array('user31', 'user32', 'userall')), + 'userall' => array('canview' => array('user1', 'user2', 'user31', 'user32', 'userall')), + ), + ), + + 'Course with separate groups, filtering by groupid (not having moodle/site:accessallgroups)' => + array( + 'settings' => array( + 'coursegroupmode' => SEPARATEGROUPS, + 'withcapability' => null, + 'groupid' => 'group2', + 'onlyactive' => false, + 'allowedcaps' => array(), + ), + 'results' => array( // Only group 2 members and only for members. Exception for non-members. + 'user0' => array('exception' => array( + 'type' => 'required_capability_exception', + 'message' => 'Access all groups')), + 'user1' => array('exception' => array( + 'type' => 'required_capability_exception', + 'message' => 'Access all groups')), + 'user2' => array('canview' => array('user2', 'user2su', 'userall')), + 'userall' => array('canview' => array('user2', 'user2su', 'userall')), + ), + ), + + 'Course with separate groups, filtering by groupid (having moodle/site:accessallgroups)' => + array( + 'settings' => array( + 'coursegroupmode' => SEPARATEGROUPS, + 'withcapability' => null, + 'groupid' => 'group2', + 'onlyactive' => false, + 'allowedcaps' => array('moodle/site:accessallgroups'), + ), + 'results' => array( // All users with 'moodle/site:accessallgroups' can view group 2 + 'user0' => array('canview' => array('user2', 'user2su', 'userall')), + 'user1' => array('canview' => array('user2', 'user2su', 'userall')), + 'user2' => array('canview' => array('user2', 'user2su', 'userall')), + 'userall' => array('canview' => array('user2', 'user2su', 'userall')), + ), + ), + + 'Course with separate groups, filtering by withcapability (not having moodle/role:review)' => + array( + 'settings' => array( + 'coursegroupmode' => SEPARATEGROUPS, + 'withcapability' => 'moodle/course:bulkmessaging', + 'groupid' => null, + 'onlyactive' => false, + 'allowedcaps' => array(), + ), + 'results' => array( // No user has 'moodle/role:review' so exception. + 'user0' => array('exception' => array( + 'type' => 'required_capability_exception', + 'message' => 'Review permissions for others')), + 'user1' => array('exception' => array( + 'type' => 'required_capability_exception', + 'message' => 'Review permissions for others')), + 'user2' => array('exception' => array( + 'type' => 'required_capability_exception', + 'message' => 'Review permissions for others')), + 'userall' => array('exception' => array( + 'type' => 'required_capability_exception', + 'message' => 'Review permissions for others')), + ), + ), + + 'Course with separate groups, filtering by withcapability (having moodle/role:review)' => + array( + 'settings' => array( + 'coursegroupmode' => SEPARATEGROUPS, + 'withcapability' => 'moodle/course:bulkmessaging', + 'groupid' => null, + 'onlyactive' => false, + 'allowedcaps' => array('moodle/role:review'), + ), + 'results' => array( // No user has withcapability, but all have 'moodle/role:review'. Empties. + 'user0' => array('canview' => array()), + 'user1' => array('canview' => array()), + 'user2' => array('canview' => array()), + 'userall' => array('canview' => array()), + ), + ), + + 'Course with separate groups, filtering by withcapability (having moodle/role:review)' => + array( + 'settings' => array( + 'coursegroupmode' => SEPARATEGROUPS, + 'withcapability' => 'moodle/course:bulkmessaging', + 'groupid' => null, + 'onlyactive' => false, + 'allowedcaps' => array('moodle/role:review', 'moodle/course:bulkmessaging'), + ), + 'results' => array( // Users (previous) have withcapability, and all have 'moodle/role:review'. + 'user0' => array('canview' => array()), + 'user1' => array('canview' => array('user1')), + 'user2' => array('canview' => array('user2')), + 'userall' => array('canview' => array('user1', 'user2', 'userall')), + ), + ), + ); + } + + + /** + * Verify get_enrolled_users() returned users are the expected in every situation. + * + * @dataProvider get_enrolled_users_visibility_provider + */ + public function test_get_enrolled_users_visibility($settings, $results) { + + global $USER; + + $this->resetAfterTest(); + + // Create the course and the users. + $course = $this->getDataGenerator()->create_course(array('groupmode' => $settings['coursegroupmode'])); + $coursecontext = context_course::instance($course->id); + $user0 = $this->getDataGenerator()->create_user(array('username' => 'user0')); // A user without group. + $user1 = $this->getDataGenerator()->create_user(array('username' => 'user1')); // User for group 1. + $user2 = $this->getDataGenerator()->create_user(array('username' => 'user2')); // Two users for group 2. + $user2su = $this->getDataGenerator()->create_user(array('username' => 'user2su')); // (one suspended). + $user31 = $this->getDataGenerator()->create_user(array('username' => 'user31')); // Two users for group 3. + $user32 = $this->getDataGenerator()->create_user(array('username' => 'user32')); // (both enabled). + $userall = $this->getDataGenerator()->create_user(array('username' => 'userall')); // A user in all groups. + + // Create utility array of created users, to produce better assertion messages. + $createdusers = array(); + foreach (array($user0, $user1, $user2, $user2su, $user31, $user32, $userall) as $createduser) { + $createdusers[$createduser->id] = $createduser->username; + } + + // Enrol the users in the course. + $this->getDataGenerator()->enrol_user($user0->id, $course->id); + $this->getDataGenerator()->enrol_user($user1->id, $course->id); + $this->getDataGenerator()->enrol_user($user2->id, $course->id); + $this->getDataGenerator()->enrol_user($user2su->id, $course->id, null, 'manual', 0, 0, ENROL_USER_SUSPENDED); + $this->getDataGenerator()->enrol_user($user31->id, $course->id); + $this->getDataGenerator()->enrol_user($user32->id, $course->id); + $this->getDataGenerator()->enrol_user($userall->id, $course->id); + + // Create 3 groups. + $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course->id)); + $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course->id)); + $group3 = $this->getDataGenerator()->create_group(array('courseid' => $course->id)); + + // Add the users to the groups. + $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user1->id)); + $this->getDataGenerator()->create_group_member(array('groupid' => $group2->id, 'userid' => $user2->id)); + $this->getDataGenerator()->create_group_member(array('groupid' => $group2->id, 'userid' => $user2su->id)); + $this->getDataGenerator()->create_group_member(array('groupid' => $group3->id, 'userid' => $user31->id)); + $this->getDataGenerator()->create_group_member(array('groupid' => $group3->id, 'userid' => $user32->id)); + $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $userall->id)); + $this->getDataGenerator()->create_group_member(array('groupid' => $group2->id, 'userid' => $userall->id)); + $this->getDataGenerator()->create_group_member(array('groupid' => $group3->id, 'userid' => $userall->id)); + + // Create a role to add the allowedcaps. Users will have this role assigned. + $roleid = $this->getDataGenerator()->create_role(); + // Allow the specified capabilities. + if (!empty($settings['allowedcaps'])) { + foreach ($settings['allowedcaps'] as $capability) { + assign_capability($capability, CAP_ALLOW, $roleid, $coursecontext); + } + } + + // For each of the users, configure everything, perform the call, and assert results. + foreach ($results as $user => $expectations) { + // Convert canview expectations into a nice array of ids for easier handling. + $canview = array(); + $exception = null; + // Analyse the expectations. + if (isset($expectations['canview'])) { + foreach ($expectations['canview'] as $canviewuser) { + $canview[] = $createdusers[${$canviewuser}->id]; + } + } else if (isset($expectations['exception'])) { + $exception = $expectations['exception']; + $this->setExpectedException($exception['type'], $exception['message']); + } else { + // Failed, only canview and exception are supported. + $this->markTestIncomplete('Incomplete, only canview and exception are supported'); + } + // Switch to the user and assign the role. + $this->setUser(${$user}); + role_assign($roleid, $USER->id, $coursecontext); + + // Convert groupid to proper id. + $groupid = 0; + if (isset($settings['groupid'])) { + $groupid = ${$settings['groupid']}->id; + } + + // Call to the function. + $options = array( + array('name' => 'withcapability', 'value' => $settings['withcapability']), + array('name' => 'groupid', 'value' => $groupid), + array('name' => 'onlyactive', 'value' => $settings['onlyactive']), + array('name' => 'userfields', 'value' => 'id') + ); + $enrolledusers = core_enrol_external::get_enrolled_users($course->id, $options); + + // We are only interested in ids to check visibility. + $viewed = array(); + // Verify the user canview the expected users. + foreach ($enrolledusers as $enrolleduser) { + $viewed[] = $createdusers[$enrolleduser['id']]; + } + // Verify viewed matches canview expectation (using canonicalize to ignore ordering). + $this->assertEquals($canview, $viewed, "Problem checking visible users for '{$createdusers[$USER->id]}'", 0, 1, true); + } + } + + /** * Test get_enrolled_users */ public function test_get_enrolled_users() { -- 2.11.4.GIT