on-demand release 3.3dev+
[moodle.git] / enrol / tests / enrollib_test.php
CommitLineData
05f6da14
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.
13//
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/>.
16
17/**
18 * Test non-plugin enrollib parts.
19 *
31ac2aef 20 * @package core_enrol
05f6da14
21 * @category phpunit
22 * @copyright 2012 Petr Skoda {@link http://skodak.org}
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 */
25
26defined('MOODLE_INTERNAL') || die();
27
28
29/**
30 * Test non-plugin enrollib parts.
31 *
32 * @package core
33 * @category phpunit
34 * @copyright 2012 Petr Skoda {@link http://skodak.org}
35 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
36 */
8252b7c2 37class core_enrollib_testcase extends advanced_testcase {
05f6da14
38
39 public function test_enrol_get_all_users_courses() {
40 global $DB, $CFG;
41
42 $this->resetAfterTest();
43
44 $studentrole = $DB->get_record('role', array('shortname'=>'student'));
45 $this->assertNotEmpty($studentrole);
46 $teacherrole = $DB->get_record('role', array('shortname'=>'teacher'));
47 $this->assertNotEmpty($teacherrole);
48
49 $admin = get_admin();
50 $user1 = $this->getDataGenerator()->create_user();
51 $user2 = $this->getDataGenerator()->create_user();
52 $user3 = $this->getDataGenerator()->create_user();
53 $user4 = $this->getDataGenerator()->create_user();
54 $user5 = $this->getDataGenerator()->create_user();
55
56 $category1 = $this->getDataGenerator()->create_category(array('visible'=>0));
57 $category2 = $this->getDataGenerator()->create_category();
58 $course1 = $this->getDataGenerator()->create_course(array('category'=>$category1->id));
59 $course2 = $this->getDataGenerator()->create_course(array('category'=>$category2->id));
60 $course3 = $this->getDataGenerator()->create_course(array('category'=>$category2->id, 'visible'=>0));
61 $course4 = $this->getDataGenerator()->create_course(array('category'=>$category2->id));
62
63 $maninstance1 = $DB->get_record('enrol', array('courseid'=>$course1->id, 'enrol'=>'manual'), '*', MUST_EXIST);
64 $DB->set_field('enrol', 'status', ENROL_INSTANCE_DISABLED, array('id'=>$maninstance1->id));
65 $maninstance1 = $DB->get_record('enrol', array('courseid'=>$course1->id, 'enrol'=>'manual'), '*', MUST_EXIST);
66 $maninstance2 = $DB->get_record('enrol', array('courseid'=>$course2->id, 'enrol'=>'manual'), '*', MUST_EXIST);
67 $maninstance3 = $DB->get_record('enrol', array('courseid'=>$course3->id, 'enrol'=>'manual'), '*', MUST_EXIST);
68 $maninstance4 = $DB->get_record('enrol', array('courseid'=>$course4->id, 'enrol'=>'manual'), '*', MUST_EXIST);
69
70 $manual = enrol_get_plugin('manual');
71 $this->assertNotEmpty($manual);
72
73 $manual->enrol_user($maninstance1, $user1->id, $teacherrole->id);
74 $manual->enrol_user($maninstance1, $user2->id, $studentrole->id);
75 $manual->enrol_user($maninstance1, $user4->id, $teacherrole->id, 0, 0, ENROL_USER_SUSPENDED);
76 $manual->enrol_user($maninstance1, $admin->id, $studentrole->id);
77
78 $manual->enrol_user($maninstance2, $user1->id);
79 $manual->enrol_user($maninstance2, $user2->id);
80 $manual->enrol_user($maninstance2, $user3->id, 0, 1, time()+(60*60));
81
82 $manual->enrol_user($maninstance3, $user1->id);
83 $manual->enrol_user($maninstance3, $user2->id);
84 $manual->enrol_user($maninstance3, $user3->id, 0, 1, time()-(60*60));
85 $manual->enrol_user($maninstance3, $user4->id, 0, 0, 0, ENROL_USER_SUSPENDED);
86
87
88 $courses = enrol_get_all_users_courses($CFG->siteguest);
89 $this->assertSame(array(), $courses);
90
91 $courses = enrol_get_all_users_courses(0);
92 $this->assertSame(array(), $courses);
93
94 // Results are sorted by visibility, sortorder by default (in our case order of creation)
95
96 $courses = enrol_get_all_users_courses($admin->id);
97 $this->assertCount(1, $courses);
98 $this->assertEquals(array($course1->id), array_keys($courses));
99
100 $courses = enrol_get_all_users_courses($admin->id, true);
101 $this->assertCount(0, $courses);
102 $this->assertEquals(array(), array_keys($courses));
103
104 $courses = enrol_get_all_users_courses($user1->id);
105 $this->assertCount(3, $courses);
106 $this->assertEquals(array($course2->id, $course1->id, $course3->id), array_keys($courses));
107
108 $courses = enrol_get_all_users_courses($user1->id, true);
109 $this->assertCount(2, $courses);
110 $this->assertEquals(array($course2->id, $course3->id), array_keys($courses));
111
112 $courses = enrol_get_all_users_courses($user2->id);
113 $this->assertCount(3, $courses);
114 $this->assertEquals(array($course2->id, $course1->id, $course3->id), array_keys($courses));
115
116 $courses = enrol_get_all_users_courses($user2->id, true);
117 $this->assertCount(2, $courses);
118 $this->assertEquals(array($course2->id, $course3->id), array_keys($courses));
119
120 $courses = enrol_get_all_users_courses($user3->id);
121 $this->assertCount(2, $courses);
122 $this->assertEquals(array($course2->id, $course3->id), array_keys($courses));
123
124 $courses = enrol_get_all_users_courses($user3->id, true);
125 $this->assertCount(1, $courses);
126 $this->assertEquals(array($course2->id), array_keys($courses));
127
128 $courses = enrol_get_all_users_courses($user4->id);
129 $this->assertCount(2, $courses);
130 $this->assertEquals(array($course1->id, $course3->id), array_keys($courses));
131
132 $courses = enrol_get_all_users_courses($user4->id, true);
133 $this->assertCount(0, $courses);
134 $this->assertEquals(array(), array_keys($courses));
135
136 // Make sure sorting and columns work.
137
138 $basefields = array('id', 'category', 'sortorder', 'shortname', 'fullname', 'idnumber',
d26eae4a 139 'startdate', 'visible', 'groupmode', 'groupmodeforce', 'defaultgroupingid');
05f6da14
140
141 $courses = enrol_get_all_users_courses($user2->id, true);
142 $course = reset($courses);
143 context_helper::preload_from_record($course);
144 $course = (array)$course;
145 $this->assertEquals($basefields, array_keys($course), '', 0, 10, true);
146
4a3fb71c 147 $courses = enrol_get_all_users_courses($user2->id, false, 'timecreated');
05f6da14 148 $course = reset($courses);
4a3fb71c 149 $this->assertTrue(property_exists($course, 'timecreated'));
05f6da14
150
151 $courses = enrol_get_all_users_courses($user2->id, false, null, 'id DESC');
152 $this->assertEquals(array($course3->id, $course2->id, $course1->id), array_keys($courses));
153 }
154
155 public function test_enrol_user_sees_own_courses() {
156 global $DB, $CFG;
157
158 $this->resetAfterTest();
159
160 $studentrole = $DB->get_record('role', array('shortname'=>'student'));
161 $this->assertNotEmpty($studentrole);
162 $teacherrole = $DB->get_record('role', array('shortname'=>'teacher'));
163 $this->assertNotEmpty($teacherrole);
164
165 $admin = get_admin();
166 $user1 = $this->getDataGenerator()->create_user();
167 $user2 = $this->getDataGenerator()->create_user();
168 $user3 = $this->getDataGenerator()->create_user();
169 $user4 = $this->getDataGenerator()->create_user();
170 $user5 = $this->getDataGenerator()->create_user();
171 $user6 = $this->getDataGenerator()->create_user();
172
173 $category1 = $this->getDataGenerator()->create_category(array('visible'=>0));
174 $category2 = $this->getDataGenerator()->create_category();
175 $course1 = $this->getDataGenerator()->create_course(array('category'=>$category1->id));
176 $course2 = $this->getDataGenerator()->create_course(array('category'=>$category2->id));
177 $course3 = $this->getDataGenerator()->create_course(array('category'=>$category2->id, 'visible'=>0));
178 $course4 = $this->getDataGenerator()->create_course(array('category'=>$category2->id));
179
180 $maninstance1 = $DB->get_record('enrol', array('courseid'=>$course1->id, 'enrol'=>'manual'), '*', MUST_EXIST);
181 $DB->set_field('enrol', 'status', ENROL_INSTANCE_DISABLED, array('id'=>$maninstance1->id));
182 $maninstance1 = $DB->get_record('enrol', array('courseid'=>$course1->id, 'enrol'=>'manual'), '*', MUST_EXIST);
183 $maninstance2 = $DB->get_record('enrol', array('courseid'=>$course2->id, 'enrol'=>'manual'), '*', MUST_EXIST);
184 $maninstance3 = $DB->get_record('enrol', array('courseid'=>$course3->id, 'enrol'=>'manual'), '*', MUST_EXIST);
185 $maninstance4 = $DB->get_record('enrol', array('courseid'=>$course4->id, 'enrol'=>'manual'), '*', MUST_EXIST);
186
187 $manual = enrol_get_plugin('manual');
188 $this->assertNotEmpty($manual);
189
190 $manual->enrol_user($maninstance1, $admin->id, $studentrole->id);
191
192 $manual->enrol_user($maninstance3, $user1->id, $teacherrole->id);
193
194 $manual->enrol_user($maninstance2, $user2->id, $studentrole->id);
195
196 $manual->enrol_user($maninstance1, $user3->id, $studentrole->id, 1, time()+(60*60));
197 $manual->enrol_user($maninstance2, $user3->id, 0, 1, time()-(60*60));
198 $manual->enrol_user($maninstance3, $user2->id, $studentrole->id);
199 $manual->enrol_user($maninstance4, $user2->id, 0, 0, 0, ENROL_USER_SUSPENDED);
200
201 $manual->enrol_user($maninstance1, $user4->id, $teacherrole->id, 0, 0, ENROL_USER_SUSPENDED);
202 $manual->enrol_user($maninstance3, $user4->id, 0, 0, 0, ENROL_USER_SUSPENDED);
203
204
205 $this->assertFalse(enrol_user_sees_own_courses($CFG->siteguest));
206 $this->assertFalse(enrol_user_sees_own_courses(0));
207 $this->assertFalse(enrol_user_sees_own_courses($admin));
208 $this->assertFalse(enrol_user_sees_own_courses(-222)); // Nonexistent user.
209
210 $this->assertTrue(enrol_user_sees_own_courses($user1));
211 $this->assertTrue(enrol_user_sees_own_courses($user2->id));
212 $this->assertFalse(enrol_user_sees_own_courses($user3->id));
213 $this->assertFalse(enrol_user_sees_own_courses($user4));
214 $this->assertFalse(enrol_user_sees_own_courses($user5));
215
216 $this->setAdminUser();
217 $this->assertFalse(enrol_user_sees_own_courses());
218
219 $this->setGuestUser();
220 $this->assertFalse(enrol_user_sees_own_courses());
221
222 $this->setUser(0);
223 $this->assertFalse(enrol_user_sees_own_courses());
224
225 $this->setUser($user1);
226 $this->assertTrue(enrol_user_sees_own_courses());
227
228 $this->setUser($user2);
229 $this->assertTrue(enrol_user_sees_own_courses());
230
231 $this->setUser($user3);
232 $this->assertFalse(enrol_user_sees_own_courses());
233
234 $this->setUser($user4);
235 $this->assertFalse(enrol_user_sees_own_courses());
236
237 $this->setUser($user5);
238 $this->assertFalse(enrol_user_sees_own_courses());
239
240 $user1 = $DB->get_record('user', array('id'=>$user1->id));
241 $this->setUser($user1);
242 $reads = $DB->perf_get_reads();
243 $this->assertTrue(enrol_user_sees_own_courses());
244 $this->assertGreaterThan($reads, $DB->perf_get_reads());
245
246 $user1 = $DB->get_record('user', array('id'=>$user1->id));
247 $this->setUser($user1);
248 require_login($course3);
249 $reads = $DB->perf_get_reads();
250 $this->assertTrue(enrol_user_sees_own_courses());
251 $this->assertEquals($reads, $DB->perf_get_reads());
252 }
631d9f66
DP
253
254 public function test_enrol_get_shared_courses() {
255 $this->resetAfterTest();
256
257 $user1 = $this->getDataGenerator()->create_user();
258 $user2 = $this->getDataGenerator()->create_user();
259 $user3 = $this->getDataGenerator()->create_user();
260
261 $course1 = $this->getDataGenerator()->create_course();
262 $this->getDataGenerator()->enrol_user($user1->id, $course1->id);
263 $this->getDataGenerator()->enrol_user($user2->id, $course1->id);
264
265 $course2 = $this->getDataGenerator()->create_course();
266 $this->getDataGenerator()->enrol_user($user1->id, $course2->id);
267
268 // Test that user1 and user2 have courses in common.
269 $this->assertTrue(enrol_get_shared_courses($user1, $user2, false, true));
270 // Test that user1 and user3 have no courses in common.
271 $this->assertFalse(enrol_get_shared_courses($user1, $user3, false, true));
272
273 // Test retrieving the courses in common.
274 $sharedcourses = enrol_get_shared_courses($user1, $user2, true);
275
276 // Only should be one shared course.
277 $this->assertCount(1, $sharedcourses);
278 $sharedcourse = array_shift($sharedcourses);
279 // It should be course 1.
280 $this->assertEquals($sharedcourse->id, $course1->id);
281 }
bb78e249
RT
282
283 /**
284 * Test user enrolment created event.
285 */
286 public function test_user_enrolment_created_event() {
287 global $DB;
288
289 $this->resetAfterTest();
290
291 $studentrole = $DB->get_record('role', array('shortname'=>'student'));
292 $this->assertNotEmpty($studentrole);
293
294 $admin = get_admin();
295
296 $course1 = $this->getDataGenerator()->create_course();
297
298 $maninstance1 = $DB->get_record('enrol', array('courseid'=>$course1->id, 'enrol'=>'manual'), '*', MUST_EXIST);
299
300 $manual = enrol_get_plugin('manual');
301 $this->assertNotEmpty($manual);
302
303 // Enrol user and capture event.
304 $sink = $this->redirectEvents();
305 $manual->enrol_user($maninstance1, $admin->id, $studentrole->id);
306 $events = $sink->get_events();
307 $sink->close();
308 $event = array_shift($events);
309
310 $dbuserenrolled = $DB->get_record('user_enrolments', array('userid' => $admin->id));
311 $this->assertInstanceOf('\core\event\user_enrolment_created', $event);
312 $this->assertEquals($dbuserenrolled->id, $event->objectid);
f1f4f4fd 313 $this->assertEquals(context_course::instance($course1->id), $event->get_context());
bb78e249
RT
314 $this->assertEquals('user_enrolled', $event->get_legacy_eventname());
315 $expectedlegacyeventdata = $dbuserenrolled;
316 $expectedlegacyeventdata->enrol = $manual->get_name();
317 $expectedlegacyeventdata->courseid = $course1->id;
318 $this->assertEventLegacyData($expectedlegacyeventdata, $event);
f1f4f4fd
MN
319 $expected = array($course1->id, 'course', 'enrol', '../enrol/users.php?id=' . $course1->id, $course1->id);
320 $this->assertEventLegacyLogData($expected, $event);
623a32e5 321 $this->assertEventContextNotUsed($event);
bb78e249 322 }
63245172
MN
323
324 /**
325 * Test user_enrolment_deleted event.
326 */
327 public function test_user_enrolment_deleted_event() {
328 global $DB;
329
330 $this->resetAfterTest(true);
331
332 $manualplugin = enrol_get_plugin('manual');
333 $user = $this->getDataGenerator()->create_user();
334 $course = $this->getDataGenerator()->create_course();
335 $student = $DB->get_record('role', array('shortname' => 'student'));
336
337 $enrol = $DB->get_record('enrol', array('courseid' => $course->id, 'enrol' => 'manual'), '*', MUST_EXIST);
338
339 // Enrol user.
340 $manualplugin->enrol_user($enrol, $user->id, $student->id);
341
342 // Get the user enrolment information, used to validate legacy event data.
343 $dbuserenrolled = $DB->get_record('user_enrolments', array('userid' => $user->id));
344
345 // Unenrol user and capture event.
346 $sink = $this->redirectEvents();
347 $manualplugin->unenrol_user($enrol, $user->id);
348 $events = $sink->get_events();
349 $sink->close();
350 $event = array_pop($events);
351
352 // Validate the event.
353 $this->assertInstanceOf('\core\event\user_enrolment_deleted', $event);
354 $this->assertEquals(context_course::instance($course->id), $event->get_context());
355 $this->assertEquals('user_unenrolled', $event->get_legacy_eventname());
356 $expectedlegacyeventdata = $dbuserenrolled;
357 $expectedlegacyeventdata->enrol = $manualplugin->get_name();
358 $expectedlegacyeventdata->courseid = $course->id;
359 $expectedlegacyeventdata->lastenrol = true;
360 $this->assertEventLegacyData($expectedlegacyeventdata, $event);
361 $expected = array($course->id, 'course', 'unenrol', '../enrol/users.php?id=' . $course->id, $course->id);
362 $this->assertEventLegacyLogData($expected, $event);
623a32e5 363 $this->assertEventContextNotUsed($event);
63245172 364 }
080c7d47
MG
365
366 /**
367 * Test enrol_instance_created, enrol_instance_updated and enrol_instance_deleted events.
368 */
369 public function test_instance_events() {
370 global $DB;
371
372 $this->resetAfterTest(true);
373
374 $selfplugin = enrol_get_plugin('self');
375 $studentrole = $DB->get_record('role', array('shortname' => 'student'));
376
377 $course = $this->getDataGenerator()->create_course();
378
379 // Creating enrol instance.
380 $sink = $this->redirectEvents();
381 $instanceid = $selfplugin->add_instance($course, array('status' => ENROL_INSTANCE_ENABLED,
382 'name' => 'Test instance 1',
383 'customint6' => 1,
384 'roleid' => $studentrole->id));
385 $events = $sink->get_events();
386 $sink->close();
387
388 $this->assertCount(1, $events);
389 $event = array_pop($events);
390 $this->assertInstanceOf('\core\event\enrol_instance_created', $event);
391 $this->assertEquals(context_course::instance($course->id), $event->get_context());
392 $this->assertEquals('self', $event->other['enrol']);
393 $this->assertEventContextNotUsed($event);
394
395 // Updating enrol instance.
396 $instance = $DB->get_record('enrol', array('id' => $instanceid));
397 $sink = $this->redirectEvents();
398 $selfplugin->update_status($instance, ENROL_INSTANCE_DISABLED);
399
400 $events = $sink->get_events();
401 $sink->close();
402
403 $this->assertCount(1, $events);
404 $event = array_pop($events);
405 $this->assertInstanceOf('\core\event\enrol_instance_updated', $event);
406 $this->assertEquals(context_course::instance($course->id), $event->get_context());
407 $this->assertEquals('self', $event->other['enrol']);
408 $this->assertEventContextNotUsed($event);
409
410 // Deleting enrol instance.
411 $instance = $DB->get_record('enrol', array('id' => $instanceid));
412 $sink = $this->redirectEvents();
413 $selfplugin->delete_instance($instance);
414
415 $events = $sink->get_events();
416 $sink->close();
417
418 $this->assertCount(1, $events);
419 $event = array_pop($events);
420 $this->assertInstanceOf('\core\event\enrol_instance_deleted', $event);
421 $this->assertEquals(context_course::instance($course->id), $event->get_context());
422 $this->assertEquals('self', $event->other['enrol']);
423 $this->assertEventContextNotUsed($event);
424 }
618336bf
DM
425
426 /**
427 * Confirms that timemodified field was updated after modification of user enrollment
428 */
429 public function test_enrollment_update_timemodified() {
430 global $DB;
431
432 $this->resetAfterTest(true);
433 $datagen = $this->getDataGenerator();
434
435 /** @var enrol_manual_plugin $manualplugin */
436 $manualplugin = enrol_get_plugin('manual');
437 $this->assertNotNull($manualplugin);
438
439 $studentroleid = $DB->get_field('role', 'id', ['shortname' => 'student'], MUST_EXIST);
440 $course = $datagen->create_course();
441 $user = $datagen->create_user();
442
443 $instanceid = null;
444 $instances = enrol_get_instances($course->id, true);
445 foreach ($instances as $inst) {
446 if ($inst->enrol == 'manual') {
447 $instanceid = (int)$inst->id;
448 break;
449 }
450 }
451 if (empty($instanceid)) {
452 $instanceid = $manualplugin->add_default_instance($course);
453 if (empty($instanceid)) {
454 $instanceid = $manualplugin->add_instance($course);
455 }
456 }
457 $this->assertNotNull($instanceid);
458
459 $instance = $DB->get_record('enrol', ['id' => $instanceid], '*', MUST_EXIST);
460 $manualplugin->enrol_user($instance, $user->id, $studentroleid, 0, 0, ENROL_USER_ACTIVE);
461 $userenrolorig = (int)$DB->get_field(
462 'user_enrolments',
463 'timemodified',
464 ['enrolid' => $instance->id, 'userid' => $user->id],
465 MUST_EXIST
466 );
467 $this->waitForSecond();
468 $this->waitForSecond();
469 $manualplugin->update_user_enrol($instance, $user->id, ENROL_USER_SUSPENDED);
470 $userenrolpost = (int)$DB->get_field(
471 'user_enrolments',
472 'timemodified',
473 ['enrolid' => $instance->id, 'userid' => $user->id],
474 MUST_EXIST
475 );
476
477 $this->assertGreaterThan($userenrolorig, $userenrolpost);
478 }
1ef06b43
RW
479
480 /**
481 * Test to confirm that enrol_get_my_courses only return the courses that
482 * the logged in user is enrolled in.
483 */
484 public function test_enrol_get_my_courses_only_enrolled_courses() {
485 $user = $this->getDataGenerator()->create_user();
486 $course1 = $this->getDataGenerator()->create_course();
487 $course2 = $this->getDataGenerator()->create_course();
488 $course3 = $this->getDataGenerator()->create_course();
489 $course4 = $this->getDataGenerator()->create_course();
490
491 $this->getDataGenerator()->enrol_user($user->id, $course1->id);
492 $this->getDataGenerator()->enrol_user($user->id, $course2->id);
493 $this->getDataGenerator()->enrol_user($user->id, $course3->id);
494 $this->resetAfterTest(true);
495 $this->setUser($user);
496
497 // By default this function should return all of the courses the user
498 // is enrolled in.
499 $courses = enrol_get_my_courses();
500
501 $this->assertCount(3, $courses);
502 $this->assertEquals($course1->id, $courses[$course1->id]->id);
503 $this->assertEquals($course2->id, $courses[$course2->id]->id);
504 $this->assertEquals($course3->id, $courses[$course3->id]->id);
505
506 // If a set of course ids are provided then the result set will only contain
507 // these courses.
508 $courseids = [$course1->id, $course2->id];
509 $courses = enrol_get_my_courses(['id'], 'visible DESC,sortorder ASC', 0, $courseids);
510
511 $this->assertCount(2, $courses);
512 $this->assertEquals($course1->id, $courses[$course1->id]->id);
513 $this->assertEquals($course2->id, $courses[$course2->id]->id);
514
515 // If the course ids list contains any ids for courses the user isn't enrolled in
516 // then they will be ignored (in this case $course4).
517 $courseids = [$course1->id, $course2->id, $course4->id];
518 $courses = enrol_get_my_courses(['id'], 'visible DESC,sortorder ASC', 0, $courseids);
519
520 $this->assertCount(2, $courses);
521 $this->assertEquals($course1->id, $courses[$course1->id]->id);
522 $this->assertEquals($course2->id, $courses[$course2->id]->id);
523 }
05f6da14 524}