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