Merge branch 'MDL-77436-401' of https://github.com/meirzamoodle/moodle into MOODLE_40...
[moodle.git] / enrol / tests / course_enrolment_manager_test.php
blobce8d6a97f49b4b113d3b6f8fee20838ed5487aa0
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17 namespace core_enrol;
19 use course_enrolment_manager;
21 /**
22 * Test course_enrolment_manager parts.
24 * @package core_enrol
25 * @category test
26 * @copyright 2016 Ruslan Kabalin, Lancaster University
27 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
29 class course_enrolment_manager_test extends \advanced_testcase {
30 /**
31 * The course context used in tests.
32 * @var stdClass
34 private $course = null;
35 /**
36 * List of users used in tests.
37 * @var array
39 private $users = array();
40 /**
41 * List of groups used in tests.
42 * @var array
44 private $groups = array();
46 /**
47 * Tests set up
49 protected function setUp(): void {
50 global $CFG;
51 require_once($CFG->dirroot . '/enrol/locallib.php');
52 $this->setAdminUser();
54 $users = array();
55 $groups = array();
56 // Create the course and the users.
57 $course = $this->getDataGenerator()->create_course();
58 $users['user0'] = $this->getDataGenerator()->create_user(
59 array('username' => 'user0', 'firstname' => 'user0')); // A user without group.
60 $users['user1'] = $this->getDataGenerator()->create_user(
61 array('username' => 'user1', 'firstname' => 'user1')); // User for group 1.
62 $users['user21'] = $this->getDataGenerator()->create_user(
63 array('username' => 'user21', 'firstname' => 'user21')); // Two users for group 2.
64 $users['user22'] = $this->getDataGenerator()->create_user(
65 array('username' => 'user22', 'firstname' => 'user22'));
66 $users['userall'] = $this->getDataGenerator()->create_user(
67 array('username' => 'userall', 'firstname' => 'userall')); // A user in all groups.
68 $users['usertch'] = $this->getDataGenerator()->create_user(
69 array('username' => 'usertch', 'firstname' => 'usertch')); // A user with teacher role.
71 // Enrol the users in the course.
72 $this->getDataGenerator()->enrol_user($users['user0']->id, $course->id, 'student'); // Student.
73 $this->getDataGenerator()->enrol_user($users['user1']->id, $course->id, 'student'); // Student.
74 $this->getDataGenerator()->enrol_user($users['user21']->id, $course->id, 'student'); // Student.
75 $this->getDataGenerator()->enrol_user($users['user22']->id, $course->id, 'student', 'manual', 0, 0, ENROL_USER_SUSPENDED); // Suspended student.
76 $this->getDataGenerator()->enrol_user($users['userall']->id, $course->id, 'student'); // Student.
77 $this->getDataGenerator()->enrol_user($users['usertch']->id, $course->id, 'editingteacher'); // Teacher.
79 // Create 2 groups.
80 $groups['group1'] = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
81 $groups['group2'] = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
83 // Add the users to the groups.
84 $this->getDataGenerator()->create_group_member(
85 array('groupid' => $groups['group1']->id, 'userid' => $users['user1']->id));
86 $this->getDataGenerator()->create_group_member(
87 array('groupid' => $groups['group2']->id, 'userid' => $users['user21']->id));
88 $this->getDataGenerator()->create_group_member(
89 array('groupid' => $groups['group2']->id, 'userid' => $users['user22']->id));
90 $this->getDataGenerator()->create_group_member(
91 array('groupid' => $groups['group1']->id, 'userid' => $users['userall']->id));
92 $this->getDataGenerator()->create_group_member(
93 array('groupid' => $groups['group2']->id, 'userid' => $users['userall']->id));
95 // Make setup data accessible from test methods.
96 $this->course = $course;
97 $this->users = $users;
98 $this->groups = $groups;
100 // Make sample users and not enroll to any course.
101 $this->getDataGenerator()->create_user([
102 'username' => 'testapiuser1',
103 'firstname' => 'testapiuser 1'
105 $this->getDataGenerator()->create_user([
106 'username' => 'testapiuser2',
107 'firstname' => 'testapiuser 2'
109 $this->getDataGenerator()->create_user([
110 'username' => 'testapiuser3',
111 'firstname' => 'testapiuser 3'
116 * Verify get_total_users() returned number of users expected in every situation.
118 public function test_get_total_users() {
119 global $PAGE;
121 $this->resetAfterTest();
123 // All users filtering.
124 $manager = new course_enrolment_manager($PAGE, $this->course);
125 $totalusers = $manager->get_total_users();
126 $this->assertEquals(6, $totalusers, 'All users must be returned when no filtering is applied.');
128 // Student role filtering.
129 $manager = new course_enrolment_manager($PAGE, $this->course, null, 5);
130 $totalusers = $manager->get_total_users();
131 $this->assertEquals(5, $totalusers, 'Only students must be returned when student role filtering is applied.');
133 // Teacher role filtering.
134 $manager = new course_enrolment_manager($PAGE, $this->course, null, 3);
135 $totalusers = $manager->get_total_users();
136 $this->assertEquals(1, $totalusers, 'Only teacher must be returned when teacher role filtering is applied.');
138 // Search user filtering.
139 $manager = new course_enrolment_manager($PAGE, $this->course, null, 0, 'userall');
140 $totalusers = $manager->get_total_users();
141 $this->assertEquals(1, $totalusers, 'Only searchable user must be returned when search filtering is applied.');
143 // Group 1 filtering.
144 $manager = new course_enrolment_manager($PAGE, $this->course, null, 0, '', $this->groups['group1']->id);
145 $totalusers = $manager->get_total_users();
146 $this->assertEquals(2, $totalusers, 'Only group members must be returned when group filtering is applied.');
148 // Group 2 filtering.
149 $manager = new course_enrolment_manager($PAGE, $this->course, null, 0, '', $this->groups['group2']->id);
150 $totalusers = $manager->get_total_users();
151 $this->assertEquals(3, $totalusers, 'Only group members must be returned when group filtering is applied.');
153 // 'No groups' filtering.
154 $manager = new course_enrolment_manager($PAGE, $this->course, null, 0, '', -1);
155 $totalusers = $manager->get_total_users();
156 $this->assertEquals(2, $totalusers, 'Only non-group members must be returned when \'no groups\' filtering is applied.');
158 // Active users filtering.
159 $manager = new course_enrolment_manager($PAGE, $this->course, null, 0, '', 0, ENROL_USER_ACTIVE);
160 $totalusers = $manager->get_total_users();
161 $this->assertEquals(5, $totalusers, 'Only active users must be returned when active users filtering is applied.');
163 // Suspended users filtering.
164 $manager = new course_enrolment_manager($PAGE, $this->course, null, 0, '', 0, ENROL_USER_SUSPENDED);
165 $totalusers = $manager->get_total_users();
166 $this->assertEquals(1, $totalusers, 'Only suspended users must be returned when suspended users filtering is applied.');
170 * Verify get_users() returned number of users expected in every situation.
172 public function test_get_users() {
173 global $PAGE;
175 $this->resetAfterTest();
177 // All users filtering.
178 $manager = new course_enrolment_manager($PAGE, $this->course);
179 $users = $manager->get_users('id');
180 $this->assertCount(6, $users, 'All users must be returned when no filtering is applied.');
181 $this->assertArrayHasKey($this->users['user0']->id, $users);
182 $this->assertArrayHasKey($this->users['user1']->id, $users);
183 $this->assertArrayHasKey($this->users['user21']->id, $users);
184 $this->assertArrayHasKey($this->users['user22']->id, $users);
185 $this->assertArrayHasKey($this->users['userall']->id, $users);
186 $this->assertArrayHasKey($this->users['usertch']->id, $users);
188 // Student role filtering.
189 $manager = new course_enrolment_manager($PAGE, $this->course, null, 5);
190 $users = $manager->get_users('id');
191 $this->assertCount(5, $users, 'Only students must be returned when student role filtering is applied.');
192 $this->assertArrayHasKey($this->users['user0']->id, $users);
193 $this->assertArrayHasKey($this->users['user1']->id, $users);
194 $this->assertArrayHasKey($this->users['user21']->id, $users);
195 $this->assertArrayHasKey($this->users['user22']->id, $users);
196 $this->assertArrayHasKey($this->users['userall']->id, $users);
198 // Teacher role filtering.
199 $manager = new course_enrolment_manager($PAGE, $this->course, null, 3);
200 $users = $manager->get_users('id');
201 $this->assertCount(1, $users, 'Only teacher must be returned when teacher role filtering is applied.');
202 $this->assertArrayHasKey($this->users['usertch']->id, $users);
204 // Search user filtering.
205 $manager = new course_enrolment_manager($PAGE, $this->course, null, 0, 'userall');
206 $users = $manager->get_users('id');
207 $this->assertCount(1, $users, 'Only searchable user must be returned when search filtering is applied.');
208 $this->assertArrayHasKey($this->users['userall']->id, $users);
210 // Group 1 filtering.
211 $manager = new course_enrolment_manager($PAGE, $this->course, null, 0, '', $this->groups['group1']->id);
212 $users = $manager->get_users('id');
213 $this->assertCount(2, $users, 'Only group members must be returned when group filtering is applied.');
214 $this->assertArrayHasKey($this->users['user1']->id, $users);
215 $this->assertArrayHasKey($this->users['userall']->id, $users);
217 // Group 2 filtering.
218 $manager = new course_enrolment_manager($PAGE, $this->course, null, 0, '', $this->groups['group2']->id);
219 $users = $manager->get_users('id');
220 $this->assertCount(3, $users, 'Only group members must be returned when group filtering is applied.');
221 $this->assertArrayHasKey($this->users['user21']->id, $users);
222 $this->assertArrayHasKey($this->users['user22']->id, $users);
223 $this->assertArrayHasKey($this->users['userall']->id, $users);
225 // 'No groups' filtering.
226 $manager = new course_enrolment_manager($PAGE, $this->course, null, 0, '', -1);
227 $users = $manager->get_users('id');
228 $this->assertCount(2, $users, 'Only non-group members must be returned when \'no groups\' filtering is applied.');
229 $this->assertArrayHasKey($this->users['user0']->id, $users);
230 $this->assertArrayHasKey($this->users['usertch']->id, $users);
232 // Active users filtering.
233 $manager = new course_enrolment_manager($PAGE, $this->course, null, 0, '', 0, ENROL_USER_ACTIVE);
234 $users = $manager->get_users('id');
235 $this->assertCount(5, $users, 'Only active users must be returned when active users filtering is applied.');
236 $this->assertArrayHasKey($this->users['user0']->id, $users);
237 $this->assertArrayHasKey($this->users['user1']->id, $users);
238 $this->assertArrayHasKey($this->users['user21']->id, $users);
239 $this->assertArrayHasKey($this->users['userall']->id, $users);
240 $this->assertArrayHasKey($this->users['usertch']->id, $users);
242 // Suspended users filtering.
243 $manager = new course_enrolment_manager($PAGE, $this->course, null, 0, '', 0, ENROL_USER_SUSPENDED);
244 $users = $manager->get_users('id');
245 $this->assertCount(1, $users, 'Only suspended users must be returned when suspended users filtering is applied.');
246 $this->assertArrayHasKey($this->users['user22']->id, $users);
250 * Sets up a custom profile field and the showuseridentity option, and creates a test user
251 * with suitable values set.
253 * @return stdClass Test user
255 protected function setup_for_user_identity_tests(): \stdClass {
256 // Configure extra fields to include one normal user field and one profile field, and
257 // set the values for a new test user.
258 $generator = $this->getDataGenerator();
259 $generator->create_custom_profile_field(['datatype' => 'text',
260 'shortname' => 'researchtopic', 'name' => 'Research topic']);
261 set_config('showuseridentity', 'email,department,profile_field_researchtopic');
262 return $generator->create_user(
263 ['username' => 'newuser', 'department' => 'Amphibian studies', 'email' => 'x@x.org',
264 'profile_field_researchtopic' => 'Frogs', 'imagealt' => 'Smart suit']);
268 * Checks that the get_users function returns the correct user fields.
270 public function test_get_users_fields() {
271 global $PAGE;
273 $this->resetAfterTest();
274 $newuser = $this->setup_for_user_identity_tests();
276 // Enrol the user in test course.
277 $this->getDataGenerator()->enrol_user($newuser->id, $this->course->id, 'student');
279 // Get all users and fish out the one we're interested in.
280 $manager = new course_enrolment_manager($PAGE, $this->course);
281 $users = $manager->get_users('id');
282 $user = $users[$newuser->id];
284 // Should include core required fields...
285 $this->assertEquals($newuser->id, $user->id);
287 // ...And the ones specified in showuseridentity (one of which is also needed for user pics).
288 $this->assertEquals('Amphibian studies', $user->department);
289 $this->assertEquals('Frogs', $user->profile_field_researchtopic);
290 $this->assertEquals('x@x.org', $user->email);
292 // And the ones necessary for user pics.
293 $this->assertEquals('Smart suit', $user->imagealt);
295 // But not some random other field like city.
296 $this->assertObjectNotHasAttribute('city', $user);
300 * Checks that the get_other_users function returns the correct user fields.
302 public function test_get_other_users_fields() {
303 global $PAGE, $DB;
305 $this->resetAfterTest();
307 // Configure extra fields to include one normal user field and one profile field, and
308 // set the values for a new test user.
309 $newuser = $this->setup_for_user_identity_tests();
310 $context = \context_course::instance($this->course->id);
311 role_assign($DB->get_field('role', 'id', ['shortname' => 'manager']), $newuser->id, $context->id);
313 // Get the 'other' (role but not enrolled) users and fish out the one we're interested in.
314 $manager = new course_enrolment_manager($PAGE, $this->course);
315 $users = array_values($manager->get_other_users('id'));
316 $user = $users[0];
318 // Should include core required fields...
319 $this->assertEquals($newuser->id, $user->id);
321 // ...And the ones specified in showuseridentity (one of which is also needed for user pics).
322 $this->assertEquals('Amphibian studies', $user->department);
323 $this->assertEquals('Frogs', $user->profile_field_researchtopic);
324 $this->assertEquals('x@x.org', $user->email);
326 // And the ones necessary for user pics.
327 $this->assertEquals('Smart suit', $user->imagealt);
329 // But not some random other field like city.
330 $this->assertObjectNotHasAttribute('city', $user);
334 * Checks that the get_potential_users function returns the correct user fields.
336 public function test_get_potential_users_fields() {
337 global $PAGE;
339 $this->resetAfterTest();
341 // Configure extra fields to include one normal user field and one profile field, and
342 // set the values for a new test user.
343 $newuser = $this->setup_for_user_identity_tests();
345 // Get the 'potential' (not enrolled) users and fish out the one we're interested in.
346 $manager = new course_enrolment_manager($PAGE, $this->course);
347 foreach (enrol_get_instances($this->course->id, true) as $enrolinstance) {
348 if ($enrolinstance->enrol === 'manual') {
349 $enrolid = $enrolinstance->id;
352 $users = array_values($manager->get_potential_users($enrolid));
353 $user = $users[0][$newuser->id];
355 // Should include core required fields...
356 $this->assertEquals($newuser->id, $user->id);
358 // ...And the ones specified in showuseridentity (one of which is also needed for user pics).
359 $this->assertEquals('Amphibian studies', $user->department);
360 $this->assertEquals('Frogs', $user->profile_field_researchtopic);
361 $this->assertEquals('x@x.org', $user->email);
363 // And the ones necessary for user pics.
364 $this->assertEquals('Smart suit', $user->imagealt);
366 // But not some random other field like city.
367 $this->assertObjectNotHasAttribute('city', $user);
371 * Test get_potential_users without returnexactcount param.
373 * @dataProvider search_users_provider
375 * @param int $perpage Number of users per page.
376 * @param bool $returnexactcount Return the exact count or not.
377 * @param int $expectedusers Expected number of users return.
378 * @param int $expectedtotalusers Expected total of users in database.
379 * @param bool $expectedmoreusers Expected for more users return or not.
381 public function test_get_potential_users($perpage, $returnexactcount, $expectedusers, $expectedtotalusers, $expectedmoreusers) {
382 global $DB, $PAGE;
383 $this->resetAfterTest();
384 $this->setAdminUser();
386 $enrol = $DB->get_record('enrol', array('courseid' => $this->course->id, 'enrol' => 'manual'));
387 $manager = new course_enrolment_manager($PAGE, $this->course);
388 $users = $manager->get_potential_users($enrol->id,
389 'testapiuser',
390 true,
392 $perpage,
394 $returnexactcount);
396 $this->assertCount($expectedusers, $users['users']);
397 $this->assertEquals($expectedmoreusers, $users['moreusers']);
398 if ($returnexactcount) {
399 $this->assertArrayHasKey('totalusers', $users);
400 $this->assertEquals($expectedtotalusers, $users['totalusers']);
401 } else {
402 $this->assertArrayNotHasKey('totalusers', $users);
407 * Tests get_potential_users when the search term includes a custom field.
409 public function test_get_potential_users_search_fields() {
410 global $PAGE;
412 $this->resetAfterTest();
414 // Configure extra fields to include one normal user field and one profile field, and
415 // set the values for a new test user.
416 $newuser = $this->setup_for_user_identity_tests();
418 // Set up the enrolment manager.
419 $manager = new course_enrolment_manager($PAGE, $this->course);
420 foreach (enrol_get_instances($this->course->id, true) as $enrolinstance) {
421 if ($enrolinstance->enrol === 'manual') {
422 $enrolid = $enrolinstance->id;
426 // Search for text included in a 'standard' (user table) identity field.
427 $users = array_values($manager->get_potential_users($enrolid, 'Amphibian studies'));
428 $this->assertEquals([$newuser->id], array_keys($users[0]));
430 // And for text included in a custom field.
431 $users = array_values($manager->get_potential_users($enrolid, 'Frogs'));
432 $this->assertEquals([$newuser->id], array_keys($users[0]));
434 // With partial matches.
435 $users = array_values($manager->get_potential_users($enrolid, 'Amphibian'));
436 $this->assertEquals([$newuser->id], array_keys($users[0]));
437 $users = array_values($manager->get_potential_users($enrolid, 'Fro'));
438 $this->assertEquals([$newuser->id], array_keys($users[0]));
440 // With partial in-the-middle matches.
441 $users = array_values($manager->get_potential_users($enrolid, 'phibian'));
442 $this->assertEquals([], array_keys($users[0]));
443 $users = array_values($manager->get_potential_users($enrolid, 'rog'));
444 $this->assertEquals([], array_keys($users[0]));
445 $users = array_values($manager->get_potential_users($enrolid, 'phibian', true));
446 $this->assertEquals([$newuser->id], array_keys($users[0]));
447 $users = array_values($manager->get_potential_users($enrolid, 'rog', true));
448 $this->assertEquals([$newuser->id], array_keys($users[0]));
450 // If the current user doesn't have access to identity fields then these searches won't work.
451 $this->setUser($this->getDataGenerator()->create_user());
452 $users = array_values($manager->get_potential_users($enrolid, 'Amphibian studies'));
453 $this->assertEquals([], array_keys($users[0]));
454 $users = array_values($manager->get_potential_users($enrolid, 'Frogs'));
455 $this->assertEquals([], array_keys($users[0]));
457 // Search for username field (there is special handling for this one field).
458 set_config('showuseridentity', 'username');
459 $this->setAdminUser();
460 $users = array_values($manager->get_potential_users($enrolid, 'newuse'));
461 $this->assertEquals([$newuser->id], array_keys($users[0]));
465 * Test search_other_users with returnexactcount param.
467 * @dataProvider search_users_provider
469 * @param int $perpage Number of users per page.
470 * @param bool $returnexactcount Return the exact count or not.
471 * @param int $expectedusers Expected number of users return.
472 * @param int $expectedtotalusers Expected total of users in database.
473 * @param bool $expectedmoreusers Expected for more users return or not.
475 public function test_search_other_users($perpage, $returnexactcount, $expectedusers, $expectedtotalusers, $expectedmoreusers) {
476 global $PAGE;
477 $this->resetAfterTest();
478 $this->setAdminUser();
480 $manager = new course_enrolment_manager($PAGE, $this->course);
481 $users = $manager->search_other_users(
482 'testapiuser',
483 true,
485 $perpage,
486 $returnexactcount);
488 $this->assertCount($expectedusers, $users['users']);
489 $this->assertEquals($expectedmoreusers, $users['moreusers']);
490 if ($returnexactcount) {
491 $this->assertArrayHasKey('totalusers', $users);
492 $this->assertEquals($expectedtotalusers, $users['totalusers']);
493 } else {
494 $this->assertArrayNotHasKey('totalusers', $users);
499 * Test case for test_get_potential_users, test_search_other_users and test_search_users tests.
501 * @return array Dataset
503 public function search_users_provider() {
504 return [
505 [2, false, 2, 3, true],
506 [5, false, 3, 3, false],
507 [2, true, 2, 3, true],
508 [5, true, 3, 3, false]
513 * Test search_users function.
515 * @dataProvider search_users_provider
517 * @param int $perpage Number of users per page.
518 * @param bool $returnexactcount Return the exact count or not.
519 * @param int $expectedusers Expected number of users return.
520 * @param int $expectedtotalusers Expected total of users in database.
521 * @param bool $expectedmoreusers Expected for more users return or not.
523 public function test_search_users($perpage, $returnexactcount, $expectedusers, $expectedtotalusers, $expectedmoreusers) {
524 global $PAGE;
525 $this->resetAfterTest();
527 $this->getDataGenerator()->create_and_enrol($this->course, 'student', ['firstname' => 'sutest 1']);
528 $this->getDataGenerator()->create_and_enrol($this->course, 'student', ['firstname' => 'sutest 2']);
529 $this->getDataGenerator()->create_and_enrol($this->course, 'student', ['firstname' => 'sutest 3']);
531 $manager = new course_enrolment_manager($PAGE, $this->course);
532 $users = $manager->search_users(
533 'sutest',
534 true,
536 $perpage,
537 $returnexactcount
540 $this->assertCount($expectedusers, $users['users']);
541 $this->assertEquals($expectedmoreusers, $users['moreusers']);
542 if ($returnexactcount) {
543 $this->assertArrayHasKey('totalusers', $users);
544 $this->assertEquals($expectedtotalusers, $users['totalusers']);
545 } else {
546 $this->assertArrayNotHasKey('totalusers', $users);