Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/lib/simpletest/fulltestaccesslib.php
Go to the documentation of this file.
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 
 All Data Structures Namespaces Files Functions Variables Enumerations