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