MDL-41192 course: Added unittests for cm_info properties
[moodle.git] / lib / tests / modinfolib_test.php
CommitLineData
69632d42
AD
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
25defined('MOODLE_INTERNAL') || die();
26
27global $CFG;
28require_once($CFG->libdir . '/modinfolib.php');
29require_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 */
e2262d70 37class core_modinfolib_testcase extends advanced_testcase {
4e430906
MG
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 // Generate the module and add availability conditions.
62 $conditionscompletion = array($prereqforum->cmid => COMPLETION_COMPLETE);
63 $conditionsgrade = array(666 => (object)array('min' => 0.4, 'max' => null, 'name' => '!missing'));
64 $conditionsfield = array('email' => (object)array(
65 'fieldname' => 'email',
66 'operator' => 'contains',
67 'value' => 'test'
68 ));
69 $sectiondb = $DB->get_record('course_sections', array('course' => $course->id, 'section' => 2));
70 $ci = new condition_info_section((object)array('id' => $sectiondb->id), CONDITION_MISSING_EVERYTHING);
71 foreach ($conditionscompletion as $cmid => $requiredcompletion) {
72 $ci->add_completion_condition($cmid, $requiredcompletion);
73 }
74 foreach ($conditionsgrade as $gradeid => $conditiongrade) {
75 $ci->add_grade_condition($gradeid, $conditiongrade->min, $conditiongrade->max, true);
76 }
77 foreach ($conditionsfield as $conditionfield) {
78 $ci->add_user_field_condition($conditionfield->fieldname, $conditionfield->operator, $conditionfield->value);
79 }
80
81 // Create and enrol a student.
82 $studentrole = $DB->get_record('role', array('shortname' => 'student'), '*', MUST_EXIST);
83 $student = $this->getDataGenerator()->create_user();
84 role_assign($studentrole->id, $student->id, $coursecontext);
85 $enrolplugin = enrol_get_plugin('manual');
86 $enrolinstance = $DB->get_record('enrol', array('courseid' => $course->id, 'enrol' => 'manual'));
87 $enrolplugin->enrol_user($enrolinstance, $student->id);
88 $this->setUser($student);
89
90 // Get modinfo.
91 $modinfo = get_fast_modinfo($course->id);
92 $si = $modinfo->get_section_info(2);
93
94 $this->assertEquals($sectiondb->id, $si->id);
95 $this->assertEquals($sectiondb->course, $si->course);
96 $this->assertEquals($sectiondb->section, $si->section);
97 $this->assertEquals($sectiondb->name, $si->name);
98 $this->assertEquals($sectiondb->visible, $si->visible);
99 $this->assertEquals($sectiondb->summary, $si->summary);
100 $this->assertEquals($sectiondb->summaryformat, $si->summaryformat);
101 $this->assertEquals($sectiondb->showavailability, $si->showavailability);
102 $this->assertEquals($sectiondb->availablefrom, $si->availablefrom);
103 $this->assertEquals($sectiondb->availableuntil, $si->availableuntil);
104 $this->assertEquals($sectiondb->groupingid, $si->groupingid);
105 $this->assertEquals($sectiondb->sequence, $si->sequence); // Since this section does not contain invalid modules.
106 $this->assertEquals($conditionscompletion, $si->conditionscompletion);
107 $this->assertEquals($conditionsgrade, $si->conditionsgrade);
108 $this->assertEquals($conditionsfield, $si->conditionsfield);
109
110 // Dynamic fields, just test that they can be retrieved (must be carefully tested in each activity type).
111 $this->assertEquals(0, $si->available);
112 $this->assertNotEmpty($si->availableinfo); // Lists all unmet availability conditions.
113 $this->assertEquals(0, $si->uservisible);
114
115 // Restore settings.
116 set_config('enableavailability', $oldcfgenableavailability);
117 set_config('enablecompletion', $oldcfgenablecompletion);
118 }
119
cbd6b1fc
MG
120 public function test_cm_info_properties() {
121 global $DB, $CFG;
122
123 $this->resetAfterTest();
124 $oldcfgenableavailability = $CFG->enableavailability;
125 $oldcfgenablecompletion = $CFG->enablecompletion;
126 set_config('enableavailability', 1);
127 set_config('enablecompletion', 1);
128 $this->setAdminUser();
129
130 // Generate the course and pre-requisite module.
131 $course = $this->getDataGenerator()->create_course(
132 array('format' => 'topics',
133 'numsections' => 3,
134 'enablecompletion' => 1,
135 'groupmode' => SEPARATEGROUPS,
136 'forcegroupmode' => 0),
137 array('createsections' => true));
138 $coursecontext = context_course::instance($course->id);
139 $prereqforum = $this->getDataGenerator()->create_module('forum',
140 array('course' => $course->id),
141 array('completion' => 1));
142
143 // Generate the module and add availability conditions.
144 $conditionscompletion = array($prereqforum->cmid => COMPLETION_COMPLETE);
145 $conditionsgrade = array(666 => (object)array('min' => 0.4, 'max' => null, 'name' => '!missing'));
146 $conditionsfield = array('email' => (object)array(
147 'fieldname' => 'email',
148 'operator' => 'contains',
149 'value' => 'test'
150 ));
151 $assign = $this->getDataGenerator()->create_module('assign',
152 array('course' => $course->id),
153 array('idnumber' => 123,
154 'groupmode' => VISIBLEGROUPS,
155 'availablefrom' => time() + 3600,
156 'availableuntil' => time() + 5*3600));
157 $ci = new condition_info((object)array('id' => $assign->cmid), CONDITION_MISSING_EVERYTHING);
158 foreach ($conditionscompletion as $cmid => $requiredcompletion) {
159 $ci->add_completion_condition($cmid, $requiredcompletion);
160 }
161 foreach ($conditionsgrade as $gradeid => $conditiongrade) {
162 $ci->add_grade_condition($gradeid, $conditiongrade->min, $conditiongrade->max, true);
163 }
164 foreach ($conditionsfield as $conditionfield) {
165 $ci->add_user_field_condition($conditionfield->fieldname, $conditionfield->operator, $conditionfield->value);
166 }
167
168 // Retrieve all related records from DB.
169 $assigndb = $DB->get_record('assign', array('id' => $assign->id));
170 $moduletypedb = $DB->get_record('modules', array('name' => 'assign'));
171 $moduledb = $DB->get_record('course_modules', array('module' => $moduletypedb->id, 'instance' => $assign->id));
172 $sectiondb = $DB->get_record('course_sections', array('id' => $moduledb->section));
173 $modnamessingular = get_module_types_names(false);
174 $modnamesplural = get_module_types_names(true);
175
176 // Create and enrol a student.
177 $studentrole = $DB->get_record('role', array('shortname' => 'student'), '*', MUST_EXIST);
178 $student = $this->getDataGenerator()->create_user();
179 role_assign($studentrole->id, $student->id, $coursecontext);
180 $enrolplugin = enrol_get_plugin('manual');
181 $enrolinstance = $DB->get_record('enrol', array('courseid' => $course->id, 'enrol' => 'manual'));
182 $enrolplugin->enrol_user($enrolinstance, $student->id);
183 $this->setUser($student);
184
185 // Emulate data used in building course cache to receive the same instance of cached_cm_info as was used in building modinfo.
186 $rawmods = get_course_mods($course->id);
187 $cachedcminfo = assign_get_coursemodule_info($rawmods[$moduledb->id]);
188
189 // Get modinfo.
190 $modinfo = get_fast_modinfo($course->id);
191 $cm = $modinfo->instances['assign'][$assign->id];
192
193 $this->assertEquals($moduledb->id, $cm->id);
194 $this->assertEquals($assigndb->id, $cm->instance);
195 $this->assertEquals($moduledb->course, $cm->course);
196 $this->assertEquals($moduledb->idnumber, $cm->idnumber);
197 $this->assertEquals($moduledb->added, $cm->added);
198 $this->assertEquals($moduledb->visible, $cm->visible);
199 $this->assertEquals($moduledb->visibleold, $cm->visibleold);
200 $this->assertEquals($moduledb->groupmode, $cm->groupmode);
201 $this->assertEquals(VISIBLEGROUPS, $cm->groupmode);
202 $this->assertEquals($moduledb->groupingid, $cm->groupingid);
203 $this->assertEquals($moduledb->groupmembersonly, $cm->groupmembersonly);
204 $this->assertEquals($course->groupmodeforce, $cm->coursegroupmodeforce);
205 $this->assertEquals($course->groupmode, $cm->coursegroupmode);
206 $this->assertEquals(SEPARATEGROUPS, $cm->coursegroupmode);
207 $this->assertEquals($course->groupmodeforce ? $course->groupmode : $moduledb->groupmode,
208 $cm->effectivegroupmode); // (since mod_assign supports groups).
209 $this->assertEquals(VISIBLEGROUPS, $cm->effectivegroupmode);
210 $this->assertEquals($moduledb->indent, $cm->indent);
211 $this->assertEquals($moduledb->completion, $cm->completion);
212 $this->assertEquals($moduledb->completiongradeitemnumber, $cm->completiongradeitemnumber);
213 $this->assertEquals($moduledb->completionview, $cm->completionview);
214 $this->assertEquals($moduledb->completionexpected, $cm->completionexpected);
215 $this->assertEquals($moduledb->availablefrom, $cm->availablefrom);
216 $this->assertEquals($moduledb->availableuntil, $cm->availableuntil);
217 $this->assertEquals($moduledb->showavailability, $cm->showavailability);
218 $this->assertEquals($moduledb->showdescription, $cm->showdescription);
219 $this->assertEquals(null, $cm->extra); // Deprecated field. Used in module types that don't return cached_cm_info.
220 $this->assertEquals($cachedcminfo->icon, $cm->icon);
221 $this->assertEquals($cachedcminfo->iconcomponent, $cm->iconcomponent);
222 $this->assertEquals('assign', $cm->modname);
223 $this->assertEquals($moduledb->module, $cm->module);
224 $this->assertEquals($cachedcminfo->name, $cm->name);
225 $this->assertEquals($sectiondb->section, $cm->sectionnum);
226 $this->assertEquals($moduledb->section, $cm->section);
227 $this->assertEquals($conditionscompletion, $cm->conditionscompletion);
228 $this->assertEquals($conditionsgrade, $cm->conditionsgrade);
229 $this->assertEquals($conditionsfield, $cm->conditionsfield);
230 $this->assertEquals(context_module::instance($moduledb->id), $cm->context);
231 $this->assertEquals($modnamessingular['assign'], $cm->modfullname);
232 $this->assertEquals($modnamesplural['assign'], $cm->modplural);
233 $this->assertEquals(new moodle_url('/mod/assign/view.php', array('id' => $moduledb->id)), $cm->url);
234 $this->assertEquals($cachedcminfo->customdata, $cm->customdata);
235
236 // Dynamic fields, just test that they can be retrieved (must be carefully tested in each activity type).
237 $this->assertNotEmpty($cm->availableinfo); // Lists all unmet availability conditions.
238 $this->assertEquals(0, $cm->uservisible);
239 $this->assertEquals('', $cm->extraclasses);
240 $this->assertEquals('', $cm->onclick);
241 $this->assertEquals(null, $cm->afterlink);
242 $this->assertEquals(null, $cm->afterediticons);
243 $this->assertEquals('', $cm->content);
244
245 // Attempt to access and set non-existing field.
246 $this->assertTrue(empty($modinfo->somefield));
247 $this->assertFalse(isset($modinfo->somefield));
248 $cm->somefield;
249 $this->assertDebuggingCalled();
250 $cm->somefield = 'Some value';
251 $this->assertDebuggingCalled();
252 $this->assertEmpty($cm->somefield);
253 $this->assertDebuggingCalled();
254
255 // Attempt to overwrite an existing field.
256 $prevvalue = $cm->name;
257 $this->assertNotEmpty($cm->name);
258 $this->assertFalse(empty($cm->name));
259 $this->assertTrue(isset($cm->name));
260 $cm->name = 'Illegal overwriting';
261 $this->assertDebuggingCalled();
262 $this->assertEquals($prevvalue, $cm->name);
263 $this->assertDebuggingNotCalled();
264
265 // Restore settings.
266 set_config('enableavailability', $oldcfgenableavailability);
267 set_config('enablecompletion', $oldcfgenablecompletion);
268 }
69632d42
AD
269
270 /**
271 * Test is_user_access_restricted_by_group()
272 *
273 * The underlying groups system is more thoroughly tested in lib/tests/grouplib_test.php
274 */
275 public function test_is_user_access_restricted_by_group() {
276 global $DB, $CFG, $USER;
277
e2262d70 278 $this->resetAfterTest();
69632d42 279
e2262d70 280 // Create a course.
69632d42
AD
281 $course = $this->getDataGenerator()->create_course();
282 $coursecontext = context_course::instance($course->id);
283
e2262d70 284 // Create a mod_assign instance.
69632d42
AD
285 $assign = $this->getDataGenerator()->create_module('assign', array('course'=>$course->id));
286 $cm_info = get_fast_modinfo($course)->instances['assign'][$assign->id];
287
e2262d70
PS
288 // Create and enrol a student.
289 // Enrolment is necessary for groups to work.
69632d42
AD
290 $studentrole = $DB->get_record('role', array('shortname'=>'student'), '*', MUST_EXIST);
291 $student = $this->getDataGenerator()->create_user();
292 role_assign($studentrole->id, $student->id, $coursecontext);
293 $enrolplugin = enrol_get_plugin('manual');
294 $enrolplugin->add_instance($course);
295 $enrolinstances = enrol_get_instances($course->id, false);
296 foreach ($enrolinstances as $enrolinstance) {
297 if ($enrolinstance->enrol === 'manual') {
298 break;
299 }
300 }
301 $enrolplugin->enrol_user($enrolinstance, $student->id);
302
e2262d70 303 // Switch to a student and reload the context info.
69632d42 304 $this->setUser($student);
88715ba2 305 $cm_info = get_fast_modinfo($course)->instances['assign'][$assign->id];
69632d42 306
e2262d70 307 // Create up a teacher.
69632d42
AD
308 $teacherrole = $DB->get_record('role', array('shortname'=>'editingteacher'), '*', MUST_EXIST);
309 $teacher = $this->getDataGenerator()->create_user();
310 role_assign($teacherrole->id, $teacher->id, $coursecontext);
311
e2262d70 312 // Create 2 groupings.
69632d42
AD
313 $grouping1 = $this->getDataGenerator()->create_grouping(array('courseid' => $course->id, 'name' => 'grouping1'));
314 $grouping2 = $this->getDataGenerator()->create_grouping(array('courseid' => $course->id, 'name' => 'grouping2'));
315
e2262d70 316 // Create 2 groups and put them in the groupings.
69632d42
AD
317 $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course->id, 'idnumber' => 'group1'));
318 groups_assign_grouping($grouping1->id, $group1->id);
319 $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course->id, 'idnumber' => 'group2'));
320 groups_assign_grouping($grouping2->id, $group2->id);
321
322 // If groups are disabled, the activity isn't restricted.
323 $CFG->enablegroupmembersonly = false;
324 $this->assertFalse($cm_info->is_user_access_restricted_by_group());
325
88715ba2 326 // Turn groups setting on.
69632d42 327 $CFG->enablegroupmembersonly = true;
88715ba2
MG
328 // Create a mod_assign instance with "group members only", the activity should not be restricted.
329 $assignnogroups = $this->getDataGenerator()->create_module('assign', array('course'=>$course->id),
330 array('groupmembersonly' => NOGROUPS));
331 $cm_info = get_fast_modinfo($course->id)->instances['assign'][$assignnogroups->id];
69632d42
AD
332 $this->assertFalse($cm_info->is_user_access_restricted_by_group());
333
334 // If "group members only" is on but user is in the wrong group, the activity is restricted.
88715ba2
MG
335 $assignsepgroups = $this->getDataGenerator()->create_module('assign', array('course'=>$course->id),
336 array('groupmembersonly' => SEPARATEGROUPS, 'groupingid' => $grouping1->id));
69632d42 337 $this->assertTrue(groups_add_member($group2, $USER));
88715ba2
MG
338 get_fast_modinfo($course->id, 0, true);
339 $cm_info = get_fast_modinfo($course->id)->instances['assign'][$assignsepgroups->id];
340 $this->assertEquals($grouping1->id, $cm_info->groupingid);
69632d42
AD
341 $this->assertTrue($cm_info->is_user_access_restricted_by_group());
342
343 // If the user is in the required group, the activity isn't restricted.
344 groups_remove_member($group2, $USER);
345 $this->assertTrue(groups_add_member($group1, $USER));
88715ba2
MG
346 get_fast_modinfo($course->id, 0, true);
347 $cm_info = get_fast_modinfo($course->id)->instances['assign'][$assignsepgroups->id];
69632d42
AD
348 $this->assertFalse($cm_info->is_user_access_restricted_by_group());
349
e2262d70 350 // Switch to a teacher and reload the context info.
69632d42 351 $this->setUser($teacher);
88715ba2 352 $cm_info = get_fast_modinfo($course->id)->instances['assign'][$assignsepgroups->id];
69632d42
AD
353
354 // If the user isn't in the required group but has 'moodle/site:accessallgroups', the activity isn't restricted.
355 $this->assertTrue(has_capability('moodle/site:accessallgroups', $coursecontext));
356 $this->assertFalse($cm_info->is_user_access_restricted_by_group());
357 }
358
359 /**
360 * Test is_user_access_restricted_by_conditional_access()
361 *
362 * The underlying conditional access system is more thoroughly tested in lib/tests/conditionlib_test.php
363 */
364 public function test_is_user_access_restricted_by_conditional_access() {
365 global $DB, $CFG;
366
e2262d70 367 $this->resetAfterTest();
69632d42 368
88715ba2 369 // Create a course.
69632d42 370 $course = $this->getDataGenerator()->create_course();
88715ba2
MG
371 // 1. Create an activity that is currently unavailable and hidden entirely (for students).
372 $assign1 = $this->getDataGenerator()->create_module('assign', array('course'=>$course->id),
373 array('availablefrom' => time() + 10000, 'showavailability' => CONDITION_STUDENTVIEW_HIDE));
374 // 2. Create an activity that is currently available.
375 $assign2 = $this->getDataGenerator()->create_module('assign', array('course'=>$course->id));
376 // 3. Create an activity that is currently unavailable and set to be greyed out.
377 $assign3 = $this->getDataGenerator()->create_module('assign', array('course'=>$course->id),
378 array('availablefrom' => time() + 10000, 'showavailability' => CONDITION_STUDENTVIEW_SHOW));
69632d42 379
e2262d70 380 // Set up a teacher.
69632d42
AD
381 $coursecontext = context_course::instance($course->id);
382 $teacherrole = $DB->get_record('role', array('shortname'=>'editingteacher'), '*', MUST_EXIST);
383 $teacher = $this->getDataGenerator()->create_user();
384 role_assign($teacherrole->id, $teacher->id, $coursecontext);
385
e2262d70 386 // If conditional availability is disabled the activity will always be unrestricted.
69632d42 387 $CFG->enableavailability = false;
88715ba2 388 $cm_info = get_fast_modinfo($course)->instances['assign'][$assign1->id];
69632d42
AD
389 $this->assertFalse($cm_info->is_user_access_restricted_by_conditional_access());
390
88715ba2 391 // Turn on conditional availability and reset the get_fast_modinfo cache.
69632d42 392 $CFG->enableavailability = true;
88715ba2 393 get_fast_modinfo($course, 0, true);
69632d42 394
e2262d70 395 // The unavailable, hidden entirely activity should now be restricted.
88715ba2
MG
396 $cm_info = get_fast_modinfo($course)->instances['assign'][$assign1->id];
397 $this->assertFalse($cm_info->available);
398 $this->assertEquals(CONDITION_STUDENTVIEW_HIDE, $cm_info->showavailability);
69632d42
AD
399 $this->assertTrue($cm_info->is_user_access_restricted_by_conditional_access());
400
e2262d70 401 // If the activity is available it should not be restricted.
88715ba2
MG
402 $cm_info = get_fast_modinfo($course)->instances['assign'][$assign2->id];
403 $this->assertTrue($cm_info->available);
69632d42
AD
404 $this->assertFalse($cm_info->is_user_access_restricted_by_conditional_access());
405
e2262d70 406 // If the activity is unavailable and set to be greyed out it should not be restricted.
88715ba2
MG
407 $cm_info = get_fast_modinfo($course)->instances['assign'][$assign3->id];
408 $this->assertFalse($cm_info->available);
409 $this->assertEquals(CONDITION_STUDENTVIEW_SHOW, $cm_info->showavailability);
69632d42
AD
410 $this->assertFalse($cm_info->is_user_access_restricted_by_conditional_access());
411
e2262d70 412 // If the activity is unavailable and set to be hidden entirely its restricted unless user has 'moodle/course:viewhiddenactivities'.
e2262d70 413 // Switch to a teacher and reload the context info.
69632d42 414 $this->setUser($teacher);
88715ba2
MG
415 $cm_info = get_fast_modinfo($course)->instances['assign'][$assign1->id];
416 $this->assertFalse($cm_info->available);
417 $this->assertEquals(CONDITION_STUDENTVIEW_HIDE, $cm_info->showavailability);
69632d42
AD
418
419 $this->assertTrue(has_capability('moodle/course:viewhiddenactivities', $coursecontext));
420 $this->assertFalse($cm_info->is_user_access_restricted_by_conditional_access());
421 }
086f5f9e 422
3e439915
MG
423 public function test_is_user_access_restricted_by_capability() {
424 global $DB;
425
426 $this->resetAfterTest();
427
428 // Create a course and a mod_assign instance.
429 $course = $this->getDataGenerator()->create_course();
430 $assign = $this->getDataGenerator()->create_module('assign', array('course'=>$course->id));
431
432 // Create and enrol a student.
433 $coursecontext = context_course::instance($course->id);
434 $studentrole = $DB->get_record('role', array('shortname' => 'student'), '*', MUST_EXIST);
435 $student = $this->getDataGenerator()->create_user();
436 role_assign($studentrole->id, $student->id, $coursecontext);
437 $enrolplugin = enrol_get_plugin('manual');
438 $enrolinstance = $DB->get_record('enrol', array('courseid' => $course->id, 'enrol' => 'manual'));
439 $enrolplugin->enrol_user($enrolinstance, $student->id);
440 $this->setUser($student);
441
442 // Make sure student can see the module.
443 $cm = get_fast_modinfo($course->id)->instances['assign'][$assign->id];
444 $this->assertTrue($cm->uservisible);
445 $this->assertFalse($cm->is_user_access_restricted_by_capability());
446
447 // Prohibit student to view mod_assign for the course.
448 role_change_permission($studentrole->id, $coursecontext, 'mod/assign:view', CAP_PROHIBIT);
449 get_fast_modinfo($course->id, 0, true);
450 $cm = get_fast_modinfo($course->id)->instances['assign'][$assign->id];
451 $this->assertFalse($cm->uservisible);
452 $this->assertTrue($cm->is_user_access_restricted_by_capability());
453
454 // Restore permission to student to view mod_assign for the course.
455 role_change_permission($studentrole->id, $coursecontext, 'mod/assign:view', CAP_INHERIT);
456 get_fast_modinfo($course->id, 0, true);
457 $cm = get_fast_modinfo($course->id)->instances['assign'][$assign->id];
458 $this->assertTrue($cm->uservisible);
459 $this->assertFalse($cm->is_user_access_restricted_by_capability());
460
461 // Prohibit student to view mod_assign for the particular module.
462 role_change_permission($studentrole->id, context_module::instance($cm->id), 'mod/assign:view', CAP_PROHIBIT);
463 get_fast_modinfo($course->id, 0, true);
464 $cm = get_fast_modinfo($course->id)->instances['assign'][$assign->id];
465 $this->assertFalse($cm->uservisible);
466 $this->assertTrue($cm->is_user_access_restricted_by_capability());
467
468 // Check calling get_fast_modinfo() for different user:
469 $this->setAdminUser();
470 $cm = get_fast_modinfo($course->id)->instances['assign'][$assign->id];
471 $this->assertTrue($cm->uservisible);
472 $this->assertFalse($cm->is_user_access_restricted_by_capability());
473 $cm = get_fast_modinfo($course->id, $student->id)->instances['assign'][$assign->id];
474 $this->assertFalse($cm->uservisible);
475 $this->assertTrue($cm->is_user_access_restricted_by_capability());
476 }
69632d42 477}