See Release Notes
Long Term Support Release
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 */ 276 public function test_users_are_enroled_on_courses() { 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 */ 304 public function test_no_action_when_unenrol_disabled() { 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 */ 363 public function test_existing_roles_and_enrolments_unaffected() { 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 */ 448 public function test_disable_enrolments_only() { 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 */ 525 public function test_disable_enrolments_and_remove_roles() { 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 */ 603 public function test_delete_roles_and_enrolments() { 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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body