Merge branch 'MDL-41993-master-fix1' of git://github.com/damyon/moodle
[moodle.git] / lib / tests / moodle_page_test.php
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/>.
17 /**
18  * Tests for the moodle_page class.
19  *
20  * @package   core
21  * @category  phpunit
22  * @copyright 2009 Tim Hunt
23  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24  */
26 defined('MOODLE_INTERNAL') || die();
28 global $CFG;
29 require_once($CFG->libdir . '/pagelib.php');
30 require_once($CFG->libdir . '/blocklib.php');
33 class core_moodle_page_testcase extends advanced_testcase {
34     protected $testpage;
36     public function setUp() {
37         parent::setUp();
38         $this->resetAfterTest();
39         $this->testpage = new testable_moodle_page();
40     }
42     public function test_course_returns_site_before_set() {
43         global $SITE;
44         // Validated.
45         $this->assertSame($SITE, $this->testpage->course);
46     }
48     public function test_setting_course_works() {
49         // Setup fixture.
50         $course = $this->getDataGenerator()->create_course();
51         $this->testpage->set_context(context_system::instance()); // Avoid trying to set the context.
52         // Exercise SUT.
53         $this->testpage->set_course($course);
54         // Validated.
55         $this->assertEquals($course, $this->testpage->course);
56     }
58     public function test_global_course_and_page_course_are_same_with_global_page() {
59         global $COURSE, $PAGE;
60         // Setup fixture.
61         $course = $this->getDataGenerator()->create_course();
62         $this->testpage->set_context(context_system::instance()); // Avoid trying to set the context.
63         $PAGE = $this->testpage;
64         // Exercise SUT.
65         $this->testpage->set_course($course);
66         // Validated.
67         $this->assertSame($COURSE, $this->testpage->course);
68     }
70     public function test_global_course_not_changed_with_non_global_page() {
71         global $COURSE;
72         $originalcourse = $COURSE;
73         // Setup fixture.
74         $course = $this->getDataGenerator()->create_course();
75         $this->testpage->set_context(context_system::instance()); // Avoid trying to set the context.
76         // Exercise SUT.
77         $this->testpage->set_course($course);
78         // Validated.
79         $this->assertSame($originalcourse, $COURSE);
80     }
82     public function test_cannot_set_course_once_theme_set() {
83         // Setup fixture.
84         $this->testpage->force_theme(theme_config::DEFAULT_THEME);
85         $course = $this->getDataGenerator()->create_course();
86         // Set expectation.
87         $this->setExpectedException('coding_exception');
88         // Exercise SUT.
89         $this->testpage->set_course($course);
90     }
92     public function test_cannot_set_category_once_theme_set() {
93         // Setup fixture.
94         $this->testpage->force_theme(theme_config::DEFAULT_THEME);
95         // Set expectation.
96         $this->setExpectedException('coding_exception');
97         // Exercise SUT.
98         $this->testpage->set_category_by_id(123);
99     }
101     public function test_cannot_set_category_once_course_set() {
102         // Setup fixture.
103         $course = $this->getDataGenerator()->create_course();
104         $this->testpage->set_context(context_system::instance()); // Avoid trying to set the context.
105         $this->testpage->set_course($course);
106         // Set expectation.
107         $this->setExpectedException('coding_exception');
108         // Exercise SUT.
109         $this->testpage->set_category_by_id(123);
110     }
112     public function test_categories_array_empty_for_front_page() {
113         global $SITE;
114         // Setup fixture.
115         $this->testpage->set_context(context_system::instance()); // Avoid trying to set the context.
116         $this->testpage->set_course($SITE);
117         // Exercise SUT and validate.
118         $this->assertEquals(array(), $this->testpage->categories);
119     }
121     public function test_set_state_normal_path() {
122         $course = $this->getDataGenerator()->create_course();
123         $this->testpage->set_context(context_system::instance());
124         $this->testpage->set_course($course);
126         $this->assertEquals(moodle_page::STATE_BEFORE_HEADER, $this->testpage->state);
128         $this->testpage->set_state(moodle_page::STATE_PRINTING_HEADER);
129         $this->assertEquals(moodle_page::STATE_PRINTING_HEADER, $this->testpage->state);
131         $this->testpage->set_state(moodle_page::STATE_IN_BODY);
132         $this->assertEquals(moodle_page::STATE_IN_BODY, $this->testpage->state);
134         $this->testpage->set_state(moodle_page::STATE_DONE);
135         $this->assertEquals(moodle_page::STATE_DONE, $this->testpage->state);
136     }
138     public function test_set_state_cannot_skip_one() {
139         // Set expectation.
140         $this->setExpectedException('coding_exception');
141         // Exercise SUT.
142         $this->testpage->set_state(moodle_page::STATE_IN_BODY);
143     }
145     public function test_header_printed_false_initially() {
146         // Validated.
147         $this->assertFalse($this->testpage->headerprinted);
148     }
150     public function test_header_printed_becomes_true() {
151         $course = $this->getDataGenerator()->create_course();
152         $this->testpage->set_context(context_system::instance());
153         $this->testpage->set_course($course);
155         // Exercise SUT.
156         $this->testpage->set_state(moodle_page::STATE_PRINTING_HEADER);
157         $this->testpage->set_state(moodle_page::STATE_IN_BODY);
158         // Validated.
159         $this->assertTrue($this->testpage->headerprinted);
160     }
162     public function test_set_context() {
163         // Setup fixture.
164         $course = $this->getDataGenerator()->create_course();
165         $context = context_course::instance($course->id);
166         // Exercise SUT.
167         $this->testpage->set_context($context);
168         // Validated.
169         $this->assertSame($context, $this->testpage->context);
170     }
172     public function test_pagetype_defaults_to_script() {
173         global $SCRIPT;
174         // Exercise SUT and validate.
175         $SCRIPT = '/index.php';
176         $this->testpage->initialise_default_pagetype();
177         $this->assertSame('site-index', $this->testpage->pagetype);
178     }
180     public function test_set_pagetype() {
181         // Exercise SUT.
182         $this->testpage->set_pagetype('a-page-type');
183         // Validated.
184         $this->assertSame('a-page-type', $this->testpage->pagetype);
185     }
187     public function test_initialise_default_pagetype() {
188         // Exercise SUT.
189         $this->testpage->initialise_default_pagetype('admin/tool/unittest/index.php');
190         // Validated.
191         $this->assertSame('admin-tool-unittest-index', $this->testpage->pagetype);
192     }
194     public function test_initialise_default_pagetype_fp() {
195         // Exercise SUT.
196         $this->testpage->initialise_default_pagetype('index.php');
197         // Validated.
198         $this->assertSame('site-index', $this->testpage->pagetype);
199     }
201     public function test_get_body_classes_empty() {
202         // Validated.
203         $this->assertSame('', $this->testpage->bodyclasses);
204     }
206     public function test_get_body_classes_single() {
207         // Exercise SUT.
208         $this->testpage->add_body_class('aclassname');
209         // Validated.
210         $this->assertSame('aclassname', $this->testpage->bodyclasses);
211     }
213     public function test_get_body_classes() {
214         // Exercise SUT.
215         $this->testpage->add_body_classes(array('aclassname', 'anotherclassname'));
216         // Validated.
217         $this->assertSame('aclassname anotherclassname', $this->testpage->bodyclasses);
218     }
220     public function test_url_to_class_name() {
221         $this->assertSame('example-com', $this->testpage->url_to_class_name('http://example.com'));
222         $this->assertSame('example-com--80', $this->testpage->url_to_class_name('http://example.com:80'));
223         $this->assertSame('example-com--moodle', $this->testpage->url_to_class_name('https://example.com/moodle'));
224         $this->assertSame('example-com--8080--nested-moodle', $this->testpage->url_to_class_name('https://example.com:8080/nested/moodle'));
225     }
227     public function test_set_docs_path() {
228         // Exercise SUT.
229         $this->testpage->set_docs_path('a/file/path');
230         // Validated.
231         $this->assertSame('a/file/path', $this->testpage->docspath);
232     }
234     public function test_docs_path_defaults_from_pagetype() {
235         // Exercise SUT.
236         $this->testpage->set_pagetype('a-page-type');
237         // Validated.
238         $this->assertSame('a/page/type', $this->testpage->docspath);
239     }
241     public function test_set_url_root() {
242         global $CFG;
243         // Exercise SUT.
244         $this->testpage->set_url('/');
245         // Validated.
246         $this->assertSame($CFG->wwwroot . '/', $this->testpage->url->out());
247     }
249     public function test_set_url_one_param() {
250         global $CFG;
251         // Exercise SUT.
252         $this->testpage->set_url('/mod/quiz/attempt.php', array('attempt' => 123));
253         // Validated.
254         $this->assertSame($CFG->wwwroot . '/mod/quiz/attempt.php?attempt=123', $this->testpage->url->out());
255     }
257     public function test_set_url_two_params() {
258         global $CFG;
259         // Exercise SUT.
260         $this->testpage->set_url('/mod/quiz/attempt.php', array('attempt' => 123, 'page' => 7));
261         // Validated.
262         $this->assertSame($CFG->wwwroot . '/mod/quiz/attempt.php?attempt=123&amp;page=7', $this->testpage->url->out());
263     }
265     public function test_set_url_using_moodle_url() {
266         global $CFG;
267         // Fixture setup.
268         $url = new moodle_url('/mod/workshop/allocation.php', array('cmid' => 29, 'method' => 'manual'));
269         // Exercise SUT.
270         $this->testpage->set_url($url);
271         // Validated.
272         $this->assertSame($CFG->wwwroot . '/mod/workshop/allocation.php?cmid=29&amp;method=manual', $this->testpage->url->out());
273     }
275     public function test_set_url_sets_page_type() {
276         // Exercise SUT.
277         $this->testpage->set_url('/mod/quiz/attempt.php', array('attempt' => 123, 'page' => 7));
278         // Validated.
279         $this->assertSame('mod-quiz-attempt', $this->testpage->pagetype);
280     }
282     public function test_set_url_does_not_change_explicit_page_type() {
283         // Setup fixture.
284         $this->testpage->set_pagetype('a-page-type');
285         // Exercise SUT.
286         $this->testpage->set_url('/mod/quiz/attempt.php', array('attempt' => 123, 'page' => 7));
287         // Validated.
288         $this->assertSame('a-page-type', $this->testpage->pagetype);
289     }
291     public function test_set_subpage() {
292         // Exercise SUT.
293         $this->testpage->set_subpage('somestring');
294         // Validated.
295         $this->assertSame('somestring', $this->testpage->subpage);
296     }
298     public function test_set_heading() {
299         // Exercise SUT.
300         $this->testpage->set_heading('a heading');
301         // Validated.
302         $this->assertSame('a heading', $this->testpage->heading);
303     }
305     public function test_set_title() {
306         // Exercise SUT.
307         $this->testpage->set_title('a title');
308         // Validated.
309         $this->assertSame('a title', $this->testpage->title);
310     }
312     public function test_default_pagelayout() {
313         // Exercise SUT and Validate.
314         $this->assertSame('base', $this->testpage->pagelayout);
315     }
317     public function test_set_pagelayout() {
318         // Exercise SUT.
319         $this->testpage->set_pagelayout('type');
320         // Validated.
321         $this->assertSame('type', $this->testpage->pagelayout);
322     }
324     public function test_setting_course_sets_context() {
325         // Setup fixture.
326         $course = $this->getDataGenerator()->create_course();
327         $context = context_course::instance($course->id);
329         // Exercise SUT.
330         $this->testpage->set_course($course);
332         // Validated.
333         $this->assertSame($context, $this->testpage->context);
334     }
336     public function test_set_category_top_level() {
337         global $DB;
338         // Setup fixture.
339         $cat = $this->getDataGenerator()->create_category();
340         $catdbrecord = $DB->get_record('course_categories', array('id' => $cat->id));
341         // Exercise SUT.
342         $this->testpage->set_category_by_id($cat->id);
343         // Validated.
344         $this->assertEquals($catdbrecord, $this->testpage->category);
345         $this->assertSame(context_coursecat::instance($cat->id), $this->testpage->context);
346     }
348     public function test_set_nested_categories() {
349         global $DB;
350         // Setup fixture.
351         $topcat = $this->getDataGenerator()->create_category();
352         $topcatdbrecord = $DB->get_record('course_categories', array('id' => $topcat->id));
353         $subcat = $this->getDataGenerator()->create_category(array('parent'=>$topcat->id));
354         $subcatdbrecord = $DB->get_record('course_categories', array('id' => $subcat->id));
355         // Exercise SUT.
356         $this->testpage->set_category_by_id($subcat->id);
357         // Validated.
358         $categories = $this->testpage->categories;
359         $this->assertCount(2, $categories);
360         $this->assertEquals($topcatdbrecord, array_pop($categories));
361         $this->assertEquals($subcatdbrecord, array_pop($categories));
362     }
364     public function test_cm_null_initially() {
365         // Validated.
366         $this->assertNull($this->testpage->cm);
367     }
369     public function test_set_cm() {
370         // Setup fixture.
371         $course = $this->getDataGenerator()->create_course();
372         $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id));
373         $cm = get_coursemodule_from_id('forum', $forum->cmid);
374         // Exercise SUT.
375         $this->testpage->set_cm($cm);
376         // Validated.
377         $this->assertEquals($cm->id, $this->testpage->cm->id);
378     }
380     public function test_cannot_set_activity_record_before_cm() {
381         // Setup fixture.
382         $course = $this->getDataGenerator()->create_course();
383         $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id));
384         $cm = get_coursemodule_from_id('forum', $forum->cmid);
385         // Set expectation.
386         $this->setExpectedException('coding_exception');
387         // Exercise SUT.
388         $this->testpage->set_activity_record($forum);
389     }
391     public function test_setting_cm_sets_context() {
392         // Setup fixture.
393         $course = $this->getDataGenerator()->create_course();
394         $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id));
395         $cm = get_coursemodule_from_id('forum', $forum->cmid);
396         // Exercise SUT.
397         $this->testpage->set_cm($cm);
398         // Validated.
399         $this->assertSame(context_module::instance($cm->id), $this->testpage->context);
400     }
402     public function test_activity_record_loaded_if_not_set() {
403         // Setup fixture.
404         $course = $this->getDataGenerator()->create_course();
405         $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id));
406         $cm = get_coursemodule_from_id('forum', $forum->cmid);
407         // Exercise SUT.
408         $this->testpage->set_cm($cm);
409         // Validated.
410         unset($forum->cmid);
411         $this->assertEquals($forum, $this->testpage->activityrecord);
412     }
414     public function test_set_activity_record() {
415         // Setup fixture.
416         $course = $this->getDataGenerator()->create_course();
417         $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id));
418         $cm = get_coursemodule_from_id('forum', $forum->cmid);
419         $this->testpage->set_cm($cm);
420         // Exercise SUT.
421         $this->testpage->set_activity_record($forum);
422         // Validated.
423         unset($forum->cmid);
424         $this->assertEquals($forum, $this->testpage->activityrecord);
425     }
427     public function test_cannot_set_inconsistent_activity_record_course() {
428         // Setup fixture.
429         $course = $this->getDataGenerator()->create_course();
430         $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id));
431         $cm = get_coursemodule_from_id('forum', $forum->cmid);
432         $this->testpage->set_cm($cm);
433         // Set expectation.
434         $this->setExpectedException('coding_exception');
435         // Exercise SUT.
436         $forum->course = 13;
437         $this->testpage->set_activity_record($forum);
438     }
440     public function test_cannot_set_inconsistent_activity_record_instance() {
441         // Setup fixture.
442         $course = $this->getDataGenerator()->create_course();
443         $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id));
444         $cm = get_coursemodule_from_id('forum', $forum->cmid);
445         $this->testpage->set_cm($cm);
446         // Set expectation.
447         $this->setExpectedException('coding_exception');
448         // Exercise SUT.
449         $forum->id = 13;
450         $this->testpage->set_activity_record($forum);
451     }
453     public function test_setting_cm_sets_course() {
454         // Setup fixture.
455         $course = $this->getDataGenerator()->create_course();
456         $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id));
457         $cm = get_coursemodule_from_id('forum', $forum->cmid);
458         // Exercise SUT.
459         $this->testpage->set_cm($cm);
460         // Validated.
461         $this->assertEquals($course->id, $this->testpage->course->id);
462     }
464     public function test_set_cm_with_course_and_activity_no_db() {
465         // Setup fixture.
466         $course = $this->getDataGenerator()->create_course();
467         $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id));
468         $cm = get_coursemodule_from_id('forum', $forum->cmid);
469         // This only works without db if we already have modinfo cache
470         // Exercise SUT.
471         $this->testpage->set_cm($cm, $course, $forum);
472         // Validated.
473         $this->assertEquals($cm->id, $this->testpage->cm->id);
474         $this->assertEquals($course->id, $this->testpage->course->id);
475         unset($forum->cmid);
476         $this->assertEquals($forum, $this->testpage->activityrecord);
477     }
479     public function test_cannot_set_cm_with_inconsistent_course() {
480         // Setup fixture.
481         $course = $this->getDataGenerator()->create_course();
482         $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id));
483         $cm = get_coursemodule_from_id('forum', $forum->cmid);
484         // Set expectation.
485         $this->setExpectedException('coding_exception');
486         // Exercise SUT.
487         $cm->course = 13;
488         $this->testpage->set_cm($cm, $course);
489     }
491     public function test_get_activity_name() {
492         // Setup fixture.
493         $course = $this->getDataGenerator()->create_course();
494         $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id));
495         $cm = get_coursemodule_from_id('forum', $forum->cmid);
496         // Exercise SUT.
497         $this->testpage->set_cm($cm, $course, $forum);
498         // Validated.
499         $this->assertSame('forum', $this->testpage->activityname);
500     }
502     public function test_user_is_editing_on() {
503         // We are relying on the fact that unit tests are always run by admin, to
504         // ensure the user_allows_editing call returns true.
506         // Setup fixture.
507         global $USER;
509         $this->testpage->set_context(context_system::instance());
510         $this->setAdminUser();
512         $USER->editing = true;
513         // Validated.
514         $this->assertTrue($this->testpage->user_is_editing());
515     }
517     public function test_user_is_editing_off() {
518         // We are relying on the fact that unit tests are always run by admin, to
519         // ensure the user_allows_editing call returns true.
521         // Setup fixture.
522         global $USER;
524         $this->testpage->set_context(context_system::instance());
525         $this->setAdminUser();
527         $USER->editing = false;
528         // Validated.
529         $this->assertFalse($this->testpage->user_is_editing());
530     }
532     public function test_default_editing_capabilities() {
533         $this->testpage->set_context(context_system::instance());
534         $this->setAdminUser();
536         // Validated.
537         $this->assertEquals(array('moodle/site:manageblocks'), $this->testpage->all_editing_caps());
538     }
540     public function test_other_block_editing_cap() {
541         $this->testpage->set_context(context_system::instance());
542         $this->setAdminUser();
544         // Exercise SUT.
545         $this->testpage->set_blocks_editing_capability('moodle/my:manageblocks');
546         // Validated.
547         $this->assertEquals(array('moodle/my:manageblocks'), $this->testpage->all_editing_caps());
548     }
550     public function test_other_editing_cap() {
551         $this->testpage->set_context(context_system::instance());
552         $this->setAdminUser();
554         // Exercise SUT.
555         $this->testpage->set_other_editing_capability('moodle/course:manageactivities');
556         // Validated.
557         $actualcaps = $this->testpage->all_editing_caps();
558         $expectedcaps = array('moodle/course:manageactivities', 'moodle/site:manageblocks');
559         $this->assertEquals(array_values($expectedcaps), array_values($actualcaps));
560     }
562     public function test_other_editing_caps() {
563         $this->testpage->set_context(context_system::instance());
564         $this->setAdminUser();
566         // Exercise SUT.
567         $this->testpage->set_other_editing_capability(array('moodle/course:manageactivities', 'moodle/site:other'));
568         // Validated.
569         $actualcaps = $this->testpage->all_editing_caps();
570         $expectedcaps = array('moodle/course:manageactivities', 'moodle/site:other', 'moodle/site:manageblocks');
571         $this->assertEquals(array_values($expectedcaps), array_values($actualcaps));
572     }
576 /**
577  * Test-specific subclass to make some protected things public.
578  */
579 class testable_moodle_page extends moodle_page {
580     public function initialise_default_pagetype($script = null) {
581         parent::initialise_default_pagetype($script);
582     }
583     public function url_to_class_name($url) {
584         return parent::url_to_class_name($url);
585     }
586     public function all_editing_caps() {
587         return parent::all_editing_caps();
588     }