Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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
 *
20
 * @package    core_enrol
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
 
26
use core\plugininfo\enrol;
27
 
28
defined('MOODLE_INTERNAL') || die();
29
 
30
 
31
/**
32
 * Test non-plugin enrollib parts.
33
 *
34
 * @package    core
35
 * @category   phpunit
36
 * @copyright  2012 Petr Skoda {@link http://skodak.org}
37
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
38
 */
39
class enrollib_test extends advanced_testcase {
40
 
11 efrain 41
    public function test_enrol_get_all_users_courses(): void {
1 efrain 42
        global $DB, $CFG;
43
 
44
        $this->resetAfterTest();
45
 
46
        $studentrole = $DB->get_record('role', array('shortname'=>'student'));
47
        $this->assertNotEmpty($studentrole);
48
        $teacherrole = $DB->get_record('role', array('shortname'=>'teacher'));
49
        $this->assertNotEmpty($teacherrole);
50
 
51
        $admin = get_admin();
52
        $user1 = $this->getDataGenerator()->create_user();
53
        $user2 = $this->getDataGenerator()->create_user();
54
        $user3 = $this->getDataGenerator()->create_user();
55
        $user4 = $this->getDataGenerator()->create_user();
56
        $user5 = $this->getDataGenerator()->create_user();
57
 
58
        $category1 = $this->getDataGenerator()->create_category(array('visible'=>0));
59
        $category2 = $this->getDataGenerator()->create_category();
60
 
61
        $course1 = $this->getDataGenerator()->create_course(array(
62
            'shortname' => 'Z',
63
            'idnumber' => '123',
64
            'category' => $category1->id,
65
        ));
66
        $course2 = $this->getDataGenerator()->create_course(array(
67
            'shortname' => 'X',
68
            'idnumber' => '789',
69
            'category' => $category2->id,
70
        ));
71
        $course3 = $this->getDataGenerator()->create_course(array(
72
            'shortname' => 'Y',
73
            'idnumber' => '456',
74
            'category' => $category2->id,
75
            'visible' => 0,
76
        ));
77
        $course4 = $this->getDataGenerator()->create_course(array(
78
            'shortname' => 'W',
79
            'category' => $category2->id,
80
        ));
81
 
82
        $maninstance1 = $DB->get_record('enrol', array('courseid'=>$course1->id, 'enrol'=>'manual'), '*', MUST_EXIST);
83
        $DB->set_field('enrol', 'status', ENROL_INSTANCE_DISABLED, array('id'=>$maninstance1->id));
84
        $maninstance1 = $DB->get_record('enrol', array('courseid'=>$course1->id, 'enrol'=>'manual'), '*', MUST_EXIST);
85
        $maninstance2 = $DB->get_record('enrol', array('courseid'=>$course2->id, 'enrol'=>'manual'), '*', MUST_EXIST);
86
        $maninstance3 = $DB->get_record('enrol', array('courseid'=>$course3->id, 'enrol'=>'manual'), '*', MUST_EXIST);
87
        $maninstance4 = $DB->get_record('enrol', array('courseid'=>$course4->id, 'enrol'=>'manual'), '*', MUST_EXIST);
88
 
89
        $manual = enrol_get_plugin('manual');
90
        $this->assertNotEmpty($manual);
91
 
92
        $manual->enrol_user($maninstance1, $user1->id, $teacherrole->id);
93
        $manual->enrol_user($maninstance1, $user2->id, $studentrole->id);
94
        $manual->enrol_user($maninstance1, $user4->id, $teacherrole->id, 0, 0, ENROL_USER_SUSPENDED);
95
        $manual->enrol_user($maninstance1, $admin->id, $studentrole->id);
96
 
97
        $manual->enrol_user($maninstance2, $user1->id);
98
        $manual->enrol_user($maninstance2, $user2->id);
99
        $manual->enrol_user($maninstance2, $user3->id, 0, 1, time()+(60*60));
100
 
101
        $manual->enrol_user($maninstance3, $user1->id);
102
        $manual->enrol_user($maninstance3, $user2->id);
103
        $manual->enrol_user($maninstance3, $user3->id, 0, 1, time()-(60*60));
104
        $manual->enrol_user($maninstance3, $user4->id, 0, 0, 0, ENROL_USER_SUSPENDED);
105
 
106
 
107
        $courses = enrol_get_all_users_courses($CFG->siteguest);
108
        $this->assertSame(array(), $courses);
109
 
110
        $courses = enrol_get_all_users_courses(0);
111
        $this->assertSame(array(), $courses);
112
 
113
        // Results are sorted by visibility, sortorder by default (in our case order of creation)
114
 
115
        $courses = enrol_get_all_users_courses($admin->id);
116
        $this->assertCount(1, $courses);
117
        $this->assertEquals(array($course1->id), array_keys($courses));
118
 
119
        $courses = enrol_get_all_users_courses($admin->id, true);
120
        $this->assertCount(0, $courses);
121
        $this->assertEquals(array(), array_keys($courses));
122
 
123
        $courses = enrol_get_all_users_courses($user1->id);
124
        $this->assertCount(3, $courses);
125
        $this->assertEquals(array($course2->id, $course1->id, $course3->id), array_keys($courses));
126
 
127
        $courses = enrol_get_all_users_courses($user1->id, true);
128
        $this->assertCount(2, $courses);
129
        $this->assertEquals(array($course2->id, $course3->id), array_keys($courses));
130
 
131
        $courses = enrol_get_all_users_courses($user2->id);
132
        $this->assertCount(3, $courses);
133
        $this->assertEquals(array($course2->id, $course1->id, $course3->id), array_keys($courses));
134
 
135
        $courses = enrol_get_all_users_courses($user2->id, true);
136
        $this->assertCount(2, $courses);
137
        $this->assertEquals(array($course2->id, $course3->id), array_keys($courses));
138
 
139
        $courses = enrol_get_all_users_courses($user3->id);
140
        $this->assertCount(2, $courses);
141
        $this->assertEquals(array($course2->id, $course3->id), array_keys($courses));
142
 
143
        $courses = enrol_get_all_users_courses($user3->id, true);
144
        $this->assertCount(1, $courses);
145
        $this->assertEquals(array($course2->id), array_keys($courses));
146
 
147
        $courses = enrol_get_all_users_courses($user4->id);
148
        $this->assertCount(2, $courses);
149
        $this->assertEquals(array($course1->id, $course3->id), array_keys($courses));
150
 
151
        $courses = enrol_get_all_users_courses($user4->id, true);
152
        $this->assertCount(0, $courses);
153
        $this->assertEquals(array(), array_keys($courses));
154
 
155
        // Make sure sorting and columns work.
156
 
157
        $basefields = array('id', 'category', 'sortorder', 'shortname', 'fullname', 'idnumber',
158
            'startdate', 'visible', 'groupmode', 'groupmodeforce', 'defaultgroupingid');
159
 
160
        $courses = enrol_get_all_users_courses($user2->id, true);
161
        $course = reset($courses);
162
        context_helper::preload_from_record($course);
163
        $course = (array)$course;
164
        $this->assertEqualsCanonicalizing($basefields, array_keys($course));
165
 
166
        $courses = enrol_get_all_users_courses($user2->id, false, 'timecreated');
167
        $course = reset($courses);
168
        $this->assertTrue(property_exists($course, 'timecreated'));
169
 
170
        $courses = enrol_get_all_users_courses($user2->id, false, null, 'id DESC');
171
        $this->assertEquals(array($course2->id, $course3->id, $course1->id), array_keys($courses));
172
 
173
        // Make sure that implicit sorting defined in navsortmycoursessort is respected.
174
 
175
        $CFG->navsortmycoursessort = 'shortname';
176
 
177
        $courses = enrol_get_all_users_courses($user1->id);
178
        $this->assertEquals(array($course2->id, $course3->id, $course1->id), array_keys($courses));
179
 
180
        // But still the explicit sorting takes precedence over the implicit one.
181
 
182
        $courses = enrol_get_all_users_courses($user1->id, false, null, 'shortname DESC');
183
        $this->assertEquals(array($course2->id, $course1->id, $course3->id), array_keys($courses));
184
 
185
        // Make sure that implicit visibility sorting defined in navsortmycourseshiddenlast is respected for all course sortings.
186
 
187
        $CFG->navsortmycoursessort = 'sortorder';
188
        $CFG->navsortmycourseshiddenlast = true;
189
        $courses = enrol_get_all_users_courses($user1->id);
190
        $this->assertEquals(array($course2->id, $course1->id, $course3->id), array_keys($courses));
191
 
192
        $CFG->navsortmycoursessort = 'sortorder';
193
        $CFG->navsortmycourseshiddenlast = false;
194
        $courses = enrol_get_all_users_courses($user1->id);
195
        $this->assertEquals(array($course1->id, $course3->id, $course2->id), array_keys($courses));
196
 
197
        $CFG->navsortmycoursessort = 'fullname';
198
        $CFG->navsortmycourseshiddenlast = true;
199
        $courses = enrol_get_all_users_courses($user1->id);
200
        $this->assertEquals(array($course2->id, $course1->id, $course3->id), array_keys($courses));
201
 
202
        $CFG->navsortmycoursessort = 'fullname';
203
        $CFG->navsortmycourseshiddenlast = false;
204
        $courses = enrol_get_all_users_courses($user1->id);
205
        $this->assertEquals(array($course1->id, $course2->id, $course3->id), array_keys($courses));
206
 
207
        $CFG->navsortmycoursessort = 'shortname';
208
        $CFG->navsortmycourseshiddenlast = true;
209
        $courses = enrol_get_all_users_courses($user1->id);
210
        $this->assertEquals(array($course2->id, $course3->id, $course1->id), array_keys($courses));
211
 
212
        $CFG->navsortmycoursessort = 'shortname';
213
        $CFG->navsortmycourseshiddenlast = false;
214
        $courses = enrol_get_all_users_courses($user1->id);
215
        $this->assertEquals(array($course2->id, $course3->id, $course1->id), array_keys($courses));
216
 
217
        $CFG->navsortmycoursessort = 'idnumber';
218
        $CFG->navsortmycourseshiddenlast = true;
219
        $courses = enrol_get_all_users_courses($user1->id);
220
        $this->assertEquals(array($course2->id, $course1->id, $course3->id), array_keys($courses));
221
 
222
        $CFG->navsortmycoursessort = 'idnumber';
223
        $CFG->navsortmycourseshiddenlast = false;
224
        $courses = enrol_get_all_users_courses($user1->id);
225
        $this->assertEquals(array($course1->id, $course3->id, $course2->id), array_keys($courses));
226
 
227
        // But still the explicit visibility sorting takes precedence over the implicit one.
228
 
229
        $courses = enrol_get_all_users_courses($user1->id, false, null, 'visible DESC, shortname DESC');
230
        $this->assertEquals(array($course2->id, $course1->id, $course3->id), array_keys($courses));
231
    }
232
 
233
    /**
234
     * Test enrol_course_delete() without passing a user id. When a value for user id is not present, the method
235
     * should delete all enrolment related data in the course.
236
     */
11 efrain 237
    public function test_enrol_course_delete_without_userid(): void {
1 efrain 238
        global $DB;
239
 
240
        $this->resetAfterTest();
241
 
242
        // Create users.
243
        $user1 = $this->getDataGenerator()->create_user();
244
        $user2 = $this->getDataGenerator()->create_user();
245
        // Create a course.
246
        $course = $this->getDataGenerator()->create_course();
247
        $coursecontext = context_course::instance($course->id);
248
 
249
        $studentrole = $DB->get_record('role', ['shortname' => 'student']);
250
 
251
        $manual = enrol_get_plugin('manual');
252
        $manualinstance = $DB->get_record('enrol', ['courseid' => $course->id, 'enrol' => 'manual'], '*', MUST_EXIST);
253
        // Enrol user1 as a student in the course using manual enrolment.
254
        $manual->enrol_user($manualinstance, $user1->id, $studentrole->id);
255
 
256
        $self = enrol_get_plugin('self');
257
        $selfinstance = $DB->get_record('enrol', ['courseid' => $course->id, 'enrol' => 'self'], '*', MUST_EXIST);
258
        $self->update_status($selfinstance, ENROL_INSTANCE_ENABLED);
259
        // Enrol user2 as a student in the course using self enrolment.
260
        $self->enrol_user($selfinstance, $user2->id, $studentrole->id);
261
 
262
        // Delete all enrolment related records in the course.
263
        enrol_course_delete($course);
264
 
265
        // The course enrolment of user1 should not exists.
266
        $user1enrolment = $DB->get_record('user_enrolments',
267
            ['enrolid' => $manualinstance->id, 'userid' => $user1->id]);
268
        $this->assertFalse($user1enrolment);
269
 
270
        // The role assignment of user1 should not exists.
271
        $user1roleassignment = $DB->get_record('role_assignments',
272
            ['roleid' => $studentrole->id, 'userid'=> $user1->id, 'contextid' => $coursecontext->id]
273
        );
274
        $this->assertFalse($user1roleassignment);
275
 
276
        // The course enrolment of user2 should not exists.
277
        $user2enrolment = $DB->get_record('user_enrolments',
278
            ['enrolid' => $selfinstance->id, 'userid' => $user2->id]);
279
        $this->assertFalse($user2enrolment);
280
 
281
        // The role assignment of user2 should not exists.
282
        $user2roleassignment = $DB->get_record('role_assignments',
283
            ['roleid' => $studentrole->id, 'userid'=> $user2->id, 'contextid' => $coursecontext->id]);
284
        $this->assertFalse($user2roleassignment);
285
 
286
        // All existing course enrolment instances should not exists.
287
        $enrolmentinstances = enrol_get_instances($course->id, false);
288
        $this->assertCount(0, $enrolmentinstances);
289
    }
290
 
291
    /**
292
     * Test enrol_course_delete() when user id is present.
293
     * When a value for user id is present, the method should make sure the user has the proper capability to
294
     * un-enrol users before removing the enrolment data. If the capabilities are missing the data should not be removed.
295
     *
296
     * @dataProvider enrol_course_delete_with_userid_provider
297
     * @param array $excludedcapabilities The capabilities that should be excluded from the user's role
298
     * @param bool $expected The expected results
299
     */
11 efrain 300
    public function test_enrol_course_delete_with_userid($excludedcapabilities, $expected): void {
1 efrain 301
        global $DB;
302
 
303
        $this->resetAfterTest();
304
        // Create users.
305
        $user1 = $this->getDataGenerator()->create_user();
306
        $user2 = $this->getDataGenerator()->create_user();
307
        $user3 = $this->getDataGenerator()->create_user();
308
        // Create a course.
309
        $course = $this->getDataGenerator()->create_course();
310
        $coursecontext = context_course::instance($course->id);
311
 
312
        $studentrole = $DB->get_record('role', ['shortname' => 'student']);
313
        $editingteacherrole = $DB->get_record('role', ['shortname' => 'editingteacher']);
314
 
315
        $manual = enrol_get_plugin('manual');
316
        $manualinstance = $DB->get_record('enrol', ['courseid' => $course->id, 'enrol' => 'manual'],
317
            '*', MUST_EXIST);
318
        // Enrol user1 as a student in the course using manual enrolment.
319
        $manual->enrol_user($manualinstance, $user1->id, $studentrole->id);
320
        // Enrol user3 as an editing teacher in the course using manual enrolment.
321
        // By default, the editing teacher role has the capability to un-enroll users which have been enrolled using
322
        // the existing enrolment methods.
323
        $manual->enrol_user($manualinstance, $user3->id, $editingteacherrole->id);
324
 
325
        $self = enrol_get_plugin('self');
326
        $selfinstance = $DB->get_record('enrol', ['courseid' => $course->id, 'enrol' => 'self'],
327
            '*', MUST_EXIST);
328
        $self->update_status($selfinstance, ENROL_INSTANCE_ENABLED);
329
        // Enrol user2 as a student in the course using self enrolment.
330
        $self->enrol_user($selfinstance, $user2->id, $studentrole->id);
331
 
332
        foreach($excludedcapabilities as $capability) {
333
            // Un-assign the given capability from the editing teacher role.
334
            unassign_capability($capability, $editingteacherrole->id);
335
        }
336
 
337
        // Delete only enrolment related records in the course where user3 has the required capability.
338
        enrol_course_delete($course, $user3->id);
339
 
340
        // Check the existence of the course enrolment of user1.
341
        $user1enrolmentexists = (bool) $DB->count_records('user_enrolments',
342
            ['enrolid' => $manualinstance->id, 'userid' => $user1->id]);
343
        $this->assertEquals($expected['User 1 course enrolment exists'], $user1enrolmentexists);
344
 
345
        // Check the existence of the role assignment of user1 in the course.
346
        $user1roleassignmentexists = (bool) $DB->count_records('role_assignments',
347
            ['roleid' => $studentrole->id, 'userid' => $user1->id, 'contextid' => $coursecontext->id]);
348
        $this->assertEquals($expected['User 1 role assignment exists'], $user1roleassignmentexists);
349
 
350
        // Check the existence of the course enrolment of user2.
351
        $user2enrolmentexists = (bool) $DB->count_records('user_enrolments',
352
            ['enrolid' => $selfinstance->id, 'userid' => $user2->id]);
353
        $this->assertEquals($expected['User 2 course enrolment exists'], $user2enrolmentexists);
354
 
355
        // Check the existence of the role assignment of user2 in the course.
356
        $user2roleassignmentexists = (bool) $DB->count_records('role_assignments',
357
            ['roleid' => $studentrole->id, 'userid' => $user2->id, 'contextid' => $coursecontext->id]);
358
        $this->assertEquals($expected['User 2 role assignment exists'], $user2roleassignmentexists);
359
 
360
        // Check the existence of the course enrolment of user3.
361
        $user3enrolmentexists = (bool) $DB->count_records('user_enrolments',
362
            ['enrolid' => $manualinstance->id, 'userid' => $user3->id]);
363
        $this->assertEquals($expected['User 3 course enrolment exists'], $user3enrolmentexists);
364
 
365
        // Check the existence of the role assignment of user3 in the course.
366
        $user3roleassignmentexists = (bool) $DB->count_records('role_assignments',
367
            ['roleid' => $editingteacherrole->id, 'userid' => $user3->id, 'contextid' => $coursecontext->id]);
368
        $this->assertEquals($expected['User 3 role assignment exists'], $user3roleassignmentexists);
369
 
370
        // Check the existence of the manual enrolment instance in the course.
371
        $manualinstance = (bool) $DB->count_records('enrol', ['enrol' => 'manual', 'courseid' => $course->id]);
372
        $this->assertEquals($expected['Manual course enrolment instance exists'], $manualinstance);
373
 
374
        // Check existence of the self enrolment instance in the course.
375
        $selfinstance = (bool) $DB->count_records('enrol', ['enrol' => 'self', 'courseid' => $course->id]);
376
        $this->assertEquals($expected['Self course enrolment instance exists'], $selfinstance);
377
    }
378
 
379
    /**
380
     * Data provider for test_enrol_course_delete_with_userid().
381
     *
382
     * @return array
383
     */
384
    public function enrol_course_delete_with_userid_provider() {
385
        return [
386
            'The teacher can un-enrol users in a course' =>
387
                [
388
                    'excludedcapabilities' => [],
389
                    'results' => [
390
                        // Whether certain enrolment related data still exists in the course after the deletion.
391
                        // When the user has the capabilities to un-enrol users and the enrolment plugins allow manual
392
                        // unenerolment than all course enrolment data should be removed.
393
                        'Manual course enrolment instance exists' => false,
394
                        'Self course enrolment instance exists' => false,
395
                        'User 1 course enrolment exists' => false,
396
                        'User 1 role assignment exists' => false,
397
                        'User 2 course enrolment exists' => false,
398
                        'User 2 role assignment exists' => false,
399
                        'User 3 course enrolment exists' => false,
400
                        'User 3 role assignment exists' => false
401
                    ],
402
                ],
403
            'The teacher cannot un-enrol self enrolled users'  =>
404
                [
405
                    'excludedcapabilities' => [
406
                        // Exclude the following capabilities for the editing teacher.
407
                        'enrol/self:unenrol'
408
                    ],
409
                    'results' => [
410
                        // When the user does not have the capabilities to un-enrol self enrolled users, the data
411
                        // related to this enrolment method should not be removed. Everything else should be removed.
412
                        'Manual course enrolment instance exists' => false,
413
                        'Self course enrolment instance exists' => true,
414
                        'User 1 course enrolment exists' => false,
415
                        'User 1 role assignment exists' => false,
416
                        'User 2 course enrolment exists' => true,
417
                        'User 2 role assignment exists' => true,
418
                        'User 3 course enrolment exists' => false,
419
                        'User 3 role assignment exists' => false
420
                    ],
421
                ],
422
            'The teacher cannot un-enrol self and manually enrolled users' =>
423
                [
424
                    'excludedcapabilities' => [
425
                        // Exclude the following capabilities for the editing teacher.
426
                        'enrol/manual:unenrol',
427
                        'enrol/self:unenrol'
428
                    ],
429
                    'results' => [
430
                        // When the user does not have the capabilities to un-enrol self and manually enrolled users,
431
                        // the data related to these enrolment methods should not be removed.
432
                        'Manual course enrolment instance exists' => true,
433
                        'Self course enrolment instance exists' => true,
434
                        'User 1 course enrolment exists' => true,
435
                        'User 1 role assignment exists' => true,
436
                        'User 2 course enrolment exists' => true,
437
                        'User 2 role assignment exists' => true,
438
                        'User 3 course enrolment exists' => true,
439
                        'User 3 role assignment exists' => true
440
                    ],
441
                ],
442
        ];
443
    }
444
 
445
 
11 efrain 446
    public function test_enrol_user_sees_own_courses(): void {
1 efrain 447
        global $DB, $CFG;
448
 
449
        $this->resetAfterTest();
450
 
451
        $studentrole = $DB->get_record('role', array('shortname'=>'student'));
452
        $this->assertNotEmpty($studentrole);
453
        $teacherrole = $DB->get_record('role', array('shortname'=>'teacher'));
454
        $this->assertNotEmpty($teacherrole);
455
 
456
        $admin = get_admin();
457
        $user1 = $this->getDataGenerator()->create_user();
458
        $user2 = $this->getDataGenerator()->create_user();
459
        $user3 = $this->getDataGenerator()->create_user();
460
        $user4 = $this->getDataGenerator()->create_user();
461
        $user5 = $this->getDataGenerator()->create_user();
462
        $user6 = $this->getDataGenerator()->create_user();
463
 
464
        $category1 = $this->getDataGenerator()->create_category(array('visible'=>0));
465
        $category2 = $this->getDataGenerator()->create_category();
466
        $course1 = $this->getDataGenerator()->create_course(array('category'=>$category1->id));
467
        $course2 = $this->getDataGenerator()->create_course(array('category'=>$category2->id));
468
        $course3 = $this->getDataGenerator()->create_course(array('category'=>$category2->id, 'visible'=>0));
469
        $course4 = $this->getDataGenerator()->create_course(array('category'=>$category2->id));
470
 
471
        $maninstance1 = $DB->get_record('enrol', array('courseid'=>$course1->id, 'enrol'=>'manual'), '*', MUST_EXIST);
472
        $DB->set_field('enrol', 'status', ENROL_INSTANCE_DISABLED, array('id'=>$maninstance1->id));
473
        $maninstance1 = $DB->get_record('enrol', array('courseid'=>$course1->id, 'enrol'=>'manual'), '*', MUST_EXIST);
474
        $maninstance2 = $DB->get_record('enrol', array('courseid'=>$course2->id, 'enrol'=>'manual'), '*', MUST_EXIST);
475
        $maninstance3 = $DB->get_record('enrol', array('courseid'=>$course3->id, 'enrol'=>'manual'), '*', MUST_EXIST);
476
        $maninstance4 = $DB->get_record('enrol', array('courseid'=>$course4->id, 'enrol'=>'manual'), '*', MUST_EXIST);
477
 
478
        $manual = enrol_get_plugin('manual');
479
        $this->assertNotEmpty($manual);
480
 
481
        $manual->enrol_user($maninstance1, $admin->id, $studentrole->id);
482
 
483
        $manual->enrol_user($maninstance3, $user1->id, $teacherrole->id);
484
 
485
        $manual->enrol_user($maninstance2, $user2->id, $studentrole->id);
486
 
487
        $manual->enrol_user($maninstance1, $user3->id, $studentrole->id, 1, time()+(60*60));
488
        $manual->enrol_user($maninstance2, $user3->id, 0, 1, time()-(60*60));
489
        $manual->enrol_user($maninstance3, $user2->id, $studentrole->id);
490
        $manual->enrol_user($maninstance4, $user2->id, 0, 0, 0, ENROL_USER_SUSPENDED);
491
 
492
        $manual->enrol_user($maninstance1, $user4->id, $teacherrole->id, 0, 0, ENROL_USER_SUSPENDED);
493
        $manual->enrol_user($maninstance3, $user4->id, 0, 0, 0, ENROL_USER_SUSPENDED);
494
 
495
 
496
        $this->assertFalse(enrol_user_sees_own_courses($CFG->siteguest));
497
        $this->assertFalse(enrol_user_sees_own_courses(0));
498
        $this->assertFalse(enrol_user_sees_own_courses($admin));
499
        $this->assertFalse(enrol_user_sees_own_courses(-222)); // Nonexistent user.
500
 
501
        $this->assertTrue(enrol_user_sees_own_courses($user1));
502
        $this->assertTrue(enrol_user_sees_own_courses($user2->id));
503
        $this->assertFalse(enrol_user_sees_own_courses($user3->id));
504
        $this->assertFalse(enrol_user_sees_own_courses($user4));
505
        $this->assertFalse(enrol_user_sees_own_courses($user5));
506
 
507
        $this->setAdminUser();
508
        $this->assertFalse(enrol_user_sees_own_courses());
509
 
510
        $this->setGuestUser();
511
        $this->assertFalse(enrol_user_sees_own_courses());
512
 
513
        $this->setUser(0);
514
        $this->assertFalse(enrol_user_sees_own_courses());
515
 
516
        $this->setUser($user1);
517
        $this->assertTrue(enrol_user_sees_own_courses());
518
 
519
        $this->setUser($user2);
520
        $this->assertTrue(enrol_user_sees_own_courses());
521
 
522
        $this->setUser($user3);
523
        $this->assertFalse(enrol_user_sees_own_courses());
524
 
525
        $this->setUser($user4);
526
        $this->assertFalse(enrol_user_sees_own_courses());
527
 
528
        $this->setUser($user5);
529
        $this->assertFalse(enrol_user_sees_own_courses());
530
 
531
        $user1 = $DB->get_record('user', array('id'=>$user1->id));
532
        $this->setUser($user1);
533
        $reads = $DB->perf_get_reads();
534
        $this->assertTrue(enrol_user_sees_own_courses());
535
        $this->assertGreaterThan($reads, $DB->perf_get_reads());
536
 
537
        $user1 = $DB->get_record('user', array('id'=>$user1->id));
538
        $this->setUser($user1);
539
        require_login($course3);
540
        $reads = $DB->perf_get_reads();
541
        $this->assertTrue(enrol_user_sees_own_courses());
542
        $this->assertEquals($reads, $DB->perf_get_reads());
543
    }
544
 
11 efrain 545
    public function test_enrol_get_shared_courses(): void {
1 efrain 546
        $this->resetAfterTest();
547
 
548
        $user1 = $this->getDataGenerator()->create_user();
549
        $user2 = $this->getDataGenerator()->create_user();
550
        $user3 = $this->getDataGenerator()->create_user();
551
 
552
        $course1 = $this->getDataGenerator()->create_course();
553
        $this->getDataGenerator()->enrol_user($user1->id, $course1->id);
554
        $this->getDataGenerator()->enrol_user($user2->id, $course1->id);
555
 
556
        $course2 = $this->getDataGenerator()->create_course();
557
        $this->getDataGenerator()->enrol_user($user1->id, $course2->id);
558
 
559
        // Test that user1 and user2 have courses in common.
560
        $this->assertTrue(enrol_get_shared_courses($user1, $user2, false, true));
561
        // Test that user1 and user3 have no courses in common.
562
        $this->assertFalse(enrol_get_shared_courses($user1, $user3, false, true));
563
 
564
        // Test retrieving the courses in common.
565
        $sharedcourses = enrol_get_shared_courses($user1, $user2, true);
566
 
567
        // Only should be one shared course.
568
        $this->assertCount(1, $sharedcourses);
569
        $sharedcourse = array_shift($sharedcourses);
570
        // It should be course 1.
571
        $this->assertEquals($sharedcourse->id, $course1->id);
572
    }
573
 
11 efrain 574
    public function test_enrol_get_shared_courses_different_methods(): void {
1 efrain 575
        global $DB, $CFG;
576
 
577
        require_once($CFG->dirroot . '/enrol/self/externallib.php');
578
 
579
        $this->resetAfterTest();
580
 
581
        $user1 = $this->getDataGenerator()->create_user();
582
        $user2 = $this->getDataGenerator()->create_user();
583
        $user3 = $this->getDataGenerator()->create_user();
584
 
585
        $course1 = $this->getDataGenerator()->create_course();
586
 
587
        // Enrol user1 and user2 in course1 with a different enrolment methode.
588
        // Add self enrolment method for course1.
589
        $selfplugin = enrol_get_plugin('self');
590
        $this->assertNotEmpty($selfplugin);
591
 
592
        $studentrole = $DB->get_record('role', array('shortname' => 'student'));
593
        $this->assertNotEmpty($studentrole);
594
 
595
        $instance1id = $selfplugin->add_instance($course1, array('status' => ENROL_INSTANCE_ENABLED,
596
                                                                 'name' => 'Test instance 1',
597
                                                                 'customint6' => 1,
598
                                                                 'roleid' => $studentrole->id));
599
 
600
        $instance1 = $DB->get_record('enrol', array('id' => $instance1id), '*', MUST_EXIST);
601
 
602
        self::setUser($user2);
603
        // Self enrol me (user2).
604
        $result = enrol_self_external::enrol_user($course1->id);
605
 
606
        // Enrol user1 manually.
607
        $this->getDataGenerator()->enrol_user($user1->id, $course1->id, null, 'manual');
608
 
609
        $course2 = $this->getDataGenerator()->create_course();
610
        $this->getDataGenerator()->enrol_user($user1->id, $course2->id);
611
 
612
        $course3 = $this->getDataGenerator()->create_course();
613
        $this->getDataGenerator()->enrol_user($user2->id, $course3->id);
614
 
615
        // Test that user1 and user2 have courses in common.
616
        $this->assertTrue(enrol_get_shared_courses($user1, $user2, false, true));
617
        // Test that user1 and user3 have no courses in common.
618
        $this->assertFalse(enrol_get_shared_courses($user1, $user3, false, true));
619
 
620
        // Test retrieving the courses in common.
621
        $sharedcourses = enrol_get_shared_courses($user1, $user2, true);
622
 
623
        // Only should be one shared course.
624
        $this->assertCount(1, $sharedcourses);
625
        $sharedcourse = array_shift($sharedcourses);
626
        // It should be course 1.
627
        $this->assertEquals($sharedcourse->id, $course1->id);
628
    }
629
 
630
    /**
631
     * Test user enrolment created event.
632
     */
11 efrain 633
    public function test_user_enrolment_created_event(): void {
1 efrain 634
        global $DB;
635
 
636
        $this->resetAfterTest();
637
 
638
        $studentrole = $DB->get_record('role', array('shortname'=>'student'));
639
        $this->assertNotEmpty($studentrole);
640
 
641
        $admin = get_admin();
642
 
643
        $course1 = $this->getDataGenerator()->create_course();
644
 
645
        $maninstance1 = $DB->get_record('enrol', array('courseid'=>$course1->id, 'enrol'=>'manual'), '*', MUST_EXIST);
646
 
647
        $manual = enrol_get_plugin('manual');
648
        $this->assertNotEmpty($manual);
649
 
650
        // Enrol user and capture event.
651
        $sink = $this->redirectEvents();
652
        $manual->enrol_user($maninstance1, $admin->id, $studentrole->id);
653
        $events = $sink->get_events();
654
        $sink->close();
655
        $event = array_shift($events);
656
 
657
        $dbuserenrolled = $DB->get_record('user_enrolments', array('userid' => $admin->id));
658
        $this->assertInstanceOf('\core\event\user_enrolment_created', $event);
659
        $this->assertEquals($dbuserenrolled->id, $event->objectid);
660
        $this->assertEquals(context_course::instance($course1->id), $event->get_context());
661
        $this->assertEventContextNotUsed($event);
662
    }
663
 
664
    /**
665
     * Test user_enrolment_deleted event.
666
     */
11 efrain 667
    public function test_user_enrolment_deleted_event(): void {
1 efrain 668
        global $DB;
669
 
670
        $this->resetAfterTest(true);
671
 
672
        $manualplugin = enrol_get_plugin('manual');
673
        $user = $this->getDataGenerator()->create_user();
674
        $course = $this->getDataGenerator()->create_course();
675
        $student = $DB->get_record('role', array('shortname' => 'student'));
676
 
677
        $enrol = $DB->get_record('enrol', array('courseid' => $course->id, 'enrol' => 'manual'), '*', MUST_EXIST);
678
 
679
        // Enrol user.
680
        $manualplugin->enrol_user($enrol, $user->id, $student->id);
681
 
682
        // Get the user enrolment information, used to validate legacy event data.
683
        $dbuserenrolled = $DB->get_record('user_enrolments', array('userid' => $user->id));
684
 
685
        // Unenrol user and capture event.
686
        $sink = $this->redirectEvents();
687
        $manualplugin->unenrol_user($enrol, $user->id);
688
        $events = $sink->get_events();
689
        $sink->close();
690
        $event = array_pop($events);
691
 
692
        // Validate the event.
693
        $this->assertInstanceOf('\core\event\user_enrolment_deleted', $event);
694
        $this->assertEquals(context_course::instance($course->id), $event->get_context());
695
        $this->assertEventContextNotUsed($event);
696
    }
697
 
698
    /**
699
     * Test enrol_instance_created, enrol_instance_updated and enrol_instance_deleted events.
700
     */
11 efrain 701
    public function test_instance_events(): void {
1 efrain 702
        global $DB;
703
 
704
        $this->resetAfterTest(true);
705
 
706
        $selfplugin = enrol_get_plugin('self');
707
        $studentrole = $DB->get_record('role', array('shortname' => 'student'));
708
 
709
        $course = $this->getDataGenerator()->create_course();
710
 
711
        // Creating enrol instance.
712
        $sink = $this->redirectEvents();
713
        $instanceid = $selfplugin->add_instance($course, array('status' => ENROL_INSTANCE_ENABLED,
714
                                                                'name' => 'Test instance 1',
715
                                                                'customint6' => 1,
716
                                                                'roleid' => $studentrole->id));
717
        $events = $sink->get_events();
718
        $sink->close();
719
 
720
        $this->assertCount(1, $events);
721
        $event = array_pop($events);
722
        $this->assertInstanceOf('\core\event\enrol_instance_created', $event);
723
        $this->assertEquals(context_course::instance($course->id), $event->get_context());
724
        $this->assertEquals('self', $event->other['enrol']);
725
        $this->assertEventContextNotUsed($event);
726
 
727
        // Updating enrol instance.
728
        $instance = $DB->get_record('enrol', array('id' => $instanceid));
729
        $sink = $this->redirectEvents();
730
        $selfplugin->update_status($instance, ENROL_INSTANCE_DISABLED);
731
 
732
        $events = $sink->get_events();
733
        $sink->close();
734
 
735
        $this->assertCount(1, $events);
736
        $event = array_pop($events);
737
        $this->assertInstanceOf('\core\event\enrol_instance_updated', $event);
738
        $this->assertEquals(context_course::instance($course->id), $event->get_context());
739
        $this->assertEquals('self', $event->other['enrol']);
740
        $this->assertEventContextNotUsed($event);
741
 
742
        // Deleting enrol instance.
743
        $instance = $DB->get_record('enrol', array('id' => $instanceid));
744
        $sink = $this->redirectEvents();
745
        $selfplugin->delete_instance($instance);
746
 
747
        $events = $sink->get_events();
748
        $sink->close();
749
 
750
        $this->assertCount(1, $events);
751
        $event = array_pop($events);
752
        $this->assertInstanceOf('\core\event\enrol_instance_deleted', $event);
753
        $this->assertEquals(context_course::instance($course->id), $event->get_context());
754
        $this->assertEquals('self', $event->other['enrol']);
755
        $this->assertEventContextNotUsed($event);
756
    }
757
 
758
    /**
759
     * Confirms that timemodified field was updated after modification of user enrollment
760
     */
11 efrain 761
    public function test_enrollment_update_timemodified(): void {
1 efrain 762
        global $DB;
763
 
764
        $this->resetAfterTest(true);
765
        $datagen = $this->getDataGenerator();
766
 
767
        /** @var enrol_manual_plugin $manualplugin */
768
        $manualplugin = enrol_get_plugin('manual');
769
        $this->assertNotNull($manualplugin);
770
 
771
        $studentroleid = $DB->get_field('role', 'id', ['shortname' => 'student'], MUST_EXIST);
772
        $course = $datagen->create_course();
773
        $user = $datagen->create_user();
774
 
775
        $instanceid = null;
776
        $instances = enrol_get_instances($course->id, true);
777
        foreach ($instances as $inst) {
778
            if ($inst->enrol == 'manual') {
779
                $instanceid = (int)$inst->id;
780
                break;
781
            }
782
        }
783
        if (empty($instanceid)) {
784
            $instanceid = $manualplugin->add_default_instance($course);
785
            if (empty($instanceid)) {
786
                $instanceid = $manualplugin->add_instance($course);
787
            }
788
        }
789
        $this->assertNotNull($instanceid);
790
 
791
        $instance = $DB->get_record('enrol', ['id' => $instanceid], '*', MUST_EXIST);
792
        $manualplugin->enrol_user($instance, $user->id, $studentroleid, 0, 0, ENROL_USER_ACTIVE);
793
        $userenrolorig = (int)$DB->get_field(
794
            'user_enrolments',
795
            'timemodified',
796
            ['enrolid' => $instance->id, 'userid' => $user->id],
797
            MUST_EXIST
798
        );
799
        $this->waitForSecond();
800
        $this->waitForSecond();
801
        $manualplugin->update_user_enrol($instance, $user->id, ENROL_USER_SUSPENDED);
802
        $userenrolpost = (int)$DB->get_field(
803
            'user_enrolments',
804
            'timemodified',
805
            ['enrolid' => $instance->id, 'userid' => $user->id],
806
            MUST_EXIST
807
        );
808
 
809
        $this->assertGreaterThan($userenrolorig, $userenrolpost);
810
    }
811
 
812
    /**
813
     * Test to confirm that enrol_get_my_courses only return the courses that
814
     * the logged in user is enrolled in.
815
     */
11 efrain 816
    public function test_enrol_get_my_courses_only_enrolled_courses(): void {
1 efrain 817
        $user = $this->getDataGenerator()->create_user();
818
        $course1 = $this->getDataGenerator()->create_course();
819
        $course2 = $this->getDataGenerator()->create_course();
820
        $course3 = $this->getDataGenerator()->create_course();
821
        $course4 = $this->getDataGenerator()->create_course();
822
 
823
        $this->getDataGenerator()->enrol_user($user->id, $course1->id);
824
        $this->getDataGenerator()->enrol_user($user->id, $course2->id);
825
        $this->getDataGenerator()->enrol_user($user->id, $course3->id);
826
        $this->resetAfterTest(true);
827
        $this->setUser($user);
828
 
829
        // By default this function should return all of the courses the user
830
        // is enrolled in.
831
        $courses = enrol_get_my_courses();
832
 
833
        $this->assertCount(3, $courses);
834
        $this->assertEquals($course1->id, $courses[$course1->id]->id);
835
        $this->assertEquals($course2->id, $courses[$course2->id]->id);
836
        $this->assertEquals($course3->id, $courses[$course3->id]->id);
837
 
838
        // If a set of course ids are provided then the result set will only contain
839
        // these courses.
840
        $courseids = [$course1->id, $course2->id];
841
        $courses = enrol_get_my_courses(['id'], 'visible DESC,sortorder ASC', 0, $courseids);
842
 
843
        $this->assertCount(2, $courses);
844
        $this->assertEquals($course1->id, $courses[$course1->id]->id);
845
        $this->assertEquals($course2->id, $courses[$course2->id]->id);
846
 
847
        // If the course ids list contains any ids for courses the user isn't enrolled in
848
        // then they will be ignored (in this case $course4).
849
        $courseids = [$course1->id, $course2->id, $course4->id];
850
        $courses = enrol_get_my_courses(['id'], 'visible DESC,sortorder ASC', 0, $courseids);
851
 
852
        $this->assertCount(2, $courses);
853
        $this->assertEquals($course1->id, $courses[$course1->id]->id);
854
        $this->assertEquals($course2->id, $courses[$course2->id]->id);
855
    }
856
 
857
    /**
858
     * Tests the enrol_get_my_courses function when using the $includehidden parameter, which
859
     * should remove any courses hidden from the user's timeline
860
     *
861
     * @throws coding_exception
862
     * @throws dml_exception
863
     */
11 efrain 864
    public function test_enrol_get_my_courses_include_hidden(): void {
1 efrain 865
        global $DB, $CFG;
866
 
867
        $this->resetAfterTest(true);
868
 
869
        // Create test user and 4 courses, two of which have guest access enabled.
870
        $user = $this->getDataGenerator()->create_user();
871
        $course1 = $this->getDataGenerator()->create_course(
872
            (object)array('shortname' => 'X',
873
                'enrol_guest_status_0' => ENROL_INSTANCE_DISABLED,
874
                'enrol_guest_password_0' => ''));
875
        $course2 = $this->getDataGenerator()->create_course(
876
            (object)array('shortname' => 'Z',
877
                'enrol_guest_status_0' => ENROL_INSTANCE_ENABLED,
878
                'enrol_guest_password_0' => ''));
879
        $course3 = $this->getDataGenerator()->create_course(
880
            (object)array('shortname' => 'Y',
881
                'enrol_guest_status_0' => ENROL_INSTANCE_ENABLED,
882
                'enrol_guest_password_0' => 'frog'));
883
        $course4 = $this->getDataGenerator()->create_course(
884
            (object)array('shortname' => 'W',
885
                'enrol_guest_status_0' => ENROL_INSTANCE_DISABLED,
886
                'enrol_guest_password_0' => ''));
887
 
888
        // User is enrolled in first course.
889
        $this->getDataGenerator()->enrol_user($user->id, $course1->id);
890
        $this->getDataGenerator()->enrol_user($user->id, $course2->id);
891
        $this->getDataGenerator()->enrol_user($user->id, $course3->id);
892
        $this->getDataGenerator()->enrol_user($user->id, $course4->id);
893
 
894
        // Check enrol_get_my_courses basic use (without include hidden provided).
895
        $this->setUser($user);
896
        $courses = enrol_get_my_courses();
897
        $this->assertEquals([$course4->id, $course3->id, $course2->id, $course1->id], array_keys($courses));
898
 
899
        // Hide a course.
900
        set_user_preference('block_myoverview_hidden_course_' . $course3->id, true);
901
 
902
        // Hidden course shouldn't be returned.
903
        $courses = enrol_get_my_courses(null, null, 0, [], false, 0, [$course3->id]);
904
        $this->assertEquals([$course4->id, $course2->id, $course1->id], array_keys($courses));
905
 
906
        // Offset should take into account hidden course.
907
        $courses = enrol_get_my_courses(null, null, 0, [], false, 2, [$course3->id]);
908
        $this->assertEquals([$course1->id], array_keys($courses));
909
    }
910
 
911
    /**
912
     * Tests the enrol_get_my_courses function when using the $allaccessible parameter, which
913
     * includes a wider range of courses (enrolled courses + other accessible ones).
914
     */
11 efrain 915
    public function test_enrol_get_my_courses_all_accessible(): void {
1 efrain 916
        global $DB, $CFG;
917
 
918
        $this->resetAfterTest(true);
919
 
920
        // Create test user and 4 courses, two of which have guest access enabled.
921
        $user = $this->getDataGenerator()->create_user();
922
        $course1 = $this->getDataGenerator()->create_course(
923
                (object)array('shortname' => 'X',
924
                'enrol_guest_status_0' => ENROL_INSTANCE_DISABLED,
925
                'enrol_guest_password_0' => ''));
926
        $course2 = $this->getDataGenerator()->create_course(
927
                (object)array('shortname' => 'Z',
928
                'enrol_guest_status_0' => ENROL_INSTANCE_ENABLED,
929
                'enrol_guest_password_0' => ''));
930
        $course3 = $this->getDataGenerator()->create_course(
931
                (object)array('shortname' => 'Y',
932
                'enrol_guest_status_0' => ENROL_INSTANCE_ENABLED,
933
                'enrol_guest_password_0' => 'frog'));
934
        $course4 = $this->getDataGenerator()->create_course(
935
                (object)array('shortname' => 'W',
936
                'enrol_guest_status_0' => ENROL_INSTANCE_DISABLED,
937
                'enrol_guest_password_0' => ''));
938
 
939
        // User is enrolled in first course.
940
        $this->getDataGenerator()->enrol_user($user->id, $course1->id);
941
 
942
        // Check enrol_get_my_courses basic use (without all accessible).
943
        $this->setUser($user);
944
        $courses = enrol_get_my_courses();
945
        $this->assertEquals([$course1->id], array_keys($courses));
946
 
947
        // Turn on all accessible, now they can access the second course too.
948
        $courses = enrol_get_my_courses(null, 'id', 0, [], true);
949
        $this->assertEquals([$course1->id, $course2->id], array_keys($courses));
950
 
951
        // Log in as guest to third course.
952
        load_temp_course_role(context_course::instance($course3->id), $CFG->guestroleid);
953
        $courses = enrol_get_my_courses(null, 'id', 0, [], true);
954
        $this->assertEquals([$course1->id, $course2->id, $course3->id], array_keys($courses));
955
 
956
        // Check fields parameter still works. Fields default (certain base fields).
957
        $this->assertObjectHasProperty('id', $courses[$course3->id]);
958
        $this->assertObjectHasProperty('shortname', $courses[$course3->id]);
959
        $this->assertObjectNotHasProperty('summary', $courses[$course3->id]);
960
 
961
        // Specified fields (one, string).
962
        $courses = enrol_get_my_courses('summary', 'id', 0, [], true);
963
        $this->assertObjectHasProperty('id', $courses[$course3->id]);
964
        $this->assertObjectHasProperty('shortname', $courses[$course3->id]);
965
        $this->assertObjectHasProperty('summary', $courses[$course3->id]);
966
        $this->assertObjectNotHasProperty('summaryformat', $courses[$course3->id]);
967
 
968
        // Specified fields (two, string).
969
        $courses = enrol_get_my_courses('summary, summaryformat', 'id', 0, [], true);
970
        $this->assertObjectHasProperty('summary', $courses[$course3->id]);
971
        $this->assertObjectHasProperty('summaryformat', $courses[$course3->id]);
972
 
973
        // Specified fields (two, array).
974
        $courses = enrol_get_my_courses(['summary', 'summaryformat'], 'id', 0, [], true);
975
        $this->assertObjectHasProperty('summary', $courses[$course3->id]);
976
        $this->assertObjectHasProperty('summaryformat', $courses[$course3->id]);
977
 
978
        // By default, courses are ordered by sortorder - which by default is most recent first.
979
        $courses = enrol_get_my_courses(null, null, 0, [], true);
980
        $this->assertEquals([$course3->id, $course2->id, $course1->id], array_keys($courses));
981
 
982
        // Make sure that implicit sorting defined in navsortmycoursessort is respected.
983
        $CFG->navsortmycoursessort = 'shortname';
984
        $courses = enrol_get_my_courses(null, null, 0, [], true);
985
        $this->assertEquals([$course1->id, $course3->id, $course2->id], array_keys($courses));
986
 
987
        // But still the explicit sorting takes precedence over the implicit one.
988
        $courses = enrol_get_my_courses(null, 'shortname DESC', 0, [], true);
989
        $this->assertEquals([$course2->id, $course3->id, $course1->id], array_keys($courses));
990
 
991
        // Check filter parameter still works.
992
        $courses = enrol_get_my_courses(null, 'id', 0, [$course2->id, $course3->id, $course4->id], true);
993
        $this->assertEquals([$course2->id, $course3->id], array_keys($courses));
994
 
995
        // Check limit parameter.
996
        $courses = enrol_get_my_courses(null, 'id', 2, [], true);
997
        $this->assertEquals([$course1->id, $course2->id], array_keys($courses));
998
 
999
        // Now try access for a different user who has manager role at system level.
1000
        $manager = $this->getDataGenerator()->create_user();
1001
        $managerroleid = $DB->get_field('role', 'id', ['shortname' => 'manager']);
1002
        role_assign($managerroleid, $manager->id, \context_system::instance()->id);
1003
        $this->setUser($manager);
1004
 
1005
        // With default get enrolled, they don't have any courses.
1006
        $courses = enrol_get_my_courses();
1007
        $this->assertCount(0, $courses);
1008
 
1009
        // But with all accessible, they have 4 because they have moodle/course:view everywhere.
1010
        $courses = enrol_get_my_courses(null, 'id', 0, [], true);
1011
        $this->assertEquals([$course1->id, $course2->id, $course3->id, $course4->id],
1012
                array_keys($courses));
1013
 
1014
        // If we prohibit manager from course:view on course 1 though...
1015
        assign_capability('moodle/course:view', CAP_PROHIBIT, $managerroleid,
1016
                \context_course::instance($course1->id));
1017
        $courses = enrol_get_my_courses(null, 'id', 0, [], true);
1018
        $this->assertEquals([$course2->id, $course3->id, $course4->id], array_keys($courses));
1019
 
1020
        // Check for admin user, which has a slightly different query.
1021
        $this->setAdminUser();
1022
        $courses = enrol_get_my_courses(null, 'id', 0, [], true);
1023
        $this->assertEquals([$course1->id, $course2->id, $course3->id, $course4->id], array_keys($courses));
1024
    }
1025
 
1026
    /**
1027
     * Data provider for {@see test_enrol_get_my_courses_by_time}
1028
     *
1029
     * @return array
1030
     */
1031
    public function enrol_get_my_courses_by_time_provider(): array {
1032
        return [
1033
            'No start or end time' =>
1034
                [null, null, true],
1035
            'Start time now, no end time' =>
1036
                [0, null, true],
1037
            'Start time now, end time in the future' =>
1038
                [0, MINSECS, true],
1039
            'Start time in the past, no end time' =>
1040
                [-MINSECS, null, true],
1041
            'Start time in the past, end time in the future' =>
1042
                [-MINSECS, MINSECS, true],
1043
            'Start time in the past, end time in the past' =>
1044
                [-DAYSECS, -HOURSECS, false],
1045
            'Start time in the future' =>
1046
                [MINSECS, null, false],
1047
        ];
1048
    }
1049
 
1050
    /**
1051
     * Test that expected course enrolments are returned when they have timestart / timeend specified
1052
     *
1053
     * @param int|null $timestartoffset Null for 0, otherwise offset from current time
1054
     * @param int|null $timeendoffset Null for 0, otherwise offset from current time
1055
     * @param bool $expectreturn
1056
     *
1057
     * @dataProvider enrol_get_my_courses_by_time_provider
1058
     */
1059
    public function test_enrol_get_my_courses_by_time(?int $timestartoffset, ?int $timeendoffset, bool $expectreturn): void {
1060
        $this->resetAfterTest();
1061
 
1062
        $time = time();
1063
        $timestart = $timestartoffset === null ? 0 : $time + $timestartoffset;
1064
        $timeend = $timeendoffset === null ? 0 : $time + $timeendoffset;
1065
 
1066
        $course = $this->getDataGenerator()->create_course();
1067
        $user = $this->getDataGenerator()->create_and_enrol($course, 'student', null, 'manual', $timestart, $timeend);
1068
        $this->setUser($user);
1069
 
1070
        $courses = enrol_get_my_courses();
1071
        if ($expectreturn) {
1072
            $this->assertCount(1, $courses);
1073
            $this->assertEquals($course->id, reset($courses)->id);
1074
        } else {
1075
            $this->assertEmpty($courses);
1076
        }
1077
    }
1078
 
1079
    /**
1080
     * test_course_users
1081
     *
1082
     * @return void
1083
     */
11 efrain 1084
    public function test_course_users(): void {
1 efrain 1085
        $this->resetAfterTest();
1086
 
1087
        $user1 = $this->getDataGenerator()->create_user();
1088
        $user2 = $this->getDataGenerator()->create_user();
1089
        $course1 = $this->getDataGenerator()->create_course();
1090
        $course2 = $this->getDataGenerator()->create_course();
1091
 
1092
        $this->getDataGenerator()->enrol_user($user1->id, $course1->id);
1093
        $this->getDataGenerator()->enrol_user($user2->id, $course1->id);
1094
        $this->getDataGenerator()->enrol_user($user1->id, $course2->id);
1095
 
1096
        $this->assertCount(2, enrol_get_course_users($course1->id));
1097
        $this->assertCount(2, enrol_get_course_users($course1->id, true));
1098
 
1099
        $this->assertCount(1, enrol_get_course_users($course1->id, true, array($user1->id)));
1100
 
1101
        $this->assertCount(2, enrol_get_course_users(false, false, array($user1->id)));
1102
 
1103
        $instances = enrol_get_instances($course1->id, true);
1104
        $manualinstance = reset($instances);
1105
 
1106
        $manualplugin = enrol_get_plugin('manual');
1107
        $manualplugin->update_user_enrol($manualinstance, $user1->id, ENROL_USER_SUSPENDED);
1108
        $this->assertCount(2, enrol_get_course_users($course1->id, false));
1109
        $this->assertCount(1, enrol_get_course_users($course1->id, true));
1110
    }
1111
 
1112
    /**
1113
     * test_course_users in groups
1114
     *
1115
     * @covers \enrol_get_course_users()
1116
     * @return void
1117
     */
11 efrain 1118
    public function test_course_users_in_groups(): void {
1 efrain 1119
        $this->resetAfterTest();
1120
 
1121
        $user1 = $this->getDataGenerator()->create_user();
1122
        $user2 = $this->getDataGenerator()->create_user();
1123
        $user3 = $this->getDataGenerator()->create_user();
1124
        $course = $this->getDataGenerator()->create_course();
1125
        $group1 = $this->getDataGenerator()->create_group(['courseid' => $course->id]);
1126
        $group2 = $this->getDataGenerator()->create_group(['courseid' => $course->id]);
1127
 
1128
        $this->getDataGenerator()->enrol_user($user1->id, $course->id);
1129
        $this->getDataGenerator()->enrol_user($user2->id, $course->id);
1130
        $this->getDataGenerator()->enrol_user($user3->id, $course->id);
1131
 
1132
        $this->getDataGenerator()->create_group_member(['groupid' => $group1->id, 'userid' => $user1->id]);
1133
        $this->getDataGenerator()->create_group_member(['groupid' => $group2->id, 'userid' => $user1->id]);
1134
        $this->getDataGenerator()->create_group_member(['groupid' => $group2->id, 'userid' => $user2->id]);
1135
 
1136
        $this->assertCount(3, enrol_get_course_users($course->id));
1137
        $this->assertCount(1, enrol_get_course_users($course->id, false, [], [], [$group1->id]));
1138
        $this->assertCount(2, enrol_get_course_users($course->id, false, [], [], [$group2->id]));
1139
 
1140
        $instances = enrol_get_instances($course->id, true);
1141
        $manualinstance = reset($instances);
1142
 
1143
        $manualplugin = enrol_get_plugin('manual');
1144
        $manualplugin->update_user_enrol($manualinstance, $user1->id, ENROL_USER_SUSPENDED);
1145
        $this->assertCount(2, enrol_get_course_users($course->id, false, [], [], [$group2->id]));
1146
        $this->assertCount(1, enrol_get_course_users($course->id, true, [], [], [$group2->id]));
1147
    }
1148
 
1149
    /**
1150
     * Test count of enrolled users
1151
     *
1152
     * @return void
1153
     */
11 efrain 1154
    public function test_count_enrolled_users(): void {
1 efrain 1155
        global $DB;
1156
 
1157
        $this->resetAfterTest(true);
1158
 
1159
        $course = $this->getDataGenerator()->create_course();
1160
        $context = \context_course::instance($course->id);
1161
 
1162
        $user1 = $this->getDataGenerator()->create_user();
1163
        $user2 = $this->getDataGenerator()->create_user();
1164
 
1165
        $studentrole = $DB->get_record('role', ['shortname' => 'student']);
1166
 
1167
        // Add each user to the manual enrolment instance.
1168
        $manual = enrol_get_plugin('manual');
1169
 
1170
        $manualinstance = $DB->get_record('enrol', ['courseid' => $course->id, 'enrol' => 'manual'], '*', MUST_EXIST);
1171
 
1172
        $manual->enrol_user($manualinstance, $user1->id, $studentrole->id);
1173
        $manual->enrol_user($manualinstance, $user2->id, $studentrole->id);
1174
 
1175
        $this->assertEquals(2, count_enrolled_users($context));
1176
 
1177
        // Create a self enrolment instance, enrol first user only.
1178
        $self = enrol_get_plugin('self');
1179
 
1180
        $selfid = $self->add_instance($course,
1181
            ['status' => ENROL_INSTANCE_ENABLED, 'name' => 'Self', 'customint6' => 1, 'roleid' => $studentrole->id]);
1182
        $selfinstance = $DB->get_record('enrol', ['id' => $selfid], '*', MUST_EXIST);
1183
 
1184
        $self->enrol_user($selfinstance, $user1->id, $studentrole->id);
1185
 
1186
        // There are still only two distinct users.
1187
        $this->assertEquals(2, count_enrolled_users($context));
1188
    }
1189
 
1190
    /**
1191
     * Test cases for the test_enrol_get_my_courses_sort_by_last_access test.
1192
     */
1193
    public function get_enrol_get_my_courses_sort_by_last_access_test_cases() {
1194
        $now = time();
1195
 
1196
        $enrolledcoursesdata = [
1197
            ['shortname' => 'a', 'lastaccess' => $now - 2],
1198
            ['shortname' => 'b', 'lastaccess' => $now - 1],
1199
            ['shortname' => 'c', 'lastaccess' => $now],
1200
            ['shortname' => 'd', 'lastaccess' => $now - 1],
1201
            ['shortname' => 'e']
1202
        ];
1203
        $unenrolledcoursesdata = [
1204
            ['shortname' => 'x', 'lastaccess' => $now - 2],
1205
            ['shortname' => 'y', 'lastaccess' => $now - 1],
1206
            ['shortname' => 'z', 'lastaccess' => $now]
1207
        ];
1208
 
1209
        return [
1210
            'empty set' => [
1211
                'enrolledcoursesdata' => [],
1212
                'unenrolledcoursesdata' => $unenrolledcoursesdata,
1213
                'sort' => 'ul.timeaccess asc',
1214
                'limit' => 0,
1215
                'offset' => 0,
1216
                'expectedcourses' => []
1217
            ],
1218
            'ul.timeaccess asc, shortname asc no limit or offset' => [
1219
                'enrolledcoursesdata' => $enrolledcoursesdata,
1220
                'unenrolledcoursesdata' => $unenrolledcoursesdata,
1221
                'sort' => 'ul.timeaccess asc, shortname asc',
1222
                'limit' => 0,
1223
                'offset' => 0,
1224
                'expectedcourses' => ['e', 'a', 'b', 'd', 'c']
1225
            ],
1226
            'ul.timeaccess asc, shortname asc with limit no offset' => [
1227
                'enrolledcoursesdata' => $enrolledcoursesdata,
1228
                'unenrolledcoursesdata' => $unenrolledcoursesdata,
1229
                'sort' => 'ul.timeaccess asc, shortname asc',
1230
                'limit' => 2,
1231
                'offset' => 0,
1232
                'expectedcourses' => ['e', 'a']
1233
            ],
1234
            'ul.timeaccess asc, shortname asc with limit and offset' => [
1235
                'enrolledcoursesdata' => $enrolledcoursesdata,
1236
                'unenrolledcoursesdata' => $unenrolledcoursesdata,
1237
                'sort' => 'ul.timeaccess asc, shortname asc',
1238
                'limit' => 2,
1239
                'offset' => 2,
1240
                'expectedcourses' => ['b', 'd']
1241
            ],
1242
            'ul.timeaccess asc, shortname asc with limit and offset beyond end of data set' => [
1243
                'enrolledcoursesdata' => $enrolledcoursesdata,
1244
                'unenrolledcoursesdata' => $unenrolledcoursesdata,
1245
                'sort' => 'ul.timeaccess asc, shortname asc',
1246
                'limit' => 2,
1247
                'offset' => 4,
1248
                'expectedcourses' => ['c']
1249
            ],
1250
            'ul.timeaccess desc, shortname asc no limit or offset' => [
1251
                'enrolledcoursesdata' => $enrolledcoursesdata,
1252
                'unenrolledcoursesdata' => $unenrolledcoursesdata,
1253
                'sort' => 'ul.timeaccess desc, shortname asc',
1254
                'limit' => 0,
1255
                'offset' => 0,
1256
                'expectedcourses' => ['c', 'b', 'd', 'a', 'e']
1257
            ],
1258
            'ul.timeaccess desc, shortname desc, no limit or offset' => [
1259
                'enrolledcoursesdata' => $enrolledcoursesdata,
1260
                'unenrolledcoursesdata' => $unenrolledcoursesdata,
1261
                'sort' => 'ul.timeaccess desc, shortname desc',
1262
                'limit' => 0,
1263
                'offset' => 0,
1264
                'expectedcourses' => ['c', 'd', 'b', 'a', 'e']
1265
            ],
1266
            'ul.timeaccess asc, shortname desc, no limit or offset' => [
1267
                'enrolledcoursesdata' => $enrolledcoursesdata,
1268
                'unenrolledcoursesdata' => $unenrolledcoursesdata,
1269
                'sort' => 'ul.timeaccess asc, shortname desc',
1270
                'limit' => 0,
1271
                'offset' => 0,
1272
                'expectedcourses' => ['e', 'a', 'd', 'b', 'c']
1273
            ],
1274
            'shortname asc, no limit or offset' => [
1275
                'enrolledcoursesdata' => $enrolledcoursesdata,
1276
                'unenrolledcoursesdata' => $unenrolledcoursesdata,
1277
                'sort' => 'shortname asc',
1278
                'limit' => 0,
1279
                'offset' => 0,
1280
                'expectedcourses' => ['a', 'b', 'c', 'd', 'e']
1281
            ],
1282
            'shortname desc, no limit or offset' => [
1283
                'enrolledcoursesdata' => $enrolledcoursesdata,
1284
                'unenrolledcoursesdata' => $unenrolledcoursesdata,
1285
                'sort' => 'shortname desc',
1286
                'limit' => 0,
1287
                'offset' => 0,
1288
                'expectedcourses' => ['e', 'd', 'c', 'b', 'a']
1289
            ],
1290
        ];
1291
    }
1292
 
1293
    /**
1294
     * Test the get_enrolled_courses_by_timeline_classification function.
1295
     *
1296
     * @dataProvider get_enrol_get_my_courses_sort_by_last_access_test_cases()
1297
     * @param array $enrolledcoursesdata Courses to create and enrol the user in
1298
     * @param array $unenrolledcoursesdata Courses to create nut not enrol the user in
1299
     * @param string $sort Sort string for the enrol function
1300
     * @param int $limit Maximum number of results
1301
     * @param int $offset Offset the courses result set by this amount
1302
     * @param array $expectedcourses Expected courses in result
1303
     */
1304
    public function test_enrol_get_my_courses_sort_by_last_access(
1305
        $enrolledcoursesdata,
1306
        $unenrolledcoursesdata,
1307
        $sort,
1308
        $limit,
1309
        $offset,
1310
        $expectedcourses
11 efrain 1311
    ): void {
1 efrain 1312
        global $DB, $CFG;
1313
 
1314
        $this->resetAfterTest();
1315
        $generator = $this->getDataGenerator();
1316
        $student = $generator->create_user();
1317
        $lastaccessrecords = [];
1318
 
1319
        foreach ($enrolledcoursesdata as $coursedata) {
1320
            $lastaccess = null;
1321
 
1322
            if (isset($coursedata['lastaccess'])) {
1323
                $lastaccess = $coursedata['lastaccess'];
1324
                unset($coursedata['lastaccess']);
1325
            }
1326
 
1327
            $course = $generator->create_course($coursedata);
1328
            $generator->enrol_user($student->id, $course->id, 'student');
1329
 
1330
            if (!is_null($lastaccess)) {
1331
                $lastaccessrecords[] = [
1332
                    'userid' => $student->id,
1333
                    'courseid' => $course->id,
1334
                    'timeaccess' => $lastaccess
1335
                ];
1336
            }
1337
        }
1338
 
1339
        foreach ($unenrolledcoursesdata as $coursedata) {
1340
            $lastaccess = null;
1341
 
1342
            if (isset($coursedata['lastaccess'])) {
1343
                $lastaccess = $coursedata['lastaccess'];
1344
                unset($coursedata['lastaccess']);
1345
            }
1346
 
1347
            $course = $generator->create_course($coursedata);
1348
 
1349
            if (!is_null($lastaccess)) {
1350
                $lastaccessrecords[] = [
1351
                    'userid' => $student->id,
1352
                    'courseid' => $course->id,
1353
                    'timeaccess' => $lastaccess
1354
                ];
1355
            }
1356
        }
1357
 
1358
        if (!empty($lastaccessrecords)) {
1359
            $DB->insert_records('user_lastaccess', $lastaccessrecords);
1360
        }
1361
 
1362
        $this->setUser($student);
1363
 
1364
        $result = enrol_get_my_courses('shortname', $sort, $limit, [], false, $offset);
1365
        $actual = array_map(function($course) {
1366
            return $course->shortname;
1367
        }, array_values($result));
1368
 
1369
        $this->assertEquals($expectedcourses, $actual);
1370
    }
1371
 
1372
    /**
1373
     * Test enrol_get_course_users_roles function.
1374
     *
1375
     * @return void
1376
     */
11 efrain 1377
    public function test_enrol_get_course_users_roles(): void {
1 efrain 1378
        global $DB;
1379
 
1380
        $this->resetAfterTest();
1381
 
1382
        $user1 = $this->getDataGenerator()->create_user();
1383
        $user2 = $this->getDataGenerator()->create_user();
1384
        $course = $this->getDataGenerator()->create_course();
1385
        $context = context_course::instance($course->id);
1386
 
1387
        $roles = array();
1388
        $roles['student'] = $DB->get_field('role', 'id', array('shortname' => 'student'), MUST_EXIST);
1389
        $roles['teacher'] = $DB->get_field('role', 'id', array('shortname' => 'teacher'), MUST_EXIST);
1390
 
1391
        $manual = enrol_get_plugin('manual');
1392
        $this->assertNotEmpty($manual);
1393
 
1394
        $enrol = $DB->get_record('enrol', array('courseid' => $course->id, 'enrol' => 'manual'), '*', MUST_EXIST);
1395
 
1396
        // Test without enrolments.
1397
        $this->assertEmpty(enrol_get_course_users_roles($course->id));
1398
 
1399
        // Test with 1 user, 1 role.
1400
        $manual->enrol_user($enrol, $user1->id, $roles['student']);
1401
        $return = enrol_get_course_users_roles($course->id);
1402
        $this->assertArrayHasKey($user1->id, $return);
1403
        $this->assertArrayHasKey($roles['student'], $return[$user1->id]);
1404
        $this->assertArrayNotHasKey($roles['teacher'], $return[$user1->id]);
1405
 
1406
        // Test with 1 user, 2 role.
1407
        $manual->enrol_user($enrol, $user1->id, $roles['teacher']);
1408
        $return = enrol_get_course_users_roles($course->id);
1409
        $this->assertArrayHasKey($user1->id, $return);
1410
        $this->assertArrayHasKey($roles['student'], $return[$user1->id]);
1411
        $this->assertArrayHasKey($roles['teacher'], $return[$user1->id]);
1412
 
1413
        // Test with another user, 1 role.
1414
        $manual->enrol_user($enrol, $user2->id, $roles['student']);
1415
        $return = enrol_get_course_users_roles($course->id);
1416
        $this->assertArrayHasKey($user1->id, $return);
1417
        $this->assertArrayHasKey($roles['student'], $return[$user1->id]);
1418
        $this->assertArrayHasKey($roles['teacher'], $return[$user1->id]);
1419
        $this->assertArrayHasKey($user2->id, $return);
1420
        $this->assertArrayHasKey($roles['student'], $return[$user2->id]);
1421
        $this->assertArrayNotHasKey($roles['teacher'], $return[$user2->id]);
1422
    }
1423
 
1424
    /**
1425
     * Test enrol_calculate_duration function
1426
     */
11 efrain 1427
    public function test_enrol_calculate_duration(): void {
1 efrain 1428
        // Start time 07/01/2019 @ 12:00am (UTC).
1429
        $timestart = 1561939200;
1430
        // End time 07/05/2019 @ 12:00am (UTC).
1431
        $timeend = 1562284800;
1432
        $duration = enrol_calculate_duration($timestart, $timeend);
1433
        $durationinday = $duration / DAYSECS;
1434
        $this->assertEquals(4, $durationinday);
1435
 
1436
        // End time 07/10/2019 @ 12:00am (UTC).
1437
        $timeend = 1562716800;
1438
        $duration = enrol_calculate_duration($timestart, $timeend);
1439
        $durationinday = $duration / DAYSECS;
1440
        $this->assertEquals(9, $durationinday);
1441
    }
1442
 
1443
    /**
1444
     * Test get_enrolled_with_capabilities_join cannotmatchanyrows attribute.
1445
     *
1446
     * @dataProvider get_enrolled_with_capabilities_join_cannotmatchanyrows_data()
1447
     * @param string $capability the tested capability
1448
     * @param bool $useprohibit if the capability must be assigned to prohibit
1449
     * @param int $expectedmatch expected cannotmatchanyrows value
1450
     * @param int $expectedcount expceted count value
1451
     */
1452
    public function test_get_enrolled_with_capabilities_join_cannotmatchanyrows(
1453
        string $capability,
1454
        bool $useprohibit,
1455
        int $expectedmatch,
1456
        int $expectedcount
11 efrain 1457
    ): void {
1 efrain 1458
        global $DB, $CFG;
1459
 
1460
        $this->resetAfterTest();
1461
 
1462
        $course = $this->getDataGenerator()->create_course();
1463
        $context = context_course::instance($course->id);
1464
 
1465
        $roleid = $CFG->defaultuserroleid;
1466
 
1467
        // Override capability if necessary.
1468
        if ($useprohibit && $capability) {
1469
            assign_capability($capability, CAP_PROHIBIT, $roleid, $context);
1470
        }
1471
 
1472
        // Check if we must enrol or not.
1473
        $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
1474
 
1475
        $join = get_enrolled_with_capabilities_join($context, '', $capability);
1476
 
1477
        // Execute query.
1478
        $sql = "SELECT COUNT(DISTINCT u.id)
1479
                  FROM {user} u {$join->joins}
1480
                 WHERE {$join->wheres}";
1481
        $countrecords = $DB->count_records_sql($sql, $join->params);
1482
 
1483
        // Validate cannotmatchanyrows.
1484
        $this->assertEquals($expectedmatch, $join->cannotmatchanyrows);
1485
        $this->assertEquals($expectedcount, $countrecords);
1486
    }
1487
 
1488
    /**
1489
     * Data provider for test_get_enrolled_with_capabilities_join_cannotmatchanyrows
1490
     *
1491
     * @return @array of testing scenarios
1492
     */
1493
    public function get_enrolled_with_capabilities_join_cannotmatchanyrows_data() {
1494
        return [
1495
            'no prohibits, no capability' => [
1496
                'capability' => '',
1497
                'useprohibit' => false,
1498
                'expectedmatch' => 0,
1499
                'expectedcount' => 1,
1500
            ],
1501
            'no prohibits with capability' => [
1502
                'capability' => 'moodle/course:manageactivities',
1503
                'useprohibit' => false,
1504
                'expectedmatch' => 0,
1505
                'expectedcount' => 1,
1506
            ],
1507
            'prohibits with capability' => [
1508
                'capability' => 'moodle/course:manageactivities',
1509
                'useprohibit' => true,
1510
                'expectedmatch' => 1,
1511
                'expectedcount' => 0,
1512
            ],
1513
        ];
1514
    }
1515
 
1516
    /**
1517
     * Test last_time_enrolments_synced not recorded with "force" option for enrol_check_plugins.
1518
     * @covers ::enrol_check_plugins
1519
     */
11 efrain 1520
    public function test_enrol_check_plugins_with_forced_option(): void {
1 efrain 1521
        $this->resetAfterTest();
1522
        $user = $this->getDataGenerator()->create_user();
1523
 
1524
        $this->assertNull(get_user_preferences('last_time_enrolments_synced', null, $user));
1525
        enrol_check_plugins($user);
1526
        $this->assertNull(get_user_preferences('last_time_enrolments_synced', null, $user));
1527
    }
1528
 
1529
    /**
1530
     * Data provided for test_enrol_check_plugins_with_empty_config_value test.
1531
     * @return array
1532
     */
1533
    public function empty_config_data_provider(): array {
1534
        return [
1535
            [0],
1536
            ["0"],
1537
            [false],
1538
            [''],
1539
            ['string'],
1540
        ];
1541
    }
1542
 
1543
    /**
1544
     * Test that empty 'enrolments_sync_interval' is treated as forced option for enrol_check_plugins.
1545
     *
1546
     * @dataProvider empty_config_data_provider
1547
     * @covers ::enrol_check_plugins
1548
     *
1549
     * @param mixed $config Config value.
1550
     */
11 efrain 1551
    public function test_enrol_check_plugins_with_empty_config_value($config): void {
1 efrain 1552
        global $CFG;
1553
 
1554
        $this->resetAfterTest();
1555
        $CFG->enrolments_sync_interval = $config;
1556
        $user = $this->getDataGenerator()->create_user();
1557
 
1558
        $this->assertNull(get_user_preferences('last_time_enrolments_synced', null, $user));
1559
        enrol_check_plugins($user, false);
1560
        $this->assertNull(get_user_preferences('last_time_enrolments_synced', null, $user));
1561
    }
1562
 
1563
    /**
1564
     * Test last_time_enrolments_synced is recorded without "force" option for enrol_check_plugins.
1565
     * @covers ::enrol_check_plugins
1566
     */
11 efrain 1567
    public function test_last_time_enrolments_synced_is_set_if_not_forced(): void {
1 efrain 1568
        $this->resetAfterTest();
1569
        $user = $this->getDataGenerator()->create_user();
1570
 
1571
        $this->assertNull(get_user_preferences('last_time_enrolments_synced', null, $user));
1572
 
1573
        enrol_check_plugins($user, false);
1574
        $firstrun = get_user_preferences('last_time_enrolments_synced', null, $user);
1575
        $this->assertNotNull($firstrun);
1576
        sleep(1);
1577
 
1578
        enrol_check_plugins($user, false);
1579
        $secondrun = get_user_preferences('last_time_enrolments_synced', null, $user);
1580
        $this->assertNotNull($secondrun);
1581
        $this->assertTrue((int)$secondrun == (int)$firstrun);
1582
    }
1583
 
1584
    /**
1585
     * Test last_time_enrolments_synced is recorded correctly without "force" option for enrol_check_plugins.
1586
     * @covers ::enrol_check_plugins
1587
     */
11 efrain 1588
    public function test_last_time_enrolments_synced_is_set_if_not_forced_if_have_not_passed_interval(): void {
1 efrain 1589
        global $CFG;
1590
 
1591
        $this->resetAfterTest();
1592
        $CFG->enrolments_sync_interval = 1;
1593
        $user = $this->getDataGenerator()->create_user();
1594
 
1595
        $this->assertNull(get_user_preferences('last_time_enrolments_synced', null, $user));
1596
 
1597
        enrol_check_plugins($user, false);
1598
        $firstrun = get_user_preferences('last_time_enrolments_synced', null, $user);
1599
        $this->assertNotNull($firstrun);
1600
        sleep(2);
1601
 
1602
        enrol_check_plugins($user, false);
1603
        $secondrun = get_user_preferences('last_time_enrolments_synced', null, $user);
1604
        $this->assertNotNull($secondrun);
1605
        $this->assertTrue((int)$secondrun > (int)$firstrun);
1606
    }
1607
 
1608
    /**
1609
     * Test enrol_selfenrol_available function behavior.
1610
     *
1611
     * @covers ::enrol_selfenrol_available
1612
     */
11 efrain 1613
    public function test_enrol_selfenrol_available(): void {
1 efrain 1614
        global $DB, $CFG;
1615
 
1616
        $this->resetAfterTest();
1617
        $this->preventResetByRollback(); // Messaging does not like transactions...
1618
 
1619
        $selfplugin = enrol_get_plugin('self');
1620
 
1621
        $user1 = $this->getDataGenerator()->create_user();
1622
        $user2 = $this->getDataGenerator()->create_user();
1623
 
1624
        $studentrole = $DB->get_record('role', ['shortname' => 'student'], '*', MUST_EXIST);
1625
        $course = $this->getDataGenerator()->create_course();
1626
        $cohort1 = $this->getDataGenerator()->create_cohort();
1627
        $cohort2 = $this->getDataGenerator()->create_cohort();
1628
 
1629
        // New enrolments are allowed and enrolment instance is enabled.
1630
        $instance = $DB->get_record('enrol', ['courseid' => $course->id, 'enrol' => 'self'], '*', MUST_EXIST);
1631
        $instance->customint6 = 1;
1632
        $DB->update_record('enrol', $instance);
1633
        $selfplugin->update_status($instance, ENROL_INSTANCE_ENABLED);
1634
        $this->setUser($user1);
1635
        $this->assertTrue(enrol_selfenrol_available($course->id));
1636
        $this->setGuestUser();
1637
        $this->assertTrue(enrol_selfenrol_available($course->id));
1638
 
1639
        $canntenrolerror = get_string('canntenrol', 'enrol_self');
1640
 
1641
        // New enrolments are not allowed, but enrolment instance is enabled.
1642
        $instance->customint6 = 0;
1643
        $DB->update_record('enrol', $instance);
1644
        $this->setUser($user1);
1645
        $this->assertFalse(enrol_selfenrol_available($course->id));
1646
        $this->setGuestUser();
1647
        $this->assertFalse(enrol_selfenrol_available($course->id));
1648
 
1649
        // New enrolments are allowed, but enrolment instance is disabled.
1650
        $instance->customint6 = 1;
1651
        $DB->update_record('enrol', $instance);
1652
        $selfplugin->update_status($instance, ENROL_INSTANCE_DISABLED);
1653
        $this->setUser($user1);
1654
        $this->assertFalse(enrol_selfenrol_available($course->id));
1655
        $this->setGuestUser();
1656
        $this->assertFalse(enrol_selfenrol_available($course->id));
1657
 
1658
        // New enrolments are not allowed and enrolment instance is disabled.
1659
        $instance->customint6 = 0;
1660
        $DB->update_record('enrol', $instance);
1661
        $this->setUser($user1);
1662
        $this->assertFalse(enrol_selfenrol_available($course->id));
1663
        $this->setGuestUser();
1664
        $this->assertFalse(enrol_selfenrol_available($course->id));
1665
 
1666
        // Enable enrolment instance for the rest of the tests.
1667
        $selfplugin->update_status($instance, ENROL_INSTANCE_ENABLED);
1668
 
1669
        // Enrol start date is in future.
1670
        $instance->customint6 = 1;
1671
        $instance->enrolstartdate = time() + 60;
1672
        $DB->update_record('enrol', $instance);
1673
        $error = get_string('canntenrolearly', 'enrol_self', userdate($instance->enrolstartdate));
1674
        $this->setUser($user1);
1675
        $this->assertFalse(enrol_selfenrol_available($course->id));
1676
        $this->setGuestUser();
1677
        $this->assertFalse(enrol_selfenrol_available($course->id));
1678
 
1679
        // Enrol start date is in past.
1680
        $instance->enrolstartdate = time() - 60;
1681
        $DB->update_record('enrol', $instance);
1682
        $this->setUser($user1);
1683
        $this->assertTrue(enrol_selfenrol_available($course->id));
1684
        $this->setGuestUser();
1685
        $this->assertTrue(enrol_selfenrol_available($course->id));
1686
 
1687
        // Enrol end date is in future.
1688
        $instance->enrolstartdate = 0;
1689
        $instance->enrolenddate = time() + 60;
1690
        $DB->update_record('enrol', $instance);
1691
        $this->setUser($user1);
1692
        $this->assertTrue(enrol_selfenrol_available($course->id));
1693
        $this->setGuestUser();
1694
        $this->assertTrue(enrol_selfenrol_available($course->id));
1695
 
1696
        // Enrol end date is in past.
1697
        $instance->enrolenddate = time() - 60;
1698
        $DB->update_record('enrol', $instance);
1699
        $error = get_string('canntenrollate', 'enrol_self', userdate($instance->enrolenddate));
1700
        $this->setUser($user1);
1701
        $this->assertFalse(enrol_selfenrol_available($course->id));
1702
        $this->setGuestUser();
1703
        $this->assertFalse(enrol_selfenrol_available($course->id));
1704
 
1705
        // Maximum enrolments reached.
1706
        $instance->customint3 = 1;
1707
        $instance->enrolenddate = 0;
1708
        $DB->update_record('enrol', $instance);
1709
        $selfplugin->enrol_user($instance, $user2->id, $studentrole->id);
1710
        $error = get_string('maxenrolledreached', 'enrol_self');
1711
        $this->setUser($user1);
1712
        $this->assertFalse(enrol_selfenrol_available($course->id));
1713
        $this->setGuestUser();
1714
        $this->assertFalse(enrol_selfenrol_available($course->id));
1715
 
1716
        // Maximum enrolments not reached.
1717
        $instance->customint3 = 3;
1718
        $DB->update_record('enrol', $instance);
1719
        $this->setUser($user1);
1720
        $this->assertTrue(enrol_selfenrol_available($course->id));
1721
        $this->setGuestUser();
1722
        $this->assertTrue(enrol_selfenrol_available($course->id));
1723
 
1724
        require_once("$CFG->dirroot/cohort/lib.php");
1725
        cohort_add_member($cohort1->id, $user2->id);
1726
 
1727
        // Cohort test.
1728
        $instance->customint5 = $cohort1->id;
1729
        $DB->update_record('enrol', $instance);
1730
        $error = get_string('cohortnonmemberinfo', 'enrol_self', $cohort1->name);
1731
        $this->setUser($user1);
1732
        $this->assertFalse(enrol_selfenrol_available($course->id));
1733
        $this->setGuestUser();
1734
        $this->assertFalse(enrol_selfenrol_available($course->id));
1735
        $this->setUser($user2);
1736
        $this->assertFalse(enrol_selfenrol_available($course->id));
1737
    }
1738
 
1739
    /**
1740
     * Test the behaviour of validate_enrol_plugin_data().
1741
     *
1742
     * @covers ::validate_enrol_plugin_data
1743
     */
1744
    public function test_validate_enrol_plugin_data(): void {
1745
        $this->resetAfterTest();
1746
 
1747
        // Plugin is disabled in system.
1748
        enrol::enable_plugin('manual', false);
1749
        $manualplugin = enrol_get_plugin('manual');
1750
 
1751
        $enrolmentdata = [];
1752
        $errors = $manualplugin->validate_enrol_plugin_data($enrolmentdata);
1753
        $this->assertArrayHasKey('plugindisabled', $errors);
1754
        $this->assertArrayNotHasKey('errorunsupportedmethod', $errors);
1755
 
1756
        $categoryplugin = enrol_get_plugin('category');
1757
        $errors = $categoryplugin->validate_enrol_plugin_data($enrolmentdata);
1758
        $this->assertArrayHasKey('errorunsupportedmethod', $errors);
1759
    }
1760
 
1761
    /**
1762
     * Test the behaviour of update_enrol_plugin_data().
1763
     *
1764
     * @covers ::update_enrol_plugin_data
1765
     */
1766
    public function test_update_enrol_plugin_data(): void {
1767
        global $DB;
1768
        $this->resetAfterTest();
1769
        $manualplugin = enrol_get_plugin('manual');
1770
 
1771
        $admin = get_admin();
1772
        $this->setUser($admin);
1773
 
1774
        $enrolmentdata = [];
1775
 
1776
        $cat = $this->getDataGenerator()->create_category();
1777
        $course = $this->getDataGenerator()->create_course(['category' => $cat->id, 'shortname' => 'ANON']);
1778
        $instance = $DB->get_record('enrol', ['courseid' => $course->id, 'enrol' => 'manual'], '*', MUST_EXIST);
1779
 
1780
        $teacherroleid = $DB->get_field('role', 'id', ['shortname' => 'teacher']);
1781
        $editingteacherroleid = $DB->get_field('role', 'id', ['shortname' => 'editingteacher']);
1782
 
1783
        $enrolmentdata['startdate'] = '3 Feb 2024';
1784
        $enrolmentdata['enddate'] = '4 Feb 2024';
1785
        $enrolmentdata['role'] = 'teacher';
1786
        $enrolmentdata['name'] = 'testinstance';
1787
 
1788
        $expectedinstance = $instance;
1789
        $expectedinstance->enrolstartdate = strtotime($enrolmentdata['startdate']);
1790
        $expectedinstance->enrolenddate = strtotime($enrolmentdata['enddate']);
1791
        $expectedinstance->role = $teacherroleid;
1792
        $expectedinstance->name = $enrolmentdata['name'];
1793
        $expectedinstance->enrolperiod = $expectedinstance->enrolenddate - $expectedinstance->enrolstartdate;
1794
        $modifiedinstance = $manualplugin->update_enrol_plugin_data($course->id, $enrolmentdata, $instance);
1795
        $this->assertEquals($expectedinstance, $modifiedinstance);
1796
 
1797
        $enrolmentdata['roleid'] = $editingteacherroleid;
1798
        unset($enrolmentdata['startdate']);
1799
        unset($enrolmentdata['enddate']);
1800
        unset($enrolmentdata['role']);
1801
        $enrolmentdata['enrolperiod'] = $modifiedinstance->enrolperiod++;
1802
        $expectedinstance->roleid = $editingteacherroleid;
1803
        $expectedinstance->enrolstartdate = 0;
1804
        $expectedinstance->enrolenddate = 0;
1805
        $expectedinstance->enrolperiod++;
1806
        $modifiedinstance = $manualplugin->update_enrol_plugin_data($course->id, $enrolmentdata, $instance);
1807
        $this->assertEquals($expectedinstance, $modifiedinstance);
1808
 
1809
        $enrolmentdata['startdate'] = '3 Feb 2024';
1810
        $enrolmentdata['enrolperiod'] = 3600;
1811
        $expectedinstance->enrolstartdate = strtotime($enrolmentdata['startdate']);
1812
        $expectedinstance->enrolperiod = $enrolmentdata['enrolperiod'];
1813
        $expectedinstance->enrolenddate = $expectedinstance->enrolstartdate + $enrolmentdata['enrolperiod'];
1814
        $modifiedinstance = $manualplugin->update_enrol_plugin_data($course->id, $enrolmentdata, $instance);
1815
        $this->assertEquals($expectedinstance, $modifiedinstance);
1816
 
1817
        $enrolmentdata['enddate'] = '5 Feb 2024';
1818
        unset($enrolmentdata['enrolperiod']);
1819
        $expectedinstance->enrolenddate = strtotime($enrolmentdata['startdate']);
1820
        $expectedinstance->enrolperiod = $expectedinstance->enrolenddate - $expectedinstance->enrolstartdate;
1821
        $modifiedinstance = $manualplugin->update_enrol_plugin_data($course->id, $enrolmentdata, $instance);
1822
        $this->assertEquals($expectedinstance, $modifiedinstance);
1823
 
1824
        $enrolmentdata['enrolperiod'] = '2hours';
1825
        $expectedinstance->enrolperiod = 7200;
1826
        $expectedinstance->enrolenddate = $expectedinstance->enrolstartdate + $expectedinstance->enrolperiod;
1827
        $modifiedinstance = $manualplugin->update_enrol_plugin_data($course->id, $enrolmentdata, $instance);
1828
        $this->assertEquals($expectedinstance, $modifiedinstance);
1829
    }
1830
}