[ Index ]

PHP Cross Reference of moodle-2.8

title

Body

[close]

/lib/tests/ -> modinfolib_test.php (source)

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * Unit tests for lib/modinfolib.php.
  19   *
  20   * @package    core
  21   * @category   phpunit
  22   * @copyright  2012 Andrew Davis
  23   */
  24  
  25  defined('MOODLE_INTERNAL') || die();
  26  
  27  global $CFG;
  28  require_once($CFG->libdir . '/modinfolib.php');
  29  require_once($CFG->libdir . '/conditionlib.php');
  30  
  31  /**
  32   * Unit tests for modinfolib.php
  33   *
  34   * @copyright 2012 Andrew Davis
  35   * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  36   */
  37  class core_modinfolib_testcase extends advanced_testcase {
  38      public function test_section_info_properties() {
  39          global $DB, $CFG;
  40  
  41          $this->resetAfterTest();
  42          $oldcfgenableavailability = $CFG->enableavailability;
  43          $oldcfgenablecompletion = $CFG->enablecompletion;
  44          set_config('enableavailability', 1);
  45          set_config('enablecompletion', 1);
  46          $this->setAdminUser();
  47  
  48          // Generate the course and pre-requisite module.
  49          $course = $this->getDataGenerator()->create_course(
  50                  array('format' => 'topics',
  51                      'numsections' => 3,
  52                      'enablecompletion' => 1,
  53                      'groupmode' => SEPARATEGROUPS,
  54                      'forcegroupmode' => 0),
  55                  array('createsections' => true));
  56          $coursecontext = context_course::instance($course->id);
  57          $prereqforum = $this->getDataGenerator()->create_module('forum',
  58                  array('course' => $course->id),
  59                  array('completion' => 1));
  60  
  61          // Add availability conditions.
  62          $availability = '{"op":"&","showc":[true,true,true],"c":[' .
  63                  '{"type":"completion","cm":' . $prereqforum->cmid . ',"e":"' .
  64                      COMPLETION_COMPLETE . '"},' .
  65                  '{"type":"grade","id":666,"min":0.4},' .
  66                  '{"type":"profile","op":"contains","sf":"email","v":"test"}' .
  67                  ']}';
  68          $DB->set_field('course_sections', 'availability', $availability,
  69                  array('course' => $course->id, 'section' => 2));
  70          rebuild_course_cache($course->id, true);
  71          $sectiondb = $DB->get_record('course_sections', array('course' => $course->id, 'section' => 2));
  72  
  73          // Create and enrol a student.
  74          $studentrole = $DB->get_record('role', array('shortname' => 'student'), '*', MUST_EXIST);
  75          $student = $this->getDataGenerator()->create_user();
  76          role_assign($studentrole->id, $student->id, $coursecontext);
  77          $enrolplugin = enrol_get_plugin('manual');
  78          $enrolinstance = $DB->get_record('enrol', array('courseid' => $course->id, 'enrol' => 'manual'));
  79          $enrolplugin->enrol_user($enrolinstance, $student->id);
  80          $this->setUser($student);
  81  
  82          // Get modinfo.
  83          $modinfo = get_fast_modinfo($course->id);
  84          $si = $modinfo->get_section_info(2);
  85  
  86          $this->assertEquals($sectiondb->id, $si->id);
  87          $this->assertEquals($sectiondb->course, $si->course);
  88          $this->assertEquals($sectiondb->section, $si->section);
  89          $this->assertEquals($sectiondb->name, $si->name);
  90          $this->assertEquals($sectiondb->visible, $si->visible);
  91          $this->assertEquals($sectiondb->summary, $si->summary);
  92          $this->assertEquals($sectiondb->summaryformat, $si->summaryformat);
  93          $this->assertEquals($sectiondb->sequence, $si->sequence); // Since this section does not contain invalid modules.
  94          $this->assertEquals($availability, $si->availability);
  95  
  96          // Dynamic fields, just test that they can be retrieved (must be carefully tested in each activity type).
  97          $this->assertEquals(0, $si->available);
  98          $this->assertNotEmpty($si->availableinfo); // Lists all unmet availability conditions.
  99          $this->assertEquals(0, $si->uservisible);
 100  
 101          // Restore settings.
 102          set_config('enableavailability', $oldcfgenableavailability);
 103          set_config('enablecompletion', $oldcfgenablecompletion);
 104      }
 105  
 106      public function test_cm_info_properties() {
 107          global $DB, $CFG;
 108  
 109          $this->resetAfterTest();
 110          $oldcfgenableavailability = $CFG->enableavailability;
 111          $oldcfgenablecompletion = $CFG->enablecompletion;
 112          set_config('enableavailability', 1);
 113          set_config('enablecompletion', 1);
 114          $this->setAdminUser();
 115  
 116          // Generate the course and pre-requisite module.
 117          $course = $this->getDataGenerator()->create_course(
 118                  array('format' => 'topics',
 119                      'numsections' => 3,
 120                      'enablecompletion' => 1,
 121                      'groupmode' => SEPARATEGROUPS,
 122                      'forcegroupmode' => 0),
 123                  array('createsections' => true));
 124          $coursecontext = context_course::instance($course->id);
 125          $prereqforum = $this->getDataGenerator()->create_module('forum',
 126                  array('course' => $course->id),
 127                  array('completion' => 1));
 128  
 129          // Generate module and add availability conditions.
 130          $availability = '{"op":"&","showc":[true,true,true],"c":[' .
 131                  '{"type":"completion","cm":' . $prereqforum->cmid . ',"e":"' .
 132                      COMPLETION_COMPLETE . '"},' .
 133                  '{"type":"grade","id":666,"min":0.4},' .
 134                  '{"type":"profile","op":"contains","sf":"email","v":"test"}' .
 135                  ']}';
 136          $assign = $this->getDataGenerator()->create_module('assign',
 137                  array('course' => $course->id),
 138                  array('idnumber' => 123,
 139                      'groupmode' => VISIBLEGROUPS,
 140                      'availability' => $availability));
 141          rebuild_course_cache($course->id, true);
 142  
 143          // Retrieve all related records from DB.
 144          $assigndb = $DB->get_record('assign', array('id' => $assign->id));
 145          $moduletypedb = $DB->get_record('modules', array('name' => 'assign'));
 146          $moduledb = $DB->get_record('course_modules', array('module' => $moduletypedb->id, 'instance' => $assign->id));
 147          $sectiondb = $DB->get_record('course_sections', array('id' => $moduledb->section));
 148          $modnamessingular = get_module_types_names(false);
 149          $modnamesplural = get_module_types_names(true);
 150  
 151          // Create and enrol a student.
 152          $studentrole = $DB->get_record('role', array('shortname' => 'student'), '*', MUST_EXIST);
 153          $student = $this->getDataGenerator()->create_user();
 154          role_assign($studentrole->id, $student->id, $coursecontext);
 155          $enrolplugin = enrol_get_plugin('manual');
 156          $enrolinstance = $DB->get_record('enrol', array('courseid' => $course->id, 'enrol' => 'manual'));
 157          $enrolplugin->enrol_user($enrolinstance, $student->id);
 158          $this->setUser($student);
 159  
 160          // Emulate data used in building course cache to receive the same instance of cached_cm_info as was used in building modinfo.
 161          $rawmods = get_course_mods($course->id);
 162          $cachedcminfo = assign_get_coursemodule_info($rawmods[$moduledb->id]);
 163  
 164          // Get modinfo.
 165          $modinfo = get_fast_modinfo($course->id);
 166          $cm = $modinfo->instances['assign'][$assign->id];
 167  
 168          $this->assertEquals($moduledb->id, $cm->id);
 169          $this->assertEquals($assigndb->id, $cm->instance);
 170          $this->assertEquals($moduledb->course, $cm->course);
 171          $this->assertEquals($moduledb->idnumber, $cm->idnumber);
 172          $this->assertEquals($moduledb->added, $cm->added);
 173          $this->assertEquals($moduledb->visible, $cm->visible);
 174          $this->assertEquals($moduledb->visibleold, $cm->visibleold);
 175          $this->assertEquals($moduledb->groupmode, $cm->groupmode);
 176          $this->assertEquals(VISIBLEGROUPS, $cm->groupmode);
 177          $this->assertEquals($moduledb->groupingid, $cm->groupingid);
 178          $this->assertEquals($course->groupmodeforce, $cm->coursegroupmodeforce);
 179          $this->assertEquals($course->groupmode, $cm->coursegroupmode);
 180          $this->assertEquals(SEPARATEGROUPS, $cm->coursegroupmode);
 181          $this->assertEquals($course->groupmodeforce ? $course->groupmode : $moduledb->groupmode,
 182                  $cm->effectivegroupmode); // (since mod_assign supports groups).
 183          $this->assertEquals(VISIBLEGROUPS, $cm->effectivegroupmode);
 184          $this->assertEquals($moduledb->indent, $cm->indent);
 185          $this->assertEquals($moduledb->completion, $cm->completion);
 186          $this->assertEquals($moduledb->completiongradeitemnumber, $cm->completiongradeitemnumber);
 187          $this->assertEquals($moduledb->completionview, $cm->completionview);
 188          $this->assertEquals($moduledb->completionexpected, $cm->completionexpected);
 189          $this->assertEquals($moduledb->showdescription, $cm->showdescription);
 190          $this->assertEquals(null, $cm->extra); // Deprecated field. Used in module types that don't return cached_cm_info.
 191          $this->assertEquals($cachedcminfo->icon, $cm->icon);
 192          $this->assertEquals($cachedcminfo->iconcomponent, $cm->iconcomponent);
 193          $this->assertEquals('assign', $cm->modname);
 194          $this->assertEquals($moduledb->module, $cm->module);
 195          $this->assertEquals($cachedcminfo->name, $cm->name);
 196          $this->assertEquals($sectiondb->section, $cm->sectionnum);
 197          $this->assertEquals($moduledb->section, $cm->section);
 198          $this->assertEquals($availability, $cm->availability);
 199          $this->assertEquals(context_module::instance($moduledb->id), $cm->context);
 200          $this->assertEquals($modnamessingular['assign'], $cm->modfullname);
 201          $this->assertEquals($modnamesplural['assign'], $cm->modplural);
 202          $this->assertEquals(new moodle_url('/mod/assign/view.php', array('id' => $moduledb->id)), $cm->url);
 203          $this->assertEquals($cachedcminfo->customdata, $cm->customdata);
 204  
 205          // Deprecated field.
 206          $this->assertEquals(0, $cm->groupmembersonly);
 207          $this->assertDebuggingCalled();
 208  
 209          // Dynamic fields, just test that they can be retrieved (must be carefully tested in each activity type).
 210          $this->assertNotEmpty($cm->availableinfo); // Lists all unmet availability conditions.
 211          $this->assertEquals(0, $cm->uservisible);
 212          $this->assertEquals('', $cm->extraclasses);
 213          $this->assertEquals('', $cm->onclick);
 214          $this->assertEquals(null, $cm->afterlink);
 215          $this->assertEquals(null, $cm->afterediticons);
 216          $this->assertEquals('', $cm->content);
 217  
 218          // Attempt to access and set non-existing field.
 219          $this->assertTrue(empty($modinfo->somefield));
 220          $this->assertFalse(isset($modinfo->somefield));
 221          $cm->somefield;
 222          $this->assertDebuggingCalled();
 223          $cm->somefield = 'Some value';
 224          $this->assertDebuggingCalled();
 225          $this->assertEmpty($cm->somefield);
 226          $this->assertDebuggingCalled();
 227  
 228          // Attempt to overwrite an existing field.
 229          $prevvalue = $cm->name;
 230          $this->assertNotEmpty($cm->name);
 231          $this->assertFalse(empty($cm->name));
 232          $this->assertTrue(isset($cm->name));
 233          $cm->name = 'Illegal overwriting';
 234          $this->assertDebuggingCalled();
 235          $this->assertEquals($prevvalue, $cm->name);
 236          $this->assertDebuggingNotCalled();
 237  
 238          // Restore settings.
 239          set_config('enableavailability', $oldcfgenableavailability);
 240          set_config('enablecompletion', $oldcfgenablecompletion);
 241      }
 242  
 243      public function test_matching_cacherev() {
 244          global $DB, $CFG;
 245  
 246          $this->resetAfterTest();
 247          $this->setAdminUser();
 248          $cache = cache::make('core', 'coursemodinfo');
 249  
 250          // Generate the course and pre-requisite module.
 251          $course = $this->getDataGenerator()->create_course(
 252                  array('format' => 'topics',
 253                      'numsections' => 3),
 254                  array('createsections' => true));
 255  
 256          // Make sure the cacherev is set.
 257          $cacherev = $DB->get_field('course', 'cacherev', array('id' => $course->id));
 258          $this->assertGreaterThan(0, $cacherev);
 259          $prevcacherev = $cacherev;
 260  
 261          // Reset course cache and make sure cacherev is bumped up but cache is empty.
 262          rebuild_course_cache($course->id, true);
 263          $cacherev = $DB->get_field('course', 'cacherev', array('id' => $course->id));
 264          $this->assertGreaterThan($prevcacherev, $cacherev);
 265          $this->assertEmpty($cache->get($course->id));
 266          $prevcacherev = $cacherev;
 267  
 268          // Build course cache. Cacherev should not change but cache is now not empty. Make sure cacherev is the same everywhere.
 269          $modinfo = get_fast_modinfo($course->id);
 270          $cacherev = $DB->get_field('course', 'cacherev', array('id' => $course->id));
 271          $this->assertEquals($prevcacherev, $cacherev);
 272          $cachedvalue = $cache->get($course->id);
 273          $this->assertNotEmpty($cachedvalue);
 274          $this->assertEquals($cacherev, $cachedvalue->cacherev);
 275          $this->assertEquals($cacherev, $modinfo->get_course()->cacherev);
 276          $prevcacherev = $cacherev;
 277  
 278          // Little trick to check that cache is not rebuilt druing the next step - substitute the value in MUC and later check that it is still there.
 279          $cache->set($course->id, (object)array_merge((array)$cachedvalue, array('secretfield' => 1)));
 280  
 281          // Clear static cache and call get_fast_modinfo() again (pretend we are in another request). Cache should not be rebuilt.
 282          course_modinfo::clear_instance_cache();
 283          $modinfo = get_fast_modinfo($course->id);
 284          $cacherev = $DB->get_field('course', 'cacherev', array('id' => $course->id));
 285          $this->assertEquals($prevcacherev, $cacherev);
 286          $cachedvalue = $cache->get($course->id);
 287          $this->assertNotEmpty($cachedvalue);
 288          $this->assertEquals($cacherev, $cachedvalue->cacherev);
 289          $this->assertNotEmpty($cachedvalue->secretfield);
 290          $this->assertEquals($cacherev, $modinfo->get_course()->cacherev);
 291          $prevcacherev = $cacherev;
 292  
 293          // Rebuild course cache. Cacherev must be incremented everywhere.
 294          rebuild_course_cache($course->id);
 295          $cacherev = $DB->get_field('course', 'cacherev', array('id' => $course->id));
 296          $this->assertGreaterThan($prevcacherev, $cacherev);
 297          $cachedvalue = $cache->get($course->id);
 298          $this->assertNotEmpty($cachedvalue);
 299          $this->assertEquals($cacherev, $cachedvalue->cacherev);
 300          $modinfo = get_fast_modinfo($course->id);
 301          $this->assertEquals($cacherev, $modinfo->get_course()->cacherev);
 302          $prevcacherev = $cacherev;
 303  
 304          // Update cacherev in DB and make sure the cache will be rebuilt on the next call to get_fast_modinfo().
 305          increment_revision_number('course', 'cacherev', 'id = ?', array($course->id));
 306          // We need to clear static cache for course_modinfo instances too.
 307          course_modinfo::clear_instance_cache();
 308          $modinfo = get_fast_modinfo($course->id);
 309          $cacherev = $DB->get_field('course', 'cacherev', array('id' => $course->id));
 310          $this->assertGreaterThan($prevcacherev, $cacherev);
 311          $cachedvalue = $cache->get($course->id);
 312          $this->assertNotEmpty($cachedvalue);
 313          $this->assertEquals($cacherev, $cachedvalue->cacherev);
 314          $this->assertEquals($cacherev, $modinfo->get_course()->cacherev);
 315          $prevcacherev = $cacherev;
 316  
 317          // Reset cache for all courses and make sure this course cache is reset.
 318          rebuild_course_cache(0, true);
 319          $cacherev = $DB->get_field('course', 'cacherev', array('id' => $course->id));
 320          $this->assertGreaterThan($prevcacherev, $cacherev);
 321          $this->assertEmpty($cache->get($course->id));
 322          // Rebuild again.
 323          $modinfo = get_fast_modinfo($course->id);
 324          $cachedvalue = $cache->get($course->id);
 325          $this->assertNotEmpty($cachedvalue);
 326          $this->assertEquals($cacherev, $cachedvalue->cacherev);
 327          $this->assertEquals($cacherev, $modinfo->get_course()->cacherev);
 328          $prevcacherev = $cacherev;
 329  
 330          // Purge all caches and make sure cacherev is increased and data from MUC erased.
 331          purge_all_caches();
 332          $cacherev = $DB->get_field('course', 'cacherev', array('id' => $course->id));
 333          $this->assertGreaterThan($prevcacherev, $cacherev);
 334          $this->assertEmpty($cache->get($course->id));
 335      }
 336  
 337      public function test_course_modinfo_properties() {
 338          global $USER, $DB;
 339  
 340          $this->resetAfterTest();
 341          $this->setAdminUser();
 342  
 343          // Generate the course and some modules. Make one section hidden.
 344          $course = $this->getDataGenerator()->create_course(
 345                  array('format' => 'topics',
 346                      'numsections' => 3),
 347                  array('createsections' => true));
 348          $DB->execute('UPDATE {course_sections} SET visible = 0 WHERE course = ? and section = ?',
 349                  array($course->id, 3));
 350          $coursecontext = context_course::instance($course->id);
 351          $forum0 = $this->getDataGenerator()->create_module('forum',
 352                  array('course' => $course->id), array('section' => 0));
 353          $assign0 = $this->getDataGenerator()->create_module('assign',
 354                  array('course' => $course->id), array('section' => 0, 'visible' => 0));
 355          $forum1 = $this->getDataGenerator()->create_module('forum',
 356                  array('course' => $course->id), array('section' => 1));
 357          $assign1 = $this->getDataGenerator()->create_module('assign',
 358                  array('course' => $course->id), array('section' => 1));
 359          $page1 = $this->getDataGenerator()->create_module('page',
 360                  array('course' => $course->id), array('section' => 1));
 361          $page3 = $this->getDataGenerator()->create_module('page',
 362                  array('course' => $course->id), array('section' => 3));
 363  
 364          $modinfo = get_fast_modinfo($course->id);
 365  
 366          $this->assertEquals(array($forum0->cmid, $assign0->cmid, $forum1->cmid, $assign1->cmid, $page1->cmid, $page3->cmid),
 367                  array_keys($modinfo->cms));
 368          $this->assertEquals($course->id, $modinfo->courseid);
 369          $this->assertEquals($USER->id, $modinfo->userid);
 370          $this->assertEquals(array(0 => array($forum0->cmid, $assign0->cmid),
 371              1 => array($forum1->cmid, $assign1->cmid, $page1->cmid), 3 => array($page3->cmid)), $modinfo->sections);
 372          $this->assertEquals(array('forum', 'assign', 'page'), array_keys($modinfo->instances));
 373          $this->assertEquals(array($assign0->id, $assign1->id), array_keys($modinfo->instances['assign']));
 374          $this->assertEquals(array($forum0->id, $forum1->id), array_keys($modinfo->instances['forum']));
 375          $this->assertEquals(array($page1->id, $page3->id), array_keys($modinfo->instances['page']));
 376          $this->assertEquals(groups_get_user_groups($course->id), $modinfo->groups);
 377          $this->assertEquals(array(0 => array($forum0->cmid, $assign0->cmid),
 378              1 => array($forum1->cmid, $assign1->cmid, $page1->cmid),
 379              3 => array($page3->cmid)), $modinfo->get_sections());
 380          $this->assertEquals(array(0, 1, 2, 3), array_keys($modinfo->get_section_info_all()));
 381          $this->assertEquals($forum0->cmid . ',' . $assign0->cmid, $modinfo->get_section_info(0)->sequence);
 382          $this->assertEquals($forum1->cmid . ',' . $assign1->cmid . ',' . $page1->cmid, $modinfo->get_section_info(1)->sequence);
 383          $this->assertEquals('', $modinfo->get_section_info(2)->sequence);
 384          $this->assertEquals($page3->cmid, $modinfo->get_section_info(3)->sequence);
 385          $this->assertEquals($course->id, $modinfo->get_course()->id);
 386          $this->assertEquals(array('assign', 'forum', 'page'),
 387                  array_keys($modinfo->get_used_module_names()));
 388          $this->assertEquals(array('assign', 'forum', 'page'),
 389                  array_keys($modinfo->get_used_module_names(true)));
 390          // Admin can see hidden modules/sections.
 391          $this->assertTrue($modinfo->cms[$assign0->cmid]->uservisible);
 392          $this->assertTrue($modinfo->get_section_info(3)->uservisible);
 393  
 394          // Get modinfo for non-current user (without capability to view hidden activities/sections).
 395          $user = $this->getDataGenerator()->create_user();
 396          $modinfo = get_fast_modinfo($course->id, $user->id);
 397          $this->assertEquals($user->id, $modinfo->userid);
 398          $this->assertFalse($modinfo->cms[$assign0->cmid]->uservisible);
 399          $this->assertFalse($modinfo->get_section_info(3)->uservisible);
 400  
 401          // Attempt to access and set non-existing field.
 402          $this->assertTrue(empty($modinfo->somefield));
 403          $this->assertFalse(isset($modinfo->somefield));
 404          $modinfo->somefield;
 405          $this->assertDebuggingCalled();
 406          $modinfo->somefield = 'Some value';
 407          $this->assertDebuggingCalled();
 408          $this->assertEmpty($modinfo->somefield);
 409          $this->assertDebuggingCalled();
 410  
 411          // Attempt to overwrite existing field.
 412          $this->assertFalse(empty($modinfo->cms));
 413          $this->assertTrue(isset($modinfo->cms));
 414          $modinfo->cms = 'Illegal overwriting';
 415          $this->assertDebuggingCalled();
 416          $this->assertNotEquals('Illegal overwriting', $modinfo->cms);
 417      }
 418  
 419      /**
 420       * Test is_user_access_restricted_by_conditional_access()
 421       *
 422       * The underlying conditional access system is more thoroughly tested in lib/tests/conditionlib_test.php
 423       */
 424      public function test_is_user_access_restricted_by_conditional_access() {
 425          global $DB, $CFG;
 426  
 427          $this->resetAfterTest();
 428  
 429          // Enable conditional availability before creating modules, otherwise the condition data is not written in DB.
 430          $CFG->enableavailability = true;
 431  
 432          // Create a course.
 433          $course = $this->getDataGenerator()->create_course();
 434          // 1. Create an activity that is currently unavailable and hidden entirely (for students).
 435          $assign1 = $this->getDataGenerator()->create_module('assign', array('course'=>$course->id),
 436                  array('availability' => '{"op":"|","show":false,"c":[' .
 437                  '{"type":"date","d":">=","t":' . (time() + 10000) . '}]}'));
 438          // 2. Create an activity that is currently available.
 439          $assign2 = $this->getDataGenerator()->create_module('assign', array('course'=>$course->id));
 440          // 3. Create an activity that is currently unavailable and set to be greyed out.
 441          $assign3 = $this->getDataGenerator()->create_module('assign', array('course'=>$course->id),
 442                  array('availability' => '{"op":"|","show":true,"c":[' .
 443                  '{"type":"date","d":">=","t":' . (time() + 10000) . '}]}'));
 444  
 445          // Set up a teacher.
 446          $coursecontext = context_course::instance($course->id);
 447          $teacherrole = $DB->get_record('role', array('shortname'=>'editingteacher'), '*', MUST_EXIST);
 448          $teacher = $this->getDataGenerator()->create_user();
 449          role_assign($teacherrole->id, $teacher->id, $coursecontext);
 450  
 451          // If conditional availability is disabled the activity will always be unrestricted.
 452          $CFG->enableavailability = false;
 453          $cm = get_fast_modinfo($course)->instances['assign'][$assign1->id];
 454          $this->assertTrue($cm->uservisible);
 455  
 456          // Test deprecated function.
 457          $this->assertFalse($cm->is_user_access_restricted_by_conditional_access());
 458          $this->assertEquals(1, count(phpunit_util::get_debugging_messages()));
 459          phpunit_util::reset_debugging();
 460  
 461          // Turn on conditional availability and reset the get_fast_modinfo cache.
 462          $CFG->enableavailability = true;
 463          get_fast_modinfo($course, 0, true);
 464  
 465          // The unavailable, hidden entirely activity should now be restricted.
 466          $cm = get_fast_modinfo($course)->instances['assign'][$assign1->id];
 467          $this->assertFalse($cm->uservisible);
 468          $this->assertFalse($cm->available);
 469          $this->assertEquals('', $cm->availableinfo);
 470  
 471          // Test deprecated function.
 472          $this->assertTrue($cm->is_user_access_restricted_by_conditional_access());
 473          $this->assertEquals(1, count(phpunit_util::get_debugging_messages()));
 474          phpunit_util::reset_debugging();
 475  
 476          // If the activity is available it should not be restricted.
 477          $cm = get_fast_modinfo($course)->instances['assign'][$assign2->id];
 478          $this->assertTrue($cm->uservisible);
 479          $this->assertTrue($cm->available);
 480  
 481          // If the activity is unavailable and set to be greyed out it should not be restricted.
 482          $cm = get_fast_modinfo($course)->instances['assign'][$assign3->id];
 483          $this->assertFalse($cm->uservisible);
 484          $this->assertFalse($cm->available);
 485          $this->assertNotEquals('', (string)$cm->availableinfo);
 486  
 487          // Test deprecated function (weird case, it actually checks visibility).
 488          $this->assertFalse($cm->is_user_access_restricted_by_conditional_access());
 489          $this->assertEquals(1, count(phpunit_util::get_debugging_messages()));
 490          phpunit_util::reset_debugging();
 491  
 492          // If the activity is unavailable and set to be hidden entirely its restricted unless user has 'moodle/course:viewhiddenactivities'.
 493          // Switch to a teacher and reload the context info.
 494          $this->setUser($teacher);
 495          $this->assertTrue(has_capability('moodle/course:viewhiddenactivities', $coursecontext));
 496          $cm = get_fast_modinfo($course)->instances['assign'][$assign1->id];
 497          $this->assertTrue($cm->uservisible);
 498          $this->assertFalse($cm->available);
 499      }
 500  
 501      public function test_is_user_access_restricted_by_capability() {
 502          global $DB;
 503  
 504          $this->resetAfterTest();
 505  
 506          // Create a course and a mod_assign instance.
 507          $course = $this->getDataGenerator()->create_course();
 508          $assign = $this->getDataGenerator()->create_module('assign', array('course'=>$course->id));
 509  
 510          // Create and enrol a student.
 511          $coursecontext = context_course::instance($course->id);
 512          $studentrole = $DB->get_record('role', array('shortname' => 'student'), '*', MUST_EXIST);
 513          $student = $this->getDataGenerator()->create_user();
 514          role_assign($studentrole->id, $student->id, $coursecontext);
 515          $enrolplugin = enrol_get_plugin('manual');
 516          $enrolinstance = $DB->get_record('enrol', array('courseid' => $course->id, 'enrol' => 'manual'));
 517          $enrolplugin->enrol_user($enrolinstance, $student->id);
 518          $this->setUser($student);
 519  
 520          // Make sure student can see the module.
 521          $cm = get_fast_modinfo($course->id)->instances['assign'][$assign->id];
 522          $this->assertTrue($cm->uservisible);
 523          $this->assertFalse($cm->is_user_access_restricted_by_capability());
 524  
 525          // Prohibit student to view mod_assign for the course.
 526          role_change_permission($studentrole->id, $coursecontext, 'mod/assign:view', CAP_PROHIBIT);
 527          get_fast_modinfo($course->id, 0, true);
 528          $cm = get_fast_modinfo($course->id)->instances['assign'][$assign->id];
 529          $this->assertFalse($cm->uservisible);
 530          $this->assertTrue($cm->is_user_access_restricted_by_capability());
 531  
 532          // Restore permission to student to view mod_assign for the course.
 533          role_change_permission($studentrole->id, $coursecontext, 'mod/assign:view', CAP_INHERIT);
 534          get_fast_modinfo($course->id, 0, true);
 535          $cm = get_fast_modinfo($course->id)->instances['assign'][$assign->id];
 536          $this->assertTrue($cm->uservisible);
 537          $this->assertFalse($cm->is_user_access_restricted_by_capability());
 538  
 539          // Prohibit student to view mod_assign for the particular module.
 540          role_change_permission($studentrole->id, context_module::instance($cm->id), 'mod/assign:view', CAP_PROHIBIT);
 541          get_fast_modinfo($course->id, 0, true);
 542          $cm = get_fast_modinfo($course->id)->instances['assign'][$assign->id];
 543          $this->assertFalse($cm->uservisible);
 544          $this->assertTrue($cm->is_user_access_restricted_by_capability());
 545  
 546          // Check calling get_fast_modinfo() for different user:
 547          $this->setAdminUser();
 548          $cm = get_fast_modinfo($course->id)->instances['assign'][$assign->id];
 549          $this->assertTrue($cm->uservisible);
 550          $this->assertFalse($cm->is_user_access_restricted_by_capability());
 551          $cm = get_fast_modinfo($course->id, $student->id)->instances['assign'][$assign->id];
 552          $this->assertFalse($cm->uservisible);
 553          $this->assertTrue($cm->is_user_access_restricted_by_capability());
 554      }
 555  
 556      /**
 557       * Tests that various deprecated cm_info methods are throwing debuggign messages
 558       */
 559      public function test_cm_info_property_deprecations() {
 560          global $DB, $CFG;
 561  
 562          $this->resetAfterTest();
 563  
 564          $course = $this->getDataGenerator()->create_course( array('format' => 'topics', 'numsections' => 3),
 565                  array('createsections' => true));
 566          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
 567          $cm = get_fast_modinfo($course->id)->instances['forum'][$forum->id];
 568  
 569          $cm->get_url();
 570          $this->assertDebuggingCalled('cm_info::get_url() is deprecated, please use the property cm_info->url instead.');
 571  
 572          $cm->get_content();
 573          $this->assertDebuggingCalled('cm_info::get_content() is deprecated, please use the property cm_info->content instead.');
 574  
 575          $cm->get_extra_classes();
 576          $this->assertDebuggingCalled('cm_info::get_extra_classes() is deprecated, please use the property cm_info->extraclasses instead.');
 577  
 578          $cm->get_on_click();
 579          $this->assertDebuggingCalled('cm_info::get_on_click() is deprecated, please use the property cm_info->onclick instead.');
 580  
 581          $cm->get_custom_data();
 582          $this->assertDebuggingCalled('cm_info::get_custom_data() is deprecated, please use the property cm_info->customdata instead.');
 583  
 584          $cm->get_after_link();
 585          $this->assertDebuggingCalled('cm_info::get_after_link() is deprecated, please use the property cm_info->afterlink instead.');
 586  
 587          $cm->get_after_edit_icons();
 588          $this->assertDebuggingCalled('cm_info::get_after_edit_icons() is deprecated, please use the property cm_info->afterediticons instead.');
 589  
 590          $cm->obtain_dynamic_data();
 591          $this->assertDebuggingCalled('cm_info::obtain_dynamic_data() is deprecated and should not be used.');
 592      }
 593  
 594      /**
 595       * Tests for function cm_info::get_course_module_record()
 596       */
 597      public function test_cm_info_get_course_module_record() {
 598          global $DB, $CFG;
 599  
 600          $this->resetAfterTest();
 601  
 602          set_config('enableavailability', 1);
 603          set_config('enablecompletion', 1);
 604  
 605          $course = $this->getDataGenerator()->create_course(
 606                  array('format' => 'topics', 'numsections' => 3, 'enablecompletion' => 1),
 607                  array('createsections' => true));
 608          $mods = array();
 609          $mods[0] = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
 610          $mods[1] = $this->getDataGenerator()->create_module('assign',
 611                  array('course' => $course->id,
 612                      'section' => 3,
 613                      'idnumber' => '12345',
 614                      'showdescription' => true
 615                      ));
 616          // Pick a small valid availability value to use.
 617          $availabilityvalue = '{"op":"|","show":true,"c":[{"type":"date","d":">=","t":4}]}';
 618          $mods[2] = $this->getDataGenerator()->create_module('book',
 619                  array('course' => $course->id,
 620                      'indent' => 5,
 621                      'availability' => $availabilityvalue,
 622                      'showdescription' => false,
 623                      'completion' => true,
 624                      'completionview' => true,
 625                      'completionexpected' => time() + 5000,
 626                      ));
 627          $mods[3] = $this->getDataGenerator()->create_module('forum',
 628                  array('course' => $course->id,
 629                      'visible' => 0,
 630                      'groupmode' => 1,
 631                      'availability' => null));
 632          $mods[4] = $this->getDataGenerator()->create_module('forum',
 633                  array('course' => $course->id,
 634                      'grouping' => 12));
 635  
 636          $modinfo = get_fast_modinfo($course->id);
 637  
 638          // Make sure that object returned by get_course_module_record(false) has exactly the same fields as DB table 'course_modules'.
 639          $dbfields = array_keys($DB->get_columns('course_modules'));
 640          sort($dbfields);
 641          $cmrecord = $modinfo->get_cm($mods[0]->cmid)->get_course_module_record();
 642          $cmrecordfields = array_keys((array)$cmrecord);
 643          sort($cmrecordfields);
 644          $this->assertEquals($dbfields, $cmrecordfields);
 645  
 646          // Make sure that object returned by get_course_module_record(true) has exactly the same fields
 647          // as object returned by get_coursemodule_from_id(,,,true,);
 648          $cmrecordfull = $modinfo->get_cm($mods[0]->cmid)->get_course_module_record(true);
 649          $cmrecordfullfields = array_keys((array)$cmrecordfull);
 650          $cm = get_coursemodule_from_id(null, $mods[0]->cmid, 0, true, MUST_EXIST);
 651          $cmfields = array_keys((array)$cm);
 652          $this->assertEquals($cmfields, $cmrecordfullfields);
 653  
 654          // Make sure that object returned by get_course_module_record(true) has exactly the same fields
 655          // as object returned by get_coursemodule_from_instance(,,,true,);
 656          $cm = get_coursemodule_from_instance('forum', $mods[0]->id, null, true, MUST_EXIST);
 657          $cmfields = array_keys((array)$cm);
 658          $this->assertEquals($cmfields, $cmrecordfullfields);
 659  
 660          // Make sure the objects have the same properties.
 661          $cm1 = get_coursemodule_from_id(null, $mods[0]->cmid, 0, true, MUST_EXIST);
 662          $cm2 = get_coursemodule_from_instance('forum', $mods[0]->id, 0, true, MUST_EXIST);
 663          $cminfo = $modinfo->get_cm($mods[0]->cmid);
 664          $record = $DB->get_record('course_modules', array('id' => $mods[0]->cmid));
 665          $this->assertEquals($record, $cminfo->get_course_module_record());
 666          $this->assertEquals($cm1, $cminfo->get_course_module_record(true));
 667          $this->assertEquals($cm2, $cminfo->get_course_module_record(true));
 668  
 669          $cm1 = get_coursemodule_from_id(null, $mods[1]->cmid, 0, true, MUST_EXIST);
 670          $cm2 = get_coursemodule_from_instance('assign', $mods[1]->id, 0, true, MUST_EXIST);
 671          $cminfo = $modinfo->get_cm($mods[1]->cmid);
 672          $record = $DB->get_record('course_modules', array('id' => $mods[1]->cmid));
 673          $this->assertEquals($record, $cminfo->get_course_module_record());
 674          $this->assertEquals($cm1, $cminfo->get_course_module_record(true));
 675          $this->assertEquals($cm2, $cminfo->get_course_module_record(true));
 676  
 677          $cm1 = get_coursemodule_from_id(null, $mods[2]->cmid, 0, true, MUST_EXIST);
 678          $cm2 = get_coursemodule_from_instance('book', $mods[2]->id, 0, true, MUST_EXIST);
 679          $cminfo = $modinfo->get_cm($mods[2]->cmid);
 680          $record = $DB->get_record('course_modules', array('id' => $mods[2]->cmid));
 681          $this->assertEquals($record, $cminfo->get_course_module_record());
 682          $this->assertEquals($cm1, $cminfo->get_course_module_record(true));
 683          $this->assertEquals($cm2, $cminfo->get_course_module_record(true));
 684  
 685          $cm1 = get_coursemodule_from_id(null, $mods[3]->cmid, 0, true, MUST_EXIST);
 686          $cm2 = get_coursemodule_from_instance('forum', $mods[3]->id, 0, true, MUST_EXIST);
 687          $cminfo = $modinfo->get_cm($mods[3]->cmid);
 688          $record = $DB->get_record('course_modules', array('id' => $mods[3]->cmid));
 689          $this->assertEquals($record, $cminfo->get_course_module_record());
 690          $this->assertEquals($cm1, $cminfo->get_course_module_record(true));
 691          $this->assertEquals($cm2, $cminfo->get_course_module_record(true));
 692  
 693          $cm1 = get_coursemodule_from_id(null, $mods[4]->cmid, 0, true, MUST_EXIST);
 694          $cm2 = get_coursemodule_from_instance('forum', $mods[4]->id, 0, true, MUST_EXIST);
 695          $cminfo = $modinfo->get_cm($mods[4]->cmid);
 696          $record = $DB->get_record('course_modules', array('id' => $mods[4]->cmid));
 697          $this->assertEquals($record, $cminfo->get_course_module_record());
 698          $this->assertEquals($cm1, $cminfo->get_course_module_record(true));
 699          $this->assertEquals($cm2, $cminfo->get_course_module_record(true));
 700  
 701      }
 702  
 703      /**
 704       * Tests the availability property that has been added to course modules
 705       * and sections (just to see that it is correctly saved and accessed).
 706       */
 707      public function test_availability_property() {
 708          global $DB, $CFG;
 709  
 710          $this->resetAfterTest();
 711  
 712          // Create a course with two modules and three sections.
 713          $course = $this->getDataGenerator()->create_course(
 714                  array('format' => 'topics', 'numsections' => 3),
 715                  array('createsections' => true));
 716          $forum = $this->getDataGenerator()->create_module('forum',
 717                  array('course' => $course->id));
 718          $forum2 = $this->getDataGenerator()->create_module('forum',
 719                  array('course' => $course->id));
 720  
 721          // Get modinfo. Check that availability is null for both cm and sections.
 722          $modinfo = get_fast_modinfo($course->id);
 723          $cm = $modinfo->get_cm($forum->cmid);
 724          $this->assertNull($cm->availability);
 725          $section = $modinfo->get_section_info(1, MUST_EXIST);
 726          $this->assertNull($section->availability);
 727  
 728          // Update availability for cm and section in database.
 729          $DB->set_field('course_modules', 'availability', '{}', array('id' => $cm->id));
 730          $DB->set_field('course_sections', 'availability', '{}', array('id' => $section->id));
 731  
 732          // Clear cache and get modinfo again.
 733          rebuild_course_cache($course->id, true);
 734          get_fast_modinfo(0, 0, true);
 735          $modinfo = get_fast_modinfo($course->id);
 736  
 737          // Check values that were changed.
 738          $cm = $modinfo->get_cm($forum->cmid);
 739          $this->assertEquals('{}', $cm->availability);
 740          $section = $modinfo->get_section_info(1, MUST_EXIST);
 741          $this->assertEquals('{}', $section->availability);
 742  
 743          // Check other values are still null.
 744          $cm = $modinfo->get_cm($forum2->cmid);
 745          $this->assertNull($cm->availability);
 746          $section = $modinfo->get_section_info(2, MUST_EXIST);
 747          $this->assertNull($section->availability);
 748      }
 749  
 750      /**
 751       * Some properties have been deprecated from both the section and module
 752       * classes. This checks they still work (and show warnings).
 753       */
 754      public function test_availability_deprecations() {
 755          global $CFG, $DB;
 756          $this->resetAfterTest();
 757          $CFG->enableavailability = true;
 758  
 759          // Create a course with two modules. The modules are not available to
 760          // users. One of them is set to show this information, the other is not.
 761          // Same setup for sections.
 762          $generator = $this->getDataGenerator();
 763          $course = $this->getDataGenerator()->create_course(
 764                  array('format' => 'topics', 'numsections' => 2),
 765                  array('createsections' => true));
 766          $show = '{"op":"|","show":true,"c":[{"type":"date","d":"<","t":1395857332}]}';
 767          $noshow = '{"op":"|","show":false,"c":[{"type":"date","d":"<","t":1395857332}]}';
 768          $forum1 = $generator->create_module('forum',
 769                  array('course' => $course->id, 'availability' => $show));
 770          $forum2 = $generator->create_module('forum',
 771                  array('course' => $course->id, 'availability' => $noshow));
 772          $DB->set_field('course_sections', 'availability',
 773                  $show, array('course' => $course->id, 'section' => 1));
 774          $DB->set_field('course_sections', 'availability',
 775                  $noshow, array('course' => $course->id, 'section' => 2));
 776  
 777          // Create a user without special permissions.
 778          $user = $generator->create_user();
 779          $generator->enrol_user($user->id, $course->id);
 780  
 781          // Get modinfo and cm objects.
 782          $modinfo = get_fast_modinfo($course, $user->id);
 783          $cm1 = $modinfo->get_cm($forum1->cmid);
 784          $cm2 = $modinfo->get_cm($forum2->cmid);
 785  
 786          // Check the showavailability property.
 787          $this->assertEquals(1, $cm1->showavailability);
 788          $this->assertDebuggingCalled(null, DEBUG_DEVELOPER);
 789          $this->assertEquals(0, $cm2->showavailability);
 790          $this->assertDebuggingCalled(null, DEBUG_DEVELOPER);
 791  
 792          // Check the dates (these always return 0 now).
 793          $this->assertEquals(0, $cm1->availablefrom);
 794          $this->assertDebuggingCalled(null, DEBUG_DEVELOPER);
 795          $this->assertEquals(0, $cm1->availableuntil);
 796          $this->assertDebuggingCalled(null, DEBUG_DEVELOPER);
 797  
 798          // Get section objects.
 799          $section1 = $modinfo->get_section_info(1);
 800          $section2 = $modinfo->get_section_info(2);
 801  
 802          // Check showavailability.
 803          $this->assertEquals(1, $section1->showavailability);
 804          $this->assertDebuggingCalled(null, DEBUG_DEVELOPER);
 805          $this->assertEquals(0, $section2->showavailability);
 806          $this->assertDebuggingCalled(null, DEBUG_DEVELOPER);
 807  
 808          // Check dates (zero).
 809          $this->assertEquals(0, $section1->availablefrom);
 810          $this->assertDebuggingCalled(null, DEBUG_DEVELOPER);
 811                  $this->assertEquals(0, $section1->availableuntil);
 812          $this->assertDebuggingCalled(null, DEBUG_DEVELOPER);
 813  
 814          // Check groupingid (zero).
 815          $this->assertEquals(0, $section1->groupingid);
 816          $this->assertDebuggingCalled(null, DEBUG_DEVELOPER);
 817      }
 818  
 819      /**
 820       * Tests for get_groups() method.
 821       */
 822      public function test_get_groups() {
 823          $this->resetAfterTest();
 824          $generator = $this->getDataGenerator();
 825  
 826          // Create courses.
 827          $course1 = $generator->create_course();
 828          $course2 = $generator->create_course();
 829          $course3 = $generator->create_course();
 830  
 831          // Create users.
 832          $user1 = $generator->create_user();
 833          $user2 = $generator->create_user();
 834          $user3 = $generator->create_user();
 835  
 836          // Enrol users on courses.
 837          $generator->enrol_user($user1->id, $course1->id);
 838          $generator->enrol_user($user2->id, $course2->id);
 839          $generator->enrol_user($user3->id, $course2->id);
 840          $generator->enrol_user($user3->id, $course3->id);
 841  
 842          // Create groups.
 843          $group1 = $generator->create_group(array('courseid' => $course1->id));
 844          $group2 = $generator->create_group(array('courseid' => $course2->id));
 845          $group3 = $generator->create_group(array('courseid' => $course2->id));
 846  
 847          // Assign users to groups and assert the result.
 848          $this->assertTrue($generator->create_group_member(array('groupid' => $group1->id, 'userid' => $user1->id)));
 849          $this->assertTrue($generator->create_group_member(array('groupid' => $group2->id, 'userid' => $user2->id)));
 850          $this->assertTrue($generator->create_group_member(array('groupid' => $group3->id, 'userid' => $user2->id)));
 851          $this->assertTrue($generator->create_group_member(array('groupid' => $group2->id, 'userid' => $user3->id)));
 852  
 853          // Create groupings.
 854          $grouping1 = $generator->create_grouping(array('courseid' => $course1->id));
 855          $grouping2 = $generator->create_grouping(array('courseid' => $course2->id));
 856  
 857          // Assign and assert group to groupings.
 858          groups_assign_grouping($grouping1->id, $group1->id);
 859          groups_assign_grouping($grouping2->id, $group2->id);
 860          groups_assign_grouping($grouping2->id, $group3->id);
 861  
 862          // Test with one single group.
 863          $modinfo = get_fast_modinfo($course1, $user1->id);
 864          $groups = $modinfo->get_groups($grouping1->id);
 865          $this->assertCount(1, $groups);
 866          $this->assertArrayHasKey($group1->id, $groups);
 867  
 868          // Test with two groups.
 869          $modinfo = get_fast_modinfo($course2, $user2->id);
 870          $groups = $modinfo->get_groups();
 871          $this->assertCount(2, $groups);
 872          $this->assertTrue(in_array($group2->id, $groups));
 873          $this->assertTrue(in_array($group3->id, $groups));
 874  
 875          // Test with no groups.
 876          $modinfo = get_fast_modinfo($course3, $user3->id);
 877          $groups = $modinfo->get_groups();
 878          $this->assertCount(0, $groups);
 879          $this->assertArrayNotHasKey($group1->id, $groups);
 880      }
 881  
 882      /**
 883       * Tests the function for constructing a cm_info from mixed data.
 884       */
 885      public function test_create() {
 886          global $CFG, $DB;
 887          $this->resetAfterTest();
 888  
 889          // Create a course and an activity.
 890          $generator = $this->getDataGenerator();
 891          $course = $generator->create_course();
 892          $page = $generator->create_module('page', array('course' => $course->id,
 893                  'name' => 'Annie'));
 894  
 895          // Null is passed through.
 896          $this->assertNull(cm_info::create(null));
 897  
 898          // Stdclass object turns into cm_info.
 899          $cm = cm_info::create(
 900                  (object)array('id' => $page->cmid, 'course' => $course->id));
 901          $this->assertInstanceOf('cm_info', $cm);
 902          $this->assertEquals('Annie', $cm->name);
 903  
 904          // A cm_info object stays as cm_info.
 905          $this->assertSame($cm, cm_info::create($cm));
 906  
 907          // Invalid object (missing fields) causes error.
 908          try {
 909              cm_info::create((object)array('id' => $page->cmid));
 910              $this->fail();
 911          } catch (Exception $e) {
 912              $this->assertInstanceOf('coding_exception', $e);
 913          }
 914  
 915          // Create a second hidden activity.
 916          $hiddenpage = $generator->create_module('page', array('course' => $course->id,
 917                  'name' => 'Annie', 'visible' => 0));
 918  
 919          // Create 2 user accounts, one is a manager who can see everything.
 920          $user = $generator->create_user();
 921          $generator->enrol_user($user->id, $course->id);
 922          $manager = $generator->create_user();
 923          $generator->enrol_user($manager->id, $course->id,
 924                  $DB->get_field('role', 'id', array('shortname' => 'manager'), MUST_EXIST));
 925  
 926          // User can see the normal page but not the hidden one.
 927          $cm = cm_info::create((object)array('id' => $page->cmid, 'course' => $course->id),
 928                  $user->id);
 929          $this->assertTrue($cm->uservisible);
 930          $cm = cm_info::create((object)array('id' => $hiddenpage->cmid, 'course' => $course->id),
 931                  $user->id);
 932          $this->assertFalse($cm->uservisible);
 933  
 934          // Manager can see the hidden one too.
 935          $cm = cm_info::create((object)array('id' => $hiddenpage->cmid, 'course' => $course->id),
 936                  $manager->id);
 937          $this->assertTrue($cm->uservisible);
 938      }
 939  
 940      /**
 941       * Tests function for getting $course and $cm at once quickly from modinfo
 942       * based on cmid or cm record.
 943       */
 944      public function test_get_course_and_cm_from_cmid() {
 945          global $CFG, $DB;
 946          $this->resetAfterTest();
 947  
 948          // Create a course and an activity.
 949          $generator = $this->getDataGenerator();
 950          $course = $generator->create_course(array('shortname' => 'Halls'));
 951          $page = $generator->create_module('page', array('course' => $course->id,
 952                  'name' => 'Annie'));
 953  
 954          // Successful usage.
 955          list($course, $cm) = get_course_and_cm_from_cmid($page->cmid);
 956          $this->assertEquals('Halls', $course->shortname);
 957          $this->assertInstanceOf('cm_info', $cm);
 958          $this->assertEquals('Annie', $cm->name);
 959  
 960          // Specified module type.
 961          list($course, $cm) = get_course_and_cm_from_cmid($page->cmid, 'page');
 962          $this->assertEquals('Annie', $cm->name);
 963  
 964          // With id in object.
 965          $fakecm = (object)array('id' => $page->cmid);
 966          list($course, $cm) = get_course_and_cm_from_cmid($fakecm);
 967          $this->assertEquals('Halls', $course->shortname);
 968          $this->assertEquals('Annie', $cm->name);
 969  
 970          // With both id and course in object.
 971          $fakecm->course = $course->id;
 972          list($course, $cm) = get_course_and_cm_from_cmid($fakecm);
 973          $this->assertEquals('Halls', $course->shortname);
 974          $this->assertEquals('Annie', $cm->name);
 975  
 976          // With supplied course id.
 977          list($course, $cm) = get_course_and_cm_from_cmid($page->cmid, 'page', $course->id);
 978          $this->assertEquals('Annie', $cm->name);
 979  
 980          // With supplied course object (modified just so we can check it is
 981          // indeed reusing the supplied object).
 982          $course->silly = true;
 983          list($course, $cm) = get_course_and_cm_from_cmid($page->cmid, 'page', $course);
 984          $this->assertEquals('Annie', $cm->name);
 985          $this->assertTrue($course->silly);
 986  
 987          // Incorrect module type.
 988          try {
 989              get_course_and_cm_from_cmid($page->cmid, 'forum');
 990              $this->fail();
 991          } catch (moodle_exception $e) {
 992              $this->assertEquals('invalidcoursemodule', $e->errorcode);
 993          }
 994  
 995          // Invalid module name.
 996          try {
 997              get_course_and_cm_from_cmid($page->cmid, 'pigs can fly');
 998              $this->fail();
 999          } catch (coding_exception $e) {
1000              $this->assertContains('Invalid modulename parameter', $e->getMessage());
1001          }
1002  
1003          // Doesn't exist.
1004          try {
1005              get_course_and_cm_from_cmid($page->cmid + 1);
1006              $this->fail();
1007          } catch (moodle_exception $e) {
1008              $this->assertInstanceOf('dml_exception', $e);
1009          }
1010  
1011          // Create a second hidden activity.
1012          $hiddenpage = $generator->create_module('page', array('course' => $course->id,
1013                  'name' => 'Annie', 'visible' => 0));
1014  
1015          // Create 2 user accounts, one is a manager who can see everything.
1016          $user = $generator->create_user();
1017          $generator->enrol_user($user->id, $course->id);
1018          $manager = $generator->create_user();
1019          $generator->enrol_user($manager->id, $course->id,
1020                  $DB->get_field('role', 'id', array('shortname' => 'manager'), MUST_EXIST));
1021  
1022          // User can see the normal page but not the hidden one.
1023          list($course, $cm) = get_course_and_cm_from_cmid($page->cmid, 'page', 0, $user->id);
1024          $this->assertTrue($cm->uservisible);
1025          list($course, $cm) = get_course_and_cm_from_cmid($hiddenpage->cmid, 'page', 0, $user->id);
1026          $this->assertFalse($cm->uservisible);
1027  
1028          // Manager can see the hidden one too.
1029          list($course, $cm) = get_course_and_cm_from_cmid($hiddenpage->cmid, 'page', 0, $manager->id);
1030          $this->assertTrue($cm->uservisible);
1031      }
1032  
1033      /**
1034       * Tests function for getting $course and $cm at once quickly from modinfo
1035       * based on instance id or record.
1036       */
1037      public function test_get_course_and_cm_from_instance() {
1038          global $CFG, $DB;
1039          $this->resetAfterTest();
1040  
1041          // Create a course and an activity.
1042          $generator = $this->getDataGenerator();
1043          $course = $generator->create_course(array('shortname' => 'Halls'));
1044          $page = $generator->create_module('page', array('course' => $course->id,
1045                  'name' => 'Annie'));
1046  
1047          // Successful usage.
1048          list($course, $cm) = get_course_and_cm_from_instance($page->id, 'page');
1049          $this->assertEquals('Halls', $course->shortname);
1050          $this->assertInstanceOf('cm_info', $cm);
1051          $this->assertEquals('Annie', $cm->name);
1052  
1053          // With id in object.
1054          $fakeinstance = (object)array('id' => $page->id);
1055          list($course, $cm) = get_course_and_cm_from_instance($fakeinstance, 'page');
1056          $this->assertEquals('Halls', $course->shortname);
1057          $this->assertEquals('Annie', $cm->name);
1058  
1059          // With both id and course in object.
1060          $fakeinstance->course = $course->id;
1061          list($course, $cm) = get_course_and_cm_from_instance($fakeinstance, 'page');
1062          $this->assertEquals('Halls', $course->shortname);
1063          $this->assertEquals('Annie', $cm->name);
1064  
1065          // With supplied course id.
1066          list($course, $cm) = get_course_and_cm_from_instance($page->id, 'page', $course->id);
1067          $this->assertEquals('Annie', $cm->name);
1068  
1069          // With supplied course object (modified just so we can check it is
1070          // indeed reusing the supplied object).
1071          $course->silly = true;
1072          list($course, $cm) = get_course_and_cm_from_instance($page->id, 'page', $course);
1073          $this->assertEquals('Annie', $cm->name);
1074          $this->assertTrue($course->silly);
1075  
1076          // Doesn't exist (or is wrong type).
1077          try {
1078              get_course_and_cm_from_instance($page->id, 'forum');
1079              $this->fail();
1080          } catch (moodle_exception $e) {
1081              $this->assertInstanceOf('dml_exception', $e);
1082          }
1083  
1084          // Invalid module name.
1085          try {
1086              get_course_and_cm_from_cmid($page->cmid, '1337 h4x0ring');
1087              $this->fail();
1088          } catch (coding_exception $e) {
1089              $this->assertContains('Invalid modulename parameter', $e->getMessage());
1090          }
1091  
1092          // Create a second hidden activity.
1093          $hiddenpage = $generator->create_module('page', array('course' => $course->id,
1094                  'name' => 'Annie', 'visible' => 0));
1095  
1096          // Create 2 user accounts, one is a manager who can see everything.
1097          $user = $generator->create_user();
1098          $generator->enrol_user($user->id, $course->id);
1099          $manager = $generator->create_user();
1100          $generator->enrol_user($manager->id, $course->id,
1101                  $DB->get_field('role', 'id', array('shortname' => 'manager'), MUST_EXIST));
1102  
1103          // User can see the normal page but not the hidden one.
1104          list($course, $cm) = get_course_and_cm_from_cmid($page->cmid, 'page', 0, $user->id);
1105          $this->assertTrue($cm->uservisible);
1106          list($course, $cm) = get_course_and_cm_from_cmid($hiddenpage->cmid, 'page', 0, $user->id);
1107          $this->assertFalse($cm->uservisible);
1108  
1109          // Manager can see the hidden one too.
1110          list($course, $cm) = get_course_and_cm_from_cmid($hiddenpage->cmid, 'page', 0, $manager->id);
1111          $this->assertTrue($cm->uservisible);
1112      }
1113  }


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1