|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 // This file is part of Moodle - http://moodle.org/ 00003 // 00004 // Moodle is free software: you can redistribute it and/or modify 00005 // it under the terms of the GNU General Public License as published by 00006 // the Free Software Foundation, either version 3 of the License, or 00007 // (at your option) any later version. 00008 // 00009 // Moodle is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 00016 00029 defined('MOODLE_INTERNAL') || die(); 00030 00031 00035 class context_inspection extends context_helper { 00036 public static function test_context_cache_size() { 00037 return self::$cache_count; 00038 } 00039 } 00040 00041 00047 class accesslib_test extends UnitTestCaseUsingDatabase { 00048 // NOTE: The UnitTestCaseUsingDatabase is problematic and VERY dangerous especially for production servers! 00049 // 00050 // 1. We could create full install without plugins and use the test DB since the very beginning in lib/setup.php. 00051 // 2. We should not execute the tests from the web UI because the static caches all over the place collide, instead 00052 // we could use CLI 00053 // 3. SimpleTest appears to be dead - unfortunately nobody else thinks we should switch to PHPUnit asap 00054 // 4. switching of USER->id alone is not acceptable at all, we must switch the complete USER record 00055 // and probably deal with _SESSION['USER'] too 00056 // 5. we must close session before messing with anything in $USER or $SESSION 00057 // 6. $SITE is not switched 00058 // 7. tons of other static caches are not reset 00059 // 8. etc. 00060 // 00061 // -- 00062 // skodak 00063 00064 //TODO: add more tests for the remaining accesslib parts that were not touched by the refactoring in 2.2dev 00065 00066 public static $includecoverage = array('lib/accesslib.php'); 00067 00068 protected $accesslibprevuser = null; 00069 protected $accesslibprevsite = null; 00070 00074 public function test_everything_in_accesslib() { 00075 global $USER, $SITE, $CFG, $DB, $ACCESSLIB_PRIVATE; 00076 00077 // First of all finalize the session, we must not carry over any of this mess to the next page via SESSION!!! 00078 session_get_instance()->write_close(); 00079 00080 // hack - this is going to take very long time 00081 set_time_limit(3600); 00082 00083 // Get rid of current user that would not work anyway, 00084 // do NOT even think about using $this->switch_global_user_id()! 00085 if (!isset($this->accesslibprevuser)) { 00086 $this->accesslibprevuser = clone($USER); 00087 $USER = new stdClass(); 00088 $USER->id = 0; 00089 } 00090 00091 // Backup $SITE global 00092 if (!isset($this->accesslibprevsite)) { 00093 $this->accesslibprevsite = $SITE; 00094 } 00095 00096 // Switch DB, if it somehow fails or you specified wrong unittest prefix it will nuke real data, you have been warned! 00097 $this->switch_to_test_db(); 00098 00099 // Let's switch the CFG 00100 $prevcfg = clone($CFG); 00101 $this->switch_to_test_cfg(); 00102 $CFG->config_php_settings = $prevcfg->config_php_settings; 00103 $CFG->noemailever = true; 00104 $CFG->admin = $prevcfg->admin; 00105 $CFG->lang = 'en'; 00106 $CFG->tempdir = $prevcfg->tempdir; 00107 $CFG->cachedir = $prevcfg->cachedir; 00108 $CFG->directorypermissions = $prevcfg->directorypermissions; 00109 $CFG->filepermissions = $prevcfg->filepermissions; 00110 00111 // Reset all caches 00112 accesslib_clear_all_caches_for_unit_testing(); 00113 00114 // Add some core tables - this is known to break constantly because we keep adding dependencies... 00115 $tablenames = array('config', 'config_plugins', 'modules', 'course', 'course_modules', 'course_sections', 'course_categories', 'mnet_host', 'mnet_application', 00116 'capabilities', 'context', 'context_temp', 'role', 'role_capabilities', 'role_allow_switch', 'license', 'my_pages', 'block', 'block_instances', 'block_positions', 00117 'role_allow_assign', 'role_allow_override', 'role_assignments', 'role_context_levels' ,'enrol', 'user_enrolments', 'filter_active', 'filter_config', 'comments', 00118 'user', 'groups_members', 'cache_flags', 'events_handlers', 'user_lastaccess', 'rating', 'files', 'role_names', 'user_preferences', 'grading_areas'); 00119 $this->create_test_tables($tablenames, 'lib'); 00120 00121 // Create all core default records and default settings 00122 require_once("$CFG->libdir/db/install.php"); 00123 xmldb_main_install(); // installs the capabilities too 00124 00125 // Fake mod_page install 00126 $tablenames = array('page'); 00127 $this->create_test_tables($tablenames, 'mod/page'); 00128 $module = new stdClass(); 00129 require($CFG->dirroot .'/mod/page/version.php'); 00130 $module->name = 'page'; 00131 $pagemoduleid = $DB->insert_record('modules', $module); 00132 update_capabilities('mod_page'); 00133 00134 // Fake block_online_users install 00135 $plugin = new stdClass(); 00136 $plugin->version = NULL; 00137 $plugin->cron = 0; 00138 include($CFG->dirroot.'/blocks/online_users/version.php'); 00139 $plugin->name = 'online_users'; 00140 $onlineusersblockid = $DB->insert_record('block', $plugin); 00141 update_capabilities('block_online_users'); 00142 00143 // Finish roles setup 00144 set_config('defaultfrontpageroleid', $DB->get_field('role', 'id', array('archetype'=>'frontpage'))); 00145 set_config('defaultuserroleid', $DB->get_field('role', 'id', array('archetype'=>'user'))); 00146 set_config('notloggedinroleid', $DB->get_field('role', 'id', array('archetype'=>'guest'))); 00147 set_config('rolesactive', 1); 00148 00149 // Init manual enrol 00150 set_config('status', ENROL_INSTANCE_ENABLED, 'enrol_manual'); 00151 set_config('defaultperiod', 0, 'enrol_manual'); 00152 $manualenrol = enrol_get_plugin('manual'); 00153 00154 // Fill the site with some real data 00155 $testcategories = array(); 00156 $testcourses = array(); 00157 $testpages = array(); 00158 $testblocks = array(); 00159 $allroles = $DB->get_records_menu('role', array(), 'id', 'archetype, id'); 00160 00161 $systemcontext = context_system::instance(); 00162 $frontpagecontext = context_course::instance(SITEID); 00163 00164 // Add block to system context 00165 $bi = new stdClass(); 00166 $bi->blockname = 'online_users'; 00167 $bi->parentcontextid = $systemcontext->id; 00168 $bi->showinsubcontexts = 1; 00169 $bi->pagetypepattern = ''; 00170 $bi->subpagepattern = ''; 00171 $bi->defaultregion = ''; 00172 $bi->defaultweight = 0; 00173 $bi->configdata = ''; 00174 $biid = $DB->insert_record('block_instances', $bi); 00175 context_block::instance($biid); 00176 $testblocks[] = $biid; 00177 00178 // Some users 00179 $testusers = array(); 00180 for($i=0; $i<20; $i++) { 00181 $user = new stdClass(); 00182 $user->auth = 'manual'; 00183 $user->firstname = 'user'.$i; 00184 $user->lastname = 'user'.$i; 00185 $user->username = 'user'.$i; 00186 $user->password = 'doesnotexist'; 00187 $user->email = "user$i@example.com"; 00188 $user->confirmed = 1; 00189 $user->mnethostid = $CFG->mnet_localhost_id; 00190 $user->lang = $CFG->lang; 00191 $user->maildisplay = 1; 00192 $user->timemodified = time(); 00193 $user->deleted = 0; 00194 $user->lastip = '0.0.0.0'; 00195 $userid = $DB->insert_record('user', $user); 00196 $testusers[$i] = $userid; 00197 $usercontext = context_user::instance($userid); 00198 00199 // Add block to user profile 00200 $bi->parentcontextid = $usercontext->id; 00201 $biid = $DB->insert_record('block_instances', $bi); 00202 context_block::instance($biid); 00203 $testblocks[] = $biid; 00204 } 00205 // Deleted user - should be ignored everywhere, can not have context 00206 $user = new stdClass(); 00207 $user->auth = 'manual'; 00208 $user->firstname = ''; 00209 $user->lastname = ''; 00210 $user->username = 'user@example.com121132132'; 00211 $user->password = ''; 00212 $user->email = ''; 00213 $user->confirmed = 1; 00214 $user->mnethostid = $CFG->mnet_localhost_id; 00215 $user->lang = $CFG->lang; 00216 $user->maildisplay = 1; 00217 $user->timemodified = time(); 00218 $user->deleted = 1; 00219 $user->lastip = '0.0.0.0'; 00220 $DB->insert_record('user', $user); 00221 unset($user); 00222 00223 // Add block to frontpage 00224 $bi->parentcontextid = $frontpagecontext->id; 00225 $biid = $DB->insert_record('block_instances', $bi); 00226 $frontpageblockcontext = context_block::instance($biid); 00227 $testblocks[] = $biid; 00228 00229 // Add a resource to frontpage 00230 $page = new stdClass(); 00231 $page->course = $SITE->id; 00232 $page->intro = '...'; 00233 $page->introformat = FORMAT_HTML; 00234 $page->content = '...'; 00235 $page->contentformat = FORMAT_HTML; 00236 $pageid = $DB->insert_record('page', $page); 00237 $testpages[] = $pageid; 00238 $cm = new stdClass(); 00239 $cm->course = $SITE->id; 00240 $cm->module = $pagemoduleid; 00241 $cm->section = 1; 00242 $cm->instance = $pageid; 00243 $cmid = $DB->insert_record('course_modules', $cm); 00244 $frontpagepagecontext = context_module::instance($cmid); 00245 00246 // Add block to frontpage resource 00247 $bi->parentcontextid = $frontpagepagecontext->id; 00248 $biid = $DB->insert_record('block_instances', $bi); 00249 $frontpagepageblockcontext = context_block::instance($biid); 00250 $testblocks[] = $biid; 00251 00252 // Some nested course categories with courses 00253 require_once("$CFG->dirroot/course/lib.php"); 00254 $path = ''; 00255 $parentcat = 0; 00256 for($i=0; $i<5; $i++) { 00257 $cat = new stdClass(); 00258 $cat->name = 'category'.$i; 00259 $cat->parent = $parentcat; 00260 $cat->depth = $i+1; 00261 $cat->sortorder = MAX_COURSES_IN_CATEGORY * ($i+2); 00262 $cat->timemodified = time(); 00263 $catid = $DB->insert_record('course_categories', $cat); 00264 $path = $path . '/' . $catid; 00265 $DB->set_field('course_categories', 'path', $path, array('id'=>$catid)); 00266 $parentcat = $catid; 00267 $testcategories[] = $catid; 00268 $catcontext = context_coursecat::instance($catid); 00269 00270 if ($i >=4) { 00271 continue; 00272 } 00273 00274 // Add resource to each category 00275 $bi->parentcontextid = $catcontext->id; 00276 $biid = $DB->insert_record('block_instances', $bi); 00277 context_block::instance($biid); 00278 00279 // Add a few courses to each category 00280 for($j=0; $j<6; $j++) { 00281 $course = new stdClass(); 00282 $course->fullname = 'course'.$j; 00283 $course->shortname = 'c'.$j; 00284 $course->summary = 'bah bah bah'; 00285 $course->newsitems = 0; 00286 $course->numsections = 1; 00287 $course->category = $catid; 00288 $course->format = 'topics'; 00289 $course->timecreated = time(); 00290 $course->visible = 1; 00291 $course->timemodified = $course->timecreated; 00292 $courseid = $DB->insert_record('course', $course); 00293 $section = new stdClass(); 00294 $section->course = $courseid; 00295 $section->section = 0; 00296 $section->summaryformat = FORMAT_HTML; 00297 $DB->insert_record('course_sections', $section); 00298 $section->section = 1; 00299 $DB->insert_record('course_sections', $section); 00300 $testcourses[] = $courseid; 00301 $coursecontext = context_course::instance($courseid); 00302 00303 if ($j >= 5) { 00304 continue; 00305 } 00306 // Add manual enrol instance 00307 $manualenrol->add_default_instance($DB->get_record('course', array('id'=>$courseid))); 00308 00309 // Add block to each course 00310 $bi->parentcontextid = $coursecontext->id; 00311 $biid = $DB->insert_record('block_instances', $bi); 00312 context_block::instance($biid); 00313 $testblocks[] = $biid; 00314 00315 // Add a resource to each course 00316 $page->course = $courseid; 00317 $pageid = $DB->insert_record('page', $page); 00318 $testpages[] = $pageid; 00319 $cm->course = $courseid; 00320 $cm->instance = $pageid; 00321 $cm->id = $DB->insert_record('course_modules', $cm); 00322 $modcontext = context_module::instance($cm->id); 00323 00324 // Add block to each module 00325 $bi->parentcontextid = $modcontext->id; 00326 $biid = $DB->insert_record('block_instances', $bi); 00327 context_block::instance($biid); 00328 $testblocks[] = $biid; 00329 } 00330 } 00331 00332 // Make sure all contexts were created properly 00333 $count = 1; //system 00334 $count += $DB->count_records('user', array('deleted'=>0)); 00335 $count += $DB->count_records('course_categories'); 00336 $count += $DB->count_records('course'); 00337 $count += $DB->count_records('course_modules'); 00338 $count += $DB->count_records('block_instances'); 00339 $this->assertEqual($DB->count_records('context'), $count); 00340 $this->assertEqual($DB->count_records('context', array('depth'=>0)), 0); 00341 $this->assertEqual($DB->count_records('context', array('path'=>NULL)), 0); 00342 00343 00344 // ====== context_helper::get_level_name() ================================ 00345 00346 $levels = context_helper::get_all_levels(); 00347 foreach ($levels as $level=>$classname) { 00348 $name = context_helper::get_level_name($level); 00349 $this->assertFalse(empty($name)); 00350 } 00351 00352 00353 // ======= context::instance_by_id(), context_xxx::instance(); 00354 00355 $context = context::instance_by_id($frontpagecontext->id); 00356 $this->assertidentical($context->contextlevel, CONTEXT_COURSE); 00357 $this->assertFalse(context::instance_by_id(-1, IGNORE_MISSING)); 00358 try { 00359 context::instance_by_id(-1); 00360 $this->fail('exception expected'); 00361 } catch (Exception $e) { 00362 $this->assertTrue(true); 00363 } 00364 $this->assertTrue(context_system::instance() instanceof context_system); 00365 $this->assertTrue(context_coursecat::instance($testcategories[0]) instanceof context_coursecat); 00366 $this->assertTrue(context_course::instance($testcourses[0]) instanceof context_course); 00367 $this->assertTrue(context_module::instance($testpages[0]) instanceof context_module); 00368 $this->assertTrue(context_block::instance($testblocks[0]) instanceof context_block); 00369 00370 $this->assertFalse(context_coursecat::instance(-1, IGNORE_MISSING)); 00371 $this->assertFalse(context_course::instance(-1, IGNORE_MISSING)); 00372 $this->assertFalse(context_module::instance(-1, IGNORE_MISSING)); 00373 $this->assertFalse(context_block::instance(-1, IGNORE_MISSING)); 00374 try { 00375 context_coursecat::instance(-1); 00376 $this->fail('exception expected'); 00377 } catch (Exception $e) { 00378 $this->assertTrue(true); 00379 } 00380 try { 00381 context_course::instance(-1); 00382 $this->fail('exception expected'); 00383 } catch (Exception $e) { 00384 $this->assertTrue(true); 00385 } 00386 try { 00387 context_module::instance(-1); 00388 $this->fail('exception expected'); 00389 } catch (Exception $e) { 00390 $this->assertTrue(true); 00391 } 00392 try { 00393 context_block::instance(-1); 00394 $this->fail('exception expected'); 00395 } catch (Exception $e) { 00396 $this->assertTrue(true); 00397 } 00398 00399 00400 // ======= $context->get_url(), $context->get_context_name(), $context->get_capabilities() ========= 00401 00402 $testcontexts = array(); 00403 $testcontexts[CONTEXT_SYSTEM] = context_system::instance(); 00404 $testcontexts[CONTEXT_COURSECAT] = context_coursecat::instance($testcategories[0]); 00405 $testcontexts[CONTEXT_COURSE] = context_course::instance($testcourses[0]); 00406 $testcontexts[CONTEXT_MODULE] = context_module::instance($testpages[0]); 00407 $testcontexts[CONTEXT_BLOCK] = context_block::instance($testblocks[0]); 00408 00409 foreach ($testcontexts as $context) { 00410 $name = $context->get_context_name(true, true); 00411 $this->assertFalse(empty($name)); 00412 00413 $this->assertTrue($context->get_url() instanceof moodle_url); 00414 00415 $caps = $context->get_capabilities(); 00416 $this->assertTrue(is_array($caps)); 00417 foreach ($caps as $cap) { 00418 $cap = (array)$cap; 00419 $this->assertIdentical(array_keys($cap), array('id', 'name', 'captype', 'contextlevel', 'component', 'riskbitmask')); 00420 } 00421 } 00422 unset($testcontexts); 00423 00424 // ===== $context->get_course_context() ========================================= 00425 00426 $this->assertFalse($systemcontext->get_course_context(false)); 00427 try { 00428 $systemcontext->get_course_context(); 00429 $this->fail('exception expected'); 00430 } catch (Exception $e) { 00431 $this->assertTrue(true); 00432 } 00433 $context = context_coursecat::instance($testcategories[0]); 00434 $this->assertFalse($context->get_course_context(false)); 00435 try { 00436 $context->get_course_context(); 00437 $this->fail('exception expected'); 00438 } catch (Exception $e) { 00439 $this->assertTrue(true); 00440 } 00441 $this->assertIdentical($frontpagecontext->get_course_context(true), $frontpagecontext); 00442 $this->assertIdentical($frontpagepagecontext->get_course_context(true), $frontpagecontext); 00443 $this->assertIdentical($frontpagepageblockcontext->get_course_context(true), $frontpagecontext); 00444 00445 00446 // ======= $context->get_parent_context(), $context->get_parent_contexts(), $context->get_parent_context_ids() ======= 00447 00448 $userid = reset($testusers); 00449 $usercontext = context_user::instance($userid); 00450 $this->assertIdentical($usercontext->get_parent_context(), $systemcontext); 00451 $this->assertIdentical($usercontext->get_parent_contexts(), array($systemcontext->id=>$systemcontext)); 00452 $this->assertIdentical($usercontext->get_parent_contexts(true), array($usercontext->id=>$usercontext, $systemcontext->id=>$systemcontext)); 00453 00454 $this->assertIdentical($systemcontext->get_parent_contexts(), array()); 00455 $this->assertIdentical($systemcontext->get_parent_contexts(true), array($systemcontext->id=>$systemcontext)); 00456 $this->assertIdentical($systemcontext->get_parent_context_ids(), array()); 00457 $this->assertIdentical($systemcontext->get_parent_context_ids(true), array($systemcontext->id)); 00458 00459 $this->assertIdentical($frontpagecontext->get_parent_context(), $systemcontext); 00460 $this->assertIdentical($frontpagecontext->get_parent_contexts(), array($systemcontext->id=>$systemcontext)); 00461 $this->assertIdentical($frontpagecontext->get_parent_contexts(true), array($frontpagecontext->id=>$frontpagecontext, $systemcontext->id=>$systemcontext)); 00462 $this->assertIdentical($frontpagecontext->get_parent_context_ids(), array($systemcontext->id)); 00463 $this->assertEqual($frontpagecontext->get_parent_context_ids(true), array($frontpagecontext->id, $systemcontext->id)); 00464 00465 $this->assertIdentical($systemcontext->get_parent_context(), false); 00466 $frontpagecontext = context_course::instance($SITE->id); 00467 $parent = $systemcontext; 00468 foreach ($testcategories as $catid) { 00469 $catcontext = context_coursecat::instance($catid); 00470 $this->assertIdentical($catcontext->get_parent_context(), $parent); 00471 $parent = $catcontext; 00472 } 00473 $this->assertIdentical($frontpagepagecontext->get_parent_context(), $frontpagecontext); 00474 $this->assertIdentical($frontpageblockcontext->get_parent_context(), $frontpagecontext); 00475 $this->assertIdentical($frontpagepageblockcontext->get_parent_context(), $frontpagepagecontext); 00476 00477 00478 // ====== $context->get_child_contexts() ================================ 00479 00480 $children = $systemcontext->get_child_contexts(); 00481 $this->assertEqual(count($children)+1, $DB->count_records('context')); 00482 00483 $context = context_coursecat::instance($testcategories[3]); 00484 $children = $context->get_child_contexts(); 00485 $countcats = 0; 00486 $countcourses = 0; 00487 $countblocks = 0; 00488 foreach ($children as $child) { 00489 if ($child->contextlevel == CONTEXT_COURSECAT) { 00490 $countcats++; 00491 } 00492 if ($child->contextlevel == CONTEXT_COURSE) { 00493 $countcourses++; 00494 } 00495 if ($child->contextlevel == CONTEXT_BLOCK) { 00496 $countblocks++; 00497 } 00498 } 00499 $this->assertEqual(count($children), 8); 00500 $this->assertEqual($countcats, 1); 00501 $this->assertEqual($countcourses, 6); 00502 $this->assertEqual($countblocks, 1); 00503 00504 $context = context_course::instance($testcourses[2]); 00505 $children = $context->get_child_contexts(); 00506 $this->assertEqual(count($children), 3); 00507 00508 $context = context_module::instance($testpages[3]); 00509 $children = $context->get_child_contexts(); 00510 $this->assertEqual(count($children), 1); 00511 00512 $context = context_block::instance($testblocks[1]); 00513 $children = $context->get_child_contexts(); 00514 $this->assertEqual(count($children), 0); 00515 00516 unset($children); 00517 unset($countcats); 00518 unset($countcourses); 00519 unset($countblocks); 00520 00521 00522 // ======= context_helper::reset_caches() ============================ 00523 00524 context_helper::reset_caches(); 00525 $this->assertEqual(context_inspection::test_context_cache_size(), 0); 00526 context_course::instance($SITE->id); 00527 $this->assertEqual(context_inspection::test_context_cache_size(), 1); 00528 00529 00530 // ======= context preloading ======================================== 00531 00532 context_helper::reset_caches(); 00533 $sql = "SELECT ".context_helper::get_preload_record_columns_sql('c')." 00534 FROM {context} c 00535 WHERE c.contextlevel <> ".CONTEXT_SYSTEM; 00536 $records = $DB->get_records_sql($sql); 00537 $firstrecord = reset($records); 00538 $columns = context_helper::get_preload_record_columns('c'); 00539 $firstrecord = (array)$firstrecord; 00540 $this->assertIdentical(array_keys($firstrecord), array_values($columns)); 00541 context_helper::reset_caches(); 00542 foreach ($records as $record) { 00543 context_helper::preload_from_record($record); 00544 $this->assertIdentical($record, new stdClass()); 00545 } 00546 $this->assertEqual(context_inspection::test_context_cache_size(), count($records)); 00547 unset($records); 00548 unset($columns); 00549 00550 context_helper::reset_caches(); 00551 context_helper::preload_course($SITE->id); 00552 $this->assertEqual(context_inspection::test_context_cache_size(), 4); 00553 00554 // ====== assign_capability(), unassign_capability() ==================== 00555 00556 $rc = $DB->get_record('role_capabilities', array('contextid'=>$frontpagecontext->id, 'roleid'=>$allroles['teacher'], 'capability'=>'moodle/site:accessallgroups')); 00557 $this->assertFalse($rc); 00558 assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $allroles['teacher'], $frontpagecontext->id); 00559 $rc = $DB->get_record('role_capabilities', array('contextid'=>$frontpagecontext->id, 'roleid'=>$allroles['teacher'], 'capability'=>'moodle/site:accessallgroups')); 00560 $this->assertEqual($rc->permission, CAP_ALLOW); 00561 assign_capability('moodle/site:accessallgroups', CAP_PREVENT, $allroles['teacher'], $frontpagecontext->id); 00562 $rc = $DB->get_record('role_capabilities', array('contextid'=>$frontpagecontext->id, 'roleid'=>$allroles['teacher'], 'capability'=>'moodle/site:accessallgroups')); 00563 $this->assertEqual($rc->permission, CAP_ALLOW); 00564 assign_capability('moodle/site:accessallgroups', CAP_PREVENT, $allroles['teacher'], $frontpagecontext, true); 00565 $rc = $DB->get_record('role_capabilities', array('contextid'=>$frontpagecontext->id, 'roleid'=>$allroles['teacher'], 'capability'=>'moodle/site:accessallgroups')); 00566 $this->assertEqual($rc->permission, CAP_PREVENT); 00567 00568 assign_capability('moodle/site:accessallgroups', CAP_INHERIT, $allroles['teacher'], $frontpagecontext); 00569 $rc = $DB->get_record('role_capabilities', array('contextid'=>$frontpagecontext->id, 'roleid'=>$allroles['teacher'], 'capability'=>'moodle/site:accessallgroups')); 00570 $this->assertFalse($rc); 00571 assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $allroles['teacher'], $frontpagecontext); 00572 unassign_capability('moodle/site:accessallgroups', $allroles['teacher'], $frontpagecontext, true); 00573 $rc = $DB->get_record('role_capabilities', array('contextid'=>$frontpagecontext->id, 'roleid'=>$allroles['teacher'], 'capability'=>'moodle/site:accessallgroups')); 00574 $this->assertFalse($rc); 00575 unassign_capability('moodle/site:accessallgroups', $allroles['teacher'], $frontpagecontext->id, true); 00576 unset($rc); 00577 00578 accesslib_clear_all_caches(false); // must be done after assign_capability() 00579 00580 00581 // ======= role_assign(), role_unassign(), role_unassign_all() ============== 00582 00583 $context = context_course::instance($testcourses[1]); 00584 $this->assertEqual($DB->count_records('role_assignments', array('contextid'=>$context->id)), 0); 00585 role_assign($allroles['teacher'], $testusers[1], $context->id); 00586 role_assign($allroles['teacher'], $testusers[2], $context->id); 00587 role_assign($allroles['manager'], $testusers[1], $context->id); 00588 $this->assertEqual($DB->count_records('role_assignments', array('contextid'=>$context->id)), 3); 00589 role_unassign($allroles['teacher'], $testusers[1], $context->id); 00590 $this->assertEqual($DB->count_records('role_assignments', array('contextid'=>$context->id)), 2); 00591 role_unassign_all(array('contextid'=>$context->id)); 00592 $this->assertEqual($DB->count_records('role_assignments', array('contextid'=>$context->id)), 0); 00593 unset($context); 00594 00595 accesslib_clear_all_caches(false); // just in case 00596 00597 00598 // ====== has_capability(), get_users_by_capability(), role_switch(), reload_all_capabilities() and friends ======================== 00599 00600 $adminid = get_admin()->id; 00601 $guestid = $CFG->siteguest; 00602 00603 // Enrol some users into some courses 00604 $course1 = $DB->get_record('course', array('id'=>$testcourses[22]), '*', MUST_EXIST); 00605 $course2 = $DB->get_record('course', array('id'=>$testcourses[7]), '*', MUST_EXIST); 00606 $cms = $DB->get_records('course_modules', array('course'=>$course1->id), 'id'); 00607 $cm1 = reset($cms); 00608 $blocks = $DB->get_records('block_instances', array('parentcontextid'=>context_module::instance($cm1->id)->id), 'id'); 00609 $block1 = reset($blocks); 00610 $instance1 = $DB->get_record('enrol', array('enrol'=>'manual', 'courseid'=>$course1->id)); 00611 $instance2 = $DB->get_record('enrol', array('enrol'=>'manual', 'courseid'=>$course2->id)); 00612 for($i=0; $i<9; $i++) { 00613 $manualenrol->enrol_user($instance1, $testusers[$i], $allroles['student']); 00614 } 00615 $manualenrol->enrol_user($instance1, $testusers[8], $allroles['teacher']); 00616 $manualenrol->enrol_user($instance1, $testusers[9], $allroles['editingteacher']); 00617 00618 for($i=10; $i<15; $i++) { 00619 $manualenrol->enrol_user($instance2, $testusers[$i], $allroles['student']); 00620 } 00621 $manualenrol->enrol_user($instance2, $testusers[15], $allroles['editingteacher']); 00622 00623 // Add tons of role assignments - the more the better 00624 role_assign($allroles['coursecreator'], $testusers[11], context_coursecat::instance($testcategories[2])); 00625 role_assign($allroles['manager'], $testusers[12], context_coursecat::instance($testcategories[1])); 00626 role_assign($allroles['student'], $testusers[9], context_module::instance($cm1->id)); 00627 role_assign($allroles['teacher'], $testusers[8], context_module::instance($cm1->id)); 00628 role_assign($allroles['guest'], $testusers[13], context_course::instance($course1->id)); 00629 role_assign($allroles['teacher'], $testusers[7], context_block::instance($block1->id)); 00630 role_assign($allroles['manager'], $testusers[9], context_block::instance($block1->id)); 00631 role_assign($allroles['editingteacher'], $testusers[9], context_course::instance($course1->id)); 00632 00633 role_assign($allroles['teacher'], $adminid, context_course::instance($course1->id)); 00634 role_assign($allroles['editingteacher'], $adminid, context_block::instance($block1->id)); 00635 00636 // Add tons of overrides - the more the better 00637 assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $CFG->defaultuserroleid, $frontpageblockcontext, true); 00638 assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $CFG->defaultfrontpageroleid, $frontpageblockcontext, true); 00639 assign_capability('moodle/block:view', CAP_PROHIBIT, $allroles['guest'], $frontpageblockcontext, true); 00640 assign_capability('block/online_users:viewlist', CAP_PREVENT, $allroles['user'], $frontpageblockcontext, true); 00641 assign_capability('block/online_users:viewlist', CAP_PREVENT, $allroles['student'], $frontpageblockcontext, true); 00642 00643 assign_capability('moodle/site:accessallgroups', CAP_PREVENT, $CFG->defaultuserroleid, $frontpagepagecontext, true); 00644 assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $CFG->defaultfrontpageroleid, $frontpagepagecontext, true); 00645 assign_capability('mod/page:view', CAP_PREVENT, $allroles['guest'], $frontpagepagecontext, true); 00646 assign_capability('mod/page:view', CAP_ALLOW, $allroles['user'], $frontpagepagecontext, true); 00647 assign_capability('moodle/page:view', CAP_ALLOW, $allroles['student'], $frontpagepagecontext, true); 00648 00649 assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $CFG->defaultuserroleid, $frontpagecontext, true); 00650 assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $CFG->defaultfrontpageroleid, $frontpagecontext, true); 00651 assign_capability('mod/page:view', CAP_ALLOW, $allroles['guest'], $frontpagecontext, true); 00652 assign_capability('mod/page:view', CAP_PROHIBIT, $allroles['user'], $frontpagecontext, true); 00653 00654 assign_capability('mod/page:view', CAP_PREVENT, $allroles['guest'], $systemcontext, true); 00655 00656 accesslib_clear_all_caches(false); // must be done after assign_capability() 00657 00658 // Extra tests for guests and not-logged-in users because they can not be verified by cross checking 00659 // with get_users_by_capability() where they are ignored 00660 $this->assertFalse(has_capability('moodle/block:view', $frontpageblockcontext, $guestid)); 00661 $this->assertFalse(has_capability('mod/page:view', $frontpagepagecontext, $guestid)); 00662 $this->assertTrue(has_capability('mod/page:view', $frontpagecontext, $guestid)); 00663 $this->assertFalse(has_capability('mod/page:view', $systemcontext, $guestid)); 00664 00665 $this->assertFalse(has_capability('moodle/block:view', $frontpageblockcontext, 0)); 00666 $this->assertFalse(has_capability('mod/page:view', $frontpagepagecontext, 0)); 00667 $this->assertTrue(has_capability('mod/page:view', $frontpagecontext, 0)); 00668 $this->assertFalse(has_capability('mod/page:view', $systemcontext, 0)); 00669 00670 $this->assertFalse(has_capability('moodle/course:create', $systemcontext, $testusers[11])); 00671 $this->assertTrue(has_capability('moodle/course:create', context_coursecat::instance($testcategories[2]), $testusers[11])); 00672 $this->assertFalse(has_capability('moodle/course:create', context_course::instance($testcourses[1]), $testusers[11])); 00673 $this->assertTrue(has_capability('moodle/course:create', context_course::instance($testcourses[19]), $testusers[11])); 00674 00675 $this->assertFalse(has_capability('moodle/course:update', context_course::instance($testcourses[1]), $testusers[9])); 00676 $this->assertFalse(has_capability('moodle/course:update', context_course::instance($testcourses[19]), $testusers[9])); 00677 $this->assertFalse(has_capability('moodle/course:update', $systemcontext, $testusers[9])); 00678 00679 // Test the list of enrolled users 00680 $coursecontext = context_course::instance($course1->id); 00681 $enrolled = get_enrolled_users($coursecontext); 00682 $this->assertEqual(count($enrolled), 10); 00683 for($i=0; $i<10; $i++) { 00684 $this->assertTrue(isset($enrolled[$testusers[$i]])); 00685 } 00686 $enrolled = get_enrolled_users($coursecontext, 'moodle/course:update'); 00687 $this->assertEqual(count($enrolled), 1); 00688 $this->assertTrue(isset($enrolled[$testusers[9]])); 00689 unset($enrolled); 00690 00691 // role switching 00692 $userid = $testusers[9]; 00693 $USER = $DB->get_record('user', array('id'=>$userid)); 00694 load_all_capabilities(); 00695 $coursecontext = context_course::instance($course1->id); 00696 $this->assertTrue(has_capability('moodle/course:update', $coursecontext)); 00697 $this->assertFalse(is_role_switched($course1->id)); 00698 role_switch($allroles['student'], $coursecontext); 00699 $this->assertTrue(is_role_switched($course1->id)); 00700 $this->assertEqual($USER->access['rsw'][$coursecontext->path], $allroles['student']); 00701 $this->assertFalse(has_capability('moodle/course:update', $coursecontext)); 00702 reload_all_capabilities(); 00703 $this->assertFalse(has_capability('moodle/course:update', $coursecontext)); 00704 role_switch(0, $coursecontext); 00705 $this->assertTrue(has_capability('moodle/course:update', $coursecontext)); 00706 $userid = $adminid; 00707 $USER = $DB->get_record('user', array('id'=>$userid)); 00708 load_all_capabilities(); 00709 $coursecontext = context_course::instance($course1->id); 00710 $blockcontext = context_block::instance($block1->id); 00711 $this->assertTrue(has_capability('moodle/course:update', $blockcontext)); 00712 role_switch($allroles['student'], $coursecontext); 00713 $this->assertEqual($USER->access['rsw'][$coursecontext->path], $allroles['student']); 00714 $this->assertFalse(has_capability('moodle/course:update', $blockcontext)); 00715 reload_all_capabilities(); 00716 $this->assertFalse(has_capability('moodle/course:update', $blockcontext)); 00717 load_all_capabilities(); 00718 $this->assertTrue(has_capability('moodle/course:update', $blockcontext)); 00719 00720 // temp course role for enrol 00721 $DB->delete_records('cache_flags', array()); // this prevents problem with dirty contexts immediately resetting the temp role - this is a known problem... 00722 $userid = $testusers[5]; 00723 $roleid = $allroles['editingteacher']; 00724 $USER = $DB->get_record('user', array('id'=>$userid)); 00725 load_all_capabilities(); 00726 $coursecontext = context_course::instance($course1->id); 00727 $this->assertFalse(has_capability('moodle/course:update', $coursecontext)); 00728 $this->assertFalse(isset($USER->access['ra'][$coursecontext->path][$roleid])); 00729 load_temp_course_role($coursecontext, $roleid); 00730 $this->assertEqual($USER->access['ra'][$coursecontext->path][$roleid], $roleid); 00731 $this->assertTrue(has_capability('moodle/course:update', $coursecontext)); 00732 remove_temp_course_roles($coursecontext); 00733 $this->assertFalse(has_capability('moodle/course:update', $coursecontext, $userid)); 00734 load_temp_course_role($coursecontext, $roleid); 00735 reload_all_capabilities(); 00736 $this->assertFalse(has_capability('moodle/course:update', $coursecontext, $userid)); 00737 $USER = new stdClass(); 00738 $USER->id = 0; 00739 00740 // Now cross check has_capability() with get_users_by_capability(), each using different code paths, 00741 // they have to be kept in sync, usually only one of them breaks, so we know when something is wrong, 00742 // at the same time validate extra restrictions (guest read only no risks, admin exception, non existent and deleted users) 00743 $contexts = $DB->get_records('context', array(), 'id'); 00744 $contexts = array_values($contexts); 00745 $capabilities = $DB->get_records('capabilities', array(), 'id'); 00746 $capabilities = array_values($capabilities); 00747 $roles = array($allroles['guest'], $allroles['user'], $allroles['teacher'], $allroles['editingteacher'], $allroles['coursecreator'], $allroles['manager']); 00748 00749 // Random time! 00750 srand(666); 00751 foreach($testusers as $userid) { // no guest or deleted 00752 // each user gets 0-20 random roles 00753 $rcount = rand(0, 10); 00754 for($j=0; $j<$rcount; $j++) { 00755 $roleid = $roles[rand(0, count($roles)-1)]; 00756 $contextid = $contexts[rand(0, count($contexts)-1)]->id; 00757 role_assign($roleid, $userid, $contextid); 00758 } 00759 } 00760 $permissions = array(CAP_ALLOW, CAP_PREVENT, CAP_INHERIT, CAP_PREVENT); 00761 for($j=0; $j<10000; $j++) { 00762 $roleid = $roles[rand(0, count($roles)-1)]; 00763 $contextid = $contexts[rand(0, count($contexts)-1)]->id; 00764 $permission = $permissions[rand(0,count($permissions)-1)]; 00765 $capname = $capabilities[rand(0, count($capabilities)-1)]->name; 00766 assign_capability($capname, $permission, $roleid, $contextid, true); 00767 } 00768 unset($permissions); 00769 unset($roles); 00770 unset($contexts); 00771 unset($users); 00772 unset($capabilities); 00773 00774 accesslib_clear_all_caches(false); // must be done after assign_capability() 00775 00776 // Test time - let's set up some real user, just in case the logic for USER affects the others... 00777 $USER = $DB->get_record('user', array('id'=>$testusers[3])); 00778 load_all_capabilities(); 00779 00780 $contexts = $DB->get_records('context', array(), 'id'); 00781 $users = $DB->get_records('user', array(), 'id', 'id'); 00782 $capabilities = $DB->get_records('capabilities', array(), 'id'); 00783 $users[0] = null; // not-logged-in user 00784 $users[-1] = null; // non-existent user 00785 00786 foreach ($contexts as $crecord) { 00787 $context = context::instance_by_id($crecord->id); 00788 if ($coursecontext = $context->get_course_context(false)) { 00789 $enrolled = get_enrolled_users($context); 00790 } else { 00791 $enrolled = array(); 00792 } 00793 foreach ($capabilities as $cap) { 00794 $allowed = get_users_by_capability($context, $cap->name, 'u.id, u.username'); 00795 if ($enrolled) { 00796 $enrolledwithcap = get_enrolled_users($context, $cap->name); 00797 } else { 00798 $enrolledwithcap = array(); 00799 } 00800 foreach ($users as $userid=>$unused) { 00801 if ($userid == 0 or isguestuser($userid)) { 00802 if ($userid == 0) { 00803 $CFG->forcelogin = true; 00804 $this->assertFalse(has_capability($cap->name, $context, $userid)); 00805 unset($CFG->forcelogin); 00806 } 00807 if (($cap->captype === 'write') or ($cap->riskbitmask & (RISK_XSS | RISK_CONFIG | RISK_DATALOSS))) { 00808 $this->assertFalse(has_capability($cap->name, $context, $userid)); 00809 } 00810 $this->assertFalse(isset($allowed[$userid])); 00811 } else { 00812 if (is_siteadmin($userid)) { 00813 $this->assertTrue(has_capability($cap->name, $context, $userid, true)); 00814 } 00815 $hascap = has_capability($cap->name, $context, $userid, false); 00816 $this->assertIdentical($hascap, isset($allowed[$userid]), "Capability result mismatch user:$userid, context:$context->id, $cap->name, hascap: ".(int)$hascap." "); 00817 if (isset($enrolled[$userid])) { 00818 $this->assertIdentical(isset($allowed[$userid]), isset($enrolledwithcap[$userid]), "Enrolment with capability result mismatch user:$userid, context:$context->id, $cap->name, hascap: ".(int)$hascap." "); 00819 } 00820 } 00821 } 00822 } 00823 } 00824 // Back to nobody 00825 $USER = new stdClass(); 00826 $USER->id = 0; 00827 unset($contexts); 00828 unset($users); 00829 unset($capabilities); 00830 00831 // Now let's do all the remaining tests that break our carefully prepared fake site 00832 00833 00834 00835 // ======= $context->mark_dirty() ======================================= 00836 00837 $DB->delete_records('cache_flags', array()); 00838 accesslib_clear_all_caches(false); 00839 $systemcontext->mark_dirty(); 00840 $dirty = get_cache_flags('accesslib/dirtycontexts', time()-2); 00841 $this->assertTrue(isset($dirty[$systemcontext->path])); 00842 $this->assertTrue(isset($ACCESSLIB_PRIVATE->dirtycontexts[$systemcontext->path])); 00843 00844 00845 // ======= $context->reload_if_dirty(); ================================= 00846 00847 $DB->delete_records('cache_flags', array()); 00848 accesslib_clear_all_caches(false); 00849 load_all_capabilities(); 00850 $context = context_course::instance($testcourses[2]); 00851 $page = $DB->get_record('page', array('course'=>$testcourses[2])); 00852 $pagecontext = context_module::instance($page->id); 00853 00854 $context->mark_dirty(); 00855 $this->assertTrue(isset($ACCESSLIB_PRIVATE->dirtycontexts[$context->path])); 00856 $USER->access['test'] = true; 00857 $context->reload_if_dirty(); 00858 $this->assertFalse(isset($USER->access['test'])); 00859 00860 $context->mark_dirty(); 00861 $this->assertTrue(isset($ACCESSLIB_PRIVATE->dirtycontexts[$context->path])); 00862 $USER->access['test'] = true; 00863 $pagecontext->reload_if_dirty(); 00864 $this->assertFalse(isset($USER->access['test'])); 00865 00866 00867 // ======= context_helper::build_all_paths() ============================ 00868 00869 $oldcontexts = $DB->get_records('context', array(), 'id'); 00870 $DB->set_field_select('context', 'path', NULL, "contextlevel <> ".CONTEXT_SYSTEM); 00871 $DB->set_field_select('context', 'depth', 0, "contextlevel <> ".CONTEXT_SYSTEM); 00872 context_helper::build_all_paths(); 00873 $newcontexts = $DB->get_records('context', array(), 'id'); 00874 $this->assertIdentical($oldcontexts, $newcontexts); 00875 unset($oldcontexts); 00876 unset($newcontexts); 00877 00878 00879 // ======= $context->reset_paths() ====================================== 00880 00881 $context = context_course::instance($testcourses[2]); 00882 $children = $context->get_child_contexts(); 00883 $context->reset_paths(false); 00884 $this->assertIdentical($DB->get_field('context', 'path', array('id'=>$context->id)), NULL); 00885 $this->assertEqual($DB->get_field('context', 'depth', array('id'=>$context->id)), 0); 00886 foreach ($children as $child) { 00887 $this->assertIdentical($DB->get_field('context', 'path', array('id'=>$child->id)), NULL); 00888 $this->assertEqual($DB->get_field('context', 'depth', array('id'=>$child->id)), 0); 00889 } 00890 $this->assertEqual(count($children)+1, $DB->count_records('context', array('depth'=>0))); 00891 $this->assertEqual(count($children)+1, $DB->count_records('context', array('path'=>NULL))); 00892 00893 $context = context_course::instance($testcourses[2]); 00894 $context->reset_paths(true); 00895 $context = context_course::instance($testcourses[2]); 00896 $this->assertEqual($DB->get_field('context', 'path', array('id'=>$context->id)), $context->path); 00897 $this->assertEqual($DB->get_field('context', 'depth', array('id'=>$context->id)), $context->depth); 00898 $this->assertEqual(0, $DB->count_records('context', array('depth'=>0))); 00899 $this->assertEqual(0, $DB->count_records('context', array('path'=>NULL))); 00900 00901 00902 // ====== $context->update_moved(); ====================================== 00903 00904 accesslib_clear_all_caches(false); 00905 $DB->delete_records('cache_flags', array()); 00906 $course = $DB->get_record('course', array('id'=>$testcourses[0])); 00907 $context = context_course::instance($course->id); 00908 $oldpath = $context->path; 00909 $miscid = $DB->get_field_sql("SELECT MIN(id) FROM {course_categories}"); 00910 $categorycontext = context_coursecat::instance($miscid); 00911 $course->category = $miscid; 00912 $DB->update_record('course', $course); 00913 $context->update_moved($categorycontext); 00914 00915 $context = context_course::instance($course->id); 00916 $this->assertIdentical($context->get_parent_context(), $categorycontext); 00917 $dirty = get_cache_flags('accesslib/dirtycontexts', time()-2); 00918 $this->assertTrue(isset($dirty[$oldpath])); 00919 $this->assertTrue(isset($dirty[$context->path])); 00920 00921 00922 // ====== $context->delete_content() ===================================== 00923 00924 context_helper::reset_caches(); 00925 $context = context_module::instance($testpages[3]); 00926 $this->assertTrue($DB->record_exists('context', array('id'=>$context->id))); 00927 $this->assertEqual(1, $DB->count_records('block_instances', array('parentcontextid'=>$context->id))); 00928 $context->delete_content(); 00929 $this->assertTrue($DB->record_exists('context', array('id'=>$context->id))); 00930 $this->assertEqual(0, $DB->count_records('block_instances', array('parentcontextid'=>$context->id))); 00931 00932 00933 // ====== $context->delete() ============================= 00934 00935 context_helper::reset_caches(); 00936 $context = context_module::instance($testpages[4]); 00937 $this->assertTrue($DB->record_exists('context', array('id'=>$context->id))); 00938 $this->assertEqual(1, $DB->count_records('block_instances', array('parentcontextid'=>$context->id))); 00939 $bi = $DB->get_record('block_instances', array('parentcontextid'=>$context->id)); 00940 $bicontext = context_block::instance($bi->id); 00941 $DB->delete_records('cache_flags', array()); 00942 $context->delete(); // should delete also linked blocks 00943 $dirty = get_cache_flags('accesslib/dirtycontexts', time()-2); 00944 $this->assertTrue(isset($dirty[$context->path])); 00945 $this->assertFalse($DB->record_exists('context', array('id'=>$context->id))); 00946 $this->assertFalse($DB->record_exists('context', array('id'=>$bicontext->id))); 00947 $this->assertFalse($DB->record_exists('context', array('contextlevel'=>CONTEXT_MODULE, 'instanceid'=>$testpages[4]))); 00948 $this->assertFalse($DB->record_exists('context', array('contextlevel'=>CONTEXT_BLOCK, 'instanceid'=>$bi->id))); 00949 $this->assertEqual(0, $DB->count_records('block_instances', array('parentcontextid'=>$context->id))); 00950 context_module::instance($testpages[4]); 00951 00952 00953 // ====== context_helper::delete_instance() ============================= 00954 00955 context_helper::reset_caches(); 00956 $lastcourse = array_pop($testcourses); 00957 $this->assertTrue($DB->record_exists('context', array('contextlevel'=>CONTEXT_COURSE, 'instanceid'=>$lastcourse))); 00958 $coursecontext = context_course::instance($lastcourse); 00959 $this->assertEqual(context_inspection::test_context_cache_size(), 1); 00960 $this->assertFalse($coursecontext->instanceid == CONTEXT_COURSE); 00961 $DB->delete_records('cache_flags', array()); 00962 context_helper::delete_instance(CONTEXT_COURSE, $lastcourse); 00963 $dirty = get_cache_flags('accesslib/dirtycontexts', time()-2); 00964 $this->assertTrue(isset($dirty[$coursecontext->path])); 00965 $this->assertEqual(context_inspection::test_context_cache_size(), 0); 00966 $this->assertFalse($DB->record_exists('context', array('contextlevel'=>CONTEXT_COURSE, 'instanceid'=>$lastcourse))); 00967 context_course::instance($lastcourse); 00968 00969 00970 // ======= context_helper::create_instances() ========================== 00971 00972 $prevcount = $DB->count_records('context'); 00973 $DB->delete_records('context', array('contextlevel'=>CONTEXT_BLOCK)); 00974 context_helper::create_instances(null, true); 00975 $this->assertIdentical($DB->count_records('context'), $prevcount); 00976 $this->assertEqual($DB->count_records('context', array('depth'=>0)), 0); 00977 $this->assertEqual($DB->count_records('context', array('path'=>NULL)), 0); 00978 00979 $DB->delete_records('context', array('contextlevel'=>CONTEXT_BLOCK)); 00980 $DB->delete_records('block_instances', array()); 00981 $prevcount = $DB->count_records('context'); 00982 $DB->delete_records_select('context', 'contextlevel <> '.CONTEXT_SYSTEM); 00983 context_helper::create_instances(null, true); 00984 $this->assertIdentical($DB->count_records('context'), $prevcount); 00985 $this->assertEqual($DB->count_records('context', array('depth'=>0)), 0); 00986 $this->assertEqual($DB->count_records('context', array('path'=>NULL)), 0); 00987 00988 00989 // ======= context_helper::cleanup_instances() ========================== 00990 00991 $lastcourse = $DB->get_field_sql("SELECT MAX(id) FROM {course}"); 00992 $DB->delete_records('course', array('id'=>$lastcourse)); 00993 $lastcategory = $DB->get_field_sql("SELECT MAX(id) FROM {course_categories}"); 00994 $DB->delete_records('course_categories', array('id'=>$lastcategory)); 00995 $lastuser = $DB->get_field_sql("SELECT MAX(id) FROM {user} WHERE deleted=0"); 00996 $DB->delete_records('user', array('id'=>$lastuser)); 00997 $DB->delete_records('block_instances', array('parentcontextid'=>$frontpagepagecontext->id)); 00998 $DB->delete_records('course_modules', array('id'=>$frontpagepagecontext->instanceid)); 00999 context_helper::cleanup_instances(); 01000 $count = 1; //system 01001 $count += $DB->count_records('user', array('deleted'=>0)); 01002 $count += $DB->count_records('course_categories'); 01003 $count += $DB->count_records('course'); 01004 $count += $DB->count_records('course_modules'); 01005 $count += $DB->count_records('block_instances'); 01006 $this->assertEqual($DB->count_records('context'), $count); 01007 01008 01009 // ======= context cache size restrictions ============================== 01010 01011 $testusers= array(); 01012 for ($i=0; $i<CONTEXT_CACHE_MAX_SIZE + 100; $i++) { 01013 $user = new stdClass(); 01014 $user->auth = 'manual'; 01015 $user->firstname = 'xuser'.$i; 01016 $user->lastname = 'xuser'.$i; 01017 $user->username = 'xuser'.$i; 01018 $user->password = 'doesnotexist'; 01019 $user->email = "xuser$i@example.com"; 01020 $user->confirmed = 1; 01021 $user->mnethostid = $CFG->mnet_localhost_id; 01022 $user->lang = $CFG->lang; 01023 $user->maildisplay = 1; 01024 $user->timemodified = time(); 01025 $user->lastip = '0.0.0.0'; 01026 $userid = $DB->insert_record('user', $user); 01027 $testusers[$i] = $userid; 01028 } 01029 context_helper::create_instances(null, true); 01030 context_helper::reset_caches(); 01031 for ($i=0; $i<CONTEXT_CACHE_MAX_SIZE + 100; $i++) { 01032 context_user::instance($testusers[$i]); 01033 if ($i == CONTEXT_CACHE_MAX_SIZE - 1) { 01034 $this->assertEqual(context_inspection::test_context_cache_size(), CONTEXT_CACHE_MAX_SIZE); 01035 } else if ($i == CONTEXT_CACHE_MAX_SIZE) { 01036 // once the limit is reached roughly 1/3 of records should be removed from cache 01037 $this->assertEqual(context_inspection::test_context_cache_size(), (int)(CONTEXT_CACHE_MAX_SIZE * (2/3) +102)); 01038 } 01039 } 01040 // We keep the first 100 cached 01041 $prevsize = context_inspection::test_context_cache_size(); 01042 for ($i=0; $i<100; $i++) { 01043 context_user::instance($testusers[$i]); 01044 $this->assertEqual(context_inspection::test_context_cache_size(), $prevsize); 01045 } 01046 context_user::instance($testusers[102]); 01047 $this->assertEqual(context_inspection::test_context_cache_size(), $prevsize+1); 01048 unset($testusers); 01049 01050 01051 01052 // ================================================================= 01053 // ======= basic test of legacy functions ========================== 01054 // ================================================================= 01055 // note: watch out, the fake site might be pretty borked already 01056 01057 $this->assertIdentical(get_system_context(), context_system::instance()); 01058 01059 foreach ($DB->get_records('context') as $contextid=>$record) { 01060 $context = context::instance_by_id($contextid); 01061 $this->assertIdentical(get_context_instance_by_id($contextid), $context); 01062 $this->assertIdentical(get_context_instance($record->contextlevel, $record->instanceid), $context); 01063 $this->assertIdentical(get_parent_contexts($context), $context->get_parent_context_ids()); 01064 if ($context->id == SYSCONTEXTID) { 01065 $this->assertIdentical(get_parent_contextid($context), false); 01066 } else { 01067 $this->assertIdentical(get_parent_contextid($context), $context->get_parent_context()->id); 01068 } 01069 } 01070 01071 $children = get_child_contexts($systemcontext); 01072 $this->assertEqual(count($children), $DB->count_records('context')-1); 01073 unset($children); 01074 01075 $DB->delete_records('context', array('contextlevel'=>CONTEXT_BLOCK)); 01076 create_contexts(); 01077 $this->assertFalse($DB->record_exists('context', array('contextlevel'=>CONTEXT_BLOCK))); 01078 01079 $DB->set_field('context', 'depth', 0, array('contextlevel'=>CONTEXT_BLOCK)); 01080 build_context_path(); 01081 $this->assertFalse($DB->record_exists('context', array('depth'=>0))); 01082 01083 $lastcourse = $DB->get_field_sql("SELECT MAX(id) FROM {course}"); 01084 $DB->delete_records('course', array('id'=>$lastcourse)); 01085 $lastcategory = $DB->get_field_sql("SELECT MAX(id) FROM {course_categories}"); 01086 $DB->delete_records('course_categories', array('id'=>$lastcategory)); 01087 $lastuser = $DB->get_field_sql("SELECT MAX(id) FROM {user} WHERE deleted=0"); 01088 $DB->delete_records('user', array('id'=>$lastuser)); 01089 $DB->delete_records('block_instances', array('parentcontextid'=>$frontpagepagecontext->id)); 01090 $DB->delete_records('course_modules', array('id'=>$frontpagepagecontext->instanceid)); 01091 cleanup_contexts(); 01092 $count = 1; //system 01093 $count += $DB->count_records('user', array('deleted'=>0)); 01094 $count += $DB->count_records('course_categories'); 01095 $count += $DB->count_records('course'); 01096 $count += $DB->count_records('course_modules'); 01097 $count += $DB->count_records('block_instances'); 01098 $this->assertEqual($DB->count_records('context'), $count); 01099 01100 context_helper::reset_caches(); 01101 preload_course_contexts($SITE->id); 01102 $this->assertEqual(context_inspection::test_context_cache_size(), 1); 01103 01104 context_helper::reset_caches(); 01105 list($select, $join) = context_instance_preload_sql('c.id', CONTEXT_COURSECAT, 'ctx'); 01106 $sql = "SELECT c.id $select FROM {course_categories} c $join"; 01107 $records = $DB->get_records_sql($sql); 01108 foreach ($records as $record) { 01109 context_instance_preload($record); 01110 $record = (array)$record; 01111 $this->assertEqual(1, count($record)); // only id left 01112 } 01113 $this->assertEqual(count($records), context_inspection::test_context_cache_size()); 01114 01115 accesslib_clear_all_caches(true); 01116 $DB->delete_records('cache_flags', array()); 01117 mark_context_dirty($systemcontext->path); 01118 $dirty = get_cache_flags('accesslib/dirtycontexts', time()-2); 01119 $this->assertTrue(isset($dirty[$systemcontext->path])); 01120 01121 accesslib_clear_all_caches(false); 01122 $DB->delete_records('cache_flags', array()); 01123 $course = $DB->get_record('course', array('id'=>$testcourses[2])); 01124 $context = get_context_instance(CONTEXT_COURSE, $course->id); 01125 $oldpath = $context->path; 01126 $miscid = $DB->get_field_sql("SELECT MIN(id) FROM {course_categories}"); 01127 $categorycontext = context_coursecat::instance($miscid); 01128 $course->category = $miscid; 01129 $DB->update_record('course', $course); 01130 context_moved($context, $categorycontext); 01131 $context = get_context_instance(CONTEXT_COURSE, $course->id); 01132 $this->assertIdentical($context->get_parent_context(), $categorycontext); 01133 01134 $this->assertTrue($DB->record_exists('context', array('contextlevel'=>CONTEXT_COURSE, 'instanceid'=>$testcourses[2]))); 01135 delete_context(CONTEXT_COURSE, $testcourses[2]); 01136 $this->assertFalse($DB->record_exists('context', array('contextlevel'=>CONTEXT_COURSE, 'instanceid'=>$testcourses[2]))); 01137 01138 $name = get_contextlevel_name(CONTEXT_COURSE); 01139 $this->assertFalse(empty($name)); 01140 01141 $context = get_context_instance(CONTEXT_COURSE, $testcourses[2]); 01142 $name = print_context_name($context); 01143 $this->assertFalse(empty($name)); 01144 01145 $url = get_context_url($coursecontext); 01146 $this->assertFalse($url instanceof modole_url); 01147 01148 $page = $DB->get_record('page', array('id'=>$testpages[7])); 01149 $context = get_context_instance(CONTEXT_MODULE, $page->id); 01150 $coursecontext = get_course_context($context); 01151 $this->assertEqual($coursecontext->contextlevel, CONTEXT_COURSE); 01152 $this->assertEqual(get_courseid_from_context($context), $page->course); 01153 01154 $caps = fetch_context_capabilities($systemcontext); 01155 $this->assertTrue(is_array($caps)); 01156 unset($caps); 01157 } 01158 01159 public function tearDown() { 01160 global $USER, $SITE; 01161 if (isset($this->accesslibprevuser)) { 01162 $USER = $this->accesslibprevuser; 01163 } 01164 if (isset($this->accesslibprevsite)) { 01165 $SITE = $this->accesslibprevsite; 01166 } 01167 01168 01169 parent::tearDown(); 01170 } 01171 } 01172