Proyectos de Subversion Moodle

Rev

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