Merge branch 'MDL-47810_master-fix-MDL-47758-changes' of git://github.com/dmonllao...
[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 {
35     /**
36      * @var testable_moodle_page
37      */
38     protected $testpage;
40     public function setUp() {
41         parent::setUp();
42         $this->resetAfterTest();
43         $this->testpage = new testable_moodle_page();
44     }
46     public function test_course_returns_site_before_set() {
47         global $SITE;
48         // Validated.
49         $this->assertSame($SITE, $this->testpage->course);
50     }
52     public function test_setting_course_works() {
53         // Setup fixture.
54         $course = $this->getDataGenerator()->create_course();
55         $this->testpage->set_context(context_system::instance()); // Avoid trying to set the context.
56         // Exercise SUT.
57         $this->testpage->set_course($course);
58         // Validated.
59         $this->assertEquals($course, $this->testpage->course);
60     }
62     public function test_global_course_and_page_course_are_same_with_global_page() {
63         global $COURSE, $PAGE;
64         // Setup fixture.
65         $course = $this->getDataGenerator()->create_course();
66         $this->testpage->set_context(context_system::instance()); // Avoid trying to set the context.
67         $PAGE = $this->testpage;
68         // Exercise SUT.
69         $this->testpage->set_course($course);
70         // Validated.
71         $this->assertSame($COURSE, $this->testpage->course);
72     }
74     public function test_global_course_not_changed_with_non_global_page() {
75         global $COURSE;
76         $originalcourse = $COURSE;
77         // Setup fixture.
78         $course = $this->getDataGenerator()->create_course();
79         $this->testpage->set_context(context_system::instance()); // Avoid trying to set the context.
80         // Exercise SUT.
81         $this->testpage->set_course($course);
82         // Validated.
83         $this->assertSame($originalcourse, $COURSE);
84     }
86     public function test_cannot_set_course_once_theme_set() {
87         // Setup fixture.
88         $this->testpage->force_theme(theme_config::DEFAULT_THEME);
89         $course = $this->getDataGenerator()->create_course();
90         // Set expectation.
91         $this->setExpectedException('coding_exception');
92         // Exercise SUT.
93         $this->testpage->set_course($course);
94     }
96     public function test_cannot_set_category_once_theme_set() {
97         // Setup fixture.
98         $this->testpage->force_theme(theme_config::DEFAULT_THEME);
99         // Set expectation.
100         $this->setExpectedException('coding_exception');
101         // Exercise SUT.
102         $this->testpage->set_category_by_id(123);
103     }
105     public function test_cannot_set_category_once_course_set() {
106         // Setup fixture.
107         $course = $this->getDataGenerator()->create_course();
108         $this->testpage->set_context(context_system::instance()); // Avoid trying to set the context.
109         $this->testpage->set_course($course);
110         // Set expectation.
111         $this->setExpectedException('coding_exception');
112         // Exercise SUT.
113         $this->testpage->set_category_by_id(123);
114     }
116     public function test_categories_array_empty_for_front_page() {
117         global $SITE;
118         // Setup fixture.
119         $this->testpage->set_context(context_system::instance()); // Avoid trying to set the context.
120         $this->testpage->set_course($SITE);
121         // Exercise SUT and validate.
122         $this->assertEquals(array(), $this->testpage->categories);
123     }
125     public function test_set_state_normal_path() {
126         $course = $this->getDataGenerator()->create_course();
127         $this->testpage->set_context(context_system::instance());
128         $this->testpage->set_course($course);
130         $this->assertEquals(moodle_page::STATE_BEFORE_HEADER, $this->testpage->state);
132         $this->testpage->set_state(moodle_page::STATE_PRINTING_HEADER);
133         $this->assertEquals(moodle_page::STATE_PRINTING_HEADER, $this->testpage->state);
135         $this->testpage->set_state(moodle_page::STATE_IN_BODY);
136         $this->assertEquals(moodle_page::STATE_IN_BODY, $this->testpage->state);
138         $this->testpage->set_state(moodle_page::STATE_DONE);
139         $this->assertEquals(moodle_page::STATE_DONE, $this->testpage->state);
140     }
142     public function test_set_state_cannot_skip_one() {
143         // Set expectation.
144         $this->setExpectedException('coding_exception');
145         // Exercise SUT.
146         $this->testpage->set_state(moodle_page::STATE_IN_BODY);
147     }
149     public function test_header_printed_false_initially() {
150         // Validated.
151         $this->assertFalse($this->testpage->headerprinted);
152     }
154     public function test_header_printed_becomes_true() {
155         $course = $this->getDataGenerator()->create_course();
156         $this->testpage->set_context(context_system::instance());
157         $this->testpage->set_course($course);
159         // Exercise SUT.
160         $this->testpage->set_state(moodle_page::STATE_PRINTING_HEADER);
161         $this->testpage->set_state(moodle_page::STATE_IN_BODY);
162         // Validated.
163         $this->assertTrue($this->testpage->headerprinted);
164     }
166     public function test_set_context() {
167         // Setup fixture.
168         $course = $this->getDataGenerator()->create_course();
169         $context = context_course::instance($course->id);
170         // Exercise SUT.
171         $this->testpage->set_context($context);
172         // Validated.
173         $this->assertSame($context, $this->testpage->context);
174     }
176     public function test_pagetype_defaults_to_script() {
177         global $SCRIPT;
178         // Exercise SUT and validate.
179         $SCRIPT = '/index.php';
180         $this->testpage->initialise_default_pagetype();
181         $this->assertSame('site-index', $this->testpage->pagetype);
182     }
184     public function test_set_pagetype() {
185         // Exercise SUT.
186         $this->testpage->set_pagetype('a-page-type');
187         // Validated.
188         $this->assertSame('a-page-type', $this->testpage->pagetype);
189     }
191     public function test_initialise_default_pagetype() {
192         // Exercise SUT.
193         $this->testpage->initialise_default_pagetype('admin/tool/unittest/index.php');
194         // Validated.
195         $this->assertSame('admin-tool-unittest-index', $this->testpage->pagetype);
196     }
198     public function test_initialise_default_pagetype_fp() {
199         // Exercise SUT.
200         $this->testpage->initialise_default_pagetype('index.php');
201         // Validated.
202         $this->assertSame('site-index', $this->testpage->pagetype);
203     }
205     public function test_get_body_classes_empty() {
206         // Validated.
207         $this->assertSame('', $this->testpage->bodyclasses);
208     }
210     public function test_get_body_classes_single() {
211         // Exercise SUT.
212         $this->testpage->add_body_class('aclassname');
213         // Validated.
214         $this->assertSame('aclassname', $this->testpage->bodyclasses);
215     }
217     public function test_get_body_classes() {
218         // Exercise SUT.
219         $this->testpage->add_body_classes(array('aclassname', 'anotherclassname'));
220         // Validated.
221         $this->assertSame('aclassname anotherclassname', $this->testpage->bodyclasses);
222     }
224     public function test_url_to_class_name() {
225         $this->assertSame('example-com', $this->testpage->url_to_class_name('http://example.com'));
226         $this->assertSame('example-com--80', $this->testpage->url_to_class_name('http://example.com:80'));
227         $this->assertSame('example-com--moodle', $this->testpage->url_to_class_name('https://example.com/moodle'));
228         $this->assertSame('example-com--8080--nested-moodle', $this->testpage->url_to_class_name('https://example.com:8080/nested/moodle'));
229     }
231     public function test_set_docs_path() {
232         // Exercise SUT.
233         $this->testpage->set_docs_path('a/file/path');
234         // Validated.
235         $this->assertSame('a/file/path', $this->testpage->docspath);
236     }
238     public function test_docs_path_defaults_from_pagetype() {
239         // Exercise SUT.
240         $this->testpage->set_pagetype('a-page-type');
241         // Validated.
242         $this->assertSame('a/page/type', $this->testpage->docspath);
243     }
245     public function test_set_url_root() {
246         global $CFG;
247         // Exercise SUT.
248         $this->testpage->set_url('/');
249         // Validated.
250         $this->assertSame($CFG->wwwroot . '/', $this->testpage->url->out());
251     }
253     public function test_set_url_one_param() {
254         global $CFG;
255         // Exercise SUT.
256         $this->testpage->set_url('/mod/quiz/attempt.php', array('attempt' => 123));
257         // Validated.
258         $this->assertSame($CFG->wwwroot . '/mod/quiz/attempt.php?attempt=123', $this->testpage->url->out());
259     }
261     public function test_set_url_two_params() {
262         global $CFG;
263         // Exercise SUT.
264         $this->testpage->set_url('/mod/quiz/attempt.php', array('attempt' => 123, 'page' => 7));
265         // Validated.
266         $this->assertSame($CFG->wwwroot . '/mod/quiz/attempt.php?attempt=123&amp;page=7', $this->testpage->url->out());
267     }
269     public function test_set_url_using_moodle_url() {
270         global $CFG;
271         // Fixture setup.
272         $url = new moodle_url('/mod/workshop/allocation.php', array('cmid' => 29, 'method' => 'manual'));
273         // Exercise SUT.
274         $this->testpage->set_url($url);
275         // Validated.
276         $this->assertSame($CFG->wwwroot . '/mod/workshop/allocation.php?cmid=29&amp;method=manual', $this->testpage->url->out());
277     }
279     public function test_set_url_sets_page_type() {
280         // Exercise SUT.
281         $this->testpage->set_url('/mod/quiz/attempt.php', array('attempt' => 123, 'page' => 7));
282         // Validated.
283         $this->assertSame('mod-quiz-attempt', $this->testpage->pagetype);
284     }
286     public function test_set_url_does_not_change_explicit_page_type() {
287         // Setup fixture.
288         $this->testpage->set_pagetype('a-page-type');
289         // Exercise SUT.
290         $this->testpage->set_url('/mod/quiz/attempt.php', array('attempt' => 123, 'page' => 7));
291         // Validated.
292         $this->assertSame('a-page-type', $this->testpage->pagetype);
293     }
295     public function test_set_subpage() {
296         // Exercise SUT.
297         $this->testpage->set_subpage('somestring');
298         // Validated.
299         $this->assertSame('somestring', $this->testpage->subpage);
300     }
302     public function test_set_heading() {
303         // Exercise SUT.
304         $this->testpage->set_heading('a heading');
305         // Validated.
306         $this->assertSame('a heading', $this->testpage->heading);
307     }
309     public function test_set_title() {
310         // Exercise SUT.
311         $this->testpage->set_title('a title');
312         // Validated.
313         $this->assertSame('a title', $this->testpage->title);
314     }
316     public function test_default_pagelayout() {
317         // Exercise SUT and Validate.
318         $this->assertSame('base', $this->testpage->pagelayout);
319     }
321     public function test_set_pagelayout() {
322         // Exercise SUT.
323         $this->testpage->set_pagelayout('type');
324         // Validated.
325         $this->assertSame('type', $this->testpage->pagelayout);
326     }
328     public function test_setting_course_sets_context() {
329         // Setup fixture.
330         $course = $this->getDataGenerator()->create_course();
331         $context = context_course::instance($course->id);
333         // Exercise SUT.
334         $this->testpage->set_course($course);
336         // Validated.
337         $this->assertSame($context, $this->testpage->context);
338     }
340     public function test_set_category_top_level() {
341         global $DB;
342         // Setup fixture.
343         $cat = $this->getDataGenerator()->create_category();
344         $catdbrecord = $DB->get_record('course_categories', array('id' => $cat->id));
345         // Exercise SUT.
346         $this->testpage->set_category_by_id($cat->id);
347         // Validated.
348         $this->assertEquals($catdbrecord, $this->testpage->category);
349         $this->assertSame(context_coursecat::instance($cat->id), $this->testpage->context);
350     }
352     public function test_set_nested_categories() {
353         global $DB;
354         // Setup fixture.
355         $topcat = $this->getDataGenerator()->create_category();
356         $topcatdbrecord = $DB->get_record('course_categories', array('id' => $topcat->id));
357         $subcat = $this->getDataGenerator()->create_category(array('parent'=>$topcat->id));
358         $subcatdbrecord = $DB->get_record('course_categories', array('id' => $subcat->id));
359         // Exercise SUT.
360         $this->testpage->set_category_by_id($subcat->id);
361         // Validated.
362         $categories = $this->testpage->categories;
363         $this->assertCount(2, $categories);
364         $this->assertEquals($topcatdbrecord, array_pop($categories));
365         $this->assertEquals($subcatdbrecord, array_pop($categories));
366     }
368     public function test_cm_null_initially() {
369         // Validated.
370         $this->assertNull($this->testpage->cm);
371     }
373     public function test_set_cm() {
374         // Setup fixture.
375         $course = $this->getDataGenerator()->create_course();
376         $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id));
377         $cm = get_coursemodule_from_id('forum', $forum->cmid);
378         // Exercise SUT.
379         $this->testpage->set_cm($cm);
380         // Validated.
381         $this->assertEquals($cm->id, $this->testpage->cm->id);
382     }
384     public function test_cannot_set_activity_record_before_cm() {
385         // Setup fixture.
386         $course = $this->getDataGenerator()->create_course();
387         $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id));
388         $cm = get_coursemodule_from_id('forum', $forum->cmid);
389         // Set expectation.
390         $this->setExpectedException('coding_exception');
391         // Exercise SUT.
392         $this->testpage->set_activity_record($forum);
393     }
395     public function test_setting_cm_sets_context() {
396         // Setup fixture.
397         $course = $this->getDataGenerator()->create_course();
398         $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id));
399         $cm = get_coursemodule_from_id('forum', $forum->cmid);
400         // Exercise SUT.
401         $this->testpage->set_cm($cm);
402         // Validated.
403         $this->assertSame(context_module::instance($cm->id), $this->testpage->context);
404     }
406     public function test_activity_record_loaded_if_not_set() {
407         // Setup fixture.
408         $course = $this->getDataGenerator()->create_course();
409         $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id));
410         $cm = get_coursemodule_from_id('forum', $forum->cmid);
411         // Exercise SUT.
412         $this->testpage->set_cm($cm);
413         // Validated.
414         unset($forum->cmid);
415         $this->assertEquals($forum, $this->testpage->activityrecord);
416     }
418     public function test_set_activity_record() {
419         // Setup fixture.
420         $course = $this->getDataGenerator()->create_course();
421         $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id));
422         $cm = get_coursemodule_from_id('forum', $forum->cmid);
423         $this->testpage->set_cm($cm);
424         // Exercise SUT.
425         $this->testpage->set_activity_record($forum);
426         // Validated.
427         unset($forum->cmid);
428         $this->assertEquals($forum, $this->testpage->activityrecord);
429     }
431     public function test_cannot_set_inconsistent_activity_record_course() {
432         // Setup fixture.
433         $course = $this->getDataGenerator()->create_course();
434         $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id));
435         $cm = get_coursemodule_from_id('forum', $forum->cmid);
436         $this->testpage->set_cm($cm);
437         // Set expectation.
438         $this->setExpectedException('coding_exception');
439         // Exercise SUT.
440         $forum->course = 13;
441         $this->testpage->set_activity_record($forum);
442     }
444     public function test_cannot_set_inconsistent_activity_record_instance() {
445         // Setup fixture.
446         $course = $this->getDataGenerator()->create_course();
447         $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id));
448         $cm = get_coursemodule_from_id('forum', $forum->cmid);
449         $this->testpage->set_cm($cm);
450         // Set expectation.
451         $this->setExpectedException('coding_exception');
452         // Exercise SUT.
453         $forum->id = 13;
454         $this->testpage->set_activity_record($forum);
455     }
457     public function test_setting_cm_sets_course() {
458         // Setup fixture.
459         $course = $this->getDataGenerator()->create_course();
460         $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id));
461         $cm = get_coursemodule_from_id('forum', $forum->cmid);
462         // Exercise SUT.
463         $this->testpage->set_cm($cm);
464         // Validated.
465         $this->assertEquals($course->id, $this->testpage->course->id);
466     }
468     public function test_set_cm_with_course_and_activity_no_db() {
469         // Setup fixture.
470         $course = $this->getDataGenerator()->create_course();
471         $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id));
472         $cm = get_coursemodule_from_id('forum', $forum->cmid);
473         // This only works without db if we already have modinfo cache
474         // Exercise SUT.
475         $this->testpage->set_cm($cm, $course, $forum);
476         // Validated.
477         $this->assertEquals($cm->id, $this->testpage->cm->id);
478         $this->assertEquals($course->id, $this->testpage->course->id);
479         unset($forum->cmid);
480         $this->assertEquals($forum, $this->testpage->activityrecord);
481     }
483     public function test_cannot_set_cm_with_inconsistent_course() {
484         // Setup fixture.
485         $course = $this->getDataGenerator()->create_course();
486         $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id));
487         $cm = get_coursemodule_from_id('forum', $forum->cmid);
488         // Set expectation.
489         $this->setExpectedException('coding_exception');
490         // Exercise SUT.
491         $cm->course = 13;
492         $this->testpage->set_cm($cm, $course);
493     }
495     public function test_get_activity_name() {
496         // Setup fixture.
497         $course = $this->getDataGenerator()->create_course();
498         $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id));
499         $cm = get_coursemodule_from_id('forum', $forum->cmid);
500         // Exercise SUT.
501         $this->testpage->set_cm($cm, $course, $forum);
502         // Validated.
503         $this->assertSame('forum', $this->testpage->activityname);
504     }
506     public function test_user_is_editing_on() {
507         // We are relying on the fact that unit tests are always run by admin, to
508         // ensure the user_allows_editing call returns true.
510         // Setup fixture.
511         global $USER;
513         $this->testpage->set_context(context_system::instance());
514         $this->setAdminUser();
516         $USER->editing = true;
517         // Validated.
518         $this->assertTrue($this->testpage->user_is_editing());
519     }
521     public function test_user_is_editing_off() {
522         // We are relying on the fact that unit tests are always run by admin, to
523         // ensure the user_allows_editing call returns true.
525         // Setup fixture.
526         global $USER;
528         $this->testpage->set_context(context_system::instance());
529         $this->setAdminUser();
531         $USER->editing = false;
532         // Validated.
533         $this->assertFalse($this->testpage->user_is_editing());
534     }
536     public function test_default_editing_capabilities() {
537         $this->testpage->set_context(context_system::instance());
538         $this->setAdminUser();
540         // Validated.
541         $this->assertEquals(array('moodle/site:manageblocks'), $this->testpage->all_editing_caps());
542     }
544     public function test_other_block_editing_cap() {
545         $this->testpage->set_context(context_system::instance());
546         $this->setAdminUser();
548         // Exercise SUT.
549         $this->testpage->set_blocks_editing_capability('moodle/my:manageblocks');
550         // Validated.
551         $this->assertEquals(array('moodle/my:manageblocks'), $this->testpage->all_editing_caps());
552     }
554     public function test_other_editing_cap() {
555         $this->testpage->set_context(context_system::instance());
556         $this->setAdminUser();
558         // Exercise SUT.
559         $this->testpage->set_other_editing_capability('moodle/course:manageactivities');
560         // Validated.
561         $actualcaps = $this->testpage->all_editing_caps();
562         $expectedcaps = array('moodle/course:manageactivities', 'moodle/site:manageblocks');
563         $this->assertEquals(array_values($expectedcaps), array_values($actualcaps));
564     }
566     public function test_other_editing_caps() {
567         $this->testpage->set_context(context_system::instance());
568         $this->setAdminUser();
570         // Exercise SUT.
571         $this->testpage->set_other_editing_capability(array('moodle/course:manageactivities', 'moodle/site:other'));
572         // Validated.
573         $actualcaps = $this->testpage->all_editing_caps();
574         $expectedcaps = array('moodle/course:manageactivities', 'moodle/site:other', 'moodle/site:manageblocks');
575         $this->assertEquals(array_values($expectedcaps), array_values($actualcaps));
576     }
578     /**
579      * Test getting a renderer.
580      */
581     public function test_get_renderer() {
582         global $OUTPUT, $PAGE;
583         $oldoutput = $OUTPUT;
584         $oldpage = $PAGE;
585         $PAGE = $this->testpage;
587         $this->testpage->set_pagelayout('standard');
588         $this->assertEquals('standard', $this->testpage->pagelayout);
589         // Initialise theme and output for the next tests.
590         $this->testpage->initialise_theme_and_output();
591         // Check the generated $OUTPUT object is a core renderer.
592         $this->assertInstanceOf('core_renderer', $OUTPUT);
593         // Check we can get a core renderer if we explicitly request one (no component).
594         $this->assertInstanceOf('core_renderer', $this->testpage->get_renderer('core'));
595         // Check we get a CLI renderer if we request a maintenance renderer. The CLI target should take precedence.
596         $this->assertInstanceOf('core_renderer_cli',
597             $this->testpage->get_renderer('core', null, RENDERER_TARGET_MAINTENANCE));
599         // Check we can get a coures renderer if we explicitly request one (valid component).
600         $this->assertInstanceOf('core_course_renderer', $this->testpage->get_renderer('core', 'course'));
602         // Check a properly invalid component.
603         try {
604             $this->testpage->get_renderer('core', 'monkeys');
605             $this->fail('Request for renderer with invalid component didn\'t throw expected exception.');
606         } catch (coding_exception $exception) {
607             $this->assertEquals('monkeys', $exception->debuginfo);
608         }
610         $PAGE = $oldpage;
611         $OUTPUT = $oldoutput;
612     }
614     /**
615      * Tests getting a renderer with a maintenance layout.
616      *
617      * This layout has special hacks in place in order to deliver a "maintenance" renderer.
618      */
619     public function test_get_renderer_maintenance() {
620         global $OUTPUT, $PAGE;
621         $oldoutput = $OUTPUT;
622         $oldpage = $PAGE;
623         $PAGE = $this->testpage;
625         $this->testpage->set_pagelayout('maintenance');
626         $this->assertEquals('maintenance', $this->testpage->pagelayout);
627         // Initialise theme and output for the next tests.
628         $this->testpage->initialise_theme_and_output();
629         // Check the generated $OUTPUT object is a core cli renderer.
630         // It shouldn't be maintenance because there the cli target should take greater precedence.
631         $this->assertInstanceOf('core_renderer_cli', $OUTPUT);
632         // Check we can get a core renderer if we explicitly request one (no component).
633         $this->assertInstanceOf('core_renderer', $this->testpage->get_renderer('core'));
634         // Check we get a CLI renderer if we request a maintenance renderer. The CLI target should take precedence.
635         $this->assertInstanceOf('core_renderer_cli',
636             $this->testpage->get_renderer('core', null, RENDERER_TARGET_MAINTENANCE));
637         // Check we can get a coures renderer if we explicitly request one (valid component).
638         $this->assertInstanceOf('core_course_renderer', $this->testpage->get_renderer('core', 'course'));
640         try {
641             $this->testpage->get_renderer('core', 'monkeys');
642             $this->fail('Request for renderer with invalid component didn\'t throw expected exception.');
643         } catch (coding_exception $exception) {
644             $this->assertEquals('monkeys', $exception->debuginfo);
645         }
647         $PAGE = $oldpage;
648         $OUTPUT = $oldoutput;
649     }
652 /**
653  * Test-specific subclass to make some protected things public.
654  */
655 class testable_moodle_page extends moodle_page {
656     public function initialise_default_pagetype($script = null) {
657         parent::initialise_default_pagetype($script);
658     }
659     public function url_to_class_name($url) {
660         return parent::url_to_class_name($url);
661     }
662     public function all_editing_caps() {
663         return parent::all_editing_caps();
664     }