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
namespace enrol_imsenterprise;
18
 
19
use core_course_category;
20
use enrol_imsenterprise_plugin;
21
use stdClass;
22
 
23
defined('MOODLE_INTERNAL') || die();
24
 
25
global $CFG;
26
require_once($CFG->dirroot . '/enrol/imsenterprise/locallib.php');
27
require_once($CFG->dirroot . '/enrol/imsenterprise/lib.php');
28
 
29
/**
30
 * IMS Enterprise test case
31
 *
32
 * @package    enrol_imsenterprise
33
 * @category   test
34
 * @copyright  2019 Segun Babalola
35
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
36
 *
37
 * @covers \enrol_imsenterprise_plugin
38
 */
39
class imsenterprise_unenrol_test extends \advanced_testcase {
40
 
41
    /**
42
     * @var $imsplugin enrol_imsenterprise_plugin IMS plugin instance.
43
     */
44
    public $imsplugin;
45
 
46
    /**
47
     * Setup required for all tests.
48
     */
49
    protected function setUp(): void {
50
        $this->resetAfterTest(true);
51
        $this->imsplugin = enrol_get_plugin('imsenterprise');
52
        $this->set_test_config();
53
    }
54
 
55
    /**
56
     * Sets the plugin configuration for testing
57
     */
58
    public function set_test_config() {
59
        $this->imsplugin->set_config('mailadmins', false);
60
        $this->imsplugin->set_config('prev_path', '');
61
        $this->imsplugin->set_config('createnewusers', true);
62
        $this->imsplugin->set_config('imsupdateusers', true);
63
        $this->imsplugin->set_config('createnewcourses', true);
64
        $this->imsplugin->set_config('updatecourses', true);
65
        $this->imsplugin->set_config('createnewcategories', true);
66
        $this->imsplugin->set_config('categoryseparator', '');
67
        $this->imsplugin->set_config('categoryidnumber', false);
68
        $this->imsplugin->set_config('nestedcategories', false);
69
    }
70
 
71
 
72
    /**
73
     * Creates an IMS enterprise XML file and adds it's path to config settings.
74
     *
75
     * @param bool|array $users false or array of users StdClass
76
     * @param bool|array $courses false or of courses StdClass
77
     * @param bool|array $usercoursemembership false or of courses StdClass
78
     */
79
    public function set_xml_file($users = false, $courses = false, $usercoursemembership = false) {
80
 
81
        $xmlcontent = '<enterprise>';
82
 
83
        // Users.
84
        if (!empty($users) && is_array($users)) {
85
            foreach ($users as $user) {
86
                $xmlcontent .= '<person' . (!empty($user->recstatus) ? ' recstatus="'.$user->recstatus.'"' : '').'>';
87
                $xmlcontent .= '<sourcedid><source>TestSource</source><id>'.$user->idnumber.'</id></sourcedid>';
88
                $xmlcontent .= '<userid' . (!empty($user->auth) ? ' authenticationtype="'.$user->auth.'"' : '');
89
                $xmlcontent .= '>'.$user->username.'</userid>';
90
                $xmlcontent .= '<name>'
91
                                .'<fn>'.$user->firstname.' '.$user->lastname.'</fn>'
92
                                .'<n><family>'.$user->lastname.'</family><given>'.$user->firstname.'</given></n>'
93
                                .'</name>'
94
                                .'<email>'.$user->email.'</email>';
95
                $xmlcontent .= '</person>';
96
            }
97
        }
98
 
99
        // Courses.
100
        // Mapping based on default course attributes - IMS group tags mapping.
101
        if (!empty($courses) && is_array($courses)) {
102
            foreach ($courses as $course) {
103
 
104
                $xmlcontent .= '<group' . (!empty($course->recstatus) ? ' recstatus="'.$course->recstatus.'"' : '').'>';
105
                $xmlcontent .= '<sourcedid><source>TestSource</source><id>'.$course->idnumber.'</id></sourcedid>';
106
                $xmlcontent .= '<description>'.(!empty($course->imsshort) ? '<short>'.$course->imsshort.'</short>' : '');
107
                $xmlcontent .= (!empty($course->imslong) ? '<long>'.$course->imslong.'</long>' : '');
108
                $xmlcontent .= (!empty($course->imsfull) ? '<full>'.$course->imsfull.'</full>' : '');
109
                $xmlcontent .= '</description>';
110
 
111
                // The orgunit tag value is used by moodle as category name.
112
                $xmlcontent .= '<org>';
113
 
114
                // Optional category name.
115
                if (isset($course->category)) {
116
                    if (is_array($course->category)) {
117
                        foreach ($course->category as $category) {
118
                            $xmlcontent .= '<orgunit>' . $category . '</orgunit>';
119
                        }
120
                    } else if (is_object($course->category)) {
121
                        $xmlcontent .= '<orgunit>' . $course->category->name . '</orgunit>';
122
                    } else if (!empty($course->category)) {
123
                        $xmlcontent .= '<orgunit>' . $course->category . '</orgunit>';
124
                    }
125
                }
126
 
127
                $xmlcontent .= '</org>';
128
                $xmlcontent .= '</group>';
129
            }
130
        }
131
 
132
        // User course membership (i.e. roles and enrolments).
133
        if (!empty($usercoursemembership) && is_array($usercoursemembership)) {
134
            foreach ($usercoursemembership as $crsemship) {
135
 
136
                // Only process records that have a source/id (i.e. course code) set in the IMS file.
137
                // Note that we could also check that there is a corresponding $course with the course code given here,
138
                // however it is possible that we want to test the behaviour of orphan  membership elements in future,
139
                // so leaving the check out for now.
140
                if (isset($crsemship->crseidnumber) && isset($crsemship->member) && is_array($crsemship->member)
141
                    && count($crsemship->member)) {
142
                    $xmlcontent .= '<membership><sourcedid><source>TestSource</source><id>'
143
                        .$crsemship->crseidnumber . '</id></sourcedid>';
144
 
145
                    foreach ($crsemship->member as $crsemember) {
146
                        if (!empty($crsemember->useridnumber)) {
147
                            $xmlcontent .= '<member>';
148
                            $xmlcontent .= '<sourcedid><source>TestSource</source><id>'. $crsemember->useridnumber
149
                                .'</id></sourcedid>';
150
 
151
                            // Indicates whether the member is a Person (1) or another Group (2).
152
                            // We're only handling user membership here, so hard-code value of 1.
153
                            $xmlcontent .= '<idtype>1</idtype>';
154
 
155
                            if (isset($crsemember->role) && is_array($crsemember->role)) {
156
                                foreach ($crsemember->role as $role) {
157
                                    $xmlcontent .= '<role roletype="'.$role->roletype.'" recstatus="'.$role->recstatus.'">';
158
                                    $xmlcontent .= '<userid/>';
159
                                    $xmlcontent .= '<status>' . $role->rolestatus . '</status>';
160
                                    $xmlcontent .= '</role>';
161
                                }
162
                            }
163
 
164
                            $xmlcontent .= '</member>';
165
                        }
166
                    }
167
 
168
                    $xmlcontent .= '</membership>';
169
                }
170
            }
171
        }
172
 
173
        $xmlcontent .= '</enterprise>';
174
 
175
        // Creating the XML file.
176
        $filename = 'ims_' . rand(1000, 9999) . '.xml';
177
        $tmpdir = make_temp_directory('enrol_imsenterprise');
178
        $xmlfilepath = $tmpdir . '/' . $filename;
179
        file_put_contents($xmlfilepath, $xmlcontent);
180
 
181
        // Setting the file path in CFG.
182
        $this->imsplugin->set_config('imsfilelocation', $xmlfilepath);
183
    }
184
 
185
    /**
186
     * Utility function for generating test user records
187
     *
188
     * @param int $numberofrecordsrequired - number of test users required
189
     * @return array of StdClass objects representing test user records
190
     */
191
    private function generate_test_user_records($numberofrecordsrequired) {
192
        $users = [];
193
        for ($i = 0; $i < $numberofrecordsrequired; $i++) {
194
            $usernumber = $i + 101;
195
            $users[] = (object)[
196
                'recstatus' => enrol_imsenterprise_plugin::IMSENTERPRISE_ADD,
197
                'idnumber' => $usernumber,
198
                'username' => 'UID' .$usernumber,
199
                'email' => 'user' . $usernumber . '@moodle.org',
200
                'firstname' => 'User' . $usernumber . ' firstname',
201
                'lastname' => 'User' . $usernumber . ' lastname'
202
            ];
203
        }
204
 
205
        return $users;
206
    }
207
 
208
    /**
209
     * Utility function for generating test course records
210
     *
211
     * @param int $numberofrecordsrequired - number of test course records required
212
     * @return array of StdClass objects representing test course records
213
     */
214
    private function generate_test_course_records($numberofrecordsrequired) {
215
        $courses = [];
216
        for ($i = 0; $i < $numberofrecordsrequired; $i++) {
217
            $coursenumber = $i + 101;
218
            $courses[] = (object)[
219
                'recstatus' => enrol_imsenterprise_plugin::IMSENTERPRISE_ADD,
220
                'idnumber' => 'CID' . $coursenumber,
221
                'imsshort' => 'Course ' . $coursenumber,
222
                'category' => core_course_category::get_default()
223
            ];
224
        }
225
 
226
        return $courses;
227
    }
228
 
229
    /**
230
     * Utility function for generating test membership structure for given users and courses.
231
     * Linkmatrix is expected to be in [row, col] format, where courses are rows and users are columns.
232
     * Each element of the link matrix is expected to contain <roletype>:<role status>:<role recstatus>.
233
     *
234
     * @param array $users
235
     * @param array $courses
236
     * @param array $linkmatrix - matrix/two dimensional array of required user course enrolments
237
     * @return array
238
     */
239
    private function link_users_with_courses($users, $courses, $linkmatrix) {
240
 
241
        $memberships = [];
242
 
243
        foreach ($courses as $i => $c) {
244
 
245
            $membership = new stdClass();
246
            $membership->member = [];
247
            $membership->crseidnumber = $c->idnumber;
248
 
249
            foreach ($users as $j => $u) {
250
                if (isset($linkmatrix[$i][$j])) {
251
 
252
                    list($roletype, $rolestatus, $rolerecstatus) = explode(':', $linkmatrix[$i][$j]);
253
 
254
                    if (strlen($rolerecstatus) && strlen($roletype) && strlen($rolestatus)) {
255
                        $membership->member[] = (object)[
256
                            'useridnumber' => $u->idnumber,
257
                            'role' => [(object)[
258
                                'roletype' => $roletype,
259
                                'rolestatus' => $rolestatus,
260
                                'recstatus' => $rolerecstatus
261
                            ]]
262
                        ];
263
                    }
264
                }
265
            }
266
 
267
            $memberships[] = $membership;
268
        }
269
 
270
        return $memberships;
271
    }
272
 
273
    /**
274
     * Add new users, courses and enrolments
275
     */
11 efrain 276
    public function test_users_are_enroled_on_courses(): void {
1 efrain 277
        global $DB;
278
 
279
        $prevnuserenrolments = $DB->count_records('user_enrolments');
280
        $prevnusers = $DB->count_records('user');
281
        $prevncourses = $DB->count_records('course');
282
 
283
        $courses = $this->generate_test_course_records(1);
284
        $users = $this->generate_test_user_records(1);
285
        $coursemembership = $this->link_users_with_courses(
286
            $users,
287
            $courses,
288
            [
289
                ['01:1:1'] // First course.
290
            ]
291
        );
292
 
293
        $this->set_xml_file($users, $courses, $coursemembership);
294
        $this->imsplugin->cron();
295
 
296
        $this->assertEquals(($prevnuserenrolments + 1), $DB->count_records('user_enrolments'));
297
        $this->assertEquals(($prevnusers + 1), $DB->count_records('user'));
298
        $this->assertEquals(($prevncourses + 1), $DB->count_records('course'));
299
    }
300
 
301
    /**
302
     * Check that the unenrol actions are completely ignored when "unenrol" setting is disabled
303
     */
11 efrain 304
    public function test_no_action_when_unenrol_disabled(): void {
1 efrain 305
        global $DB;
306
 
307
        $prevnuserenrolments = $DB->count_records('user_enrolments');
308
        $prevnusers = $DB->count_records('user');
309
        $prevncourses = $DB->count_records('course');
310
 
311
        // Create user and course.
312
        $courses = $this->generate_test_course_records(3);
313
        $users = $this->generate_test_user_records(2);
314
        $coursemembership = $this->link_users_with_courses(
315
            $users,
316
            $courses,
317
            // Role types: 01=Learner, 02=Instructor, 03=Content Dev, 04=Member, 05=Manager, 06=Mentor, 07=Admin, 08=TA.
318
            // Role statuses: 0=Inactive, 1=Active.
319
            // Role recstatus:  1=Add, 2=Update, 3=Delete.
320
            // Format of matrix elements: <roletype>:<role status>:<role recstatus>.
321
            [
322
                ['01:1:1', '01:1:1'], // Course 1.
323
                ['01:1:1', '01:1:1'], // Course 2.
324
                ['::', '01:1:1'], // Course 3.
325
            ]
326
        );
327
 
328
        $this->set_xml_file($users, $courses, $coursemembership);
329
        $this->imsplugin->cron();
330
 
331
        $this->assertEquals(($prevnuserenrolments + 5), $DB->count_records('user_enrolments'));
332
        $this->assertEquals(($prevnusers + 2), $DB->count_records('user'));
333
        $this->assertEquals(($prevncourses + 3), $DB->count_records('course'));
334
 
335
        // Disallow unenrolment, and check that unenroling has no effect.
336
        $this->imsplugin->set_config('imsunenrol', 0);
337
 
338
        $coursemembership = $this->link_users_with_courses(
339
            $users,
340
            $courses,
341
            // Role types: 01=Learner, 02=Instructor, 03=Content Dev, 04=Member, 05=Manager, 06=Mentor, 07=Admin, 08=TA.
342
            // Role statuses: 0=Inactive, 1=Active.
343
            // Role recstatus:  1=Add, 2=Update, 3=Delete.
344
            // Format of matrix elements: <roletype>:<role status>:<role recstatus>.
345
            [
346
                ['01:1:3', '01:1:3'], // Course 1.
347
                ['::', '01:1:3'], // Course 2.
348
                ['::', '01:1:3'], // Course 3.
349
            ]
350
        );
351
 
352
        $this->set_xml_file($users, $courses, $coursemembership);
353
        $this->imsplugin->cron();
354
 
355
        $this->assertEquals(($prevnuserenrolments + 5), $DB->count_records('user_enrolments'));
356
        $this->assertEquals(($prevnusers + 2), $DB->count_records('user'));
357
        $this->assertEquals(($prevncourses + 3), $DB->count_records('course'));
358
    }
359
 
360
    /**
361
     * When a user has existing roles and enrolments, they are unaffected by IMS instructions for other courses
362
     */
11 efrain 363
    public function test_existing_roles_and_enrolments_unaffected(): void {
1 efrain 364
 
365
        global $DB;
366
 
367
        $this->imsplugin->set_config('imsunenrol', 1);
368
        $this->imsplugin->set_config('unenrolaction', ENROL_EXT_REMOVED_UNENROL);
369
 
370
        $prevnuserenrolments = $DB->count_records('user_enrolments');
371
        $prevnusers = $DB->count_records('user');
372
        $prevncourses = $DB->count_records('course');
373
 
374
        $courses = $this->generate_test_course_records(2);
375
 
376
        // Create_course seems to expect the category to be passed as ID, so extract from the object.
377
        $course1 = $courses[0];
378
        $course1->category = $course1->category->id;
379
        $course1 = $this->getDataGenerator()->create_course($courses[0]);
380
 
381
        // Enrol user1 on course1.
382
        $DB->insert_record('enrol', (object)['enrol' => 'imsenterprise',
383
            'courseid' => $course1->id, 'status' => 1, 'roleid' => 5
384
        ], true);
385
 
386
        $user1 = $this->getDataGenerator()->create_and_enrol($course1, 'student',
387
            ['idnumber' => 'UserIDNumber100'], 'imsenterprise');
388
        $user1->username = $user1->idnumber;
389
 
390
        // Confirm user was added and that the enrolment happened.
391
        $this->assertEquals(($prevnuserenrolments + 1), $DB->count_records('user_enrolments'));
392
        $this->assertEquals(($prevnusers + 1), $DB->count_records('user'));
393
        $this->assertEquals(($prevncourses + 1), $DB->count_records('course'));
394
 
395
        // Capture DB id of enrolment record.
396
        $initialusernerolment = $DB->get_record('user_enrolments', ['userid' => $user1->id],
397
            '*', MUST_EXIST);
398
        $initialroleassigned = $DB->get_record('role_assignments', ['userid' => $user1->id],
399
            '*', MUST_EXIST);
400
 
401
        // Add a new enrolment for the same user via IMS file.
402
        $coursemembership = $this->link_users_with_courses(
403
            [$user1],
404
            $courses,
405
            // Role types: 01=Learner, 02=Instructor, 03=Content Dev, 04=Member, 05=Manager, 06=Mentor, 07=Admin, 08=TA.
406
            // Role statuses: 0=Inactive, 1=Active.
407
            // Role recstatus:  1=Add, 2=Update, 3=Delete.
408
            // Format of matrix elements: <roletype>:<role status>:<role recstatus>.
409
            [
410
                ['::'], // Course 1.
411
                ['01:1:1'], // Course 2.
412
            ]
413
        );
414
 
415
        $this->set_xml_file([$user1], $courses, $coursemembership);
416
        $this->imsplugin->cron();
417
 
418
        $this->assertEquals(2, $DB->count_records('user_enrolments', ['userid' => $user1->id]));
419
        $this->assertEquals(($prevncourses + 2), $DB->count_records('course'));
420
 
421
        // Unenrol the user from course2 via IMS file.
422
        $coursemembership = $this->link_users_with_courses(
423
            [$user1],
424
            $courses,
425
            // Role types: 01=Learner, 02=Instructor, 03=Content Dev, 04=Member, 05=Manager, 06=Mentor, 07=Admin, 08=TA.
426
            // Role statuses: 0=Inactive, 1=Active.
427
            // Role recstatus:  1=Add, 2=Update, 3=Delete.
428
            // Format of matrix elements: <roletype>:<role status>:<role recstatus>.
429
            [
430
                ['::'], // Course 1.
431
                ['01:0:3'], // Course 2.
432
            ]
433
        );
434
 
435
        $this->set_xml_file([$user1], $courses, $coursemembership);
436
        $this->imsplugin->cron();
437
 
438
        $this->assertEquals(1, $DB->count_records('user_enrolments', ['userid' => $user1->id]));
439
        $this->assertTrue($DB->record_exists('user_enrolments', ['id' => $initialusernerolment->id,
440
            'userid' => $initialusernerolment->userid]));
441
        $this->assertTrue($DB->record_exists('role_assignments', ['id' => $initialroleassigned->id,
442
            'userid' => $initialusernerolment->userid]));
443
    }
444
 
445
    /**
446
     * Enrolments alone are disabled
447
     */
11 efrain 448
    public function test_disable_enrolments_only(): void {
1 efrain 449
 
450
        global $DB;
451
 
452
        $this->imsplugin->set_config('imsunenrol', 1);
453
        $this->imsplugin->set_config('unenrolaction', ENROL_EXT_REMOVED_SUSPEND);
454
 
455
        $prevnuserenrolments = $DB->count_records('user_enrolments');
456
        $prevnroles = $DB->count_records('role_assignments');
457
        $prevnusers = $DB->count_records('user');
458
        $prevncourses = $DB->count_records('course');
459
 
460
        $courses = $this->generate_test_course_records(1);
461
        $users = $this->generate_test_user_records(1);
462
 
463
        // Add a new enrolment for the same user via IMS file.
464
        $coursemembership = $this->link_users_with_courses(
465
            $users,
466
            $courses,
467
            // Role types: 01=Learner, 02=Instructor, 03=Content Dev, 04=Member, 05=Manager, 06=Mentor, 07=Admin, 08=TA.
468
            // Role statuses: 0=Inactive, 1=Active.
469
            // Role recstatus:  1=Add, 2=Update, 3=Delete.
470
            // Format of matrix elements: <roletype>:<role status>:<role recstatus>.
471
            [
472
                ['01:1:1'], // Course 1.
473
            ]
474
        );
475
 
476
        $this->set_xml_file($users, $courses, $coursemembership);
477
        $this->imsplugin->cron();
478
 
479
        $this->assertEquals(($prevncourses + 1), $DB->count_records('course'));
480
        $this->assertEquals(($prevnusers + 1), $DB->count_records('user'));
481
        $this->assertEquals(($prevnuserenrolments + 1), $DB->count_records('user_enrolments'));
482
        $this->assertEquals(($prevnroles + 1), $DB->count_records('role_assignments'));
483
 
484
        // Capture DB ids.
485
        $dbuser = $DB->get_record('user', ['idnumber' => $users[0]->idnumber], '*', MUST_EXIST);
486
 
487
        $dbenrolment = $DB->get_record('user_enrolments',
488
            ['userid' => $dbuser->id, 'status' => ENROL_USER_ACTIVE],
489
            '*', MUST_EXIST
490
        );
491
 
492
        $dbrole = $DB->get_record('role_assignments', ['userid' => $dbuser->id], '*', MUST_EXIST);
493
 
494
        // Unenrol the user, check that the enrolment and role exist, but the enrolment is suspended.
495
        $coursemembership = $this->link_users_with_courses(
496
            $users,
497
            $courses,
498
            // Role types: 01=Learner, 02=Instructor, 03=Content Dev, 04=Member, 05=Manager, 06=Mentor, 07=Admin, 08=TA.
499
            // Role statuses: 0=Inactive, 1=Active.
500
            // Role recstatus:  1=Add, 2=Update, 3=Delete.
501
            // Format of matrix elements: <roletype>:<role status>:<role recstatus>.
502
            [
503
                ['01:0:3'], // Course 1.
504
            ]
505
        );
506
 
507
        $this->set_xml_file($users, $courses, $coursemembership);
508
        $this->imsplugin->cron();
509
 
510
        $this->assertEquals(($prevncourses + 1), $DB->count_records('course'));
511
        $this->assertEquals(($prevnusers + 1), $DB->count_records('user'));
512
        $this->assertEquals(($prevnuserenrolments + 1), $DB->count_records('user_enrolments'));
513
        $this->assertEquals(($prevnroles + 1), $DB->count_records('role_assignments'));
514
 
515
        $this->assertEquals(1, $DB->count_records('user_enrolments',
516
            ['userid' => $dbuser->id, 'id' => $dbenrolment->id, 'status' => ENROL_USER_SUSPENDED]));
517
 
518
        $this->assertEquals(1, $DB->count_records('role_assignments',
519
            ['userid' => $dbuser->id, 'id' => $dbrole->id]));
520
    }
521
 
522
    /**
523
     * Enrolments are disabled but retained) and roles removed
524
     */
11 efrain 525
    public function test_disable_enrolments_and_remove_roles(): void {
1 efrain 526
 
527
        global $DB;
528
 
529
        $this->imsplugin->set_config('imsunenrol', 1);
530
        $this->imsplugin->set_config('unenrolaction', ENROL_EXT_REMOVED_SUSPENDNOROLES);
531
 
532
        $prevnuserenrolments = $DB->count_records('user_enrolments');
533
        $prevnroles = $DB->count_records('role_assignments');
534
        $prevnusers = $DB->count_records('user');
535
        $prevncourses = $DB->count_records('course');
536
 
537
        $courses = $this->generate_test_course_records(1);
538
        $users = $this->generate_test_user_records(1);
539
 
540
        // Add a new enrolment for the same user via IMS file.
541
        $coursemembership = $this->link_users_with_courses(
542
            $users,
543
            $courses,
544
            // Role types: 01=Learner, 02=Instructor, 03=Content Dev, 04=Member, 05=Manager, 06=Mentor, 07=Admin, 08=TA.
545
            // Role statuses: 0=Inactive, 1=Active.
546
            // Role recstatus:  1=Add, 2=Update, 3=Delete.
547
            // Format of matrix elements: <roletype>:<role status>:<role recstatus>.
548
            [
549
                ['01:1:1'], // Course 1.
550
            ]
551
        );
552
 
553
        $this->set_xml_file($users, $courses, $coursemembership);
554
        $this->imsplugin->cron();
555
 
556
        $this->assertEquals(($prevncourses + 1), $DB->count_records('course'));
557
        $this->assertEquals(($prevnusers + 1), $DB->count_records('user'));
558
        $this->assertEquals(($prevnuserenrolments + 1), $DB->count_records('user_enrolments'));
559
        $this->assertEquals(($prevnroles + 1), $DB->count_records('role_assignments'));
560
 
561
        // Capture DB ids.
562
        $dbuser = $DB->get_record('user', ['idnumber' => $users[0]->idnumber], '*', MUST_EXIST);
563
 
564
        $dbenrolment = $DB->get_record('user_enrolments',
565
            ['userid' => $dbuser->id, 'status' => ENROL_USER_ACTIVE],
566
            '*', MUST_EXIST
567
        );
568
 
569
        $dbrole = $DB->get_record('role_assignments', ['userid' => $dbuser->id], '*', MUST_EXIST);
570
 
571
        // Unenrol the user, check that the enrolment and role exist, but the enrolment is suspended.
572
        $coursemembership = $this->link_users_with_courses(
573
            $users,
574
            $courses,
575
            // Role types: 01=Learner, 02=Instructor, 03=Content Dev, 04=Member, 05=Manager, 06=Mentor, 07=Admin, 08=TA.
576
            // Role statuses: 0=Inactive, 1=Active.
577
            // Role recstatus:  1=Add, 2=Update, 3=Delete.
578
            // Format of matrix elements: <roletype>:<role status>:<role recstatus>.
579
            [
580
                ['01:0:3'], // Course 1.
581
            ]
582
        );
583
 
584
        $this->set_xml_file($users, $courses, $coursemembership);
585
        $this->imsplugin->cron();
586
 
587
        $this->assertEquals(($prevncourses + 1), $DB->count_records('course'));
588
        $this->assertEquals(($prevnusers + 1), $DB->count_records('user'));
589
        $this->assertEquals(($prevnuserenrolments + 1), $DB->count_records('user_enrolments'));
590
        $this->assertEquals(($prevnroles), $DB->count_records('role_assignments'));
591
 
592
        $this->assertEquals(1, $DB->count_records('user_enrolments',
593
            ['userid' => $dbuser->id, 'id' => $dbenrolment->id, 'status' => ENROL_USER_SUSPENDED]));
594
 
595
        $this->assertEquals(0, $DB->count_records('role_assignments',
596
            ['userid' => $dbuser->id, 'id' => $dbrole->id]));
597
 
598
    }
599
 
600
    /**
601
     * Enrolments and roles are deleted for specified user
602
     */
11 efrain 603
    public function test_delete_roles_and_enrolments(): void {
1 efrain 604
 
605
        global $DB;
606
 
607
        $this->imsplugin->set_config('imsunenrol', 1);
608
        $this->imsplugin->set_config('unenrolaction', ENROL_EXT_REMOVED_UNENROL);
609
 
610
        $prevnuserenrolments = $DB->count_records('user_enrolments');
611
        $prevnroles = $DB->count_records('role_assignments');
612
        $prevnusers = $DB->count_records('user');
613
        $prevncourses = $DB->count_records('course');
614
 
615
        $courses = $this->generate_test_course_records(1);
616
        $users = $this->generate_test_user_records(1);
617
 
618
        // Add a new enrolment for the same user via IMS file.
619
        $coursemembership = $this->link_users_with_courses(
620
            $users,
621
            $courses,
622
            // Role types: 01=Learner, 02=Instructor, 03=Content Dev, 04=Member, 05=Manager, 06=Mentor, 07=Admin, 08=TA.
623
            // Role statuses: 0=Inactive, 1=Active.
624
            // Role recstatus:  1=Add, 2=Update, 3=Delete.
625
            // Format of matrix elements: <roletype>:<role status>:<role recstatus>.
626
            [
627
                ['01:1:1'], // Course 1.
628
            ]
629
        );
630
 
631
        $this->set_xml_file($users, $courses, $coursemembership);
632
        $this->imsplugin->cron();
633
 
634
        $this->assertEquals(($prevncourses + 1), $DB->count_records('course'));
635
        $this->assertEquals(($prevnusers + 1), $DB->count_records('user'));
636
        $this->assertEquals(($prevnuserenrolments + 1), $DB->count_records('user_enrolments'));
637
        $this->assertEquals(($prevnroles + 1), $DB->count_records('role_assignments'));
638
 
639
        // Capture DB ids.
640
        $dbuser = $DB->get_record('user', ['idnumber' => $users[0]->idnumber], '*', MUST_EXIST);
641
 
642
        $dbenrolment = $DB->get_record('user_enrolments',
643
            ['userid' => $dbuser->id, 'status' => ENROL_USER_ACTIVE],
644
            '*', MUST_EXIST
645
        );
646
 
647
        $dbrole = $DB->get_record('role_assignments', ['userid' => $dbuser->id], '*', MUST_EXIST);
648
 
649
        // Unenrol the user, check that the enrolment and role exist, but the enrolment is suspended.
650
        $coursemembership = $this->link_users_with_courses(
651
            $users,
652
            $courses,
653
            // Role types: 01=Learner, 02=Instructor, 03=Content Dev, 04=Member, 05=Manager, 06=Mentor, 07=Admin, 08=TA.
654
            // Role statuses: 0=Inactive, 1=Active.
655
            // Role recstatus:  1=Add, 2=Update, 3=Delete.
656
            // Format of matrix elements: <roletype>:<role status>:<role recstatus>.
657
            [
658
                ['01:1:3'], // Course 1.
659
            ]
660
        );
661
 
662
        $this->set_xml_file($users, $courses, $coursemembership);
663
        $this->imsplugin->cron();
664
 
665
        $this->assertEquals(($prevncourses + 1), $DB->count_records('course'));
666
        $this->assertEquals(($prevnusers + 1), $DB->count_records('user'));
667
        $this->assertEquals(($prevnuserenrolments), $DB->count_records('user_enrolments'));
668
        $this->assertEquals(($prevnroles), $DB->count_records('role_assignments'));
669
 
670
        $this->assertEquals(0, $DB->count_records('user_enrolments',
671
            ['userid' => $dbuser->id, 'id' => $dbenrolment->id, 'status' => ENROL_USER_SUSPENDED]));
672
 
673
        $this->assertEquals(0, $DB->count_records('role_assignments',
674
            ['userid' => $dbuser->id, 'id' => $dbrole->id]));
675
    }
676
}