weekly release 2.5dev
[moodle.git] / course / tests / courselib_test.php
CommitLineData
354b214c
PS
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 * Course related unit tests
19 *
20 * @package core
21 * @category phpunit
22 * @copyright 2012 Petr Skoda {@link http://skodak.org}
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 */
25
26defined('MOODLE_INTERNAL') || die();
27
f70bfb84
FM
28global $CFG;
29require_once($CFG->dirroot.'/course/lib.php');
354b214c
PS
30
31class courselib_testcase extends advanced_testcase {
32
dd5d933f 33 /**
7bf4f6e9
JM
34 * Set forum specific test values for calling create_module().
35 *
36 * @param object $moduleinfo - the moduleinfo to add some specific values - passed in reference.
dd5d933f 37 */
7bf4f6e9
JM
38 private function forum_create_set_values(&$moduleinfo) {
39 // Completion specific to forum - optional.
40 $moduleinfo->completionposts = 3;
41 $moduleinfo->completiondiscussions = 1;
42 $moduleinfo->completionreplies = 2;
dd5d933f 43
7cb0ea2c 44 // Specific values to the Forum module.
dd5d933f
JM
45 $moduleinfo->forcesubscribe = FORUM_INITIALSUBSCRIBE;
46 $moduleinfo->type = 'single';
7bf4f6e9
JM
47 $moduleinfo->trackingtype = FORUM_TRACKING_ON;
48 $moduleinfo->maxbytes = 10240;
49 $moduleinfo->maxattachments = 2;
50
7cb0ea2c 51 // Post threshold for blocking - specific to forum.
7bf4f6e9
JM
52 $moduleinfo->blockperiod = 60*60*24;
53 $moduleinfo->blockafter = 10;
54 $moduleinfo->warnafter = 5;
55 }
dd5d933f 56
7bf4f6e9
JM
57 /**
58 * Execute test asserts on the saved DB data by create_module($forum).
59 *
60 * @param object $moduleinfo - the specific forum values that were used to create a forum.
61 * @param object $dbmodinstance - the DB values of the created forum.
62 */
63 private function forum_create_run_asserts($moduleinfo, $dbmodinstance) {
64 // Compare values specific to forums.
65 $this->assertEquals($moduleinfo->forcesubscribe, $dbmodinstance->forcesubscribe);
66 $this->assertEquals($moduleinfo->type, $dbmodinstance->type);
67 $this->assertEquals($moduleinfo->assessed, $dbmodinstance->assessed);
68 $this->assertEquals($moduleinfo->completionposts, $dbmodinstance->completionposts);
69 $this->assertEquals($moduleinfo->completiondiscussions, $dbmodinstance->completiondiscussions);
70 $this->assertEquals($moduleinfo->completionreplies, $dbmodinstance->completionreplies);
71 $this->assertEquals($moduleinfo->scale, $dbmodinstance->scale);
72 $this->assertEquals($moduleinfo->assesstimestart, $dbmodinstance->assesstimestart);
73 $this->assertEquals($moduleinfo->assesstimefinish, $dbmodinstance->assesstimefinish);
74 $this->assertEquals($moduleinfo->rsstype, $dbmodinstance->rsstype);
75 $this->assertEquals($moduleinfo->rssarticles, $dbmodinstance->rssarticles);
76 $this->assertEquals($moduleinfo->trackingtype, $dbmodinstance->trackingtype);
77 $this->assertEquals($moduleinfo->maxbytes, $dbmodinstance->maxbytes);
78 $this->assertEquals($moduleinfo->maxattachments, $dbmodinstance->maxattachments);
79 $this->assertEquals($moduleinfo->blockperiod, $dbmodinstance->blockperiod);
80 $this->assertEquals($moduleinfo->blockafter, $dbmodinstance->blockafter);
81 $this->assertEquals($moduleinfo->warnafter, $dbmodinstance->warnafter);
82 }
dd5d933f 83
7bf4f6e9
JM
84 /**
85 * Set assign module specific test values for calling create_module().
86 *
87 * @param object $moduleinfo - the moduleinfo to add some specific values - passed in reference.
88 */
89 private function assign_create_set_values(&$moduleinfo) {
7cb0ea2c 90 // Specific values to the Assign module.
dd5d933f
JM
91 $moduleinfo->alwaysshowdescription = true;
92 $moduleinfo->submissiondrafts = true;
93 $moduleinfo->requiresubmissionstatement = true;
94 $moduleinfo->sendnotifications = true;
95 $moduleinfo->sendlatenotifications = true;
7bf4f6e9
JM
96 $moduleinfo->duedate = time() + (7 * 24 * 3600);
97 $moduleinfo->cutoffdate = time() + (7 * 24 * 3600);
98 $moduleinfo->allowsubmissionsfromdate = time();
dd5d933f
JM
99 $moduleinfo->teamsubmission = true;
100 $moduleinfo->requireallteammemberssubmit = true;
101 $moduleinfo->teamsubmissiongroupingid = true;
102 $moduleinfo->blindmarking = true;
103 $moduleinfo->assignsubmission_onlinetext_enabled = true;
104 $moduleinfo->assignsubmission_file_enabled = true;
105 $moduleinfo->assignsubmission_file_maxfiles = 1;
106 $moduleinfo->assignsubmission_file_maxsizebytes = 1000000;
107 $moduleinfo->assignsubmission_comments_enabled = true;
108 $moduleinfo->assignfeedback_comments_enabled = true;
109 $moduleinfo->assignfeedback_offline_enabled = true;
110 $moduleinfo->assignfeedback_file_enabled = true;
111
7cb0ea2c 112 // Advanced grading.
7bf4f6e9
JM
113 $gradingmethods = grading_manager::available_methods();
114 $moduleinfo->advancedgradingmethod_submissions = current(array_keys($gradingmethods));
115 }
dd5d933f 116
7bf4f6e9
JM
117 /**
118 * Execute test asserts on the saved DB data by create_module($assign).
119 *
120 * @param object $moduleinfo - the specific assign module values that were used to create an assign module.
121 * @param object $dbmodinstance - the DB values of the created assign module.
122 */
123 private function assign_create_run_asserts($moduleinfo, $dbmodinstance) {
124 global $DB;
125
126 $this->assertEquals($moduleinfo->alwaysshowdescription, $dbmodinstance->alwaysshowdescription);
127 $this->assertEquals($moduleinfo->submissiondrafts, $dbmodinstance->submissiondrafts);
128 $this->assertEquals($moduleinfo->requiresubmissionstatement, $dbmodinstance->requiresubmissionstatement);
129 $this->assertEquals($moduleinfo->sendnotifications, $dbmodinstance->sendnotifications);
130 $this->assertEquals($moduleinfo->duedate, $dbmodinstance->duedate);
131 $this->assertEquals($moduleinfo->cutoffdate, $dbmodinstance->cutoffdate);
132 $this->assertEquals($moduleinfo->allowsubmissionsfromdate, $dbmodinstance->allowsubmissionsfromdate);
133 $this->assertEquals($moduleinfo->teamsubmission, $dbmodinstance->teamsubmission);
134 $this->assertEquals($moduleinfo->requireallteammemberssubmit, $dbmodinstance->requireallteammemberssubmit);
135 $this->assertEquals($moduleinfo->teamsubmissiongroupingid, $dbmodinstance->teamsubmissiongroupingid);
136 $this->assertEquals($moduleinfo->blindmarking, $dbmodinstance->blindmarking);
137 // The goal not being to fully test assign_add_instance() we'll stop here for the assign tests - to avoid too many DB queries.
138
7cb0ea2c 139 // Advanced grading.
7bf4f6e9
JM
140 $contextmodule = context_module::instance($dbmodinstance->id);
141 $advancedgradingmethod = $DB->get_record('grading_areas',
142 array('contextid' => $contextmodule->id,
143 'activemethod' => $moduleinfo->advancedgradingmethod_submissions));
144 $this->assertEquals($moduleinfo->advancedgradingmethod_submissions, $advancedgradingmethod);
145 }
146
147 /**
148 * Run some asserts test for a specific module for the function create_module().
149 *
150 * The function has been created (and is called) for $this->test_create_module().
151 * Note that the call to MODULE_create_set_values and MODULE_create_run_asserts are done after the common set values/run asserts.
152 * So if you want, you can overwrite the default values/asserts in the respective functions.
153 * @param string $modulename Name of the module ('forum', 'assign', 'book'...).
154 */
155 private function create_specific_module_test($modulename) {
156 global $DB, $CFG;
157
158 $this->resetAfterTest(true);
159
160 $this->setAdminUser();
161
162 // Warnings: you'll need to change this line if ever you come to test a module not following Moodle standard.
163 require_once($CFG->dirroot.'/mod/'. $modulename .'/lib.php');
164
165 // Enable avaibility.
166 // If not enabled all conditional fields will be ignored.
167 set_config('enableavailability', 1);
168
169 // Enable course completion.
170 // If not enabled all completion settings will be ignored.
171 set_config('enablecompletion', COMPLETION_ENABLED);
172
173 // Enable forum RSS feeds.
174 set_config('enablerssfeeds', 1);
175 set_config('forum_enablerssfeeds', 1);
176
177 $course = $this->getDataGenerator()->create_course(array('numsections'=>1, 'enablecompletion' => COMPLETION_ENABLED),
178 array('createsections'=>true));
179
180 $grouping = $this->getDataGenerator()->create_grouping(array('courseid' => $course->id));
dd5d933f 181
7cb0ea2c 182 // Create assign module instance for test.
7bf4f6e9
JM
183 $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
184 $params['course'] = $course->id;
185 $instance = $generator->create_instance($params);
186 $assigncm = get_coursemodule_from_instance('assign', $instance->id);
dd5d933f 187
7bf4f6e9
JM
188 // Module test values.
189 $moduleinfo = new stdClass();
dd5d933f 190
7bf4f6e9
JM
191 // Always mandatory generic values to any module.
192 $moduleinfo->modulename = $modulename;
193 $moduleinfo->section = 1; // This is the section number in the course. Not the section id in the database.
194 $moduleinfo->course = $course->id;
195 $moduleinfo->groupingid = $grouping->id;
196 $moduleinfo->groupmembersonly = 0;
197 $moduleinfo->visible = true;
198
199 // Sometimes optional generic values for some modules.
200 $moduleinfo->name = 'My test module';
201 $moduleinfo->showdescription = 1; // standard boolean
202 require_once($CFG->libdir . '/gradelib.php');
203 $gradecats = grade_get_categories_menu($moduleinfo->course, false);
204 $gradecatid = current(array_keys($gradecats)); // Retrieve the first key of $gradecats
205 $moduleinfo->gradecat = $gradecatid;
206 $moduleinfo->groupmode = VISIBLEGROUPS;
207 $moduleinfo->cmidnumber = 'idnumber_XXX';
208
209 // Completion common to all module.
210 $moduleinfo->completion = COMPLETION_TRACKING_AUTOMATIC;
211 $moduleinfo->completionview = COMPLETION_VIEW_REQUIRED;
7cb0ea2c 212 $moduleinfo->completiongradeitemnumber = 1;
7bf4f6e9
JM
213 $moduleinfo->completionexpected = time() + (7 * 24 * 3600);
214
215 // Conditional activity.
216 $moduleinfo->availablefrom = time();
217 $moduleinfo->availableuntil = time() + (7 * 24 * 3600);
218 $moduleinfo->showavailability = CONDITION_STUDENTVIEW_SHOW;
219 $coursegradeitem = grade_item::fetch_course_item($moduleinfo->course); //the activity will become available only when the user reach some grade into the course itself.
220 $moduleinfo->conditiongradegroup = array(array('conditiongradeitemid' => $coursegradeitem->id, 'conditiongrademin' => 10, 'conditiongrademax' => 80));
221 $moduleinfo->conditionfieldgroup = array(array('conditionfield' => 'email', 'conditionfieldoperator' => OP_CONTAINS, 'conditionfieldvalue' => '@'));
222 $moduleinfo->conditioncompletiongroup = array(array('conditionsourcecmid' => $assigncm->id, 'conditionrequiredcompletion' => COMPLETION_COMPLETE)); // "conditionsourcecmid == 0" => none
223
224 // Grading and Advanced grading.
225 require_once($CFG->dirroot . '/rating/lib.php');
226 $moduleinfo->assessed = RATING_AGGREGATE_AVERAGE;
227 $moduleinfo->scale = 10; // Note: it could be minus (for specific course scale). It is a signed number.
228 $moduleinfo->assesstimestart = time();
229 $moduleinfo->assesstimefinish = time() + (7 * 24 * 3600);
230
7cb0ea2c 231 // RSS.
7bf4f6e9
JM
232 $moduleinfo->rsstype = 2;
233 $moduleinfo->rssarticles = 10;
234
235 // Optional intro editor (depends of module).
7bf4f6e9
JM
236 $draftid_editor = 0;
237 file_prepare_draft_area($draftid_editor, null, null, null, null);
238 $moduleinfo->introeditor = array('text' => 'This is a module', 'format' => FORMAT_HTML, 'itemid' => $draftid_editor);
dd5d933f 239
7bf4f6e9
JM
240 // Following is the advanced grading method area called 'submissions' for the 'assign' module.
241 if (plugin_supports('mod', $modulename, FEATURE_GRADE_HAS_GRADE, false) && !plugin_supports('mod', $modulename, FEATURE_RATE, false)) {
242 $moduleinfo->grade = 100;
243 }
7cb0ea2c 244
7bf4f6e9
JM
245 // Plagiarism form values.
246 // No plagiarism plugin installed by default. Use this space to make your own test.
247
248 // Values specific to the module.
249 $modulesetvalues = $modulename.'_create_set_values';
250 $this->$modulesetvalues($moduleinfo);
251
252 // Create the module.
253 $result = create_module($moduleinfo);
254
255 // Retrieve the module info.
256 $dbmodinstance = $DB->get_record($moduleinfo->modulename, array('id' => $result->instance));
257 $dbcm = get_coursemodule_from_instance($moduleinfo->modulename, $result->instance);
258 // We passed the course section number to create_courses but $dbcm contain the section id.
259 // We need to retrieve the db course section number.
260 $section = $DB->get_record('course_sections', array('course' => $dbcm->course, 'id' => $dbcm->section));
7cb0ea2c 261 // Retrieve the grade item.
7bf4f6e9
JM
262 $gradeitem = $DB->get_record('grade_items', array('courseid' => $moduleinfo->course,
263 'iteminstance' => $dbmodinstance->id, 'itemmodule' => $moduleinfo->modulename));
264
265 // Compare the values common to all module instances.
266 $this->assertEquals($moduleinfo->modulename, $dbcm->modname);
267 $this->assertEquals($moduleinfo->section, $section->section);
268 $this->assertEquals($moduleinfo->course, $dbcm->course);
269 $this->assertEquals($moduleinfo->groupingid, $dbcm->groupingid);
270 $this->assertEquals($moduleinfo->groupmembersonly, $dbcm->groupmembersonly);
271 $this->assertEquals($moduleinfo->visible, $dbcm->visible);
272 $this->assertEquals($moduleinfo->completion, $dbcm->completion);
273 $this->assertEquals($moduleinfo->completionview, $dbcm->completionview);
274 $this->assertEquals($moduleinfo->completiongradeitemnumber, $dbcm->completiongradeitemnumber);
275 $this->assertEquals($moduleinfo->completionexpected, $dbcm->completionexpected);
276 $this->assertEquals($moduleinfo->availablefrom, $dbcm->availablefrom);
277 $this->assertEquals($moduleinfo->availableuntil, $dbcm->availableuntil);
278 $this->assertEquals($moduleinfo->showavailability, $dbcm->showavailability);
279 $this->assertEquals($moduleinfo->showdescription, $dbcm->showdescription);
280 $this->assertEquals($moduleinfo->groupmode, $dbcm->groupmode);
281 $this->assertEquals($moduleinfo->cmidnumber, $dbcm->idnumber);
282 $this->assertEquals($moduleinfo->gradecat, $gradeitem->categoryid);
283
284 // Optional grade testing.
285 if (plugin_supports('mod', $modulename, FEATURE_GRADE_HAS_GRADE, false) && !plugin_supports('mod', $modulename, FEATURE_RATE, false)) {
286 $this->assertEquals($moduleinfo->grade, $dbmodinstance->grade);
287 }
288
289 // Some optional (but quite common) to some module.
290 $this->assertEquals($moduleinfo->name, $dbmodinstance->name);
291 $this->assertEquals($moduleinfo->intro, $dbmodinstance->intro);
292 $this->assertEquals($moduleinfo->introformat, $dbmodinstance->introformat);
293
294 // Common values when conditional activity is enabled.
295 foreach ($moduleinfo->conditionfieldgroup as $fieldgroup) {
296 $isfieldgroupsaved = $DB->count_records('course_modules_avail_fields', array('coursemoduleid' => $dbcm->id,
297 'userfield' => $fieldgroup['conditionfield'], 'operator' => $fieldgroup['conditionfieldoperator'],
298 'value' => $fieldgroup['conditionfieldvalue']));
299 $this->assertEquals(1, $isfieldgroupsaved);
300 }
301 foreach ($moduleinfo->conditiongradegroup as $gradegroup) {
302 $isgradegroupsaved = $DB->count_records('course_modules_availability', array('coursemoduleid' => $dbcm->id,
303 'grademin' => $gradegroup['conditiongrademin'], 'grademax' => $gradegroup['conditiongrademax'],
304 'gradeitemid' => $gradegroup['conditiongradeitemid']));
305 $this->assertEquals(1, $isgradegroupsaved);
306 }
307 foreach ($moduleinfo->conditioncompletiongroup as $completiongroup) {
308 $iscompletiongroupsaved = $DB->count_records('course_modules_availability', array('coursemoduleid' => $dbcm->id,
309 'sourcecmid' => $completiongroup['conditionsourcecmid'], 'requiredcompletion' => $completiongroup['conditionrequiredcompletion']));
310 $this->assertEquals(1, $iscompletiongroupsaved);
311 }
312
7cb0ea2c 313 // Test specific to the module.
7bf4f6e9
JM
314 $modulerunasserts = $modulename.'_create_run_asserts';
315 $this->$modulerunasserts($moduleinfo, $dbmodinstance);
7bf4f6e9 316 }
dd5d933f 317
7bf4f6e9
JM
318 /**
319 * Test create_module() for multiple modules defined in the $modules array (first declaration of the function).
320 */
321 public function test_create_module() {
322 // Add the module name you want to test here.
7cb0ea2c 323 // Create the match MODULENAME_create_set_values() and MODULENAME_create_run_asserts().
7bf4f6e9
JM
324 $modules = array('forum', 'assign');
325 // Run all tests.
326 foreach ($modules as $modulename) {
327 $this->create_specific_module_test($modulename);
328 }
dd5d933f
JM
329 }
330
331 /**
7bf4f6e9 332 * Test update_module() for multiple modules defined in the $modules array (first declaration of the function).
dd5d933f
JM
333 */
334 public function test_update_module() {
7bf4f6e9 335 // Add the module name you want to test here.
7cb0ea2c 336 // Create the match MODULENAME_update_set_values() and MODULENAME_update_run_asserts().
7bf4f6e9
JM
337 $modules = array('forum');
338 // Run all tests.
339 foreach ($modules as $modulename) {
340 $this->update_specific_module_test($modulename);
341 }
342 }
343
344 /**
345 * Set forum specific test values for calling update_module().
346 *
347 * @param object $moduleinfo - the moduleinfo to add some specific values - passed in reference.
348 */
349 private function forum_update_set_values(&$moduleinfo) {
350 // Completion specific to forum - optional.
351 $moduleinfo->completionposts = 3;
352 $moduleinfo->completiondiscussions = 1;
353 $moduleinfo->completionreplies = 2;
354
7cb0ea2c 355 // Specific values to the Forum module.
7bf4f6e9
JM
356 $moduleinfo->forcesubscribe = FORUM_INITIALSUBSCRIBE;
357 $moduleinfo->type = 'single';
358 $moduleinfo->trackingtype = FORUM_TRACKING_ON;
359 $moduleinfo->maxbytes = 10240;
360 $moduleinfo->maxattachments = 2;
361
7cb0ea2c 362 // Post threshold for blocking - specific to forum.
7bf4f6e9
JM
363 $moduleinfo->blockperiod = 60*60*24;
364 $moduleinfo->blockafter = 10;
365 $moduleinfo->warnafter = 5;
366 }
367
368 /**
369 * Execute test asserts on the saved DB data by update_module($forum).
370 *
371 * @param object $moduleinfo - the specific forum values that were used to update a forum.
372 * @param object $dbmodinstance - the DB values of the updated forum.
373 */
374 private function forum_update_run_asserts($moduleinfo, $dbmodinstance) {
375 // Compare values specific to forums.
376 $this->assertEquals($moduleinfo->forcesubscribe, $dbmodinstance->forcesubscribe);
377 $this->assertEquals($moduleinfo->type, $dbmodinstance->type);
378 $this->assertEquals($moduleinfo->assessed, $dbmodinstance->assessed);
379 $this->assertEquals($moduleinfo->completionposts, $dbmodinstance->completionposts);
380 $this->assertEquals($moduleinfo->completiondiscussions, $dbmodinstance->completiondiscussions);
381 $this->assertEquals($moduleinfo->completionreplies, $dbmodinstance->completionreplies);
382 $this->assertEquals($moduleinfo->scale, $dbmodinstance->scale);
383 $this->assertEquals($moduleinfo->assesstimestart, $dbmodinstance->assesstimestart);
384 $this->assertEquals($moduleinfo->assesstimefinish, $dbmodinstance->assesstimefinish);
385 $this->assertEquals($moduleinfo->rsstype, $dbmodinstance->rsstype);
386 $this->assertEquals($moduleinfo->rssarticles, $dbmodinstance->rssarticles);
387 $this->assertEquals($moduleinfo->trackingtype, $dbmodinstance->trackingtype);
388 $this->assertEquals($moduleinfo->maxbytes, $dbmodinstance->maxbytes);
389 $this->assertEquals($moduleinfo->maxattachments, $dbmodinstance->maxattachments);
390 $this->assertEquals($moduleinfo->blockperiod, $dbmodinstance->blockperiod);
391 $this->assertEquals($moduleinfo->blockafter, $dbmodinstance->blockafter);
392 $this->assertEquals($moduleinfo->warnafter, $dbmodinstance->warnafter);
393 }
394
395
396
397 /**
398 * Test a specific type of module.
399 *
400 * @param string $modulename - the module name to test
401 */
402 private function update_specific_module_test($modulename) {
dd5d933f
JM
403 global $DB, $CFG;
404
405 $this->resetAfterTest(true);
406
407 $this->setAdminUser();
408
7bf4f6e9
JM
409 // Warnings: you'll need to change this line if ever you come to test a module not following Moodle standard.
410 require_once($CFG->dirroot.'/mod/'. $modulename .'/lib.php');
dd5d933f 411
7bf4f6e9
JM
412 // Enable avaibility.
413 // If not enabled all conditional fields will be ignored.
414 set_config('enableavailability', 1);
415
416 // Enable course completion.
417 // If not enabled all completion settings will be ignored.
418 set_config('enablecompletion', COMPLETION_ENABLED);
419
420 // Enable forum RSS feeds.
421 set_config('enablerssfeeds', 1);
422 set_config('forum_enablerssfeeds', 1);
423
424 $course = $this->getDataGenerator()->create_course(array('numsections'=>1, 'enablecompletion' => COMPLETION_ENABLED),
dd5d933f
JM
425 array('createsections'=>true));
426
427 $grouping = $this->getDataGenerator()->create_grouping(array('courseid' => $course->id));
428
7cb0ea2c 429 // Create assign module instance for testing gradeitem.
7bf4f6e9
JM
430 $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
431 $params['course'] = $course->id;
432 $instance = $generator->create_instance($params);
433 $assigncm = get_coursemodule_from_instance('assign', $instance->id);
dd5d933f 434
7cb0ea2c 435 // Create the test forum to update.
7bf4f6e9
JM
436 $initvalues = new stdClass();
437 $initvalues->introformat = FORMAT_HTML;
438 $initvalues->course = $course->id;
439 $forum = self::getDataGenerator()->create_module('forum', $initvalues);
dd5d933f 440
7cb0ea2c 441 // Retrieve course module.
7bf4f6e9 442 $cm = get_coursemodule_from_instance('forum', $forum->id);
dd5d933f 443
7bf4f6e9 444 // Module test values.
dd5d933f
JM
445 $moduleinfo = new stdClass();
446
7bf4f6e9 447 // Always mandatory generic values to any module.
dd5d933f 448 $moduleinfo->coursemodule = $cm->id;
7bf4f6e9
JM
449 $moduleinfo->modulename = $modulename;
450 $moduleinfo->course = $course->id;
451 $moduleinfo->groupingid = $grouping->id;
452 $moduleinfo->groupmembersonly = 0;
453 $moduleinfo->visible = true;
454
455 // Sometimes optional generic values for some modules.
456 $moduleinfo->name = 'My test module';
457 $moduleinfo->showdescription = 1; // standard boolean
458 require_once($CFG->libdir . '/gradelib.php');
459 $gradecats = grade_get_categories_menu($moduleinfo->course, false);
460 $gradecatid = current(array_keys($gradecats)); // Retrieve the first key of $gradecats
461 $moduleinfo->gradecat = $gradecatid;
462 $moduleinfo->groupmode = VISIBLEGROUPS;
463 $moduleinfo->cmidnumber = 'idnumber_XXX';
464
465 // Completion common to all module.
466 $moduleinfo->completion = COMPLETION_TRACKING_AUTOMATIC;
467 $moduleinfo->completionview = COMPLETION_VIEW_REQUIRED;
7cb0ea2c 468 $moduleinfo->completiongradeitemnumber = 1;
7bf4f6e9
JM
469 $moduleinfo->completionexpected = time() + (7 * 24 * 3600);
470
471 // Conditional activity.
472 $moduleinfo->availablefrom = time();
473 $moduleinfo->availableuntil = time() + (7 * 24 * 3600);
474 $moduleinfo->showavailability = CONDITION_STUDENTVIEW_SHOW;
475 $coursegradeitem = grade_item::fetch_course_item($moduleinfo->course); //the activity will become available only when the user reach some grade into the course itself.
476 $moduleinfo->conditiongradegroup = array(array('conditiongradeitemid' => $coursegradeitem->id, 'conditiongrademin' => 10, 'conditiongrademax' => 80));
477 $moduleinfo->conditionfieldgroup = array(array('conditionfield' => 'email', 'conditionfieldoperator' => OP_CONTAINS, 'conditionfieldvalue' => '@'));
478 $moduleinfo->conditioncompletiongroup = array(array('conditionsourcecmid' => $assigncm->id, 'conditionrequiredcompletion' => COMPLETION_COMPLETE)); // "conditionsourcecmid == 0" => none
479
480 // Grading and Advanced grading.
481 require_once($CFG->dirroot . '/rating/lib.php');
482 $moduleinfo->assessed = RATING_AGGREGATE_AVERAGE;
483 $moduleinfo->scale = 10; // Note: it could be minus (for specific course scale). It is a signed number.
484 $moduleinfo->assesstimestart = time();
485 $moduleinfo->assesstimefinish = time() + (7 * 24 * 3600);
486
7cb0ea2c 487 // RSS.
7bf4f6e9
JM
488 $moduleinfo->rsstype = 2;
489 $moduleinfo->rssarticles = 10;
490
491 // Optional intro editor (depends of module).
dd5d933f
JM
492 $draftid_editor = 0;
493 file_prepare_draft_area($draftid_editor, null, null, null, null);
7bf4f6e9 494 $moduleinfo->introeditor = array('text' => 'This is a module', 'format' => FORMAT_HTML, 'itemid' => $draftid_editor);
dd5d933f 495
7bf4f6e9
JM
496 // Following is the advanced grading method area called 'submissions' for the 'assign' module.
497 if (plugin_supports('mod', $modulename, FEATURE_GRADE_HAS_GRADE, false) && !plugin_supports('mod', $modulename, FEATURE_RATE, false)) {
498 $moduleinfo->grade = 100;
499 }
500 // Plagiarism form values.
dd5d933f
JM
501 // No plagiarism plugin installed by default. Use this space to make your own test.
502
7bf4f6e9
JM
503 // Values specific to the module.
504 $modulesetvalues = $modulename.'_update_set_values';
505 $this->$modulesetvalues($moduleinfo);
506
507 // Create the module.
508 $result = update_module($moduleinfo);
509
510 // Retrieve the module info.
511 $dbmodinstance = $DB->get_record($moduleinfo->modulename, array('id' => $result->instance));
512 $dbcm = get_coursemodule_from_instance($moduleinfo->modulename, $result->instance);
7cb0ea2c 513 // Retrieve the grade item.
7bf4f6e9
JM
514 $gradeitem = $DB->get_record('grade_items', array('courseid' => $moduleinfo->course,
515 'iteminstance' => $dbmodinstance->id, 'itemmodule' => $moduleinfo->modulename));
516
517 // Compare the values common to all module instances.
518 $this->assertEquals($moduleinfo->modulename, $dbcm->modname);
519 $this->assertEquals($moduleinfo->course, $dbcm->course);
520 $this->assertEquals($moduleinfo->groupingid, $dbcm->groupingid);
521 $this->assertEquals($moduleinfo->groupmembersonly, $dbcm->groupmembersonly);
522 $this->assertEquals($moduleinfo->visible, $dbcm->visible);
523 $this->assertEquals($moduleinfo->completion, $dbcm->completion);
524 $this->assertEquals($moduleinfo->completionview, $dbcm->completionview);
525 $this->assertEquals($moduleinfo->completiongradeitemnumber, $dbcm->completiongradeitemnumber);
526 $this->assertEquals($moduleinfo->completionexpected, $dbcm->completionexpected);
527 $this->assertEquals($moduleinfo->availablefrom, $dbcm->availablefrom);
528 $this->assertEquals($moduleinfo->availableuntil, $dbcm->availableuntil);
529 $this->assertEquals($moduleinfo->showavailability, $dbcm->showavailability);
530 $this->assertEquals($moduleinfo->showdescription, $dbcm->showdescription);
531 $this->assertEquals($moduleinfo->groupmode, $dbcm->groupmode);
532 $this->assertEquals($moduleinfo->cmidnumber, $dbcm->idnumber);
533 $this->assertEquals($moduleinfo->gradecat, $gradeitem->categoryid);
534
535 // Optional grade testing.
536 if (plugin_supports('mod', $modulename, FEATURE_GRADE_HAS_GRADE, false) && !plugin_supports('mod', $modulename, FEATURE_RATE, false)) {
537 $this->assertEquals($moduleinfo->grade, $dbmodinstance->grade);
538 }
539
540 // Some optional (but quite common) to some module.
541 $this->assertEquals($moduleinfo->name, $dbmodinstance->name);
542 $this->assertEquals($moduleinfo->intro, $dbmodinstance->intro);
543 $this->assertEquals($moduleinfo->introformat, $dbmodinstance->introformat);
544
545 // Common values when conditional activity is enabled.
546 foreach ($moduleinfo->conditionfieldgroup as $fieldgroup) {
547 $isfieldgroupsaved = $DB->count_records('course_modules_avail_fields', array('coursemoduleid' => $dbcm->id,
548 'userfield' => $fieldgroup['conditionfield'], 'operator' => $fieldgroup['conditionfieldoperator'],
549 'value' => $fieldgroup['conditionfieldvalue']));
550 $this->assertEquals(1, $isfieldgroupsaved);
551 }
552 foreach ($moduleinfo->conditiongradegroup as $gradegroup) {
553 $isgradegroupsaved = $DB->count_records('course_modules_availability', array('coursemoduleid' => $dbcm->id,
554 'grademin' => $gradegroup['conditiongrademin'], 'grademax' => $gradegroup['conditiongrademax'],
555 'gradeitemid' => $gradegroup['conditiongradeitemid']));
556 $this->assertEquals(1, $isgradegroupsaved);
557 }
558 foreach ($moduleinfo->conditioncompletiongroup as $completiongroup) {
559 $iscompletiongroupsaved = $DB->count_records('course_modules_availability', array('coursemoduleid' => $dbcm->id,
560 'sourcecmid' => $completiongroup['conditionsourcecmid'], 'requiredcompletion' => $completiongroup['conditionrequiredcompletion']));
561 $this->assertEquals(1, $iscompletiongroupsaved);
562 }
563
7cb0ea2c 564 // Test specific to the module.
7bf4f6e9
JM
565 $modulerunasserts = $modulename.'_update_run_asserts';
566 $this->$modulerunasserts($moduleinfo, $dbmodinstance);
567 }
dd5d933f
JM
568
569
f70bfb84
FM
570 public function test_create_course() {
571 global $DB;
572 $this->resetAfterTest(true);
573 $defaultcategory = $DB->get_field_select('course_categories', "MIN(id)", "parent=0");
574
575 $course = new stdClass();
576 $course->fullname = 'Apu loves Unit Təsts';
577 $course->shortname = 'Spread the lŭve';
578 $course->idnumber = '123';
579 $course->summary = 'Awesome!';
580 $course->summaryformat = FORMAT_PLAIN;
581 $course->format = 'topics';
582 $course->newsitems = 0;
583 $course->numsections = 5;
584 $course->category = $defaultcategory;
585
586 $created = create_course($course);
587 $context = context_course::instance($created->id);
588
589 // Compare original and created.
590 $original = (array) $course;
591 $this->assertEquals($original, array_intersect_key((array) $created, $original));
592
593 // Ensure default section is created.
594 $sectioncreated = $DB->record_exists('course_sections', array('course' => $created->id, 'section' => 0));
595 $this->assertTrue($sectioncreated);
596
597 // Ensure blocks have been associated to the course.
598 $blockcount = $DB->count_records('block_instances', array('parentcontextid' => $context->id));
599 $this->assertGreaterThan(0, $blockcount);
600 }
601
384c3510
MG
602 public function test_create_course_with_generator() {
603 global $DB;
604 $this->resetAfterTest(true);
605 $course = $this->getDataGenerator()->create_course();
606
607 // Ensure default section is created.
608 $sectioncreated = $DB->record_exists('course_sections', array('course' => $course->id, 'section' => 0));
609 $this->assertTrue($sectioncreated);
610 }
611
612 public function test_create_course_sections() {
613 global $DB;
614 $this->resetAfterTest(true);
615
616 $course = $this->getDataGenerator()->create_course(
617 array('shortname' => 'GrowingCourse',
618 'fullname' => 'Growing Course',
619 'numsections' => 5),
620 array('createsections' => true));
621
622 // Ensure all 6 (0-5) sections were created and modinfo/sectioninfo cache works properly
623 $sectionscreated = array_keys(get_fast_modinfo($course)->get_section_info_all());
624 $this->assertEquals(range(0, $course->numsections), $sectionscreated);
625
626 // this will do nothing, section already exists
627 $this->assertFalse(course_create_sections_if_missing($course, $course->numsections));
628
629 // this will create new section
630 $this->assertTrue(course_create_sections_if_missing($course, $course->numsections + 1));
631
632 // Ensure all 7 (0-6) sections were created and modinfo/sectioninfo cache works properly
633 $sectionscreated = array_keys(get_fast_modinfo($course)->get_section_info_all());
634 $this->assertEquals(range(0, $course->numsections + 1), $sectionscreated);
635 }
636
354b214c
PS
637 public function test_reorder_sections() {
638 global $DB;
639 $this->resetAfterTest(true);
640
641 $this->getDataGenerator()->create_course(array('numsections'=>5), array('createsections'=>true));
642 $course = $this->getDataGenerator()->create_course(array('numsections'=>10), array('createsections'=>true));
643 $oldsections = array();
644 $sections = array();
3a222db2 645 foreach ($DB->get_records('course_sections', array('course'=>$course->id), 'id') as $section) {
354b214c
PS
646 $oldsections[$section->section] = $section->id;
647 $sections[$section->id] = $section->section;
648 }
649 ksort($oldsections);
650
651 $neworder = reorder_sections($sections, 2, 4);
652 $neworder = array_keys($neworder);
653 $this->assertEquals($oldsections[0], $neworder[0]);
654 $this->assertEquals($oldsections[1], $neworder[1]);
655 $this->assertEquals($oldsections[2], $neworder[4]);
656 $this->assertEquals($oldsections[3], $neworder[2]);
657 $this->assertEquals($oldsections[4], $neworder[3]);
658 $this->assertEquals($oldsections[5], $neworder[5]);
659 $this->assertEquals($oldsections[6], $neworder[6]);
660
eb01aa2c
RT
661 $neworder = reorder_sections($sections, 4, 2);
662 $neworder = array_keys($neworder);
663 $this->assertEquals($oldsections[0], $neworder[0]);
664 $this->assertEquals($oldsections[1], $neworder[1]);
665 $this->assertEquals($oldsections[2], $neworder[3]);
666 $this->assertEquals($oldsections[3], $neworder[4]);
667 $this->assertEquals($oldsections[4], $neworder[2]);
668 $this->assertEquals($oldsections[5], $neworder[5]);
669 $this->assertEquals($oldsections[6], $neworder[6]);
670
354b214c
PS
671 $neworder = reorder_sections(1, 2, 4);
672 $this->assertFalse($neworder);
673 }
674
3d8fe482 675 public function test_move_section_down() {
354b214c
PS
676 global $DB;
677 $this->resetAfterTest(true);
678
679 $this->getDataGenerator()->create_course(array('numsections'=>5), array('createsections'=>true));
680 $course = $this->getDataGenerator()->create_course(array('numsections'=>10), array('createsections'=>true));
681 $oldsections = array();
682 foreach ($DB->get_records('course_sections', array('course'=>$course->id)) as $section) {
683 $oldsections[$section->section] = $section->id;
684 }
685 ksort($oldsections);
686
3d8fe482 687 // Test move section down..
354b214c
PS
688 move_section_to($course, 2, 4);
689 $sections = array();
690 foreach ($DB->get_records('course_sections', array('course'=>$course->id)) as $section) {
691 $sections[$section->section] = $section->id;
692 }
693 ksort($sections);
694
695 $this->assertEquals($oldsections[0], $sections[0]);
696 $this->assertEquals($oldsections[1], $sections[1]);
697 $this->assertEquals($oldsections[2], $sections[4]);
698 $this->assertEquals($oldsections[3], $sections[2]);
699 $this->assertEquals($oldsections[4], $sections[3]);
700 $this->assertEquals($oldsections[5], $sections[5]);
701 $this->assertEquals($oldsections[6], $sections[6]);
702 }
703
3d8fe482
DP
704 public function test_move_section_up() {
705 global $DB;
706 $this->resetAfterTest(true);
707
708 $this->getDataGenerator()->create_course(array('numsections'=>5), array('createsections'=>true));
709 $course = $this->getDataGenerator()->create_course(array('numsections'=>10), array('createsections'=>true));
710 $oldsections = array();
711 foreach ($DB->get_records('course_sections', array('course'=>$course->id)) as $section) {
712 $oldsections[$section->section] = $section->id;
713 }
714 ksort($oldsections);
715
716 // Test move section up..
717 move_section_to($course, 6, 4);
718 $sections = array();
719 foreach ($DB->get_records('course_sections', array('course'=>$course->id)) as $section) {
720 $sections[$section->section] = $section->id;
721 }
722 ksort($sections);
723
724 $this->assertEquals($oldsections[0], $sections[0]);
725 $this->assertEquals($oldsections[1], $sections[1]);
726 $this->assertEquals($oldsections[2], $sections[2]);
727 $this->assertEquals($oldsections[3], $sections[3]);
728 $this->assertEquals($oldsections[4], $sections[5]);
729 $this->assertEquals($oldsections[5], $sections[6]);
730 $this->assertEquals($oldsections[6], $sections[4]);
731 }
732
733 public function test_move_section_marker() {
734 global $DB;
735 $this->resetAfterTest(true);
736
737 $this->getDataGenerator()->create_course(array('numsections'=>5), array('createsections'=>true));
738 $course = $this->getDataGenerator()->create_course(array('numsections'=>10), array('createsections'=>true));
739
740 // Set course marker to the section we are going to move..
741 course_set_marker($course->id, 2);
742 // Verify that the course marker is set correctly.
743 $course = $DB->get_record('course', array('id' => $course->id));
744 $this->assertEquals(2, $course->marker);
745
746 // Test move the marked section down..
747 move_section_to($course, 2, 4);
748
749 // Verify that the coruse marker has been moved along with the section..
750 $course = $DB->get_record('course', array('id' => $course->id));
751 $this->assertEquals(4, $course->marker);
752
753 // Test move the marked section up..
754 move_section_to($course, 4, 3);
755
756 // Verify that the course marker has been moved along with the section..
757 $course = $DB->get_record('course', array('id' => $course->id));
758 $this->assertEquals(3, $course->marker);
759
760 // Test moving a non-marked section above the marked section..
761 move_section_to($course, 4, 2);
762
763 // Verify that the course marker has been moved down to accomodate..
764 $course = $DB->get_record('course', array('id' => $course->id));
765 $this->assertEquals(4, $course->marker);
766
767 // Test moving a non-marked section below the marked section..
768 move_section_to($course, 3, 6);
769
770 // Verify that the course marker has been up to accomodate..
771 $course = $DB->get_record('course', array('id' => $course->id));
772 $this->assertEquals(3, $course->marker);
773 }
774
354b214c
PS
775 public function test_get_course_display_name_for_list() {
776 global $CFG;
777 $this->resetAfterTest(true);
778
779 $course = $this->getDataGenerator()->create_course(array('shortname' => 'FROG101', 'fullname' => 'Introduction to pond life'));
780
781 $CFG->courselistshortnames = 0;
782 $this->assertEquals('Introduction to pond life', get_course_display_name_for_list($course));
783
784 $CFG->courselistshortnames = 1;
785 $this->assertEquals('FROG101 Introduction to pond life', get_course_display_name_for_list($course));
786 }
b1a8aa73
ARN
787
788 public function test_create_course_category() {
789 global $CFG, $DB;
790 $this->resetAfterTest(true);
791
792 // Create the category
793 $data = new stdClass();
794 $data->name = 'aaa';
795 $data->description = 'aaa';
796 $data->idnumber = '';
797
798 $category1 = create_course_category($data);
799
800 // Initially confirm that base data was inserted correctly
801 $this->assertEquals($data->name, $category1->name);
802 $this->assertEquals($data->description, $category1->description);
803 $this->assertEquals($data->idnumber, $category1->idnumber);
804
805 // sortorder should be blank initially
806 $this->assertEmpty($category1->sortorder);
807
808 // Calling fix_course_sortorder() should provide a new sortorder
809 fix_course_sortorder();
810 $category1 = $DB->get_record('course_categories', array('id' => $category1->id));
811
812 $this->assertGreaterThanOrEqual(1, $category1->sortorder);
813
814 // Create two more categories and test the sortorder worked correctly
815 $data->name = 'ccc';
816 $category2 = create_course_category($data);
817 $this->assertEmpty($category2->sortorder);
818
819 $data->name = 'bbb';
820 $category3 = create_course_category($data);
821 $this->assertEmpty($category3->sortorder);
822
823 // Calling fix_course_sortorder() should provide a new sortorder to give category1,
824 // category2, category3. New course categories are ordered by id not name
825 fix_course_sortorder();
826
827 $category1 = $DB->get_record('course_categories', array('id' => $category1->id));
828 $category2 = $DB->get_record('course_categories', array('id' => $category2->id));
829 $category3 = $DB->get_record('course_categories', array('id' => $category3->id));
830
831 $this->assertGreaterThanOrEqual($category1->sortorder, $category2->sortorder);
832 $this->assertGreaterThanOrEqual($category2->sortorder, $category3->sortorder);
833 $this->assertGreaterThanOrEqual($category1->sortorder, $category3->sortorder);
834 }
384c3510
MG
835
836 public function test_move_module_in_course() {
3f61e4cb
ARN
837 global $DB;
838
384c3510
MG
839 $this->resetAfterTest(true);
840 // Setup fixture
3f61e4cb 841 $course = $this->getDataGenerator()->create_course(array('numsections'=>5), array('createsections' => true));
384c3510
MG
842 $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id));
843
384c3510
MG
844 $cms = get_fast_modinfo($course)->get_cms();
845 $cm = reset($cms);
846
3f61e4cb
ARN
847 $newsection = get_fast_modinfo($course)->get_section_info(3);
848 $oldsectionid = $cm->section;
849
850 // Perform the move
851 moveto_module($cm, $newsection);
384c3510 852
3f61e4cb
ARN
853 // reset of get_fast_modinfo is usually called the code calling moveto_module so call it here
854 get_fast_modinfo(0, 0, true);
855 $cms = get_fast_modinfo($course)->get_cms();
856 $cm = reset($cms);
384c3510 857
3f61e4cb 858 // Check that the cached modinfo contains the correct section info
384c3510
MG
859 $modinfo = get_fast_modinfo($course);
860 $this->assertTrue(empty($modinfo->sections[0]));
861 $this->assertFalse(empty($modinfo->sections[3]));
3f61e4cb
ARN
862
863 // Check that the old section's sequence no longer contains this ID
864 $oldsection = $DB->get_record('course_sections', array('id' => $oldsectionid));
865 $oldsequences = explode(',', $newsection->sequence);
866 $this->assertFalse(in_array($cm->id, $oldsequences));
867
868 // Check that the new section's sequence now contains this ID
869 $newsection = $DB->get_record('course_sections', array('id' => $newsection->id));
870 $newsequences = explode(',', $newsection->sequence);
871 $this->assertTrue(in_array($cm->id, $newsequences));
872
873 // Check that the section number has been changed in the cm
874 $this->assertEquals($newsection->id, $cm->section);
875
876
877 // Perform a second move as some issues were only seen on the second move
878 $newsection = get_fast_modinfo($course)->get_section_info(2);
879 $oldsectionid = $cm->section;
880 $result = moveto_module($cm, $newsection);
881 $this->assertTrue($result);
882
883 // reset of get_fast_modinfo is usually called the code calling moveto_module so call it here
884 get_fast_modinfo(0, 0, true);
885 $cms = get_fast_modinfo($course)->get_cms();
886 $cm = reset($cms);
887
888 // Check that the cached modinfo contains the correct section info
889 $modinfo = get_fast_modinfo($course);
890 $this->assertTrue(empty($modinfo->sections[0]));
891 $this->assertFalse(empty($modinfo->sections[2]));
892
893 // Check that the old section's sequence no longer contains this ID
894 $oldsection = $DB->get_record('course_sections', array('id' => $oldsectionid));
895 $oldsequences = explode(',', $newsection->sequence);
896 $this->assertFalse(in_array($cm->id, $oldsequences));
897
898 // Check that the new section's sequence now contains this ID
899 $newsection = $DB->get_record('course_sections', array('id' => $newsection->id));
900 $newsequences = explode(',', $newsection->sequence);
901 $this->assertTrue(in_array($cm->id, $newsequences));
384c3510 902 }
f7d6e650
FM
903
904 public function test_module_visibility() {
905 $this->setAdminUser();
906 $this->resetAfterTest(true);
907
908 // Create course and modules.
909 $course = $this->getDataGenerator()->create_course(array('numsections' => 5));
910 $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
911 $assign = $this->getDataGenerator()->create_module('assign', array('duedate' => time(), 'course' => $course->id));
912 $modules = compact('forum', 'assign');
913
914 // Hiding the modules.
915 foreach ($modules as $mod) {
916 set_coursemodule_visible($mod->cmid, 0);
917 $this->check_module_visibility($mod, 0, 0);
918 }
919
920 // Showing the modules.
921 foreach ($modules as $mod) {
922 set_coursemodule_visible($mod->cmid, 1);
923 $this->check_module_visibility($mod, 1, 1);
924 }
925 }
926
927 public function test_section_visibility() {
928 $this->setAdminUser();
929 $this->resetAfterTest(true);
930
931 // Create course.
932 $course = $this->getDataGenerator()->create_course(array('numsections' => 3), array('createsections' => true));
933
934 // Testing an empty section.
935 $sectionnumber = 1;
936 set_section_visible($course->id, $sectionnumber, 0);
937 $section_info = get_fast_modinfo($course->id)->get_section_info($sectionnumber);
938 $this->assertEquals($section_info->visible, 0);
939 set_section_visible($course->id, $sectionnumber, 1);
940 $section_info = get_fast_modinfo($course->id)->get_section_info($sectionnumber);
941 $this->assertEquals($section_info->visible, 1);
942
943 // Testing a section with visible modules.
944 $sectionnumber = 2;
945 $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id),
946 array('section' => $sectionnumber));
947 $assign = $this->getDataGenerator()->create_module('assign', array('duedate' => time(),
948 'course' => $course->id), array('section' => $sectionnumber));
949 $modules = compact('forum', 'assign');
950 set_section_visible($course->id, $sectionnumber, 0);
951 $section_info = get_fast_modinfo($course->id)->get_section_info($sectionnumber);
952 $this->assertEquals($section_info->visible, 0);
953 foreach ($modules as $mod) {
954 $this->check_module_visibility($mod, 0, 1);
955 }
956 set_section_visible($course->id, $sectionnumber, 1);
957 $section_info = get_fast_modinfo($course->id)->get_section_info($sectionnumber);
958 $this->assertEquals($section_info->visible, 1);
959 foreach ($modules as $mod) {
960 $this->check_module_visibility($mod, 1, 1);
961 }
962
963 // Testing a section with hidden modules, which should stay hidden.
964 $sectionnumber = 3;
965 $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id),
966 array('section' => $sectionnumber));
967 $assign = $this->getDataGenerator()->create_module('assign', array('duedate' => time(),
968 'course' => $course->id), array('section' => $sectionnumber));
969 $modules = compact('forum', 'assign');
970 foreach ($modules as $mod) {
971 set_coursemodule_visible($mod->cmid, 0);
972 $this->check_module_visibility($mod, 0, 0);
973 }
974 set_section_visible($course->id, $sectionnumber, 0);
975 $section_info = get_fast_modinfo($course->id)->get_section_info($sectionnumber);
976 $this->assertEquals($section_info->visible, 0);
977 foreach ($modules as $mod) {
978 $this->check_module_visibility($mod, 0, 0);
979 }
980 set_section_visible($course->id, $sectionnumber, 1);
981 $section_info = get_fast_modinfo($course->id)->get_section_info($sectionnumber);
982 $this->assertEquals($section_info->visible, 1);
983 foreach ($modules as $mod) {
984 $this->check_module_visibility($mod, 0, 0);
985 }
986 }
987
988 /**
989 * Helper function to assert that a module has correctly been made visible, or hidden.
990 *
991 * @param stdClass $mod module information
992 * @param int $visibility the current state of the module
993 * @param int $visibleold the current state of the visibleold property
994 * @return void
995 */
996 public function check_module_visibility($mod, $visibility, $visibleold) {
997 global $DB;
998 $cm = get_fast_modinfo($mod->course)->get_cm($mod->cmid);
999 $this->assertEquals($visibility, $cm->visible);
1000 $this->assertEquals($visibleold, $cm->visibleold);
1001
1002 // Check the module grade items.
1003 $grade_items = grade_item::fetch_all(array('itemtype' => 'mod', 'itemmodule' => $cm->modname,
1004 'iteminstance' => $cm->instance, 'courseid' => $cm->course));
1005 if ($grade_items) {
1006 foreach ($grade_items as $grade_item) {
1007 if ($visibility) {
1008 $this->assertFalse($grade_item->is_hidden(), "$cm->modname grade_item not visible");
1009 } else {
1010 $this->assertTrue($grade_item->is_hidden(), "$cm->modname grade_item not hidden");
1011 }
1012 }
1013 }
1014
1015 // Check the events visibility.
1016 if ($events = $DB->get_records('event', array('instance' => $cm->instance, 'modulename' => $cm->modname))) {
1017 foreach ($events as $event) {
1018 $calevent = new calendar_event($event);
1019 $this->assertEquals($visibility, $calevent->visible, "$cm->modname calendar_event visibility");
1020 }
1021 }
1022 }
1023
b7d3bb0f
AG
1024 public function test_course_page_type_list() {
1025 global $DB;
1026 $this->resetAfterTest(true);
1027
1028 // Create a category.
1029 $category = new stdClass();
1030 $category->name = 'Test Category';
1031
1032 $testcategory = $this->getDataGenerator()->create_category($category);
1033
1034 // Create a course.
1035 $course = new stdClass();
1036 $course->fullname = 'Apu loves Unit Təsts';
1037 $course->shortname = 'Spread the lŭve';
1038 $course->idnumber = '123';
1039 $course->summary = 'Awesome!';
1040 $course->summaryformat = FORMAT_PLAIN;
1041 $course->format = 'topics';
1042 $course->newsitems = 0;
1043 $course->numsections = 5;
1044 $course->category = $testcategory->id;
1045
1046 $testcourse = $this->getDataGenerator()->create_course($course);
1047
1048 // Create contexts.
1049 $coursecontext = context_course::instance($testcourse->id);
1050 $parentcontext = $coursecontext->get_parent_context(); // Not actually used.
1051 $pagetype = 'page-course-x'; // Not used either.
1052 $pagetypelist = course_page_type_list($pagetype, $parentcontext, $coursecontext);
1053
1054 // Page type lists for normal courses.
1055 $testpagetypelist1 = array();
1056 $testpagetypelist1['*'] = 'Any page';
1057 $testpagetypelist1['course-*'] = 'Any course page';
1058 $testpagetypelist1['course-view-*'] = 'Any type of course main page';
1059
1060 $this->assertEquals($testpagetypelist1, $pagetypelist);
1061
1062 // Get the context for the front page course.
1063 $sitecoursecontext = context_course::instance(SITEID);
1064 $pagetypelist = course_page_type_list($pagetype, $parentcontext, $sitecoursecontext);
1065
1066 // Page type list for the front page course.
1067 $testpagetypelist2 = array('*' => 'Any page');
1068 $this->assertEquals($testpagetypelist2, $pagetypelist);
1069
1070 // Make sure that providing no current context to the function doesn't result in an error.
1071 // Calls made from generate_page_type_patterns() may provide null values.
1072 $pagetypelist = course_page_type_list($pagetype, null, null);
1073 $this->assertEquals($pagetypelist, $testpagetypelist1);
1074 }
354b214c 1075}