*/
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')),
+ ),
+ ),
+ );
+ }
+
- /**
- * Test get_enrolled_users
- */
- public function test_get_enrolled_users() {
- global $USER;
-
- $this->resetAfterTest(true);
-
- $course = self::getDataGenerator()->create_course();
- $user1 = self::getDataGenerator()->create_user();
- $user2 = self::getDataGenerator()->create_user();
- $user3 = self::getDataGenerator()->create_user();
- $this->setUser($user3);
-
- // Set the required capabilities by the external function.
- $context = context_course::instance($course->id);
- $roleid = $this->assignUserCapability('moodle/course:viewparticipants', $context->id);
- $this->assignUserCapability('moodle/user:viewdetails', $context->id, $roleid);
-
- // Enrol the users in the course.
- $this->getDataGenerator()->enrol_user($user1->id, $course->id, $roleid, 'manual');
- $this->getDataGenerator()->enrol_user($user2->id, $course->id, $roleid, 'manual');
- $this->getDataGenerator()->enrol_user($user3->id, $course->id, $roleid, 'manual');
-
- // Call the external function.
- $enrolledusers = core_enrol_external::get_enrolled_users($course->id);
-
- // We need to execute the return values cleaning process to simulate the web service server.
- $enrolledusers = external_api::clean_returnvalue(core_enrol_external::get_enrolled_users_returns(), $enrolledusers);
-
- // Check the result set.
- $this->assertEquals(3, count($enrolledusers));
- $this->assertArrayHasKey('email', $enrolledusers[0]);
-
- // Call the function with some parameters set.
- $enrolledusers = core_enrol_external::get_enrolled_users($course->id, array(
- array('name' => 'limitfrom', 'value' => 2),
- array('name' => 'limitnumber', 'value' => 1),
- array('name' => 'userfields', 'value' => 'id')
- ));
-
- // We need to execute the return values cleaning process to simulate the web service server.
- $enrolledusers = external_api::clean_returnvalue(core_enrol_external::get_enrolled_users_returns(), $enrolledusers);
-
- // Check the result set, we should only get the 3rd result, which is $user3.
- $this->assertCount(1, $enrolledusers);
- $this->assertEquals($user3->id, $enrolledusers[0]['id']);
- $this->assertArrayHasKey('id', $enrolledusers[0]);
- $this->assertArrayNotHasKey('email', $enrolledusers[0]);
-
- // Call without required capability.
- $this->unassignUserCapability('moodle/course:viewparticipants', $context->id, $roleid);
- $this->setExpectedException('moodle_exception');
- $categories = core_enrol_external::get_enrolled_users($course->id);
- }
-
+ /**
+ * 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_users_courses
*/