[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
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 * Full functional accesslib test. 19 * 20 * @package core 21 * @category phpunit 22 * @copyright 2011 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 * Functional test for accesslib.php 31 * 32 * Note: execution may take many minutes especially on slower servers. 33 */ 34 class core_accesslib_testcase extends advanced_testcase { 35 /** 36 * Verify comparison of context instances in phpunit asserts. 37 */ 38 public function test_context_comparisons() { 39 $frontpagecontext1 = context_course::instance(SITEID); 40 context_helper::reset_caches(); 41 $frontpagecontext2 = context_course::instance(SITEID); 42 $this->assertEquals($frontpagecontext1, $frontpagecontext2); 43 44 $user1 = context_user::instance(1); 45 $user2 = context_user::instance(2); 46 $this->assertNotEquals($user1, $user2); 47 } 48 49 /** 50 * Test resetting works. 51 */ 52 public function test_accesslib_clear_all_caches() { 53 global $ACCESSLIB_PRIVATE; 54 55 $this->resetAfterTest(); 56 57 $this->setAdminUser(); 58 load_all_capabilities(); 59 60 $this->assertNotEmpty($ACCESSLIB_PRIVATE->rolepermissions); 61 $this->assertNotEmpty($ACCESSLIB_PRIVATE->rolepermissions); 62 $this->assertNotEmpty($ACCESSLIB_PRIVATE->accessdatabyuser); 63 accesslib_clear_all_caches_for_unit_testing(); 64 $this->assertEmpty($ACCESSLIB_PRIVATE->rolepermissions); 65 $this->assertEmpty($ACCESSLIB_PRIVATE->rolepermissions); 66 $this->assertEmpty($ACCESSLIB_PRIVATE->dirtycontexts); 67 $this->assertEmpty($ACCESSLIB_PRIVATE->accessdatabyuser); 68 } 69 70 /** 71 * Check modifying capability record is not exposed to other code. 72 */ 73 public function test_capabilities_mutation() { 74 $oldcap = get_capability_info('moodle/site:config'); 75 $cap = get_capability_info('moodle/site:config'); 76 unset($cap->name); 77 $newcap = get_capability_info('moodle/site:config'); 78 79 $this->assertFalse(isset($cap->name)); 80 $this->assertTrue(isset($newcap->name)); 81 $this->assertTrue(isset($oldcap->name)); 82 } 83 84 /** 85 * Test getting of role access 86 */ 87 public function test_get_role_access() { 88 global $DB; 89 90 $roles = $DB->get_records('role'); 91 foreach ($roles as $role) { 92 $access = get_role_access($role->id); 93 94 $this->assertTrue(is_array($access)); 95 $this->assertTrue(is_array($access['ra'])); 96 $this->assertTrue(is_array($access['rdef'])); 97 $this->assertTrue(isset($access['rdef_count'])); 98 $this->assertTrue(is_array($access['loaded'])); 99 $this->assertTrue(isset($access['time'])); 100 $this->assertTrue(is_array($access['rsw'])); 101 } 102 103 // Note: the data is validated in the functional permission evaluation test at the end of this testcase. 104 } 105 106 /** 107 * Test getting of guest role. 108 */ 109 public function test_get_guest_role() { 110 global $CFG; 111 112 $guest = get_guest_role(); 113 $this->assertEquals('guest', $guest->archetype); 114 $this->assertEquals('guest', $guest->shortname); 115 116 $this->assertEquals($CFG->guestroleid, $guest->id); 117 } 118 119 /** 120 * Test if user is admin. 121 */ 122 public function test_is_siteadmin() { 123 global $DB, $CFG; 124 125 $this->resetAfterTest(); 126 127 $users = $DB->get_records('user'); 128 129 foreach ($users as $user) { 130 $this->setUser(0); 131 if ($user->username === 'admin') { 132 $this->assertTrue(is_siteadmin($user)); 133 $this->assertTrue(is_siteadmin($user->id)); 134 $this->setUser($user); 135 $this->assertTrue(is_siteadmin()); 136 $this->assertTrue(is_siteadmin(null)); 137 } else { 138 $this->assertFalse(is_siteadmin($user)); 139 $this->assertFalse(is_siteadmin($user->id)); 140 $this->setUser($user); 141 $this->assertFalse(is_siteadmin()); 142 $this->assertFalse(is_siteadmin(null)); 143 } 144 } 145 146 // Change the site admin list and check that it still works with 147 // multiple admins. We do this with userids only (not real user 148 // accounts) because it makes the test simpler. 149 $before = $CFG->siteadmins; 150 set_config('siteadmins', '666,667,668'); 151 $this->assertTrue(is_siteadmin(666)); 152 $this->assertTrue(is_siteadmin(667)); 153 $this->assertTrue(is_siteadmin(668)); 154 $this->assertFalse(is_siteadmin(669)); 155 set_config('siteadmins', '13'); 156 $this->assertTrue(is_siteadmin(13)); 157 $this->assertFalse(is_siteadmin(666)); 158 set_config('siteadmins', $before); 159 } 160 161 /** 162 * Test if user is enrolled in a course 163 */ 164 public function test_is_enrolled() { 165 global $DB; 166 167 $this->resetAfterTest(); 168 169 // Generate data. 170 $user = $this->getDataGenerator()->create_user(); 171 $course = $this->getDataGenerator()->create_course(); 172 $coursecontext = context_course::instance($course->id); 173 $role = $DB->get_record('role', array('shortname'=>'student')); 174 175 // There should be a manual enrolment as part of the default install. 176 $plugin = enrol_get_plugin('manual'); 177 $instance = $DB->get_record('enrol', array( 178 'courseid' => $course->id, 179 'enrol' => 'manual', 180 )); 181 $this->assertNotSame(false, $instance); 182 183 // Enrol the user in the course. 184 $plugin->enrol_user($instance, $user->id, $role->id); 185 186 // We'll test with the mod/assign:submit capability. 187 $capability= 'mod/assign:submit'; 188 $this->assertTrue($DB->record_exists('capabilities', array('name' => $capability))); 189 190 // Switch to our user. 191 $this->setUser($user); 192 193 // Ensure that the user has the capability first. 194 $this->assertTrue(has_capability($capability, $coursecontext, $user->id)); 195 196 // We first test whether the user is enrolled on the course as this 197 // seeds the cache, then we test for the capability. 198 $this->assertTrue(is_enrolled($coursecontext, $user, '', true)); 199 $this->assertTrue(is_enrolled($coursecontext, $user, $capability)); 200 201 // Prevent the capability for this user role. 202 assign_capability($capability, CAP_PROHIBIT, $role->id, $coursecontext); 203 $coursecontext->mark_dirty(); 204 $this->assertFalse(has_capability($capability, $coursecontext, $user->id)); 205 206 // Again, we seed the cache first by checking initial enrolment, 207 // and then we test the actual capability. 208 $this->assertTrue(is_enrolled($coursecontext, $user, '', true)); 209 $this->assertFalse(is_enrolled($coursecontext, $user, $capability)); 210 } 211 212 /** 213 * Test logged in test. 214 */ 215 public function test_isloggedin() { 216 global $USER; 217 218 $this->resetAfterTest(); 219 220 $USER->id = 0; 221 $this->assertFalse(isloggedin()); 222 $USER->id = 1; 223 $this->assertTrue(isloggedin()); 224 } 225 226 /** 227 * Test guest user test. 228 */ 229 public function test_isguestuser() { 230 global $DB; 231 232 $this->resetAfterTest(); 233 234 $guest = $DB->get_record('user', array('username'=>'guest')); 235 $this->setUser(0); 236 $this->assertFalse(isguestuser()); 237 $this->setAdminUser(); 238 $this->assertFalse(isguestuser()); 239 $this->assertTrue(isguestuser($guest)); 240 $this->assertTrue(isguestuser($guest->id)); 241 $this->setUser($guest); 242 $this->assertTrue(isguestuser()); 243 244 $users = $DB->get_records('user'); 245 foreach ($users as $user) { 246 if ($user->username === 'guest') { 247 continue; 248 } 249 $this->assertFalse(isguestuser($user)); 250 } 251 } 252 253 /** 254 * Test capability riskiness. 255 */ 256 public function test_is_safe_capability() { 257 global $DB; 258 // Note: there is not much to test, just make sure no notices are throw for the most dangerous cap. 259 $capability = $DB->get_record('capabilities', array('name'=>'moodle/site:config'), '*', MUST_EXIST); 260 $this->assertFalse(is_safe_capability($capability)); 261 } 262 263 /** 264 * Test context fetching. 265 */ 266 public function test_get_context_info_array() { 267 $this->resetAfterTest(); 268 269 $syscontext = context_system::instance(); 270 $user = $this->getDataGenerator()->create_user(); 271 $usercontext = context_user::instance($user->id); 272 $course = $this->getDataGenerator()->create_course(); 273 $catcontext = context_coursecat::instance($course->category); 274 $coursecontext = context_course::instance($course->id); 275 $page = $this->getDataGenerator()->create_module('page', array('course'=>$course->id)); 276 $modcontext = context_module::instance($page->cmid); 277 $cm = get_coursemodule_from_instance('page', $page->id); 278 $block1 = $this->getDataGenerator()->create_block('online_users', array('parentcontextid'=>$coursecontext->id)); 279 $block1context = context_block::instance($block1->id); 280 $block2 = $this->getDataGenerator()->create_block('online_users', array('parentcontextid'=>$modcontext->id)); 281 $block2context = context_block::instance($block2->id); 282 283 $result = get_context_info_array($syscontext->id); 284 $this->assertCount(3, $result); 285 $this->assertEquals($syscontext, $result[0]); 286 $this->assertNull($result[1]); 287 $this->assertNull($result[2]); 288 289 $result = get_context_info_array($usercontext->id); 290 $this->assertCount(3, $result); 291 $this->assertEquals($usercontext, $result[0]); 292 $this->assertNull($result[1]); 293 $this->assertNull($result[2]); 294 295 $result = get_context_info_array($catcontext->id); 296 $this->assertCount(3, $result); 297 $this->assertEquals($catcontext, $result[0]); 298 $this->assertNull($result[1]); 299 $this->assertNull($result[2]); 300 301 $result = get_context_info_array($coursecontext->id); 302 $this->assertCount(3, $result); 303 $this->assertEquals($coursecontext, $result[0]); 304 $this->assertEquals($course->id, $result[1]->id); 305 $this->assertSame($course->shortname, $result[1]->shortname); 306 $this->assertNull($result[2]); 307 308 $result = get_context_info_array($block1context->id); 309 $this->assertCount(3, $result); 310 $this->assertEquals($block1context, $result[0]); 311 $this->assertEquals($course->id, $result[1]->id); 312 $this->assertEquals($course->shortname, $result[1]->shortname); 313 $this->assertNull($result[2]); 314 315 $result = get_context_info_array($modcontext->id); 316 $this->assertCount(3, $result); 317 $this->assertEquals($modcontext, $result[0]); 318 $this->assertEquals($course->id, $result[1]->id); 319 $this->assertSame($course->shortname, $result[1]->shortname); 320 $this->assertEquals($cm->id, $result[2]->id); 321 322 $result = get_context_info_array($block2context->id); 323 $this->assertCount(3, $result); 324 $this->assertEquals($block2context, $result[0]); 325 $this->assertEquals($course->id, $result[1]->id); 326 $this->assertSame($course->shortname, $result[1]->shortname); 327 $this->assertEquals($cm->id, $result[2]->id); 328 } 329 330 /** 331 * Test looking for course contacts. 332 */ 333 public function test_has_coursecontact_role() { 334 global $DB, $CFG; 335 336 $this->resetAfterTest(); 337 338 $users = $DB->get_records('user'); 339 340 // Nobody is expected to have any course level roles. 341 $this->assertNotEmpty($CFG->coursecontact); 342 foreach ($users as $user) { 343 $this->assertFalse(has_coursecontact_role($user->id)); 344 } 345 346 $user = $this->getDataGenerator()->create_user(); 347 $course = $this->getDataGenerator()->create_course(); 348 role_assign($CFG->coursecontact, $user->id, context_course::instance($course->id)); 349 $this->assertTrue(has_coursecontact_role($user->id)); 350 } 351 352 /** 353 * Test creation of roles. 354 */ 355 public function test_create_role() { 356 global $DB; 357 358 $this->resetAfterTest(); 359 360 $id = create_role('New student role', 'student2', 'New student description', 'student'); 361 $role = $DB->get_record('role', array('id'=>$id)); 362 363 $this->assertNotEmpty($role); 364 $this->assertSame('New student role', $role->name); 365 $this->assertSame('student2', $role->shortname); 366 $this->assertSame('New student description', $role->description); 367 $this->assertSame('student', $role->archetype); 368 } 369 370 /** 371 * Test adding of capabilities to roles. 372 */ 373 public function test_assign_capability() { 374 global $DB; 375 376 $this->resetAfterTest(); 377 378 $user = $this->getDataGenerator()->create_user(); 379 $syscontext = context_system::instance(); 380 $frontcontext = context_course::instance(SITEID); 381 $student = $DB->get_record('role', array('shortname'=>'student'), '*', MUST_EXIST); 382 $this->assertTrue($DB->record_exists('capabilities', array('name'=>'moodle/backup:backupcourse'))); // Any capability assigned to student by default. 383 $this->assertFalse($DB->record_exists('role_capabilities', array('contextid'=>$syscontext->id, 'roleid'=>$student->id, 'capability'=>'moodle/backup:backupcourse'))); 384 $this->assertFalse($DB->record_exists('role_capabilities', array('contextid'=>$frontcontext->id, 'roleid'=>$student->id, 'capability'=>'moodle/backup:backupcourse'))); 385 386 $this->setUser($user); 387 $result = assign_capability('moodle/backup:backupcourse', CAP_ALLOW, $student->id, $frontcontext->id); 388 $this->assertTrue($result); 389 $permission = $DB->get_record('role_capabilities', array('contextid'=>$frontcontext->id, 'roleid'=>$student->id, 'capability'=>'moodle/backup:backupcourse')); 390 $this->assertNotEmpty($permission); 391 $this->assertEquals(CAP_ALLOW, $permission->permission); 392 $this->assertEquals($user->id, $permission->modifierid); 393 394 $this->setUser(0); 395 $result = assign_capability('moodle/backup:backupcourse', CAP_PROHIBIT, $student->id, $frontcontext->id, false); 396 $this->assertTrue($result); 397 $permission = $DB->get_record('role_capabilities', array('contextid'=>$frontcontext->id, 'roleid'=>$student->id, 'capability'=>'moodle/backup:backupcourse')); 398 $this->assertNotEmpty($permission); 399 $this->assertEquals(CAP_ALLOW, $permission->permission); 400 $this->assertEquals($user->id, $permission->modifierid); 401 402 $result = assign_capability('moodle/backup:backupcourse', CAP_PROHIBIT, $student->id, $frontcontext->id, true); 403 $this->assertTrue($result); 404 $permission = $DB->get_record('role_capabilities', array('contextid'=>$frontcontext->id, 'roleid'=>$student->id, 'capability'=>'moodle/backup:backupcourse')); 405 $this->assertNotEmpty($permission); 406 $this->assertEquals(CAP_PROHIBIT, $permission->permission); 407 $this->assertEquals(0, $permission->modifierid); 408 409 $result = assign_capability('moodle/backup:backupcourse', CAP_INHERIT, $student->id, $frontcontext->id); 410 $this->assertTrue($result); 411 $permission = $DB->get_record('role_capabilities', array('contextid'=>$frontcontext->id, 'roleid'=>$student->id, 'capability'=>'moodle/backup:backupcourse')); 412 $this->assertEmpty($permission); 413 414 // Test event trigger. 415 $rolecapabilityevent = \core\event\role_capabilities_updated::create(array('context' => $syscontext, 416 'objectid' => $student->id, 417 'other' => array('name' => $student->shortname) 418 )); 419 $expectedlegacylog = array(SITEID, 'role', 'view', 'admin/roles/define.php?action=view&roleid=' . $student->id, 420 $student->shortname, '', $user->id); 421 $rolecapabilityevent->set_legacy_logdata($expectedlegacylog); 422 $rolecapabilityevent->add_record_snapshot('role', $student); 423 424 $sink = $this->redirectEvents(); 425 $rolecapabilityevent->trigger(); 426 $events = $sink->get_events(); 427 $sink->close(); 428 $event = array_pop($events); 429 430 $this->assertInstanceOf('\core\event\role_capabilities_updated', $event); 431 $expectedurl = new moodle_url('/admin/roles/define.php', array('action' => 'view', 'roleid' => $student->id)); 432 $this->assertEquals($expectedurl, $event->get_url()); 433 $this->assertEventLegacyLogData($expectedlegacylog, $event); 434 $this->assertEventContextNotUsed($event); 435 } 436 437 /** 438 * Test removing of capabilities from roles. 439 */ 440 public function test_unassign_capability() { 441 global $DB; 442 443 $this->resetAfterTest(); 444 445 $syscontext = context_system::instance(); 446 $frontcontext = context_course::instance(SITEID); 447 $manager = $DB->get_record('role', array('shortname'=>'manager'), '*', MUST_EXIST); 448 $this->assertTrue($DB->record_exists('capabilities', array('name'=>'moodle/backup:backupcourse'))); // Any capability assigned to manager by default. 449 assign_capability('moodle/backup:backupcourse', CAP_ALLOW, $manager->id, $frontcontext->id); 450 451 $this->assertTrue($DB->record_exists('role_capabilities', array('contextid'=>$syscontext->id, 'roleid'=>$manager->id, 'capability'=>'moodle/backup:backupcourse'))); 452 $this->assertTrue($DB->record_exists('role_capabilities', array('contextid'=>$frontcontext->id, 'roleid'=>$manager->id, 'capability'=>'moodle/backup:backupcourse'))); 453 454 $result = unassign_capability('moodle/backup:backupcourse', $manager->id, $syscontext->id); 455 $this->assertTrue($result); 456 $this->assertFalse($DB->record_exists('role_capabilities', array('contextid'=>$syscontext->id, 'roleid'=>$manager->id, 'capability'=>'moodle/backup:backupcourse'))); 457 $this->assertTrue($DB->record_exists('role_capabilities', array('contextid'=>$frontcontext->id, 'roleid'=>$manager->id, 'capability'=>'moodle/backup:backupcourse'))); 458 unassign_capability('moodle/backup:backupcourse', $manager->id, $frontcontext); 459 $this->assertFalse($DB->record_exists('role_capabilities', array('contextid'=>$frontcontext->id, 'roleid'=>$manager->id, 'capability'=>'moodle/backup:backupcourse'))); 460 461 assign_capability('moodle/backup:backupcourse', CAP_ALLOW, $manager->id, $syscontext->id); 462 assign_capability('moodle/backup:backupcourse', CAP_ALLOW, $manager->id, $frontcontext->id); 463 $this->assertTrue($DB->record_exists('role_capabilities', array('contextid'=>$frontcontext->id, 'roleid'=>$manager->id, 'capability'=>'moodle/backup:backupcourse'))); 464 465 $result = unassign_capability('moodle/backup:backupcourse', $manager->id); 466 $this->assertTrue($result); 467 $this->assertFalse($DB->record_exists('role_capabilities', array('contextid'=>$syscontext->id, 'roleid'=>$manager->id, 'capability'=>'moodle/backup:backupcourse'))); 468 $this->assertFalse($DB->record_exists('role_capabilities', array('contextid'=>$frontcontext->id, 'roleid'=>$manager->id, 'capability'=>'moodle/backup:backupcourse'))); 469 } 470 471 /** 472 * Test role assigning. 473 */ 474 public function test_role_assign() { 475 global $DB, $USER; 476 477 $this->resetAfterTest(); 478 479 $user = $this->getDataGenerator()->create_user(); 480 $course = $this->getDataGenerator()->create_course(); 481 $role = $DB->get_record('role', array('shortname'=>'student')); 482 483 $this->setUser(0); 484 $context = context_system::instance(); 485 $this->assertFalse($DB->record_exists('role_assignments', array('userid'=>$user->id, 'roleid'=>$role->id, 'contextid'=>$context->id))); 486 role_assign($role->id, $user->id, $context->id); 487 $ras = $DB->get_record('role_assignments', array('userid'=>$user->id, 'roleid'=>$role->id, 'contextid'=>$context->id)); 488 $this->assertNotEmpty($ras); 489 $this->assertSame('', $ras->component); 490 $this->assertSame('0', $ras->itemid); 491 $this->assertEquals($USER->id, $ras->modifierid); 492 493 $this->setAdminUser(); 494 $context = context_course::instance($course->id); 495 $this->assertFalse($DB->record_exists('role_assignments', array('userid'=>$user->id, 'roleid'=>$role->id, 'contextid'=>$context->id))); 496 role_assign($role->id, $user->id, $context->id, 'enrol_self', 1, 666); 497 $ras = $DB->get_record('role_assignments', array('userid'=>$user->id, 'roleid'=>$role->id, 'contextid'=>$context->id)); 498 $this->assertNotEmpty($ras); 499 $this->assertSame('enrol_self', $ras->component); 500 $this->assertSame('1', $ras->itemid); 501 $this->assertEquals($USER->id, $ras->modifierid); 502 $this->assertEquals(666, $ras->timemodified); 503 504 // Test event triggered. 505 506 $user2 = $this->getDataGenerator()->create_user(); 507 $sink = $this->redirectEvents(); 508 $raid = role_assign($role->id, $user2->id, $context->id); 509 $events = $sink->get_events(); 510 $sink->close(); 511 $this->assertCount(1, $events); 512 $event = $events[0]; 513 $this->assertInstanceOf('\core\event\role_assigned', $event); 514 $this->assertSame('role', $event->target); 515 $this->assertSame('role', $event->objecttable); 516 $this->assertEquals($role->id, $event->objectid); 517 $this->assertEquals($context->id, $event->contextid); 518 $this->assertEquals($user2->id, $event->relateduserid); 519 $this->assertCount(3, $event->other); 520 $this->assertEquals($raid, $event->other['id']); 521 $this->assertSame('', $event->other['component']); 522 $this->assertEquals(0, $event->other['itemid']); 523 $this->assertInstanceOf('moodle_url', $event->get_url()); 524 $this->assertSame('role_assigned', $event::get_legacy_eventname()); 525 $roles = get_all_roles(); 526 $rolenames = role_fix_names($roles, $context, ROLENAME_ORIGINAL, true); 527 $expectedlegacylog = array($course->id, 'role', 'assign', 528 'admin/roles/assign.php?contextid='.$context->id.'&roleid='.$role->id, $rolenames[$role->id], '', $USER->id); 529 $this->assertEventLegacyLogData($expectedlegacylog, $event); 530 } 531 532 /** 533 * Test role unassigning. 534 */ 535 public function test_role_unassign() { 536 global $DB, $USER; 537 538 $this->resetAfterTest(); 539 540 $user = $this->getDataGenerator()->create_user(); 541 $course = $this->getDataGenerator()->create_course(); 542 $role = $DB->get_record('role', array('shortname'=>'student')); 543 544 $context = context_course::instance($course->id); 545 role_assign($role->id, $user->id, $context->id); 546 $this->assertTrue($DB->record_exists('role_assignments', array('userid'=>$user->id, 'roleid'=>$role->id, 'contextid'=>$context->id))); 547 role_unassign($role->id, $user->id, $context->id); 548 $this->assertFalse($DB->record_exists('role_assignments', array('userid'=>$user->id, 'roleid'=>$role->id, 'contextid'=>$context->id))); 549 550 role_assign($role->id, $user->id, $context->id, 'enrol_self', 1); 551 $this->assertTrue($DB->record_exists('role_assignments', array('userid'=>$user->id, 'roleid'=>$role->id, 'contextid'=>$context->id))); 552 role_unassign($role->id, $user->id, $context->id, 'enrol_self', 1); 553 $this->assertFalse($DB->record_exists('role_assignments', array('userid'=>$user->id, 'roleid'=>$role->id, 'contextid'=>$context->id))); 554 555 // Test event triggered. 556 557 role_assign($role->id, $user->id, $context->id); 558 $sink = $this->redirectEvents(); 559 role_unassign($role->id, $user->id, $context->id); 560 $events = $sink->get_events(); 561 $sink->close(); 562 $this->assertCount(1, $events); 563 $event = $events[0]; 564 $this->assertInstanceOf('\core\event\role_unassigned', $event); 565 $this->assertSame('role', $event->target); 566 $this->assertSame('role', $event->objecttable); 567 $this->assertEquals($role->id, $event->objectid); 568 $this->assertEquals($context->id, $event->contextid); 569 $this->assertEquals($user->id, $event->relateduserid); 570 $this->assertCount(3, $event->other); 571 $this->assertSame('', $event->other['component']); 572 $this->assertEquals(0, $event->other['itemid']); 573 $this->assertInstanceOf('moodle_url', $event->get_url()); 574 $roles = get_all_roles(); 575 $rolenames = role_fix_names($roles, $context, ROLENAME_ORIGINAL, true); 576 $expectedlegacylog = array($course->id, 'role', 'unassign', 577 'admin/roles/assign.php?contextid='.$context->id.'&roleid='.$role->id, $rolenames[$role->id], '', $USER->id); 578 $this->assertEventLegacyLogData($expectedlegacylog, $event); 579 } 580 581 /** 582 * Test role unassigning. 583 */ 584 public function test_role_unassign_all() { 585 global $DB; 586 587 $this->resetAfterTest(); 588 589 $user = $this->getDataGenerator()->create_user(); 590 $course = $this->getDataGenerator()->create_course(); 591 $role = $DB->get_record('role', array('shortname'=>'student')); 592 $role2 = $DB->get_record('role', array('shortname'=>'teacher')); 593 $syscontext = context_system::instance(); 594 $coursecontext = context_course::instance($course->id); 595 $page = $this->getDataGenerator()->create_module('page', array('course'=>$course->id)); 596 $modcontext = context_module::instance($page->cmid); 597 598 role_assign($role->id, $user->id, $syscontext->id); 599 role_assign($role->id, $user->id, $coursecontext->id, 'enrol_self', 1); 600 $this->assertEquals(2, $DB->count_records('role_assignments', array('userid'=>$user->id))); 601 role_unassign_all(array('userid'=>$user->id, 'roleid'=>$role->id)); 602 $this->assertEquals(0, $DB->count_records('role_assignments', array('userid'=>$user->id))); 603 604 role_assign($role->id, $user->id, $syscontext->id); 605 role_assign($role->id, $user->id, $coursecontext->id, 'enrol_self', 1); 606 role_assign($role->id, $user->id, $modcontext->id); 607 $this->assertEquals(3, $DB->count_records('role_assignments', array('userid'=>$user->id))); 608 role_unassign_all(array('userid'=>$user->id, 'contextid'=>$coursecontext->id), false); 609 $this->assertEquals(2, $DB->count_records('role_assignments', array('userid'=>$user->id))); 610 role_unassign_all(array('userid'=>$user->id, 'contextid'=>$coursecontext->id), true); 611 $this->assertEquals(1, $DB->count_records('role_assignments', array('userid'=>$user->id))); 612 role_unassign_all(array('userid'=>$user->id)); 613 $this->assertEquals(0, $DB->count_records('role_assignments', array('userid'=>$user->id))); 614 615 role_assign($role->id, $user->id, $syscontext->id); 616 role_assign($role->id, $user->id, $coursecontext->id, 'enrol_self', 1); 617 role_assign($role->id, $user->id, $coursecontext->id); 618 role_assign($role->id, $user->id, $modcontext->id); 619 $this->assertEquals(4, $DB->count_records('role_assignments', array('userid'=>$user->id))); 620 role_unassign_all(array('userid'=>$user->id, 'contextid'=>$coursecontext->id, 'component'=>'enrol_self'), true, true); 621 $this->assertEquals(1, $DB->count_records('role_assignments', array('userid'=>$user->id))); 622 623 // Test events triggered. 624 625 role_assign($role2->id, $user->id, $coursecontext->id); 626 role_assign($role2->id, $user->id, $modcontext->id); 627 $sink = $this->redirectEvents(); 628 role_unassign_all(array('userid'=>$user->id, 'roleid'=>$role2->id)); 629 $events = $sink->get_events(); 630 $sink->close(); 631 $this->assertCount(2, $events); 632 $this->assertInstanceOf('\core\event\role_unassigned', $events[0]); 633 $this->assertInstanceOf('\core\event\role_unassigned', $events[1]); 634 } 635 636 /** 637 * Test role queries. 638 */ 639 public function test_get_roles_with_capability() { 640 global $DB; 641 642 $this->resetAfterTest(); 643 644 $syscontext = context_system::instance(); 645 $frontcontext = context_course::instance(SITEID); 646 $manager = $DB->get_record('role', array('shortname'=>'manager'), '*', MUST_EXIST); 647 $teacher = $DB->get_record('role', array('shortname'=>'teacher'), '*', MUST_EXIST); 648 649 $this->assertTrue($DB->record_exists('capabilities', array('name'=>'moodle/backup:backupcourse'))); // Any capability is ok. 650 $DB->delete_records('role_capabilities', array('capability'=>'moodle/backup:backupcourse')); 651 652 $roles = get_roles_with_capability('moodle/backup:backupcourse'); 653 $this->assertEquals(array(), $roles); 654 655 assign_capability('moodle/backup:backupcourse', CAP_ALLOW, $manager->id, $syscontext->id); 656 assign_capability('moodle/backup:backupcourse', CAP_PROHIBIT, $manager->id, $frontcontext->id); 657 assign_capability('moodle/backup:backupcourse', CAP_PREVENT, $teacher->id, $frontcontext->id); 658 659 $roles = get_roles_with_capability('moodle/backup:backupcourse'); 660 $this->assertEquals(array($teacher->id, $manager->id), array_keys($roles), '', 0, 10, true); 661 662 $roles = get_roles_with_capability('moodle/backup:backupcourse', CAP_ALLOW); 663 $this->assertEquals(array($manager->id), array_keys($roles), '', 0, 10, true); 664 665 $roles = get_roles_with_capability('moodle/backup:backupcourse', null, $syscontext); 666 $this->assertEquals(array($manager->id), array_keys($roles), '', 0, 10, true); 667 } 668 669 /** 670 * Test deleting of roles. 671 */ 672 public function test_delete_role() { 673 global $DB; 674 675 $this->resetAfterTest(); 676 677 $role = $DB->get_record('role', array('shortname'=>'manager'), '*', MUST_EXIST); 678 $user = $this->getDataGenerator()->create_user(); 679 role_assign($role->id, $user->id, context_system::instance()); 680 $course = $this->getDataGenerator()->create_course(); 681 $rolename = (object)array('roleid'=>$role->id, 'name'=>'Man', 'contextid'=>context_course::instance($course->id)->id); 682 $DB->insert_record('role_names', $rolename); 683 684 $this->assertTrue($DB->record_exists('role_assignments', array('roleid'=>$role->id))); 685 $this->assertTrue($DB->record_exists('role_capabilities', array('roleid'=>$role->id))); 686 $this->assertTrue($DB->record_exists('role_names', array('roleid'=>$role->id))); 687 $this->assertTrue($DB->record_exists('role_context_levels', array('roleid'=>$role->id))); 688 $this->assertTrue($DB->record_exists('role_allow_assign', array('roleid'=>$role->id))); 689 $this->assertTrue($DB->record_exists('role_allow_assign', array('allowassign'=>$role->id))); 690 $this->assertTrue($DB->record_exists('role_allow_override', array('roleid'=>$role->id))); 691 $this->assertTrue($DB->record_exists('role_allow_override', array('allowoverride'=>$role->id))); 692 693 // Delete role and get event. 694 $sink = $this->redirectEvents(); 695 $result = delete_role($role->id); 696 $events = $sink->get_events(); 697 $sink->close(); 698 $event = array_pop($events); 699 700 $this->assertTrue($result); 701 $this->assertFalse($DB->record_exists('role', array('id'=>$role->id))); 702 $this->assertFalse($DB->record_exists('role_assignments', array('roleid'=>$role->id))); 703 $this->assertFalse($DB->record_exists('role_capabilities', array('roleid'=>$role->id))); 704 $this->assertFalse($DB->record_exists('role_names', array('roleid'=>$role->id))); 705 $this->assertFalse($DB->record_exists('role_context_levels', array('roleid'=>$role->id))); 706 $this->assertFalse($DB->record_exists('role_allow_assign', array('roleid'=>$role->id))); 707 $this->assertFalse($DB->record_exists('role_allow_assign', array('allowassign'=>$role->id))); 708 $this->assertFalse($DB->record_exists('role_allow_override', array('roleid'=>$role->id))); 709 $this->assertFalse($DB->record_exists('role_allow_override', array('allowoverride'=>$role->id))); 710 711 // Test triggered event. 712 $this->assertInstanceOf('\core\event\role_deleted', $event); 713 $this->assertSame('role', $event->target); 714 $this->assertSame('role', $event->objecttable); 715 $this->assertSame($role->id, $event->objectid); 716 $this->assertEquals(context_system::instance(), $event->get_context()); 717 $this->assertSame($role->shortname, $event->other['shortname']); 718 $this->assertSame($role->description, $event->other['description']); 719 $this->assertSame($role->archetype, $event->other['archetype']); 720 721 $expectedlegacylog = array(SITEID, 'role', 'delete', 'admin/roles/manage.php?action=delete&roleid='.$role->id, 722 $role->shortname, ''); 723 $this->assertEventLegacyLogData($expectedlegacylog, $event); 724 } 725 726 /** 727 * Test fetching of all roles. 728 */ 729 public function test_get_all_roles() { 730 global $DB; 731 732 $this->resetAfterTest(); 733 734 $allroles = get_all_roles(); 735 $this->assertInternalType('array', $allroles); 736 $this->assertCount(8, $allroles); // There are 8 roles is standard install. 737 738 $role = reset($allroles); 739 $role = (array)$role; 740 741 $this->assertEquals(array('id', 'name', 'shortname', 'description', 'sortorder', 'archetype'), array_keys($role), '', 0, 10, true); 742 743 foreach ($allroles as $roleid => $role) { 744 $this->assertEquals($role->id, $roleid); 745 } 746 747 $teacher = $DB->get_record('role', array('shortname'=>'teacher'), '*', MUST_EXIST); 748 $course = $this->getDataGenerator()->create_course(); 749 $coursecontext = context_course::instance($course->id); 750 $otherid = create_role('Other role', 'other', 'Some other role', ''); 751 $teacherename = (object)array('roleid'=>$teacher->id, 'name'=>'Učitel', 'contextid'=>$coursecontext->id); 752 $DB->insert_record('role_names', $teacherename); 753 $otherrename = (object)array('roleid'=>$otherid, 'name'=>'Ostatní', 'contextid'=>$coursecontext->id); 754 $DB->insert_record('role_names', $otherrename); 755 $renames = $DB->get_records_menu('role_names', array('contextid'=>$coursecontext->id), '', 'roleid, name'); 756 757 $allroles = get_all_roles($coursecontext); 758 $this->assertInternalType('array', $allroles); 759 $this->assertCount(9, $allroles); 760 $role = reset($allroles); 761 $role = (array)$role; 762 763 $this->assertEquals(array('id', 'name', 'shortname', 'description', 'sortorder', 'archetype', 'coursealias'), array_keys($role), '', 0, 10, true); 764 765 foreach ($allroles as $roleid => $role) { 766 $this->assertEquals($role->id, $roleid); 767 if (isset($renames[$roleid])) { 768 $this->assertSame($renames[$roleid], $role->coursealias); 769 } else { 770 $this->assertNull($role->coursealias); 771 } 772 } 773 } 774 775 /** 776 * Test getting of all archetypes. 777 */ 778 public function test_get_role_archetypes() { 779 $archetypes = get_role_archetypes(); 780 $this->assertCount(8, $archetypes); // There are 8 archetypes in standard install. 781 foreach ($archetypes as $k => $v) { 782 $this->assertSame($k, $v); 783 } 784 } 785 786 /** 787 * Test getting of roles with given archetype. 788 */ 789 public function test_get_archetype_roles() { 790 $this->resetAfterTest(); 791 792 // New install should have 1 role for each archetype. 793 $archetypes = get_role_archetypes(); 794 foreach ($archetypes as $archetype) { 795 $roles = get_archetype_roles($archetype); 796 $this->assertCount(1, $roles); 797 $role = reset($roles); 798 $this->assertSame($archetype, $role->archetype); 799 } 800 801 create_role('New student role', 'student2', 'New student description', 'student'); 802 $roles = get_archetype_roles('student'); 803 $this->assertCount(2, $roles); 804 } 805 806 /** 807 * Test aliased role names. 808 */ 809 public function test_role_get_name() { 810 global $DB; 811 812 $this->resetAfterTest(); 813 814 $allroles = $DB->get_records('role'); 815 $teacher = $DB->get_record('role', array('shortname'=>'teacher'), '*', MUST_EXIST); 816 $course = $this->getDataGenerator()->create_course(); 817 $coursecontext = context_course::instance($course->id); 818 $otherid = create_role('Other role', 'other', 'Some other role', ''); 819 $teacherename = (object)array('roleid'=>$teacher->id, 'name'=>'Učitel', 'contextid'=>$coursecontext->id); 820 $DB->insert_record('role_names', $teacherename); 821 $otherrename = (object)array('roleid'=>$otherid, 'name'=>'Ostatní', 'contextid'=>$coursecontext->id); 822 $DB->insert_record('role_names', $otherrename); 823 $renames = $DB->get_records_menu('role_names', array('contextid'=>$coursecontext->id), '', 'roleid, name'); 824 825 foreach ($allroles as $role) { 826 // Get localised name from lang pack. 827 $this->assertSame('', $role->name); 828 $name = role_get_name($role, null, ROLENAME_ORIGINAL); 829 $this->assertNotEmpty($name); 830 $this->assertNotEquals($role->shortname, $name); 831 832 if (isset($renames[$role->id])) { 833 $this->assertSame($renames[$role->id], role_get_name($role, $coursecontext)); 834 $this->assertSame($renames[$role->id], role_get_name($role, $coursecontext, ROLENAME_ALIAS)); 835 $this->assertSame($renames[$role->id], role_get_name($role, $coursecontext, ROLENAME_ALIAS_RAW)); 836 $this->assertSame("{$renames[$role->id]} ($name)", role_get_name($role, $coursecontext, ROLENAME_BOTH)); 837 } else { 838 $this->assertSame($name, role_get_name($role, $coursecontext)); 839 $this->assertSame($name, role_get_name($role, $coursecontext, ROLENAME_ALIAS)); 840 $this->assertNull(role_get_name($role, $coursecontext, ROLENAME_ALIAS_RAW)); 841 $this->assertSame($name, role_get_name($role, $coursecontext, ROLENAME_BOTH)); 842 } 843 $this->assertSame($name, role_get_name($role)); 844 $this->assertSame($name, role_get_name($role, $coursecontext, ROLENAME_ORIGINAL)); 845 $this->assertSame($name, role_get_name($role, null, ROLENAME_ORIGINAL)); 846 $this->assertSame($role->shortname, role_get_name($role, $coursecontext, ROLENAME_SHORT)); 847 $this->assertSame($role->shortname, role_get_name($role, null, ROLENAME_SHORT)); 848 $this->assertSame("$name ($role->shortname)", role_get_name($role, $coursecontext, ROLENAME_ORIGINALANDSHORT)); 849 $this->assertSame("$name ($role->shortname)", role_get_name($role, null, ROLENAME_ORIGINALANDSHORT)); 850 $this->assertNull(role_get_name($role, null, ROLENAME_ALIAS_RAW)); 851 } 852 } 853 854 /** 855 * Test tweaking of role name arrays. 856 */ 857 public function test_role_fix_names() { 858 global $DB; 859 860 $this->resetAfterTest(); 861 862 $teacher = $DB->get_record('role', array('shortname'=>'teacher'), '*', MUST_EXIST); 863 $student = $DB->get_record('role', array('shortname'=>'student'), '*', MUST_EXIST); 864 $otherid = create_role('Other role', 'other', 'Some other role', ''); 865 $anotherid = create_role('Another role', 'another', 'Yet another other role', ''); 866 $allroles = $DB->get_records('role'); 867 868 $syscontext = context_system::instance(); 869 $frontcontext = context_course::instance(SITEID); 870 $course = $this->getDataGenerator()->create_course(); 871 $coursecontext = context_course::instance($course->id); 872 $category = $DB->get_record('course_categories', array('id'=>$course->category), '*', MUST_EXIST); 873 $categorycontext = context_coursecat::instance($category->id); 874 875 $teacherename = (object)array('roleid'=>$teacher->id, 'name'=>'Učitel', 'contextid'=>$coursecontext->id); 876 $DB->insert_record('role_names', $teacherename); 877 $otherrename = (object)array('roleid'=>$otherid, 'name'=>'Ostatní', 'contextid'=>$coursecontext->id); 878 $DB->insert_record('role_names', $otherrename); 879 $renames = $DB->get_records_menu('role_names', array('contextid'=>$coursecontext->id), '', 'roleid, name'); 880 881 // Make sure all localname contain proper values for each ROLENAME_ constant, 882 // note role_get_name() on frontpage is used to get the original name for future compatibility. 883 $roles = $allroles; 884 unset($roles[$student->id]); // Remove one role to make sure no role is added or removed. 885 $rolenames = array(); 886 foreach ($roles as $role) { 887 $rolenames[$role->id] = $role->name; 888 } 889 890 $alltypes = array(ROLENAME_ALIAS, ROLENAME_ALIAS_RAW, ROLENAME_BOTH, ROLENAME_ORIGINAL, ROLENAME_ORIGINALANDSHORT, ROLENAME_SHORT); 891 foreach ($alltypes as $type) { 892 $fixed = role_fix_names($roles, $coursecontext, $type); 893 $this->assertCount(count($roles), $fixed); 894 foreach ($fixed as $roleid => $rolename) { 895 $this->assertInstanceOf('stdClass', $rolename); 896 $role = $allroles[$roleid]; 897 $name = role_get_name($role, $coursecontext, $type); 898 $this->assertSame($name, $rolename->localname); 899 } 900 $fixed = role_fix_names($rolenames, $coursecontext, $type); 901 $this->assertCount(count($rolenames), $fixed); 902 foreach ($fixed as $roleid => $rolename) { 903 $role = $allroles[$roleid]; 904 $name = role_get_name($role, $coursecontext, $type); 905 $this->assertSame($name, $rolename); 906 } 907 } 908 } 909 910 /** 911 * Test role default allows. 912 */ 913 public function test_get_default_role_archetype_allows() { 914 $archetypes = get_role_archetypes(); 915 foreach ($archetypes as $archetype) { 916 917 $result = get_default_role_archetype_allows('assign', $archetype); 918 $this->assertInternalType('array', $result); 919 920 $result = get_default_role_archetype_allows('override', $archetype); 921 $this->assertInternalType('array', $result); 922 923 $result = get_default_role_archetype_allows('switch', $archetype); 924 $this->assertInternalType('array', $result); 925 } 926 927 $result = get_default_role_archetype_allows('assign', ''); 928 $this->assertSame(array(), $result); 929 930 $result = get_default_role_archetype_allows('override', ''); 931 $this->assertSame(array(), $result); 932 933 $result = get_default_role_archetype_allows('switch', ''); 934 $this->assertSame(array(), $result); 935 936 $result = get_default_role_archetype_allows('assign', 'wrongarchetype'); 937 $this->assertSame(array(), $result); 938 $this->assertDebuggingCalled(); 939 940 $result = get_default_role_archetype_allows('override', 'wrongarchetype'); 941 $this->assertSame(array(), $result); 942 $this->assertDebuggingCalled(); 943 944 $result = get_default_role_archetype_allows('switch', 'wrongarchetype'); 945 $this->assertSame(array(), $result); 946 $this->assertDebuggingCalled(); 947 } 948 949 /** 950 * Test allowing of role assignments. 951 */ 952 public function test_allow_assign() { 953 global $DB, $CFG; 954 955 $this->resetAfterTest(); 956 957 $otherid = create_role('Other role', 'other', 'Some other role', ''); 958 $student = $DB->get_record('role', array('shortname'=>'student'), '*', MUST_EXIST); 959 960 $this->assertFalse($DB->record_exists('role_allow_assign', array('roleid'=>$otherid, 'allowassign'=>$student->id))); 961 allow_assign($otherid, $student->id); 962 $this->assertTrue($DB->record_exists('role_allow_assign', array('roleid'=>$otherid, 'allowassign'=>$student->id))); 963 964 // Test event trigger. 965 $allowroleassignevent = \core\event\role_allow_assign_updated::create(array('context' => context_system::instance())); 966 $sink = $this->redirectEvents(); 967 $allowroleassignevent->trigger(); 968 $events = $sink->get_events(); 969 $sink->close(); 970 $event = array_pop($events); 971 $this->assertInstanceOf('\core\event\role_allow_assign_updated', $event); 972 $mode = 'assign'; 973 $baseurl = new moodle_url('/admin/roles/allow.php', array('mode' => $mode)); 974 $expectedlegacylog = array(SITEID, 'role', 'edit allow ' . $mode, str_replace($CFG->wwwroot . '/', '', $baseurl)); 975 $this->assertEventLegacyLogData($expectedlegacylog, $event); 976 } 977 978 /** 979 * Test allowing of role overrides. 980 */ 981 public function test_allow_override() { 982 global $DB, $CFG; 983 984 $this->resetAfterTest(); 985 986 $otherid = create_role('Other role', 'other', 'Some other role', ''); 987 $student = $DB->get_record('role', array('shortname'=>'student'), '*', MUST_EXIST); 988 989 $this->assertFalse($DB->record_exists('role_allow_override', array('roleid'=>$otherid, 'allowoverride'=>$student->id))); 990 allow_override($otherid, $student->id); 991 $this->assertTrue($DB->record_exists('role_allow_override', array('roleid'=>$otherid, 'allowoverride'=>$student->id))); 992 993 // Test event trigger. 994 $allowroleassignevent = \core\event\role_allow_override_updated::create(array('context' => context_system::instance())); 995 $sink = $this->redirectEvents(); 996 $allowroleassignevent->trigger(); 997 $events = $sink->get_events(); 998 $sink->close(); 999 $event = array_pop($events); 1000 $this->assertInstanceOf('\core\event\role_allow_override_updated', $event); 1001 $mode = 'override'; 1002 $baseurl = new moodle_url('/admin/roles/allow.php', array('mode' => $mode)); 1003 $expectedlegacylog = array(SITEID, 'role', 'edit allow ' . $mode, str_replace($CFG->wwwroot . '/', '', $baseurl)); 1004 $this->assertEventLegacyLogData($expectedlegacylog, $event); 1005 } 1006 1007 /** 1008 * Test allowing of role switching. 1009 */ 1010 public function test_allow_switch() { 1011 global $DB, $CFG; 1012 1013 $this->resetAfterTest(); 1014 1015 $otherid = create_role('Other role', 'other', 'Some other role', ''); 1016 $student = $DB->get_record('role', array('shortname'=>'student'), '*', MUST_EXIST); 1017 1018 $this->assertFalse($DB->record_exists('role_allow_switch', array('roleid'=>$otherid, 'allowswitch'=>$student->id))); 1019 allow_switch($otherid, $student->id); 1020 $this->assertTrue($DB->record_exists('role_allow_switch', array('roleid'=>$otherid, 'allowswitch'=>$student->id))); 1021 1022 // Test event trigger. 1023 $allowroleassignevent = \core\event\role_allow_switch_updated::create(array('context' => context_system::instance())); 1024 $sink = $this->redirectEvents(); 1025 $allowroleassignevent->trigger(); 1026 $events = $sink->get_events(); 1027 $sink->close(); 1028 $event = array_pop($events); 1029 $this->assertInstanceOf('\core\event\role_allow_switch_updated', $event); 1030 $mode = 'switch'; 1031 $baseurl = new moodle_url('/admin/roles/allow.php', array('mode' => $mode)); 1032 $expectedlegacylog = array(SITEID, 'role', 'edit allow ' . $mode, str_replace($CFG->wwwroot . '/', '', $baseurl)); 1033 $this->assertEventLegacyLogData($expectedlegacylog, $event); 1034 } 1035 1036 /** 1037 * Test returning of assignable roles in context. 1038 */ 1039 public function test_get_assignable_roles() { 1040 global $DB; 1041 1042 $this->resetAfterTest(); 1043 1044 $course = $this->getDataGenerator()->create_course(); 1045 $coursecontext = context_course::instance($course->id); 1046 1047 $teacherrole = $DB->get_record('role', array('shortname'=>'editingteacher'), '*', MUST_EXIST); 1048 $teacher = $this->getDataGenerator()->create_user(); 1049 role_assign($teacherrole->id, $teacher->id, $coursecontext); 1050 $teacherename = (object)array('roleid'=>$teacherrole->id, 'name'=>'Učitel', 'contextid'=>$coursecontext->id); 1051 $DB->insert_record('role_names', $teacherename); 1052 1053 $studentrole = $DB->get_record('role', array('shortname'=>'student'), '*', MUST_EXIST); 1054 $student = $this->getDataGenerator()->create_user(); 1055 role_assign($studentrole->id, $student->id, $coursecontext); 1056 1057 $contexts = $DB->get_records('context'); 1058 $users = $DB->get_records('user'); 1059 $allroles = $DB->get_records('role'); 1060 1061 // Evaluate all results for all users in all contexts. 1062 foreach ($users as $user) { 1063 $this->setUser($user); 1064 foreach ($contexts as $contextid => $unused) { 1065 $context = context_helper::instance_by_id($contextid); 1066 $roles = get_assignable_roles($context, ROLENAME_SHORT); 1067 foreach ($allroles as $roleid => $role) { 1068 if (isset($roles[$roleid])) { 1069 if (is_siteadmin()) { 1070 $this->assertTrue($DB->record_exists('role_context_levels', array('contextlevel'=>$context->contextlevel, 'roleid'=>$roleid))); 1071 } else { 1072 $this->assertTrue(user_can_assign($context, $roleid), "u:$user->id r:$roleid"); 1073 } 1074 $this->assertEquals($role->shortname, $roles[$roleid]); 1075 } else { 1076 $allowed = $DB->record_exists('role_context_levels', array('contextlevel'=>$context->contextlevel, 'roleid'=>$roleid)); 1077 if (is_siteadmin()) { 1078 $this->assertFalse($allowed); 1079 } else { 1080 $this->assertFalse($allowed and user_can_assign($context, $roleid), "u:$user->id, r:{$allroles[$roleid]->name}, c:$context->contextlevel"); 1081 } 1082 } 1083 } 1084 } 1085 } 1086 1087 // Not-logged-in user. 1088 $this->setUser(0); 1089 foreach ($contexts as $contextid => $unused) { 1090 $context = context_helper::instance_by_id($contextid); 1091 $roles = get_assignable_roles($context, ROLENAME_SHORT); 1092 $this->assertSame(array(), $roles); 1093 } 1094 1095 // Test current user. 1096 $this->setUser(0); 1097 $admin = $DB->get_record('user', array('username'=>'admin'), '*', MUST_EXIST); 1098 $roles1 = get_assignable_roles($coursecontext, ROLENAME_SHORT, false, $admin); 1099 $roles2 = get_assignable_roles($coursecontext, ROLENAME_SHORT, false, $admin->id); 1100 $this->setAdminUser(); 1101 $roles3 = get_assignable_roles($coursecontext, ROLENAME_SHORT); 1102 $this->assertSame($roles1, $roles3); 1103 $this->assertSame($roles2, $roles3); 1104 1105 // Test parameter defaults. 1106 $this->setAdminUser(); 1107 $roles1 = get_assignable_roles($coursecontext); 1108 $roles2 = get_assignable_roles($coursecontext, ROLENAME_ALIAS, false, $admin); 1109 $this->assertEquals($roles2, $roles1); 1110 1111 // Verify returned names - let's allow all roles everywhere to simplify this a bit. 1112 $alllevels = context_helper::get_all_levels(); 1113 $alllevels = array_keys($alllevels); 1114 foreach ($allroles as $roleid => $role) { 1115 set_role_contextlevels($roleid, $alllevels); 1116 } 1117 $alltypes = array(ROLENAME_ALIAS, ROLENAME_ALIAS_RAW, ROLENAME_BOTH, ROLENAME_ORIGINAL, ROLENAME_ORIGINALANDSHORT, ROLENAME_SHORT); 1118 foreach ($alltypes as $type) { 1119 $rolenames = role_fix_names($allroles, $coursecontext, $type); 1120 $roles = get_assignable_roles($coursecontext, $type, false, $admin); 1121 foreach ($roles as $roleid => $rolename) { 1122 $this->assertSame($rolenames[$roleid]->localname, $rolename); 1123 } 1124 } 1125 1126 // Verify counts. 1127 $alltypes = array(ROLENAME_ALIAS, ROLENAME_ALIAS_RAW, ROLENAME_BOTH, ROLENAME_ORIGINAL, ROLENAME_ORIGINALANDSHORT, ROLENAME_SHORT); 1128 foreach ($alltypes as $type) { 1129 $roles = get_assignable_roles($coursecontext, $type, false, $admin); 1130 list($rolenames, $rolecounts, $nameswithcounts) = get_assignable_roles($coursecontext, $type, true, $admin); 1131 $this->assertEquals($roles, $rolenames); 1132 foreach ($rolenames as $roleid => $name) { 1133 if ($roleid == $teacherrole->id or $roleid == $studentrole->id) { 1134 $this->assertEquals(1, $rolecounts[$roleid]); 1135 } else { 1136 $this->assertEquals(0, $rolecounts[$roleid]); 1137 } 1138 $this->assertSame("$name ($rolecounts[$roleid])", $nameswithcounts[$roleid]); 1139 } 1140 } 1141 } 1142 1143 /** 1144 * Test getting of all switchable roles. 1145 */ 1146 public function test_get_switchable_roles() { 1147 global $DB; 1148 1149 $this->resetAfterTest(); 1150 1151 $course = $this->getDataGenerator()->create_course(); 1152 $coursecontext = context_course::instance($course->id); 1153 1154 $teacherrole = $DB->get_record('role', array('shortname'=>'editingteacher'), '*', MUST_EXIST); 1155 $teacher = $this->getDataGenerator()->create_user(); 1156 role_assign($teacherrole->id, $teacher->id, $coursecontext); 1157 $teacherename = (object)array('roleid'=>$teacherrole->id, 'name'=>'Učitel', 'contextid'=>$coursecontext->id); 1158 $DB->insert_record('role_names', $teacherename); 1159 1160 $contexts = $DB->get_records('context'); 1161 $users = $DB->get_records('user'); 1162 $allroles = $DB->get_records('role'); 1163 1164 // Evaluate all results for all users in all contexts. 1165 foreach ($users as $user) { 1166 $this->setUser($user); 1167 foreach ($contexts as $contextid => $unused) { 1168 $context = context_helper::instance_by_id($contextid); 1169 $roles = get_switchable_roles($context); 1170 foreach ($allroles as $roleid => $role) { 1171 if (is_siteadmin()) { 1172 $this->assertTrue(isset($roles[$roleid])); 1173 } else { 1174 $parents = $context->get_parent_context_ids(true); 1175 $pcontexts = implode(',' , $parents); 1176 $allowed = $DB->record_exists_sql( 1177 "SELECT r.id 1178 FROM {role} r 1179 JOIN {role_allow_switch} ras ON ras.allowswitch = r.id 1180 JOIN {role_assignments} ra ON ra.roleid = ras.roleid 1181 WHERE ra.userid = :userid AND ra.contextid IN ($pcontexts) AND r.id = :roleid 1182 ", 1183 array('userid'=>$user->id, 'roleid'=>$roleid) 1184 ); 1185 if (isset($roles[$roleid])) { 1186 $this->assertTrue($allowed); 1187 } else { 1188 $this->assertFalse($allowed); 1189 } 1190 } 1191 1192 if (isset($roles[$roleid])) { 1193 $coursecontext = $context->get_course_context(false); 1194 $this->assertSame(role_get_name($role, $coursecontext), $roles[$roleid]); 1195 } 1196 } 1197 } 1198 } 1199 } 1200 1201 /** 1202 * Test getting of all overridable roles. 1203 */ 1204 public function test_get_overridable_roles() { 1205 global $DB; 1206 1207 $this->resetAfterTest(); 1208 1209 $course = $this->getDataGenerator()->create_course(); 1210 $coursecontext = context_course::instance($course->id); 1211 1212 $teacherrole = $DB->get_record('role', array('shortname'=>'editingteacher'), '*', MUST_EXIST); 1213 $teacher = $this->getDataGenerator()->create_user(); 1214 role_assign($teacherrole->id, $teacher->id, $coursecontext); 1215 $teacherename = (object)array('roleid'=>$teacherrole->id, 'name'=>'Učitel', 'contextid'=>$coursecontext->id); 1216 $DB->insert_record('role_names', $teacherename); 1217 $this->assertTrue($DB->record_exists('capabilities', array('name'=>'moodle/backup:backupcourse'))); // Any capability is ok. 1218 assign_capability('moodle/backup:backupcourse', CAP_PROHIBIT, $teacherrole->id, $coursecontext->id); 1219 1220 $studentrole = $DB->get_record('role', array('shortname'=>'student'), '*', MUST_EXIST); 1221 $student = $this->getDataGenerator()->create_user(); 1222 role_assign($studentrole->id, $student->id, $coursecontext); 1223 1224 $contexts = $DB->get_records('context'); 1225 $users = $DB->get_records('user'); 1226 $allroles = $DB->get_records('role'); 1227 1228 // Evaluate all results for all users in all contexts. 1229 foreach ($users as $user) { 1230 $this->setUser($user); 1231 foreach ($contexts as $contextid => $unused) { 1232 $context = context_helper::instance_by_id($contextid); 1233 $roles = get_overridable_roles($context, ROLENAME_SHORT); 1234 foreach ($allroles as $roleid => $role) { 1235 $hascap = has_any_capability(array('moodle/role:safeoverride', 'moodle/role:override'), $context); 1236 if (is_siteadmin()) { 1237 $this->assertTrue(isset($roles[$roleid])); 1238 } else { 1239 $parents = $context->get_parent_context_ids(true); 1240 $pcontexts = implode(',' , $parents); 1241 $allowed = $DB->record_exists_sql( 1242 "SELECT r.id 1243 FROM {role} r 1244 JOIN {role_allow_override} rao ON r.id = rao.allowoverride 1245 JOIN {role_assignments} ra ON rao.roleid = ra.roleid 1246 WHERE ra.userid = :userid AND ra.contextid IN ($pcontexts) AND r.id = :roleid 1247 ", 1248 array('userid'=>$user->id, 'roleid'=>$roleid) 1249 ); 1250 if (isset($roles[$roleid])) { 1251 $this->assertTrue($hascap); 1252 $this->assertTrue($allowed); 1253 } else { 1254 $this->assertFalse($hascap and $allowed); 1255 } 1256 } 1257 1258 if (isset($roles[$roleid])) { 1259 $this->assertEquals($role->shortname, $roles[$roleid]); 1260 } 1261 } 1262 } 1263 } 1264 1265 // Test parameter defaults. 1266 $this->setAdminUser(); 1267 $roles1 = get_overridable_roles($coursecontext); 1268 $roles2 = get_overridable_roles($coursecontext, ROLENAME_ALIAS, false); 1269 $this->assertEquals($roles2, $roles1); 1270 1271 $alltypes = array(ROLENAME_ALIAS, ROLENAME_ALIAS_RAW, ROLENAME_BOTH, ROLENAME_ORIGINAL, ROLENAME_ORIGINALANDSHORT, ROLENAME_SHORT); 1272 foreach ($alltypes as $type) { 1273 $rolenames = role_fix_names($allroles, $coursecontext, $type); 1274 $roles = get_overridable_roles($coursecontext, $type, false); 1275 foreach ($roles as $roleid => $rolename) { 1276 $this->assertSame($rolenames[$roleid]->localname, $rolename); 1277 } 1278 } 1279 1280 // Verify counts. 1281 $roles = get_overridable_roles($coursecontext, ROLENAME_ALIAS, false); 1282 list($rolenames, $rolecounts, $nameswithcounts) = get_overridable_roles($coursecontext, ROLENAME_ALIAS, true); 1283 $this->assertEquals($roles, $rolenames); 1284 foreach ($rolenames as $roleid => $name) { 1285 if ($roleid == $teacherrole->id) { 1286 $this->assertEquals(1, $rolecounts[$roleid]); 1287 } else { 1288 $this->assertEquals(0, $rolecounts[$roleid]); 1289 } 1290 $this->assertSame("$name ($rolecounts[$roleid])", $nameswithcounts[$roleid]); 1291 } 1292 } 1293 1294 /** 1295 * Test we have context level defaults. 1296 */ 1297 public function test_get_default_contextlevels() { 1298 $archetypes = get_role_archetypes(); 1299 $alllevels = context_helper::get_all_levels(); 1300 foreach ($archetypes as $archetype) { 1301 $defaults = get_default_contextlevels($archetype); 1302 $this->assertInternalType('array', $defaults); 1303 foreach ($defaults as $level) { 1304 $this->assertTrue(isset($alllevels[$level])); 1305 } 1306 } 1307 } 1308 1309 /** 1310 * Test role context level setup. 1311 */ 1312 public function test_set_role_contextlevels() { 1313 global $DB; 1314 1315 $this->resetAfterTest(); 1316 1317 $roleid = create_role('New student role', 'student2', 'New student description', 'student'); 1318 1319 $this->assertFalse($DB->record_exists('role_context_levels', array('roleid' => $roleid))); 1320 1321 set_role_contextlevels($roleid, array(CONTEXT_COURSE, CONTEXT_MODULE)); 1322 $levels = $DB->get_records('role_context_levels', array('roleid' => $roleid), '', 'contextlevel, contextlevel'); 1323 $this->assertCount(2, $levels); 1324 $this->assertTrue(isset($levels[CONTEXT_COURSE])); 1325 $this->assertTrue(isset($levels[CONTEXT_MODULE])); 1326 1327 set_role_contextlevels($roleid, array(CONTEXT_COURSE)); 1328 $levels = $DB->get_records('role_context_levels', array('roleid' => $roleid), '', 'contextlevel, contextlevel'); 1329 $this->assertCount(1, $levels); 1330 $this->assertTrue(isset($levels[CONTEXT_COURSE])); 1331 } 1332 1333 /** 1334 * Test getting of role context levels 1335 */ 1336 public function test_get_roles_for_contextlevels() { 1337 global $DB; 1338 1339 $allroles = get_all_roles(); 1340 foreach (context_helper::get_all_levels() as $level => $unused) { 1341 $roles = get_roles_for_contextlevels($level); 1342 foreach ($allroles as $roleid => $unused) { 1343 $exists = $DB->record_exists('role_context_levels', array('contextlevel'=>$level, 'roleid'=>$roleid)); 1344 if (in_array($roleid, $roles)) { 1345 $this->assertTrue($exists); 1346 } else { 1347 $this->assertFalse($exists); 1348 } 1349 } 1350 } 1351 } 1352 1353 /** 1354 * Test default enrol roles. 1355 */ 1356 public function test_get_default_enrol_roles() { 1357 $this->resetAfterTest(); 1358 1359 $course = $this->getDataGenerator()->create_course(); 1360 $coursecontext = context_course::instance($course->id); 1361 1362 $id2 = create_role('New student role', 'student2', 'New student description', 'student'); 1363 set_role_contextlevels($id2, array(CONTEXT_COURSE)); 1364 1365 $allroles = get_all_roles(); 1366 $expected = array($id2=>$allroles[$id2]); 1367 1368 foreach (get_role_archetypes() as $archetype) { 1369 $defaults = get_default_contextlevels($archetype); 1370 if (in_array(CONTEXT_COURSE, $defaults)) { 1371 $roles = get_archetype_roles($archetype); 1372 foreach ($roles as $role) { 1373 $expected[$role->id] = $role; 1374 } 1375 } 1376 } 1377 1378 $roles = get_default_enrol_roles($coursecontext); 1379 foreach ($allroles as $role) { 1380 $this->assertEquals(isset($expected[$role->id]), isset($roles[$role->id])); 1381 if (isset($roles[$role->id])) { 1382 $this->assertSame(role_get_name($role, $coursecontext), $roles[$role->id]); 1383 } 1384 } 1385 } 1386 1387 /** 1388 * Test getting of role users. 1389 */ 1390 public function test_get_role_users() { 1391 global $DB; 1392 1393 $this->resetAfterTest(); 1394 1395 $systemcontext = context_system::instance(); 1396 $studentrole = $DB->get_record('role', array('shortname'=>'student'), '*', MUST_EXIST); 1397 $teacherrole = $DB->get_record('role', array('shortname'=>'editingteacher'), '*', MUST_EXIST); 1398 $noeditteacherrole = $DB->get_record('role', array('shortname' => 'teacher'), '*', MUST_EXIST); 1399 $course = $this->getDataGenerator()->create_course(); 1400 $coursecontext = context_course::instance($course->id); 1401 $otherid = create_role('Other role', 'other', 'Some other role', ''); 1402 $teacherrename = (object)array('roleid'=>$teacherrole->id, 'name'=>'Učitel', 'contextid'=>$coursecontext->id); 1403 $DB->insert_record('role_names', $teacherrename); 1404 $otherrename = (object)array('roleid'=>$otherid, 'name'=>'Ostatní', 'contextid'=>$coursecontext->id); 1405 $DB->insert_record('role_names', $otherrename); 1406 1407 $user1 = $this->getDataGenerator()->create_user(array('firstname'=>'John', 'lastname'=>'Smith')); 1408 role_assign($teacherrole->id, $user1->id, $coursecontext->id); 1409 $user2 = $this->getDataGenerator()->create_user(array('firstname'=>'Jan', 'lastname'=>'Kovar')); 1410 role_assign($teacherrole->id, $user2->id, $systemcontext->id); 1411 $user3 = $this->getDataGenerator()->create_user(); 1412 $this->getDataGenerator()->enrol_user($user3->id, $course->id, $teacherrole->id); 1413 $user4 = $this->getDataGenerator()->create_user(); 1414 $this->getDataGenerator()->enrol_user($user4->id, $course->id, $studentrole->id); 1415 $this->getDataGenerator()->enrol_user($user4->id, $course->id, $noeditteacherrole->id); 1416 1417 $group = $this->getDataGenerator()->create_group(array('courseid'=>$course->id)); 1418 groups_add_member($group, $user3); 1419 1420 $users = get_role_users($teacherrole->id, $coursecontext); 1421 $this->assertCount(2, $users); 1422 $this->assertArrayHasKey($user1->id, $users); 1423 $this->assertEquals($users[$user1->id]->id, $user1->id); 1424 $this->assertEquals($users[$user1->id]->roleid, $teacherrole->id); 1425 $this->assertEquals($users[$user1->id]->rolename, $teacherrole->name); 1426 $this->assertEquals($users[$user1->id]->roleshortname, $teacherrole->shortname); 1427 $this->assertEquals($users[$user1->id]->rolecoursealias, $teacherrename->name); 1428 $this->assertArrayHasKey($user3->id, $users); 1429 $this->assertEquals($users[$user3->id]->id, $user3->id); 1430 $this->assertEquals($users[$user3->id]->roleid, $teacherrole->id); 1431 $this->assertEquals($users[$user3->id]->rolename, $teacherrole->name); 1432 $this->assertEquals($users[$user3->id]->roleshortname, $teacherrole->shortname); 1433 $this->assertEquals($users[$user3->id]->rolecoursealias, $teacherrename->name); 1434 1435 $users = get_role_users($teacherrole->id, $coursecontext, true); 1436 $this->assertCount(3, $users); 1437 1438 $users = get_role_users($teacherrole->id, $coursecontext, true, '', null, null, '', 2, 1); 1439 $this->assertCount(1, $users); 1440 1441 $users = get_role_users($teacherrole->id, $coursecontext, false, 'u.id, u.email, u.idnumber', 'u.idnumber'); 1442 $this->assertCount(2, $users); 1443 $this->assertArrayHasKey($user1->id, $users); 1444 $this->assertArrayHasKey($user3->id, $users); 1445 1446 $users = get_role_users($teacherrole->id, $coursecontext, false, 'u.id, u.email'); 1447 $this->assertDebuggingCalled('get_role_users() adding u.lastname, u.firstname to the query result because they were required by $sort but missing in $fields'); 1448 $this->assertCount(2, $users); 1449 $this->assertArrayHasKey($user1->id, $users); 1450 $this->assertObjectHasAttribute('lastname', $users[$user1->id]); 1451 $this->assertObjectHasAttribute('firstname', $users[$user1->id]); 1452 $this->assertArrayHasKey($user3->id, $users); 1453 $this->assertObjectHasAttribute('lastname', $users[$user3->id]); 1454 $this->assertObjectHasAttribute('firstname', $users[$user3->id]); 1455 1456 $users = get_role_users($teacherrole->id, $coursecontext, false, 'u.id, u.email, u.idnumber', 'u.idnumber', null, $group->id); 1457 $this->assertCount(1, $users); 1458 $this->assertArrayHasKey($user3->id, $users); 1459 1460 $users = get_role_users($teacherrole->id, $coursecontext, true, 'u.id, u.email, u.idnumber, u.firstname', 'u.idnumber', null, '', '', '', 'u.firstname = :xfirstname', array('xfirstname'=>'John')); 1461 $this->assertCount(1, $users); 1462 $this->assertArrayHasKey($user1->id, $users); 1463 1464 $users = get_role_users(array($noeditteacherrole->id, $studentrole->id), $coursecontext, false, 'ra.id', 'ra.id'); 1465 $this->assertDebuggingNotCalled(); 1466 $users = get_role_users(array($noeditteacherrole->id, $studentrole->id), $coursecontext, false, 'ra.userid', 'ra.userid'); 1467 $this->assertDebuggingCalled('get_role_users() without specifying one single roleid needs to be called prefixing ' . 1468 'role assignments id (ra.id) as unique field, you can use $fields param for it.'); 1469 $users = get_role_users(array($noeditteacherrole->id, $studentrole->id), $coursecontext, false); 1470 $this->assertDebuggingCalled('get_role_users() without specifying one single roleid needs to be called prefixing ' . 1471 'role assignments id (ra.id) as unique field, you can use $fields param for it.'); 1472 $users = get_role_users(array($noeditteacherrole->id, $studentrole->id), $coursecontext, 1473 false, 'u.id, u.firstname', 'u.id, u.firstname'); 1474 $this->assertDebuggingCalled('get_role_users() without specifying one single roleid needs to be called prefixing ' . 1475 'role assignments id (ra.id) as unique field, you can use $fields param for it.'); 1476 } 1477 1478 /** 1479 * Test used role query. 1480 */ 1481 public function test_get_roles_used_in_context() { 1482 global $DB; 1483 1484 $this->resetAfterTest(); 1485 1486 $systemcontext = context_system::instance(); 1487 $teacherrole = $DB->get_record('role', array('shortname'=>'editingteacher'), '*', MUST_EXIST); 1488 $course = $this->getDataGenerator()->create_course(); 1489 $coursecontext = context_course::instance($course->id); 1490 $otherid = create_role('Other role', 'other', 'Some other role', ''); 1491 $teacherrename = (object)array('roleid'=>$teacherrole->id, 'name'=>'Učitel', 'contextid'=>$coursecontext->id); 1492 $DB->insert_record('role_names', $teacherrename); 1493 $otherrename = (object)array('roleid'=>$otherid, 'name'=>'Ostatní', 'contextid'=>$coursecontext->id); 1494 $DB->insert_record('role_names', $otherrename); 1495 1496 $user1 = $this->getDataGenerator()->create_user(); 1497 role_assign($teacherrole->id, $user1->id, $coursecontext->id); 1498 1499 $roles = get_roles_used_in_context($coursecontext); 1500 $this->assertCount(1, $roles); 1501 $role = reset($roles); 1502 $roleid = key($roles); 1503 $this->assertEquals($roleid, $role->id); 1504 $this->assertEquals($teacherrole->id, $role->id); 1505 $this->assertSame($teacherrole->name, $role->name); 1506 $this->assertSame($teacherrole->shortname, $role->shortname); 1507 $this->assertEquals($teacherrole->sortorder, $role->sortorder); 1508 $this->assertSame($teacherrename->name, $role->coursealias); 1509 1510 $user2 = $this->getDataGenerator()->create_user(); 1511 role_assign($teacherrole->id, $user2->id, $systemcontext->id); 1512 role_assign($otherid, $user2->id, $systemcontext->id); 1513 1514 $roles = get_roles_used_in_context($systemcontext); 1515 $this->assertCount(2, $roles); 1516 } 1517 1518 /** 1519 * Test roles used in course. 1520 */ 1521 public function test_get_user_roles_in_course() { 1522 global $DB, $CFG; 1523 1524 $this->resetAfterTest(); 1525 1526 $teacherrole = $DB->get_record('role', array('shortname'=>'editingteacher'), '*', MUST_EXIST); 1527 $studentrole = $DB->get_record('role', array('shortname'=>'student'), '*', MUST_EXIST); 1528 $course = $this->getDataGenerator()->create_course(); 1529 $coursecontext = context_course::instance($course->id); 1530 $teacherrename = (object)array('roleid'=>$teacherrole->id, 'name'=>'Učitel', 'contextid'=>$coursecontext->id); 1531 $DB->insert_record('role_names', $teacherrename); 1532 1533 $roleids = explode(',', $CFG->profileroles); // Should include teacher and student in new installs. 1534 $this->assertTrue(in_array($teacherrole->id, $roleids)); 1535 $this->assertTrue(in_array($studentrole->id, $roleids)); 1536 1537 $user1 = $this->getDataGenerator()->create_user(); 1538 role_assign($teacherrole->id, $user1->id, $coursecontext->id); 1539 role_assign($studentrole->id, $user1->id, $coursecontext->id); 1540 $user2 = $this->getDataGenerator()->create_user(); 1541 role_assign($studentrole->id, $user2->id, $coursecontext->id); 1542 $user3 = $this->getDataGenerator()->create_user(); 1543 1544 $roles = get_user_roles_in_course($user1->id, $course->id); 1545 $this->assertEquals(1, preg_match_all('/,/', $roles, $matches)); 1546 $this->assertTrue(strpos($roles, role_get_name($teacherrole, $coursecontext)) !== false); 1547 1548 $roles = get_user_roles_in_course($user2->id, $course->id); 1549 $this->assertEquals(0, preg_match_all('/,/', $roles, $matches)); 1550 $this->assertTrue(strpos($roles, role_get_name($studentrole, $coursecontext)) !== false); 1551 1552 $roles = get_user_roles_in_course($user3->id, $course->id); 1553 $this->assertSame('', $roles); 1554 } 1555 1556 /** 1557 * Test has_capability(), has_any_capability() and has_all_capabilities(). 1558 */ 1559 public function test_has_capability_and_friends() { 1560 global $DB; 1561 1562 $this->resetAfterTest(); 1563 1564 $course = $this->getDataGenerator()->create_course(); 1565 $coursecontext = context_course::instance($course->id); 1566 $teacherrole = $DB->get_record('role', array('shortname'=>'editingteacher'), '*', MUST_EXIST); 1567 $teacher = $this->getDataGenerator()->create_user(); 1568 role_assign($teacherrole->id, $teacher->id, $coursecontext); 1569 $admin = $DB->get_record('user', array('username'=>'admin')); 1570 1571 // Note: Here are used default capabilities, the full test is in permission evaluation bellow, 1572 // use two capabilities that teacher has and one does not, none of them should be allowed for not-logged-in user. 1573 1574 $this->assertTrue($DB->record_exists('capabilities', array('name'=>'moodle/backup:backupsection'))); 1575 $this->assertTrue($DB->record_exists('capabilities', array('name'=>'moodle/backup:backupcourse'))); 1576 $this->assertTrue($DB->record_exists('capabilities', array('name'=>'moodle/site:approvecourse'))); 1577 1578 $sca = array('moodle/backup:backupsection', 'moodle/backup:backupcourse', 'moodle/site:approvecourse'); 1579 $sc = array('moodle/backup:backupsection', 'moodle/backup:backupcourse'); 1580 1581 $this->setUser(0); 1582 $this->assertFalse(has_capability('moodle/backup:backupsection', $coursecontext)); 1583 $this->assertFalse(has_capability('moodle/backup:backupcourse', $coursecontext)); 1584 $this->assertFalse(has_capability('moodle/site:approvecourse', $coursecontext)); 1585 $this->assertFalse(has_any_capability($sca, $coursecontext)); 1586 $this->assertFalse(has_all_capabilities($sca, $coursecontext)); 1587 1588 $this->assertTrue(has_capability('moodle/backup:backupsection', $coursecontext, $teacher)); 1589 $this->assertTrue(has_capability('moodle/backup:backupcourse', $coursecontext, $teacher)); 1590 $this->assertFalse(has_capability('moodle/site:approvecourse', $coursecontext, $teacher)); 1591 $this->assertTrue(has_any_capability($sca, $coursecontext, $teacher)); 1592 $this->assertTrue(has_all_capabilities($sc, $coursecontext, $teacher)); 1593 $this->assertFalse(has_all_capabilities($sca, $coursecontext, $teacher)); 1594 1595 $this->assertTrue(has_capability('moodle/backup:backupsection', $coursecontext, $admin)); 1596 $this->assertTrue(has_capability('moodle/backup:backupcourse', $coursecontext, $admin)); 1597 $this->assertTrue(has_capability('moodle/site:approvecourse', $coursecontext, $admin)); 1598 $this->assertTrue(has_any_capability($sca, $coursecontext, $admin)); 1599 $this->assertTrue(has_all_capabilities($sc, $coursecontext, $admin)); 1600 $this->assertTrue(has_all_capabilities($sca, $coursecontext, $admin)); 1601 1602 $this->assertFalse(has_capability('moodle/backup:backupsection', $coursecontext, $admin, false)); 1603 $this->assertFalse(has_capability('moodle/backup:backupcourse', $coursecontext, $admin, false)); 1604 $this->assertFalse(has_capability('moodle/site:approvecourse', $coursecontext, $admin, false)); 1605 $this->assertFalse(has_any_capability($sca, $coursecontext, $admin, false)); 1606 $this->assertFalse(has_all_capabilities($sc, $coursecontext, $admin, false)); 1607 $this->assertFalse(has_all_capabilities($sca, $coursecontext, $admin, false)); 1608 1609 $this->setUser($teacher); 1610 $this->assertTrue(has_capability('moodle/backup:backupsection', $coursecontext)); 1611 $this->assertTrue(has_capability('moodle/backup:backupcourse', $coursecontext)); 1612 $this->assertFalse(has_capability('moodle/site:approvecourse', $coursecontext)); 1613 $this->assertTrue(has_any_capability($sca, $coursecontext)); 1614 $this->assertTrue(has_all_capabilities($sc, $coursecontext)); 1615 $this->assertFalse(has_all_capabilities($sca, $coursecontext)); 1616 1617 $this->setAdminUser(); 1618 $this->assertTrue(has_capability('moodle/backup:backupsection', $coursecontext)); 1619 $this->assertTrue(has_capability('moodle/backup:backupcourse', $coursecontext)); 1620 $this->assertTrue(has_capability('moodle/site:approvecourse', $coursecontext)); 1621 $this->assertTrue(has_any_capability($sca, $coursecontext)); 1622 $this->assertTrue(has_all_capabilities($sc, $coursecontext)); 1623 $this->assertTrue(has_all_capabilities($sca, $coursecontext)); 1624 1625 $this->assertFalse(has_capability('moodle/backup:backupsection', $coursecontext, 0)); 1626 $this->assertFalse(has_capability('moodle/backup:backupcourse', $coursecontext, 0)); 1627 $this->assertFalse(has_capability('moodle/site:approvecourse', $coursecontext, 0)); 1628 $this->assertFalse(has_any_capability($sca, $coursecontext, 0)); 1629 $this->assertFalse(has_all_capabilities($sca, $coursecontext, 0)); 1630 } 1631 1632 /** 1633 * Test if course creator future capability lookup works. 1634 */ 1635 public function test_guess_if_creator_will_have_course_capability() { 1636 global $DB, $CFG, $USER; 1637 1638 $this->resetAfterTest(); 1639 1640 $category = $this->getDataGenerator()->create_category(); 1641 $course = $this->getDataGenerator()->create_course(array('category'=>$category->id)); 1642 1643 $syscontext = context_system::instance(); 1644 $categorycontext = context_coursecat::instance($category->id); 1645 $coursecontext = context_course::instance($course->id); 1646 $studentrole = $DB->get_record('role', array('shortname'=>'student'), '*', MUST_EXIST); 1647 $teacherrole = $DB->get_record('role', array('shortname'=>'editingteacher'), '*', MUST_EXIST); 1648 $creatorrole = $DB->get_record('role', array('shortname'=>'coursecreator'), '*', MUST_EXIST); 1649 $managerrole = $DB->get_record('role', array('shortname'=>'manager'), '*', MUST_EXIST); 1650 1651 $this->assertEquals($teacherrole->id, $CFG->creatornewroleid); 1652 1653 $creator = $this->getDataGenerator()->create_user(); 1654 $manager = $this->getDataGenerator()->create_user(); 1655 role_assign($managerrole->id, $manager->id, $categorycontext); 1656 1657 $this->assertFalse(has_capability('moodle/course:view', $categorycontext, $creator)); 1658 $this->assertFalse(has_capability('moodle/role:assign', $categorycontext, $creator)); 1659 $this->assertFalse(has_capability('moodle/course:visibility', $categorycontext, $creator)); 1660 $this->assertFalse(has_capability('moodle/course:visibility', $coursecontext, $creator)); 1661 $this->assertFalse(guess_if_creator_will_have_course_capability('moodle/course:visibility', $categorycontext, $creator)); 1662 $this->assertFalse(guess_if_creator_will_have_course_capability('moodle/course:visibility', $coursecontext, $creator)); 1663 1664 $this->assertTrue(has_capability('moodle/role:assign', $categorycontext, $manager)); 1665 $this->assertTrue(has_capability('moodle/course:visibility', $categorycontext, $manager)); 1666 $this->assertTrue(has_capability('moodle/course:visibility', $coursecontext, $manager)); 1667 $this->assertTrue(guess_if_creator_will_have_course_capability('moodle/course:visibility', $categorycontext, $manager->id)); 1668 $this->assertTrue(guess_if_creator_will_have_course_capability('moodle/course:visibility', $coursecontext, $manager->id)); 1669 1670 $this->assertEquals(0, $USER->id); 1671 $this->assertFalse(has_capability('moodle/course:view', $categorycontext)); 1672 $this->assertFalse(has_capability('moodle/role:assign', $categorycontext)); 1673 $this->assertFalse(has_capability('moodle/course:visibility', $categorycontext)); 1674 $this->assertFalse(has_capability('moodle/course:visibility', $coursecontext)); 1675 $this->assertFalse(guess_if_creator_will_have_course_capability('moodle/course:visibility', $categorycontext)); 1676 $this->assertFalse(guess_if_creator_will_have_course_capability('moodle/course:visibility', $coursecontext)); 1677 1678 $this->setUser($manager); 1679 $this->assertTrue(has_capability('moodle/role:assign', $categorycontext)); 1680 $this->assertTrue(has_capability('moodle/course:visibility', $categorycontext)); 1681 $this->assertTrue(has_capability('moodle/course:visibility', $coursecontext)); 1682 $this->assertTrue(guess_if_creator_will_have_course_capability('moodle/course:visibility', $categorycontext)); 1683 $this->assertTrue(guess_if_creator_will_have_course_capability('moodle/course:visibility', $coursecontext)); 1684 1685 $this->setAdminUser(); 1686 $this->assertTrue(has_capability('moodle/role:assign', $categorycontext)); 1687 $this->assertTrue(has_capability('moodle/course:visibility', $categorycontext)); 1688 $this->assertTrue(has_capability('moodle/course:visibility', $coursecontext)); 1689 $this->assertTrue(guess_if_creator_will_have_course_capability('moodle/course:visibility', $categorycontext)); 1690 $this->assertTrue(guess_if_creator_will_have_course_capability('moodle/course:visibility', $coursecontext)); 1691 $this->setUser(0); 1692 1693 role_assign($creatorrole->id, $creator->id, $categorycontext); 1694 1695 $this->assertFalse(has_capability('moodle/role:assign', $categorycontext, $creator)); 1696 $this->assertFalse(has_capability('moodle/course:visibility', $categorycontext, $creator)); 1697 $this->assertFalse(has_capability('moodle/course:visibility', $coursecontext, $creator)); 1698 $this->assertTrue(guess_if_creator_will_have_course_capability('moodle/course:visibility', $categorycontext, $creator)); 1699 $this->assertTrue(guess_if_creator_will_have_course_capability('moodle/course:visibility', $coursecontext, $creator)); 1700 1701 $this->setUser($creator); 1702 $this->assertFalse(has_capability('moodle/role:assign', $categorycontext, null)); 1703 $this->assertFalse(has_capability('moodle/course:visibility', $categorycontext, null)); 1704 $this->assertFalse(has_capability('moodle/course:visibility', $coursecontext, null)); 1705 $this->assertTrue(guess_if_creator_will_have_course_capability('moodle/course:visibility', $categorycontext, null)); 1706 $this->assertTrue(guess_if_creator_will_have_course_capability('moodle/course:visibility', $coursecontext, null)); 1707 $this->setUser(0); 1708 1709 set_config('creatornewroleid', $studentrole->id); 1710 1711 $this->assertFalse(has_capability('moodle/course:visibility', $categorycontext, $creator)); 1712 $this->assertFalse(has_capability('moodle/course:visibility', $coursecontext, $creator)); 1713 $this->assertFalse(guess_if_creator_will_have_course_capability('moodle/course:visibility', $categorycontext, $creator)); 1714 $this->assertFalse(guess_if_creator_will_have_course_capability('moodle/course:visibility', $coursecontext, $creator)); 1715 1716 set_config('creatornewroleid', $teacherrole->id); 1717 1718 role_change_permission($managerrole->id, $categorycontext, 'moodle/course:visibility', CAP_PREVENT); 1719 role_assign($creatorrole->id, $manager->id, $categorycontext); 1720 1721 $this->assertTrue(has_capability('moodle/course:view', $categorycontext, $manager)); 1722 $this->assertTrue(has_capability('moodle/course:view', $coursecontext, $manager)); 1723 $this->assertTrue(has_capability('moodle/role:assign', $categorycontext, $manager)); 1724 $this->assertTrue(has_capability('moodle/role:assign', $coursecontext, $manager)); 1725 $this->assertFalse(has_capability('moodle/course:visibility', $categorycontext, $manager)); 1726 $this->assertFalse(has_capability('moodle/course:visibility', $coursecontext, $manager)); 1727 $this->assertFalse(guess_if_creator_will_have_course_capability('moodle/course:visibility', $categorycontext, $manager)); 1728 $this->assertFalse(guess_if_creator_will_have_course_capability('moodle/course:visibility', $coursecontext, $manager)); 1729 1730 role_change_permission($managerrole->id, $categorycontext, 'moodle/course:view', CAP_PREVENT); 1731 $this->assertTrue(has_capability('moodle/role:assign', $categorycontext, $manager)); 1732 $this->assertFalse(has_capability('moodle/course:visibility', $categorycontext, $manager)); 1733 $this->assertFalse(has_capability('moodle/course:visibility', $coursecontext, $manager)); 1734 $this->assertTrue(guess_if_creator_will_have_course_capability('moodle/course:visibility', $categorycontext, $manager)); 1735 $this->assertTrue(guess_if_creator_will_have_course_capability('moodle/course:visibility', $coursecontext, $manager)); 1736 1737 $this->getDataGenerator()->enrol_user($manager->id, $course->id, 0); 1738 1739 $this->assertTrue(has_capability('moodle/role:assign', $categorycontext, $manager)); 1740 $this->assertTrue(has_capability('moodle/role:assign', $coursecontext, $manager)); 1741 $this->assertTrue(is_enrolled($coursecontext, $manager)); 1742 $this->assertFalse(has_capability('moodle/course:visibility', $categorycontext, $manager)); 1743 $this->assertFalse(has_capability('moodle/course:visibility', $coursecontext, $manager)); 1744 $this->assertTrue(guess_if_creator_will_have_course_capability('moodle/course:visibility', $categorycontext, $manager)); 1745 $this->assertFalse(guess_if_creator_will_have_course_capability('moodle/course:visibility', $coursecontext, $manager)); 1746 1747 // Test problems. 1748 1749 try { 1750 guess_if_creator_will_have_course_capability('moodle/course:visibility', $syscontext, $creator); 1751 $this->fail('Exception expected when non course/category context passed to guess_if_creator_will_have_course_capability()'); 1752 } catch (moodle_exception $e) { 1753 $this->assertInstanceOf('coding_exception', $e); 1754 } 1755 } 1756 1757 /** 1758 * Test require_capability() exceptions. 1759 */ 1760 public function test_require_capability() { 1761 $this->resetAfterTest(); 1762 1763 $syscontext = context_system::instance(); 1764 1765 $this->setUser(0); 1766 $this->assertFalse(has_capability('moodle/site:config', $syscontext)); 1767 try { 1768 require_capability('moodle/site:config', $syscontext); 1769 $this->fail('Exception expected from require_capability()'); 1770 } catch (moodle_exception $e) { 1771 $this->assertInstanceOf('required_capability_exception', $e); 1772 } 1773 $this->setAdminUser(); 1774 $this->assertFalse(has_capability('moodle/site:config', $syscontext, 0)); 1775 try { 1776 require_capability('moodle/site:config', $syscontext, 0); 1777 $this->fail('Exception expected from require_capability()'); 1778 } catch (moodle_exception $e) { 1779 $this->assertInstanceOf('required_capability_exception', $e); 1780 } 1781 $this->assertFalse(has_capability('moodle/site:config', $syscontext, null, false)); 1782 try { 1783 require_capability('moodle/site:config', $syscontext, null, false); 1784 $this->fail('Exception expected from require_capability()'); 1785 } catch (moodle_exception $e) { 1786 $this->assertInstanceOf('required_capability_exception', $e); 1787 } 1788 } 1789 1790 /** 1791 * Test that enrolled users SQL does not return any values for users in 1792 * other courses. 1793 */ 1794 public function test_get_enrolled_sql_different_course() { 1795 global $DB; 1796 1797 $this->resetAfterTest(); 1798 1799 $course = $this->getDataGenerator()->create_course(); 1800 $context = context_course::instance($course->id); 1801 $student = $DB->get_record('role', array('shortname' => 'student'), '*', MUST_EXIST); 1802 $user = $this->getDataGenerator()->create_user(); 1803 1804 // This user should not appear anywhere, we're not interested in that context. 1805 $course2 = $this->getDataGenerator()->create_course(); 1806 $this->getDataGenerator()->enrol_user($user->id, $course2->id, $student->id); 1807 1808 $enrolled = get_enrolled_users($context, '', 0, 'u.id', null, 0, 0, false); 1809 $active = get_enrolled_users($context, '', 0, 'u.id', null, 0, 0, true); 1810 $suspended = get_suspended_userids($context); 1811 1812 $this->assertFalse(isset($enrolled[$user->id])); 1813 $this->assertFalse(isset($active[$user->id])); 1814 $this->assertFalse(isset($suspended[$user->id])); 1815 $this->assertCount(0, $enrolled); 1816 $this->assertCount(0, $active); 1817 $this->assertCount(0, $suspended); 1818 } 1819 1820 /** 1821 * Test that enrolled users SQL does not return any values for role 1822 * assignments without an enrolment. 1823 */ 1824 public function test_get_enrolled_sql_role_only() { 1825 global $DB; 1826 1827 $this->resetAfterTest(); 1828 1829 $course = $this->getDataGenerator()->create_course(); 1830 $context = context_course::instance($course->id); 1831 $student = $DB->get_record('role', array('shortname' => 'student'), '*', MUST_EXIST); 1832 $user = $this->getDataGenerator()->create_user(); 1833 1834 // Role assignment is not the same as course enrollment. 1835 role_assign($student->id, $user->id, $context->id); 1836 1837 $enrolled = get_enrolled_users($context, '', 0, 'u.id', null, 0, 0, false); 1838 $active = get_enrolled_users($context, '', 0, 'u.id', null, 0, 0, true); 1839 $suspended = get_suspended_userids($context); 1840 1841 $this->assertFalse(isset($enrolled[$user->id])); 1842 $this->assertFalse(isset($active[$user->id])); 1843 $this->assertFalse(isset($suspended[$user->id])); 1844 $this->assertCount(0, $enrolled); 1845 $this->assertCount(0, $active); 1846 $this->assertCount(0, $suspended); 1847 } 1848 1849 /** 1850 * Test that multiple enrolments for the same user are counted correctly. 1851 */ 1852 public function test_get_enrolled_sql_multiple_enrolments() { 1853 global $DB; 1854 1855 $this->resetAfterTest(); 1856 1857 $course = $this->getDataGenerator()->create_course(); 1858 $context = context_course::instance($course->id); 1859 $student = $DB->get_record('role', array('shortname' => 'student'), '*', MUST_EXIST); 1860 $user = $this->getDataGenerator()->create_user(); 1861 1862 // Add a suspended enrol. 1863 $selfinstance = $DB->get_record('enrol', array('courseid' => $course->id, 'enrol' => 'self')); 1864 $selfplugin = enrol_get_plugin('self'); 1865 $selfplugin->update_status($selfinstance, ENROL_INSTANCE_ENABLED); 1866 $this->getDataGenerator()->enrol_user($user->id, $course->id, $student->id, 'self', 0, 0, ENROL_USER_SUSPENDED); 1867 1868 // Should be enrolled, but not active - user is suspended. 1869 $enrolled = get_enrolled_users($context, '', 0, 'u.id', null, 0, 0, false); 1870 $active = get_enrolled_users($context, '', 0, 'u.id', null, 0, 0, true); 1871 $suspended = get_suspended_userids($context); 1872 1873 $this->assertTrue(isset($enrolled[$user->id])); 1874 $this->assertFalse(isset($active[$user->id])); 1875 $this->assertTrue(isset($suspended[$user->id])); 1876 $this->assertCount(1, $enrolled); 1877 $this->assertCount(0, $active); 1878 $this->assertCount(1, $suspended); 1879 1880 // Add an active enrol for the user. Any active enrol makes them enrolled. 1881 $this->getDataGenerator()->enrol_user($user->id, $course->id, $student->id); 1882 1883 // User should be active now. 1884 $enrolled = get_enrolled_users($context, '', 0, 'u.id', null, 0, 0, false); 1885 $active = get_enrolled_users($context, '', 0, 'u.id', null, 0, 0, true); 1886 $suspended = get_suspended_userids($context); 1887 1888 $this->assertTrue(isset($enrolled[$user->id])); 1889 $this->assertTrue(isset($active[$user->id])); 1890 $this->assertFalse(isset($suspended[$user->id])); 1891 $this->assertCount(1, $enrolled); 1892 $this->assertCount(1, $active); 1893 $this->assertCount(0, $suspended); 1894 1895 } 1896 1897 public function get_enrolled_sql_provider() { 1898 return array( 1899 array( 1900 // Two users who are enrolled. 1901 'users' => array( 1902 array( 1903 'enrolled' => true, 1904 'active' => true, 1905 ), 1906 array( 1907 'enrolled' => true, 1908 'active' => true, 1909 ), 1910 ), 1911 'counts' => array( 1912 'enrolled' => 2, 1913 'active' => 2, 1914 'suspended' => 0, 1915 ), 1916 ), 1917 array( 1918 // A user who is suspended. 1919 'users' => array( 1920 array( 1921 'status' => ENROL_USER_SUSPENDED, 1922 'enrolled' => true, 1923 'suspended' => true, 1924 ), 1925 ), 1926 'counts' => array( 1927 'enrolled' => 1, 1928 'active' => 0, 1929 'suspended' => 1, 1930 ), 1931 ), 1932 array( 1933 // One of each. 1934 'users' => array( 1935 array( 1936 'enrolled' => true, 1937 'active' => true, 1938 ), 1939 array( 1940 'status' => ENROL_USER_SUSPENDED, 1941 'enrolled' => true, 1942 'suspended' => true, 1943 ), 1944 ), 1945 'counts' => array( 1946 'enrolled' => 2, 1947 'active' => 1, 1948 'suspended' => 1, 1949 ), 1950 ), 1951 array( 1952 // One user who is not yet enrolled. 1953 'users' => array( 1954 array( 1955 'timestart' => DAYSECS, 1956 'enrolled' => true, 1957 'active' => false, 1958 'suspended' => true, 1959 ), 1960 ), 1961 'counts' => array( 1962 'enrolled' => 1, 1963 'active' => 0, 1964 'suspended' => 1, 1965 ), 1966 ), 1967 array( 1968 // One user who is no longer enrolled 1969 'users' => array( 1970 array( 1971 'timeend' => -DAYSECS, 1972 'enrolled' => true, 1973 'active' => false, 1974 'suspended' => true, 1975 ), 1976 ), 1977 'counts' => array( 1978 'enrolled' => 1, 1979 'active' => 0, 1980 'suspended' => 1, 1981 ), 1982 ), 1983 array( 1984 // One user who is not yet enrolled, and one who is no longer enrolled. 1985 'users' => array( 1986 array( 1987 'timeend' => -DAYSECS, 1988 'enrolled' => true, 1989 'active' => false, 1990 'suspended' => true, 1991 ), 1992 array( 1993 'timestart' => DAYSECS, 1994 'enrolled' => true, 1995 'active' => false, 1996 'suspended' => true, 1997 ), 1998 ), 1999 'counts' => array( 2000 'enrolled' => 2, 2001 'active' => 0, 2002 'suspended' => 2, 2003 ), 2004 ), 2005 ); 2006 } 2007 2008 /** 2009 * @dataProvider get_enrolled_sql_provider 2010 */ 2011 public function test_get_enrolled_sql_course($users, $counts) { 2012 global $DB; 2013 2014 $this->resetAfterTest(); 2015 2016 $course = $this->getDataGenerator()->create_course(); 2017 $context = context_course::instance($course->id); 2018 $student = $DB->get_record('role', array('shortname' => 'student'), '*', MUST_EXIST); 2019 $createdusers = array(); 2020 2021 foreach ($users as &$userdata) { 2022 $user = $this->getDataGenerator()->create_user(); 2023 $userdata['id'] = $user->id; 2024 2025 $timestart = 0; 2026 $timeend = 0; 2027 $status = null; 2028 if (isset($userdata['timestart'])) { 2029 $timestart = time() + $userdata['timestart']; 2030 } 2031 if (isset($userdata['timeend'])) { 2032 $timeend = time() + $userdata['timeend']; 2033 } 2034 if (isset($userdata['status'])) { 2035 $status = $userdata['status']; 2036 } 2037 2038 // Enrol the user in the course. 2039 $this->getDataGenerator()->enrol_user($user->id, $course->id, $student->id, 'manual', $timestart, $timeend, $status); 2040 } 2041 2042 // After all users have been enroled, check expectations. 2043 $enrolled = get_enrolled_users($context, '', 0, 'u.id', null, 0, 0, false); 2044 $active = get_enrolled_users($context, '', 0, 'u.id', null, 0, 0, true); 2045 $suspended = get_suspended_userids($context); 2046 2047 foreach ($users as $userdata) { 2048 if (isset($userdata['enrolled']) && $userdata['enrolled']) { 2049 $this->assertTrue(isset($enrolled[$userdata['id']])); 2050 } else { 2051 $this->assertFalse(isset($enrolled[$userdata['id']])); 2052 } 2053 2054 if (isset($userdata['active']) && $userdata['active']) { 2055 $this->assertTrue(isset($active[$userdata['id']])); 2056 } else { 2057 $this->assertFalse(isset($active[$userdata['id']])); 2058 } 2059 2060 if (isset($userdata['suspended']) && $userdata['suspended']) { 2061 $this->assertTrue(isset($suspended[$userdata['id']])); 2062 } else { 2063 $this->assertFalse(isset($suspended[$userdata['id']])); 2064 } 2065 } 2066 2067 $this->assertCount($counts['enrolled'], $enrolled); 2068 $this->assertCount($counts['active'], $active); 2069 $this->assertCount($counts['suspended'], $suspended); 2070 } 2071 2072 /** 2073 * A small functional test of permission evaluations. 2074 */ 2075 public function test_permission_evaluation() { 2076 global $USER, $SITE, $CFG, $DB, $ACCESSLIB_PRIVATE; 2077 2078 $this->resetAfterTest(); 2079 2080 $generator = $this->getDataGenerator(); 2081 2082 // Fill the site with some real data. 2083 $testcategories = array(); 2084 $testcourses = array(); 2085 $testpages = array(); 2086 $testblocks = array(); 2087 $allroles = $DB->get_records_menu('role', array(), 'id', 'archetype, id'); 2088 2089 $systemcontext = context_system::instance(); 2090 $frontpagecontext = context_course::instance(SITEID); 2091 2092 // Add block to system context. 2093 $bi = $generator->create_block('online_users'); 2094 context_block::instance($bi->id); 2095 $testblocks[] = $bi->id; 2096 2097 // Some users. 2098 $testusers = array(); 2099 for ($i=0; $i<20; $i++) { 2100 $user = $generator->create_user(); 2101 $testusers[$i] = $user->id; 2102 $usercontext = context_user::instance($user->id); 2103 2104 // Add block to user profile. 2105 $bi = $generator->create_block('online_users', array('parentcontextid'=>$usercontext->id)); 2106 $testblocks[] = $bi->id; 2107 } 2108 // Deleted user - should be ignored everywhere, can not have context. 2109 $generator->create_user(array('deleted'=>1)); 2110 2111 // Add block to frontpage. 2112 $bi = $generator->create_block('online_users', array('parentcontextid'=>$frontpagecontext->id)); 2113 $frontpageblockcontext = context_block::instance($bi->id); 2114 $testblocks[] = $bi->id; 2115 2116 // Add a resource to frontpage. 2117 $page = $generator->create_module('page', array('course'=>$SITE->id)); 2118 $testpages[] = $page->cmid; 2119 $frontpagepagecontext = context_module::instance($page->cmid); 2120 2121 // Add block to frontpage resource. 2122 $bi = $generator->create_block('online_users', array('parentcontextid'=>$frontpagepagecontext->id)); 2123 $frontpagepageblockcontext = context_block::instance($bi->id); 2124 $testblocks[] = $bi->id; 2125 2126 // Some nested course categories with courses. 2127 $manualenrol = enrol_get_plugin('manual'); 2128 $parentcat = 0; 2129 for ($i=0; $i<5; $i++) { 2130 $cat = $generator->create_category(array('parent'=>$parentcat)); 2131 $testcategories[] = $cat->id; 2132 $catcontext = context_coursecat::instance($cat->id); 2133 $parentcat = $cat->id; 2134 2135 if ($i >= 4) { 2136 continue; 2137 } 2138 2139 // Add resource to each category. 2140 $bi = $generator->create_block('online_users', array('parentcontextid'=>$catcontext->id)); 2141 context_block::instance($bi->id); 2142 2143 // Add a few courses to each category. 2144 for ($j=0; $j<6; $j++) { 2145 $course = $generator->create_course(array('category'=>$cat->id)); 2146 $testcourses[] = $course->id; 2147 $coursecontext = context_course::instance($course->id); 2148 2149 if ($j >= 5) { 2150 continue; 2151 } 2152 // Add manual enrol instance. 2153 $manualenrol->add_default_instance($DB->get_record('course', array('id'=>$course->id))); 2154 2155 // Add block to each course. 2156 $bi = $generator->create_block('online_users', array('parentcontextid'=>$coursecontext->id)); 2157 $testblocks[] = $bi->id; 2158 2159 // Add a resource to each course. 2160 $page = $generator->create_module('page', array('course'=>$course->id)); 2161 $testpages[] = $page->cmid; 2162 $modcontext = context_module::instance($page->cmid); 2163 2164 // Add block to each module. 2165 $bi = $generator->create_block('online_users', array('parentcontextid'=>$modcontext->id)); 2166 $testblocks[] = $bi->id; 2167 } 2168 } 2169 2170 // Make sure all contexts were created properly. 2171 $count = 1; // System. 2172 $count += $DB->count_records('user', array('deleted'=>0)); 2173 $count += $DB->count_records('course_categories'); 2174 $count += $DB->count_records('course'); 2175 $count += $DB->count_records('course_modules'); 2176 $count += $DB->count_records('block_instances'); 2177 $this->assertEquals($count, $DB->count_records('context')); 2178 $this->assertEquals(0, $DB->count_records('context', array('depth'=>0))); 2179 $this->assertEquals(0, $DB->count_records('context', array('path'=>null))); 2180 2181 2182 // Test context_helper::get_level_name() method. 2183 2184 $levels = context_helper::get_all_levels(); 2185 foreach ($levels as $level => $classname) { 2186 $name = context_helper::get_level_name($level); 2187 $this->assertNotEmpty($name); 2188 } 2189 2190 2191 // Test context::instance_by_id(), context_xxx::instance() methods. 2192 2193 $context = context::instance_by_id($frontpagecontext->id); 2194 $this->assertSame(CONTEXT_COURSE, $context->contextlevel); 2195 $this->assertFalse(context::instance_by_id(-1, IGNORE_MISSING)); 2196 try { 2197 context::instance_by_id(-1); 2198 $this->fail('exception expected'); 2199 } catch (moodle_exception $e) { 2200 $this->assertTrue(true); 2201 } 2202 $this->assertInstanceOf('context_system', context_system::instance()); 2203 $this->assertInstanceOf('context_coursecat', context_coursecat::instance($testcategories[0])); 2204 $this->assertInstanceOf('context_course', context_course::instance($testcourses[0])); 2205 $this->assertInstanceOf('context_module', context_module::instance($testpages[0])); 2206 $this->assertInstanceOf('context_block', context_block::instance($testblocks[0])); 2207 2208 $this->assertFalse(context_coursecat::instance(-1, IGNORE_MISSING)); 2209 $this->assertFalse(context_course::instance(-1, IGNORE_MISSING)); 2210 $this->assertFalse(context_module::instance(-1, IGNORE_MISSING)); 2211 $this->assertFalse(context_block::instance(-1, IGNORE_MISSING)); 2212 try { 2213 context_coursecat::instance(-1); 2214 $this->fail('exception expected'); 2215 } catch (moodle_exception $e) { 2216 $this->assertTrue(true); 2217 } 2218 try { 2219 context_course::instance(-1); 2220 $this->fail('exception expected'); 2221 } catch (moodle_exception $e) { 2222 $this->assertTrue(true); 2223 } 2224 try { 2225 context_module::instance(-1); 2226 $this->fail('exception expected'); 2227 } catch (moodle_exception $e) { 2228 $this->assertTrue(true); 2229 } 2230 try { 2231 context_block::instance(-1); 2232 $this->fail('exception expected'); 2233 } catch (moodle_exception $e) { 2234 $this->assertTrue(true); 2235 } 2236 2237 2238 // Test $context->get_url(), $context->get_context_name(), $context->get_capabilities() methods. 2239 2240 $testcontexts = array(); 2241 $testcontexts[CONTEXT_SYSTEM] = context_system::instance(); 2242 $testcontexts[CONTEXT_COURSECAT] = context_coursecat::instance($testcategories[0]); 2243 $testcontexts[CONTEXT_COURSE] = context_course::instance($testcourses[0]); 2244 $testcontexts[CONTEXT_MODULE] = context_module::instance($testpages[0]); 2245 $testcontexts[CONTEXT_BLOCK] = context_block::instance($testblocks[0]); 2246 2247 foreach ($testcontexts as $context) { 2248 $name = $context->get_context_name(true, true); 2249 $this->assertNotEmpty($name); 2250 2251 $this->assertInstanceOf('moodle_url', $context->get_url()); 2252 2253 $caps = $context->get_capabilities(); 2254 $this->assertTrue(is_array($caps)); 2255 foreach ($caps as $cap) { 2256 $cap = (array)$cap; 2257 $this->assertSame(array_keys($cap), array('id', 'name', 'captype', 'contextlevel', 'component', 'riskbitmask')); 2258 } 2259 } 2260 unset($testcontexts); 2261 2262 // Test $context->get_course_context() method. 2263 2264 $this->assertFalse($systemcontext->get_course_context(false)); 2265 try { 2266 $systemcontext->get_course_context(); 2267 $this->fail('exception expected'); 2268 } catch (moodle_exception $e) { 2269 $this->assertInstanceOf('coding_exception', $e); 2270 } 2271 $context = context_coursecat::instance($testcategories[0]); 2272 $this->assertFalse($context->get_course_context(false)); 2273 try { 2274 $context->get_course_context(); 2275 $this->fail('exception expected'); 2276 } catch (moodle_exception $e) { 2277 $this->assertInstanceOf('coding_exception', $e); 2278 } 2279 $this->assertEquals($frontpagecontext, $frontpagecontext->get_course_context(true)); 2280 $this->assertEquals($frontpagecontext, $frontpagepagecontext->get_course_context(true)); 2281 $this->assertEquals($frontpagecontext, $frontpagepageblockcontext->get_course_context(true)); 2282 2283 2284 // Test $context->get_parent_context(), $context->get_parent_contexts(), $context->get_parent_context_ids() methods. 2285 2286 $userid = reset($testusers); 2287 $usercontext = context_user::instance($userid); 2288 $this->assertEquals($systemcontext, $usercontext->get_parent_context()); 2289 $this->assertEquals(array($systemcontext->id=>$systemcontext), $usercontext->get_parent_contexts()); 2290 $this->assertEquals(array($usercontext->id=>$usercontext, $systemcontext->id=>$systemcontext), $usercontext->get_parent_contexts(true)); 2291 2292 $this->assertEquals(array(), $systemcontext->get_parent_contexts()); 2293 $this->assertEquals(array($systemcontext->id=>$systemcontext), $systemcontext->get_parent_contexts(true)); 2294 $this->assertEquals(array(), $systemcontext->get_parent_context_ids()); 2295 $this->assertEquals(array($systemcontext->id), $systemcontext->get_parent_context_ids(true)); 2296 2297 $this->assertEquals($systemcontext, $frontpagecontext->get_parent_context()); 2298 $this->assertEquals(array($systemcontext->id=>$systemcontext), $frontpagecontext->get_parent_contexts()); 2299 $this->assertEquals(array($frontpagecontext->id=>$frontpagecontext, $systemcontext->id=>$systemcontext), $frontpagecontext->get_parent_contexts(true)); 2300 $this->assertEquals(array($systemcontext->id), $frontpagecontext->get_parent_context_ids()); 2301 $this->assertEquals(array($frontpagecontext->id, $systemcontext->id), $frontpagecontext->get_parent_context_ids(true)); 2302 2303 $this->assertFalse($systemcontext->get_parent_context()); 2304 $frontpagecontext = context_course::instance($SITE->id); 2305 $parent = $systemcontext; 2306 foreach ($testcategories as $catid) { 2307 $catcontext = context_coursecat::instance($catid); 2308 $this->assertEquals($parent, $catcontext->get_parent_context()); 2309 $parent = $catcontext; 2310 } 2311 $this->assertEquals($frontpagecontext, $frontpagepagecontext->get_parent_context()); 2312 $this->assertEquals($frontpagecontext, $frontpageblockcontext->get_parent_context()); 2313 $this->assertEquals($frontpagepagecontext, $frontpagepageblockcontext->get_parent_context()); 2314 2315 2316 // Test $context->get_child_contexts() method. 2317 2318 $children = $systemcontext->get_child_contexts(); 2319 $this->resetDebugging(); 2320 $this->assertEquals(count($children)+1, $DB->count_records('context')); 2321 2322 $context = context_coursecat::instance($testcategories[3]); 2323 $children = $context->get_child_contexts(); 2324 $countcats = 0; 2325 $countcourses = 0; 2326 $countblocks = 0; 2327 foreach ($children as $child) { 2328 if ($child->contextlevel == CONTEXT_COURSECAT) { 2329 $countcats++; 2330 } 2331 if ($child->contextlevel == CONTEXT_COURSE) { 2332 $countcourses++; 2333 } 2334 if ($child->contextlevel == CONTEXT_BLOCK) { 2335 $countblocks++; 2336 } 2337 } 2338 $this->assertCount(8, $children); 2339 $this->assertEquals(1, $countcats); 2340 $this->assertEquals(6, $countcourses); 2341 $this->assertEquals(1, $countblocks); 2342 2343 $context = context_course::instance($testcourses[2]); 2344 $children = $context->get_child_contexts(); 2345 $this->assertCount(7, $children); // Depends on number of default blocks. 2346 2347 $context = context_module::instance($testpages[3]); 2348 $children = $context->get_child_contexts(); 2349 $this->assertCount(1, $children); 2350 2351 $context = context_block::instance($testblocks[1]); 2352 $children = $context->get_child_contexts(); 2353 $this->assertCount(0, $children); 2354 2355 unset($children); 2356 unset($countcats); 2357 unset($countcourses); 2358 unset($countblocks); 2359 2360 2361 // Test context_helper::reset_caches() method. 2362 2363 context_helper::reset_caches(); 2364 $this->assertEquals(0, context_inspection::test_context_cache_size()); 2365 context_course::instance($SITE->id); 2366 $this->assertEquals(1, context_inspection::test_context_cache_size()); 2367 2368 2369 // Test context preloading. 2370 2371 context_helper::reset_caches(); 2372 $sql = "SELECT ".context_helper::get_preload_record_columns_sql('c')." 2373 FROM {context} c 2374 WHERE c.contextlevel <> ".CONTEXT_SYSTEM; 2375 $records = $DB->get_records_sql($sql); 2376 $firstrecord = reset($records); 2377 $columns = context_helper::get_preload_record_columns('c'); 2378 $firstrecord = (array)$firstrecord; 2379 $this->assertSame(array_keys($firstrecord), array_values($columns)); 2380 context_helper::reset_caches(); 2381 foreach ($records as $record) { 2382 context_helper::preload_from_record($record); 2383 $this->assertEquals(new stdClass(), $record); 2384 } 2385 $this->assertEquals(count($records), context_inspection::test_context_cache_size()); 2386 unset($records); 2387 unset($columns); 2388 2389 context_helper::reset_caches(); 2390 context_helper::preload_course($SITE->id); 2391 $numfrontpagemodules = $DB->count_records('course_modules', array('course' => $SITE->id)); 2392 $this->assertEquals(6 + $numfrontpagemodules, context_inspection::test_context_cache_size()); // Depends on number of default blocks. 2393 2394 // Test assign_capability(), unassign_capability() functions. 2395 2396 $rc = $DB->get_record('role_capabilities', array('contextid'=>$frontpagecontext->id, 'roleid'=>$allroles['teacher'], 'capability'=>'moodle/site:accessallgroups')); 2397 $this->assertFalse($rc); 2398 assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $allroles['teacher'], $frontpagecontext->id); 2399 $rc = $DB->get_record('role_capabilities', array('contextid'=>$frontpagecontext->id, 'roleid'=>$allroles['teacher'], 'capability'=>'moodle/site:accessallgroups')); 2400 $this->assertEquals(CAP_ALLOW, $rc->permission); 2401 assign_capability('moodle/site:accessallgroups', CAP_PREVENT, $allroles['teacher'], $frontpagecontext->id); 2402 $rc = $DB->get_record('role_capabilities', array('contextid'=>$frontpagecontext->id, 'roleid'=>$allroles['teacher'], 'capability'=>'moodle/site:accessallgroups')); 2403 $this->assertEquals(CAP_ALLOW, $rc->permission); 2404 assign_capability('moodle/site:accessallgroups', CAP_PREVENT, $allroles['teacher'], $frontpagecontext, true); 2405 $rc = $DB->get_record('role_capabilities', array('contextid'=>$frontpagecontext->id, 'roleid'=>$allroles['teacher'], 'capability'=>'moodle/site:accessallgroups')); 2406 $this->assertEquals(CAP_PREVENT, $rc->permission); 2407 2408 assign_capability('moodle/site:accessallgroups', CAP_INHERIT, $allroles['teacher'], $frontpagecontext); 2409 $rc = $DB->get_record('role_capabilities', array('contextid'=>$frontpagecontext->id, 'roleid'=>$allroles['teacher'], 'capability'=>'moodle/site:accessallgroups')); 2410 $this->assertFalse($rc); 2411 assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $allroles['teacher'], $frontpagecontext); 2412 unassign_capability('moodle/site:accessallgroups', $allroles['teacher'], $frontpagecontext, true); 2413 $rc = $DB->get_record('role_capabilities', array('contextid'=>$frontpagecontext->id, 'roleid'=>$allroles['teacher'], 'capability'=>'moodle/site:accessallgroups')); 2414 $this->assertFalse($rc); 2415 unassign_capability('moodle/site:accessallgroups', $allroles['teacher'], $frontpagecontext->id, true); 2416 unset($rc); 2417 2418 accesslib_clear_all_caches_for_unit_testing(); // Must be done after assign_capability(). 2419 2420 2421 // Test role_assign(), role_unassign(), role_unassign_all() functions. 2422 2423 $context = context_course::instance($testcourses[1]); 2424 $this->assertEquals(0, $DB->count_records('role_assignments', array('contextid'=>$context->id))); 2425 role_assign($allroles['teacher'], $testusers[1], $context->id); 2426 role_assign($allroles['teacher'], $testusers[2], $context->id); 2427 role_assign($allroles['manager'], $testusers[1], $context->id); 2428 $this->assertEquals(3, $DB->count_records('role_assignments', array('contextid'=>$context->id))); 2429 role_unassign($allroles['teacher'], $testusers[1], $context->id); 2430 $this->assertEquals(2, $DB->count_records('role_assignments', array('contextid'=>$context->id))); 2431 role_unassign_all(array('contextid'=>$context->id)); 2432 $this->assertEquals(0, $DB->count_records('role_assignments', array('contextid'=>$context->id))); 2433 unset($context); 2434 2435 accesslib_clear_all_caches_for_unit_testing(); // Just in case. 2436 2437 2438 // Test has_capability(), get_users_by_capability(), role_switch(), reload_all_capabilities() and friends functions. 2439 2440 $adminid = get_admin()->id; 2441 $guestid = $CFG->siteguest; 2442 2443 // Enrol some users into some courses. 2444 $course1 = $DB->get_record('course', array('id'=>$testcourses[22]), '*', MUST_EXIST); 2445 $course2 = $DB->get_record('course', array('id'=>$testcourses[7]), '*', MUST_EXIST); 2446 $cms = $DB->get_records('course_modules', array('course'=>$course1->id), 'id'); 2447 $cm1 = reset($cms); 2448 $blocks = $DB->get_records('block_instances', array('parentcontextid'=>context_module::instance($cm1->id)->id), 'id'); 2449 $block1 = reset($blocks); 2450 $instance1 = $DB->get_record('enrol', array('enrol'=>'manual', 'courseid'=>$course1->id)); 2451 $instance2 = $DB->get_record('enrol', array('enrol'=>'manual', 'courseid'=>$course2->id)); 2452 for ($i=0; $i<9; $i++) { 2453 $manualenrol->enrol_user($instance1, $testusers[$i], $allroles['student']); 2454 } 2455 $manualenrol->enrol_user($instance1, $testusers[8], $allroles['teacher']); 2456 $manualenrol->enrol_user($instance1, $testusers[9], $allroles['editingteacher']); 2457 2458 for ($i=10; $i<15; $i++) { 2459 $manualenrol->enrol_user($instance2, $testusers[$i], $allroles['student']); 2460 } 2461 $manualenrol->enrol_user($instance2, $testusers[15], $allroles['editingteacher']); 2462 2463 // Add tons of role assignments - the more the better. 2464 role_assign($allroles['coursecreator'], $testusers[11], context_coursecat::instance($testcategories[2])); 2465 role_assign($allroles['manager'], $testusers[12], context_coursecat::instance($testcategories[1])); 2466 role_assign($allroles['student'], $testusers[9], context_module::instance($cm1->id)); 2467 role_assign($allroles['teacher'], $testusers[8], context_module::instance($cm1->id)); 2468 role_assign($allroles['guest'], $testusers[13], context_course::instance($course1->id)); 2469 role_assign($allroles['teacher'], $testusers[7], context_block::instance($block1->id)); 2470 role_assign($allroles['manager'], $testusers[9], context_block::instance($block1->id)); 2471 role_assign($allroles['editingteacher'], $testusers[9], context_course::instance($course1->id)); 2472 2473 role_assign($allroles['teacher'], $adminid, context_course::instance($course1->id)); 2474 role_assign($allroles['editingteacher'], $adminid, context_block::instance($block1->id)); 2475 2476 // Add tons of overrides - the more the better. 2477 assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $CFG->defaultuserroleid, $frontpageblockcontext, true); 2478 assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $CFG->defaultfrontpageroleid, $frontpageblockcontext, true); 2479 assign_capability('moodle/block:view', CAP_PROHIBIT, $allroles['guest'], $frontpageblockcontext, true); 2480 assign_capability('block/online_users:viewlist', CAP_PREVENT, $allroles['user'], $frontpageblockcontext, true); 2481 assign_capability('block/online_users:viewlist', CAP_PREVENT, $allroles['student'], $frontpageblockcontext, true); 2482 2483 assign_capability('moodle/site:accessallgroups', CAP_PREVENT, $CFG->defaultuserroleid, $frontpagepagecontext, true); 2484 assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $CFG->defaultfrontpageroleid, $frontpagepagecontext, true); 2485 assign_capability('mod/page:view', CAP_PREVENT, $allroles['guest'], $frontpagepagecontext, true); 2486 assign_capability('mod/page:view', CAP_ALLOW, $allroles['user'], $frontpagepagecontext, true); 2487 assign_capability('moodle/page:view', CAP_ALLOW, $allroles['student'], $frontpagepagecontext, true); 2488 2489 assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $CFG->defaultuserroleid, $frontpagecontext, true); 2490 assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $CFG->defaultfrontpageroleid, $frontpagecontext, true); 2491 assign_capability('mod/page:view', CAP_ALLOW, $allroles['guest'], $frontpagecontext, true); 2492 assign_capability('mod/page:view', CAP_PROHIBIT, $allroles['user'], $frontpagecontext, true); 2493 2494 assign_capability('mod/page:view', CAP_PREVENT, $allroles['guest'], $systemcontext, true); 2495 2496 accesslib_clear_all_caches_for_unit_testing(); /// Must be done after assign_capability(). 2497 2498 // Extra tests for guests and not-logged-in users because they can not be verified by cross checking 2499 // with get_users_by_capability() where they are ignored. 2500 $this->assertFalse(has_capability('moodle/block:view', $frontpageblockcontext, $guestid)); 2501 $this->assertFalse(has_capability('mod/page:view', $frontpagepagecontext, $guestid)); 2502 $this->assertTrue(has_capability('mod/page:view', $frontpagecontext, $guestid)); 2503 $this->assertFalse(has_capability('mod/page:view', $systemcontext, $guestid)); 2504 2505 $this->assertFalse(has_capability('moodle/block:view', $frontpageblockcontext, 0)); 2506 $this->assertFalse(has_capability('mod/page:view', $frontpagepagecontext, 0)); 2507 $this->assertTrue(has_capability('mod/page:view', $frontpagecontext, 0)); 2508 $this->assertFalse(has_capability('mod/page:view', $systemcontext, 0)); 2509 2510 $this->assertFalse(has_capability('moodle/course:create', $systemcontext, $testusers[11])); 2511 $this->assertTrue(has_capability('moodle/course:create', context_coursecat::instance($testcategories[2]), $testusers[11])); 2512 $this->assertFalse(has_capability('moodle/course:create', context_course::instance($testcourses[1]), $testusers[11])); 2513 $this->assertTrue(has_capability('moodle/course:create', context_course::instance($testcourses[19]), $testusers[11])); 2514 2515 $this->assertFalse(has_capability('moodle/course:update', context_course::instance($testcourses[1]), $testusers[9])); 2516 $this->assertFalse(has_capability('moodle/course:update', context_course::instance($testcourses[19]), $testusers[9])); 2517 $this->assertFalse(has_capability('moodle/course:update', $systemcontext, $testusers[9])); 2518 2519 // Test the list of enrolled users. 2520 $coursecontext = context_course::instance($course1->id); 2521 $enrolled = get_enrolled_users($coursecontext); 2522 $this->assertCount(10, $enrolled); 2523 for ($i=0; $i<10; $i++) { 2524 $this->assertTrue(isset($enrolled[$testusers[$i]])); 2525 } 2526 $enrolled = get_enrolled_users($coursecontext, 'moodle/course:update'); 2527 $this->assertCount(1, $enrolled); 2528 $this->assertTrue(isset($enrolled[$testusers[9]])); 2529 unset($enrolled); 2530 2531 // Role switching. 2532 $userid = $testusers[9]; 2533 $USER = $DB->get_record('user', array('id'=>$userid)); 2534 load_all_capabilities(); 2535 $coursecontext = context_course::instance($course1->id); 2536 $this->assertTrue(has_capability('moodle/course:update', $coursecontext)); 2537 $this->assertFalse(is_role_switched($course1->id)); 2538 role_switch($allroles['student'], $coursecontext); 2539 $this->assertTrue(is_role_switched($course1->id)); 2540 $this->assertEquals($allroles['student'], $USER->access['rsw'][$coursecontext->path]); 2541 $this->assertFalse(has_capability('moodle/course:update', $coursecontext)); 2542 reload_all_capabilities(); 2543 $this->assertFalse(has_capability('moodle/course:update', $coursecontext)); 2544 role_switch(0, $coursecontext); 2545 $this->assertTrue(has_capability('moodle/course:update', $coursecontext)); 2546 $userid = $adminid; 2547 $USER = $DB->get_record('user', array('id'=>$userid)); 2548 load_all_capabilities(); 2549 $coursecontext = context_course::instance($course1->id); 2550 $blockcontext = context_block::instance($block1->id); 2551 $this->assertTrue(has_capability('moodle/course:update', $blockcontext)); 2552 role_switch($allroles['student'], $coursecontext); 2553 $this->assertEquals($allroles['student'], $USER->access['rsw'][$coursecontext->path]); 2554 $this->assertFalse(has_capability('moodle/course:update', $blockcontext)); 2555 reload_all_capabilities(); 2556 $this->assertFalse(has_capability('moodle/course:update', $blockcontext)); 2557 load_all_capabilities(); 2558 $this->assertTrue(has_capability('moodle/course:update', $blockcontext)); 2559 2560 // Temp course role for enrol. 2561 $DB->delete_records('cache_flags', array()); // This prevents problem with dirty contexts immediately resetting the temp role - this is a known problem... 2562 $userid = $testusers[5]; 2563 $roleid = $allroles['editingteacher']; 2564 $USER = $DB->get_record('user', array('id'=>$userid)); 2565 load_all_capabilities(); 2566 $coursecontext = context_course::instance($course1->id); 2567 $this->assertFalse(has_capability('moodle/course:update', $coursecontext)); 2568 $this->assertFalse(isset($USER->access['ra'][$coursecontext->path][$roleid])); 2569 load_temp_course_role($coursecontext, $roleid); 2570 $this->assertEquals($USER->access['ra'][$coursecontext->path][$roleid], $roleid); 2571 $this->assertTrue(has_capability('moodle/course:update', $coursecontext)); 2572 remove_temp_course_roles($coursecontext); 2573 $this->assertFalse(has_capability('moodle/course:update', $coursecontext, $userid)); 2574 load_temp_course_role($coursecontext, $roleid); 2575 reload_all_capabilities(); 2576 $this->assertFalse(has_capability('moodle/course:update', $coursecontext, $userid)); 2577 $USER = new stdClass(); 2578 $USER->id = 0; 2579 2580 // Now cross check has_capability() with get_users_by_capability(), each using different code paths, 2581 // they have to be kept in sync, usually only one of them breaks, so we know when something is wrong, 2582 // at the same time validate extra restrictions (guest read only no risks, admin exception, non existent and deleted users). 2583 $contexts = $DB->get_records('context', array(), 'id'); 2584 $contexts = array_values($contexts); 2585 $capabilities = $DB->get_records('capabilities', array(), 'id'); 2586 $capabilities = array_values($capabilities); 2587 $roles = array($allroles['guest'], $allroles['user'], $allroles['teacher'], $allroles['editingteacher'], $allroles['coursecreator'], $allroles['manager']); 2588 $userids = array_values($testusers); 2589 $userids[] = get_admin()->id; 2590 2591 if (!PHPUNIT_LONGTEST) { 2592 $contexts = array_slice($contexts, 0, 10); 2593 $capabilities = array_slice($capabilities, 0, 5); 2594 $userids = array_slice($userids, 0, 5); 2595 } 2596 2597 foreach ($userids as $userid) { // No guest or deleted. 2598 // Each user gets 0-10 random roles. 2599 $rcount = rand(0, 10); 2600 for ($j=0; $j<$rcount; $j++) { 2601 $roleid = $roles[rand(0, count($roles)-1)]; 2602 $contextid = $contexts[rand(0, count($contexts)-1)]->id; 2603 role_assign($roleid, $userid, $contextid); 2604 } 2605 } 2606 2607 $permissions = array(CAP_ALLOW, CAP_PREVENT, CAP_INHERIT, CAP_PREVENT); 2608 $maxoverrides = count($contexts)*10; 2609 for ($j=0; $j<$maxoverrides; $j++) { 2610 $roleid = $roles[rand(0, count($roles)-1)]; 2611 $contextid = $contexts[rand(0, count($contexts)-1)]->id; 2612 $permission = $permissions[rand(0, count($permissions)-1)]; 2613 $capname = $capabilities[rand(0, count($capabilities)-1)]->name; 2614 assign_capability($capname, $permission, $roleid, $contextid, true); 2615 } 2616 unset($permissions); 2617 unset($roles); 2618 2619 accesslib_clear_all_caches_for_unit_testing(); // must be done after assign_capability(). 2620 2621 // Test time - let's set up some real user, just in case the logic for USER affects the others... 2622 $USER = $DB->get_record('user', array('id'=>$testusers[3])); 2623 load_all_capabilities(); 2624 2625 $userids[] = $CFG->siteguest; 2626 $userids[] = 0; // Not-logged-in user. 2627 $userids[] = -1; // Non-existent user. 2628 2629 foreach ($contexts as $crecord) { 2630 $context = context::instance_by_id($crecord->id); 2631 if ($coursecontext = $context->get_course_context(false)) { 2632 $enrolled = get_enrolled_users($context); 2633 } else { 2634 $enrolled = array(); 2635 } 2636 foreach ($capabilities as $cap) { 2637 $allowed = get_users_by_capability($context, $cap->name, 'u.id, u.username'); 2638 if ($enrolled) { 2639 $enrolledwithcap = get_enrolled_users($context, $cap->name); 2640 } else { 2641 $enrolledwithcap = array(); 2642 } 2643 foreach ($userids as $userid) { 2644 if ($userid == 0 or isguestuser($userid)) { 2645 if ($userid == 0) { 2646 $CFG->forcelogin = true; 2647 $this->assertFalse(has_capability($cap->name, $context, $userid)); 2648 unset($CFG->forcelogin); 2649 } 2650 if (($cap->captype === 'write') or ($cap->riskbitmask & (RISK_XSS | RISK_CONFIG | RISK_DATALOSS))) { 2651 $this->assertFalse(has_capability($cap->name, $context, $userid)); 2652 } 2653 $this->assertFalse(isset($allowed[$userid])); 2654 } else { 2655 if (is_siteadmin($userid)) { 2656 $this->assertTrue(has_capability($cap->name, $context, $userid, true)); 2657 } 2658 $hascap = has_capability($cap->name, $context, $userid, false); 2659 $this->assertSame($hascap, isset($allowed[$userid]), "Capability result mismatch user:$userid, context:$context->id, $cap->name, hascap: ".(int)$hascap." "); 2660 if (isset($enrolled[$userid])) { 2661 $this->assertSame(isset($allowed[$userid]), isset($enrolledwithcap[$userid]), "Enrolment with capability result mismatch user:$userid, context:$context->id, $cap->name, hascap: ".(int)$hascap." "); 2662 } 2663 } 2664 } 2665 } 2666 } 2667 // Back to nobody. 2668 $USER = new stdClass(); 2669 $USER->id = 0; 2670 unset($contexts); 2671 unset($userids); 2672 unset($capabilities); 2673 2674 // Now let's do all the remaining tests that break our carefully prepared fake site. 2675 2676 2677 // Test $context->mark_dirty() method. 2678 2679 $DB->delete_records('cache_flags', array()); 2680 accesslib_clear_all_caches(false); 2681 $systemcontext->mark_dirty(); 2682 $dirty = get_cache_flags('accesslib/dirtycontexts', time()-2); 2683 $this->assertTrue(isset($dirty[$systemcontext->path])); 2684 $this->assertTrue(isset($ACCESSLIB_PRIVATE->dirtycontexts[$systemcontext->path])); 2685 2686 2687 // Test $context->reload_if_dirty() method. 2688 2689 $DB->delete_records('cache_flags', array()); 2690 accesslib_clear_all_caches(false); 2691 load_all_capabilities(); 2692 $context = context_course::instance($testcourses[2]); 2693 $page = $DB->get_record('page', array('course'=>$testcourses[2])); 2694 $pagecm = get_coursemodule_from_instance('page', $page->id); 2695 $pagecontext = context_module::instance($pagecm->id); 2696 2697 $context->mark_dirty(); 2698 $this->assertTrue(isset($ACCESSLIB_PRIVATE->dirtycontexts[$context->path])); 2699 $USER->access['test'] = true; 2700 $context->reload_if_dirty(); 2701 $this->assertFalse(isset($USER->access['test'])); 2702 2703 $context->mark_dirty(); 2704 $this->assertTrue(isset($ACCESSLIB_PRIVATE->dirtycontexts[$context->path])); 2705 $USER->access['test'] = true; 2706 $pagecontext->reload_if_dirty(); 2707 $this->assertFalse(isset($USER->access['test'])); 2708 2709 2710 // Test context_helper::build_all_paths() method. 2711 2712 $oldcontexts = $DB->get_records('context', array(), 'id'); 2713 $DB->set_field_select('context', 'path', null, "contextlevel <> ".CONTEXT_SYSTEM); 2714 $DB->set_field_select('context', 'depth', 0, "contextlevel <> ".CONTEXT_SYSTEM); 2715 context_helper::build_all_paths(); 2716 $newcontexts = $DB->get_records('context', array(), 'id'); 2717 $this->assertEquals($oldcontexts, $newcontexts); 2718 unset($oldcontexts); 2719 unset($newcontexts); 2720 2721 2722 // Test $context->reset_paths() method. 2723 2724 $context = context_course::instance($testcourses[2]); 2725 $children = $context->get_child_contexts(); 2726 $context->reset_paths(false); 2727 $this->assertNull($DB->get_field('context', 'path', array('id'=>$context->id))); 2728 $this->assertEquals(0, $DB->get_field('context', 'depth', array('id'=>$context->id))); 2729 foreach ($children as $child) { 2730 $this->assertNull($DB->get_field('context', 'path', array('id'=>$child->id))); 2731 $this->assertEquals(0, $DB->get_field('context', 'depth', array('id'=>$child->id))); 2732 } 2733 $this->assertEquals(count($children)+1, $DB->count_records('context', array('depth'=>0))); 2734 $this->assertEquals(count($children)+1, $DB->count_records('context', array('path'=>null))); 2735 2736 $context = context_course::instance($testcourses[2]); 2737 $context->reset_paths(true); 2738 $context = context_course::instance($testcourses[2]); 2739 $this->assertSame($context->path, $DB->get_field('context', 'path', array('id'=>$context->id))); 2740 $this->assertSame($context->depth, $DB->get_field('context', 'depth', array('id'=>$context->id))); 2741 $this->assertEquals(0, $DB->count_records('context', array('depth'=>0))); 2742 $this->assertEquals(0, $DB->count_records('context', array('path'=>null))); 2743 2744 2745 // Test $context->update_moved() method. 2746 2747 accesslib_clear_all_caches(false); 2748 $DB->delete_records('cache_flags', array()); 2749 $course = $DB->get_record('course', array('id'=>$testcourses[0])); 2750 $context = context_course::instance($course->id); 2751 $oldpath = $context->path; 2752 $miscid = $DB->get_field_sql("SELECT MIN(id) FROM {course_categories}"); 2753 $categorycontext = context_coursecat::instance($miscid); 2754 $course->category = $miscid; 2755 $DB->update_record('course', $course); 2756 $context->update_moved($categorycontext); 2757 2758 $context = context_course::instance($course->id); 2759 $this->assertEquals($categorycontext, $context->get_parent_context()); 2760 $dirty = get_cache_flags('accesslib/dirtycontexts', time()-2); 2761 $this->assertTrue(isset($dirty[$oldpath])); 2762 $this->assertTrue(isset($dirty[$context->path])); 2763 2764 2765 // Test $context->delete_content() method. 2766 2767 context_helper::reset_caches(); 2768 $context = context_module::instance($testpages[3]); 2769 $this->assertTrue($DB->record_exists('context', array('id'=>$context->id))); 2770 $this->assertEquals(1, $DB->count_records('block_instances', array('parentcontextid'=>$context->id))); 2771 $context->delete_content(); 2772 $this->assertTrue($DB->record_exists('context', array('id'=>$context->id))); 2773 $this->assertEquals(0, $DB->count_records('block_instances', array('parentcontextid'=>$context->id))); 2774 2775 2776 // Test $context->delete() method. 2777 2778 context_helper::reset_caches(); 2779 $context = context_module::instance($testpages[4]); 2780 $this->assertTrue($DB->record_exists('context', array('id'=>$context->id))); 2781 $this->assertEquals(1, $DB->count_records('block_instances', array('parentcontextid'=>$context->id))); 2782 $bi = $DB->get_record('block_instances', array('parentcontextid'=>$context->id)); 2783 $bicontext = context_block::instance($bi->id); 2784 $DB->delete_records('cache_flags', array()); 2785 $context->delete(); // Should delete also linked blocks. 2786 $dirty = get_cache_flags('accesslib/dirtycontexts', time()-2); 2787 $this->assertTrue(isset($dirty[$context->path])); 2788 $this->assertFalse($DB->record_exists('context', array('id'=>$context->id))); 2789 $this->assertFalse($DB->record_exists('context', array('id'=>$bicontext->id))); 2790 $this->assertFalse($DB->record_exists('context', array('contextlevel'=>CONTEXT_MODULE, 'instanceid'=>$testpages[4]))); 2791 $this->assertFalse($DB->record_exists('context', array('contextlevel'=>CONTEXT_BLOCK, 'instanceid'=>$bi->id))); 2792 $this->assertEquals(0, $DB->count_records('block_instances', array('parentcontextid'=>$context->id))); 2793 context_module::instance($testpages[4]); 2794 2795 2796 // Test context_helper::delete_instance() method. 2797 2798 context_helper::reset_caches(); 2799 $lastcourse = array_pop($testcourses); 2800 $this->assertTrue($DB->record_exists('context', array('contextlevel'=>CONTEXT_COURSE, 'instanceid'=>$lastcourse))); 2801 $coursecontext = context_course::instance($lastcourse); 2802 $this->assertEquals(1, context_inspection::test_context_cache_size()); 2803 $this->assertNotEquals(CONTEXT_COURSE, $coursecontext->instanceid); 2804 $DB->delete_records('cache_flags', array()); 2805 context_helper::delete_instance(CONTEXT_COURSE, $lastcourse); 2806 $dirty = get_cache_flags('accesslib/dirtycontexts', time()-2); 2807 $this->assertTrue(isset($dirty[$coursecontext->path])); 2808 $this->assertEquals(0, context_inspection::test_context_cache_size()); 2809 $this->assertFalse($DB->record_exists('context', array('contextlevel'=>CONTEXT_COURSE, 'instanceid'=>$lastcourse))); 2810 context_course::instance($lastcourse); 2811 2812 2813 // Test context_helper::create_instances() method. 2814 2815 $prevcount = $DB->count_records('context'); 2816 $DB->delete_records('context', array('contextlevel'=>CONTEXT_BLOCK)); 2817 context_helper::create_instances(null, true); 2818 $this->assertSame($DB->count_records('context'), $prevcount); 2819 $this->assertEquals(0, $DB->count_records('context', array('depth'=>0))); 2820 $this->assertEquals(0, $DB->count_records('context', array('path'=>null))); 2821 2822 $DB->delete_records('context', array('contextlevel'=>CONTEXT_BLOCK)); 2823 $DB->delete_records('block_instances', array()); 2824 $prevcount = $DB->count_records('context'); 2825 $DB->delete_records_select('context', 'contextlevel <> '.CONTEXT_SYSTEM); 2826 context_helper::create_instances(null, true); 2827 $this->assertSame($prevcount, $DB->count_records('context')); 2828 $this->assertEquals(0, $DB->count_records('context', array('depth'=>0))); 2829 $this->assertEquals(0, $DB->count_records('context', array('path'=>null))); 2830 2831 // Test context_helper::cleanup_instances() method. 2832 2833 $lastcourse = $DB->get_field_sql("SELECT MAX(id) FROM {course}"); 2834 $DB->delete_records('course', array('id'=>$lastcourse)); 2835 $lastcategory = $DB->get_field_sql("SELECT MAX(id) FROM {course_categories}"); 2836 $DB->delete_records('course_categories', array('id'=>$lastcategory)); 2837 $lastuser = $DB->get_field_sql("SELECT MAX(id) FROM {user} WHERE deleted=0"); 2838 $DB->delete_records('user', array('id'=>$lastuser)); 2839 $DB->delete_records('block_instances', array('parentcontextid'=>$frontpagepagecontext->id)); 2840 $DB->delete_records('course_modules', array('id'=>$frontpagepagecontext->instanceid)); 2841 context_helper::cleanup_instances(); 2842 $count = 1; // System. 2843 $count += $DB->count_records('user', array('deleted'=>0)); 2844 $count += $DB->count_records('course_categories'); 2845 $count += $DB->count_records('course'); 2846 $count += $DB->count_records('course_modules'); 2847 $count += $DB->count_records('block_instances'); 2848 $this->assertEquals($count, $DB->count_records('context')); 2849 2850 2851 // Test context cache size restrictions. 2852 2853 $testusers= array(); 2854 for ($i=0; $i<CONTEXT_CACHE_MAX_SIZE + 100; $i++) { 2855 $user = $generator->create_user(); 2856 $testusers[$i] = $user->id; 2857 } 2858 context_helper::create_instances(null, true); 2859 context_helper::reset_caches(); 2860 for ($i=0; $i<CONTEXT_CACHE_MAX_SIZE + 100; $i++) { 2861 context_user::instance($testusers[$i]); 2862 if ($i == CONTEXT_CACHE_MAX_SIZE - 1) { 2863 $this->assertEquals(CONTEXT_CACHE_MAX_SIZE, context_inspection::test_context_cache_size()); 2864 } else if ($i == CONTEXT_CACHE_MAX_SIZE) { 2865 // Once the limit is reached roughly 1/3 of records should be removed from cache. 2866 $this->assertEquals((int)ceil(CONTEXT_CACHE_MAX_SIZE * (2/3) + 101), context_inspection::test_context_cache_size()); 2867 } 2868 } 2869 // We keep the first 100 cached. 2870 $prevsize = context_inspection::test_context_cache_size(); 2871 for ($i=0; $i<100; $i++) { 2872 context_user::instance($testusers[$i]); 2873 $this->assertEquals($prevsize, context_inspection::test_context_cache_size()); 2874 } 2875 context_user::instance($testusers[102]); 2876 $this->assertEquals($prevsize+1, context_inspection::test_context_cache_size()); 2877 unset($testusers); 2878 2879 2880 2881 // Test basic test of legacy functions. 2882 // Note: watch out, the fake site might be pretty borked already. 2883 2884 $this->assertEquals(get_system_context(), context_system::instance()); 2885 $this->assertDebuggingCalled('get_system_context() is deprecated, please use context_system::instance() instead.', DEBUG_DEVELOPER); 2886 2887 foreach ($DB->get_records('context') as $contextid => $record) { 2888 $context = context::instance_by_id($contextid); 2889 $this->assertEquals($context, get_context_instance($record->contextlevel, $record->instanceid)); 2890 $this->assertDebuggingCalled('get_context_instance() is deprecated, please use context_xxxx::instance() instead.', DEBUG_DEVELOPER); 2891 } 2892 2893 // Make sure a debugging is thrown. 2894 get_context_instance($record->contextlevel, $record->instanceid); 2895 $this->assertDebuggingCalled('get_context_instance() is deprecated, please use context_xxxx::instance() instead.', DEBUG_DEVELOPER); 2896 get_system_context(); 2897 $this->assertDebuggingCalled('get_system_context() is deprecated, please use context_system::instance() instead.', DEBUG_DEVELOPER); 2898 } 2899 2900 /** 2901 * Test updating of role capabilities during upgrade 2902 */ 2903 public function test_update_capabilities() { 2904 global $DB, $SITE; 2905 2906 $this->resetAfterTest(true); 2907 2908 $froncontext = context_course::instance($SITE->id); 2909 $student = $DB->get_record('role', array('archetype'=>'student')); 2910 $teacher = $DB->get_record('role', array('archetype'=>'teacher')); 2911 2912 $existingcaps = $DB->get_records('capabilities', array(), 'id', 'name, captype, contextlevel, component, riskbitmask'); 2913 2914 $this->assertFalse(isset($existingcaps['moodle/site:restore'])); // Moved to new 'moodle/restore:restorecourse'. 2915 $this->assertTrue(isset($existingcaps['moodle/restore:restorecourse'])); // New cap from 'moodle/site:restore'. 2916 $this->assertTrue(isset($existingcaps['moodle/site:sendmessage'])); // New capability. 2917 $this->assertTrue(isset($existingcaps['moodle/backup:backupcourse'])); 2918 $this->assertTrue(isset($existingcaps['moodle/backup:backupsection'])); // Cloned from 'moodle/backup:backupcourse'. 2919 $this->assertTrue(isset($existingcaps['moodle/site:approvecourse'])); // Updated bitmask. 2920 $this->assertTrue(isset($existingcaps['moodle/course:manageactivities'])); 2921 $this->assertTrue(isset($existingcaps['mod/page:addinstance'])); // Cloned from core 'moodle/course:manageactivities'. 2922 2923 // Fake state before upgrade. 2924 $DB->set_field('capabilities', 'name', 'moodle/site:restore', array('name'=>'moodle/restore:restorecourse')); 2925 $DB->set_field('role_capabilities', 'capability', 'moodle/site:restore', array('capability'=>'moodle/restore:restorecourse')); 2926 assign_capability('moodle/site:restore', CAP_PROHIBIT, $teacher->id, $froncontext->id, true); 2927 $perms1 = array_values($DB->get_records('role_capabilities', array('capability'=>'moodle/site:restore', 'roleid'=>$teacher->id), 'contextid, permission', 'contextid, permission')); 2928 2929 $DB->delete_records('role_capabilities', array('capability'=>'moodle/site:sendmessage')); 2930 $DB->delete_records('capabilities', array('name'=>'moodle/site:sendmessage')); 2931 2932 $DB->delete_records('role_capabilities', array('capability'=>'moodle/backup:backupsection')); 2933 $DB->delete_records('capabilities', array('name'=>'moodle/backup:backupsection')); 2934 assign_capability('moodle/backup:backupcourse', CAP_PROHIBIT, $student->id, $froncontext->id, true); 2935 assign_capability('moodle/backup:backupcourse', CAP_ALLOW, $teacher->id, $froncontext->id, true); 2936 2937 $DB->set_field('capabilities', 'riskbitmask', 0, array('name'=>'moodle/site:approvecourse')); 2938 2939 $DB->delete_records('role_capabilities', array('capability'=>'mod/page:addinstance')); 2940 $DB->delete_records('capabilities', array('name'=>'mod/page:addinstance')); 2941 assign_capability('moodle/course:manageactivities', CAP_PROHIBIT, $student->id, $froncontext->id, true); 2942 assign_capability('moodle/course:manageactivities', CAP_ALLOW, $teacher->id, $froncontext->id, true); 2943 2944 // Execute core. 2945 update_capabilities('moodle'); 2946 2947 // Only core should be upgraded. 2948 $caps = $DB->get_records('capabilities', array(), 'id', 'name, captype, contextlevel, component, riskbitmask'); 2949 2950 $this->assertFalse(isset($existingcaps['moodle/site:restore'])); 2951 $this->assertTrue(isset($caps['moodle/restore:restorecourse'])); 2952 $this->assertEquals($existingcaps['moodle/restore:restorecourse'], $caps['moodle/restore:restorecourse']); 2953 $perms2 = array_values($DB->get_records('role_capabilities', array('capability'=>'moodle/restore:restorecourse', 'roleid'=>$teacher->id), 'contextid, permission', 'contextid, permission')); 2954 $this->assertEquals($perms1, $perms2); 2955 2956 $this->assertTrue(isset($caps['moodle/site:sendmessage'])); 2957 $this->assertEquals($existingcaps['moodle/site:sendmessage'], $caps['moodle/site:sendmessage']); 2958 2959 $this->assertTrue(isset($caps['moodle/backup:backupsection'])); 2960 $this->assertEquals($existingcaps['moodle/backup:backupsection'], $caps['moodle/backup:backupsection']); 2961 $roles = $DB->get_records_sql('SELECT DISTINCT roleid AS id FROM {role_capabilities} WHERE capability=? OR capability=?', array('moodle/backup:backupcourse', 'moodle/backup:backupsection')); 2962 foreach ($roles as $role) { 2963 $perms1 = array_values($DB->get_records('role_capabilities', array('capability'=>'moodle/backup:backupcourse', 'roleid'=>$role->id), 'contextid, permission', 'contextid, permission')); 2964 $perms2 = array_values($DB->get_records('role_capabilities', array('capability'=>'moodle/backup:backupsection', 'roleid'=>$role->id), 'contextid, permission', 'contextid, permission')); 2965 $this->assertEquals($perms1, $perms2); 2966 } 2967 2968 $this->assertTrue(isset($caps['moodle/site:approvecourse'])); 2969 $this->assertEquals($existingcaps['moodle/site:approvecourse'], $caps['moodle/site:approvecourse']); 2970 2971 $this->assertFalse(isset($caps['mod/page:addinstance'])); 2972 2973 // Execute plugin. 2974 update_capabilities('mod_page'); 2975 $caps = $DB->get_records('capabilities', array(), 'id', 'name, captype, contextlevel, component, riskbitmask'); 2976 $this->assertTrue(isset($caps['mod/page:addinstance'])); 2977 $roles = $DB->get_records_sql('SELECT DISTINCT roleid AS id FROM {role_capabilities} WHERE capability=? OR capability=?', array('moodle/course:manageactivities', 'mod/page:addinstance')); 2978 foreach ($roles as $role) { 2979 $perms1 = array_values($DB->get_records('role_capabilities', array('capability'=>'moodle/course:manageactivities', 'roleid'=>$role->id), 'contextid, permission', 'contextid, permission')); 2980 $perms2 = array_values($DB->get_records('role_capabilities', array('capability'=>'mod/page:addinstance', 'roleid'=>$role->id), 'contextid, permission', 'contextid, permission')); 2981 } 2982 $this->assertEquals($perms1, $perms2); 2983 } 2984 2985 /** 2986 * Tests reset_role_capabilities function. 2987 */ 2988 public function test_reset_role_capabilities() { 2989 global $DB; 2990 $this->resetAfterTest(true); 2991 $generator = $this->getDataGenerator(); 2992 2993 // Create test course and user, enrol one in the other. 2994 $course = $generator->create_course(); 2995 $user = $generator->create_user(); 2996 $roleid = $DB->get_field('role', 'id', array('shortname' => 'student'), MUST_EXIST); 2997 $generator->enrol_user($user->id, $course->id, $roleid); 2998 2999 // Change student role so it DOES have 'mod/forum:addinstance'. 3000 $systemcontext = context_system::instance(); 3001 assign_capability('mod/forum:addinstance', CAP_ALLOW, $roleid, $systemcontext->id); 3002 3003 // Override course so it does NOT allow students 'mod/forum:viewdiscussion'. 3004 $coursecontext = context_course::instance($course->id); 3005 assign_capability('mod/forum:viewdiscussion', CAP_PREVENT, $roleid, $coursecontext->id); 3006 3007 // Check expected capabilities so far. 3008 $this->assertTrue(has_capability('mod/forum:addinstance', $coursecontext, $user)); 3009 $this->assertFalse(has_capability('mod/forum:viewdiscussion', $coursecontext, $user)); 3010 3011 // Oops, allowing student to add forums was a mistake, let's reset the role. 3012 reset_role_capabilities($roleid); 3013 3014 // Check new expected capabilities - role capabilities should have been reset, 3015 // while the override at course level should remain. 3016 $this->assertFalse(has_capability('mod/forum:addinstance', $coursecontext, $user)); 3017 $this->assertFalse(has_capability('mod/forum:viewdiscussion', $coursecontext, $user)); 3018 } 3019 3020 /** 3021 * Tests count_role_users function. 3022 */ 3023 public function test_count_role_users() { 3024 global $DB; 3025 $this->resetAfterTest(true); 3026 $generator = self::getDataGenerator(); 3027 // Create a course in a category, and some users. 3028 $category = $generator->create_category(); 3029 $course = $generator->create_course(array('category' => $category->id)); 3030 $user1 = $generator->create_user(); 3031 $user2 = $generator->create_user(); 3032 $user3 = $generator->create_user(); 3033 $user4 = $generator->create_user(); 3034 $user5 = $generator->create_user(); 3035 $roleid1 = $DB->get_field('role', 'id', array('shortname' => 'manager'), MUST_EXIST); 3036 $roleid2 = $DB->get_field('role', 'id', array('shortname' => 'coursecreator'), MUST_EXIST); 3037 // Enrol two users as managers onto the course, and 1 onto the category. 3038 $generator->enrol_user($user1->id, $course->id, $roleid1); 3039 $generator->enrol_user($user2->id, $course->id, $roleid1); 3040 $generator->role_assign($roleid1, $user3->id, context_coursecat::instance($category->id)); 3041 // Enrol 1 user as a coursecreator onto the course, and another onto the category. 3042 // This is to ensure we do not count users with roles that are not specified. 3043 $generator->enrol_user($user4->id, $course->id, $roleid2); 3044 $generator->role_assign($roleid2, $user5->id, context_coursecat::instance($category->id)); 3045 // Check that the correct users are found on the course. 3046 $this->assertEquals(2, count_role_users($roleid1, context_course::instance($course->id), false)); 3047 $this->assertEquals(3, count_role_users($roleid1, context_course::instance($course->id), true)); 3048 // Check for the category. 3049 $this->assertEquals(1, count_role_users($roleid1, context_coursecat::instance($category->id), false)); 3050 $this->assertEquals(1, count_role_users($roleid1, context_coursecat::instance($category->id), true)); 3051 // Have a user with the same role at both the category and course level. 3052 $generator->role_assign($roleid1, $user1->id, context_coursecat::instance($category->id)); 3053 // The course level checks should remain the same. 3054 $this->assertEquals(2, count_role_users($roleid1, context_course::instance($course->id), false)); 3055 $this->assertEquals(3, count_role_users($roleid1, context_course::instance($course->id), true)); 3056 } 3057 } 3058 3059 /** 3060 * Context caching fixture 3061 */ 3062 class context_inspection extends context_helper { 3063 public static function test_context_cache_size() { 3064 return self::$cache_count; 3065 } 3066 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |