fbadf5d299b45862b3c8724ede185ee4676eaee1
[moodle.git] / lib / tests / blocklib_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 block_manager class in ../blocklib.php.
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');
31 require_once($CFG->dirroot . '/blocks/moodleblock.class.php');
34 /**
35  * Test various block related classes.
36  */
37 class core_blocklib_testcase extends advanced_testcase {
38     protected $testpage;
39     protected $blockmanager;
40     protected $isediting = null;
42     protected function setUp() {
43         parent::setUp();
44         $this->testpage = new moodle_page();
45         $this->testpage->set_context(context_system::instance());
46         $this->blockmanager = new testable_block_manager($this->testpage);
47     }
49     protected function tearDown() {
50         $this->testpage = null;
51         $this->blockmanager = null;
52         parent::tearDown();
53     }
55     protected function purge_blocks() {
56         global $DB;
57         $this->resetAfterTest();
59         $bis = $DB->get_records('block_instances');
60         foreach ($bis as $instance) {
61             blocks_delete_instance($instance);
62         }
63     }
65     public function test_no_regions_initially() {
66         // Exercise SUT & Validate.
67         $this->assertEquals(array(), $this->blockmanager->get_regions());
68     }
70     public function test_add_region() {
71         // Exercise SUT.
72         $this->blockmanager->add_region('a-region-name');
73         // Validate.
74         $this->assertEquals(array('a-region-name'), $this->blockmanager->get_regions());
75     }
77     public function test_add_regions() {
78         // Set up fixture.
79         $regions = array('a-region', 'another-region');
80         // Exercise SUT.
81         $this->blockmanager->add_regions($regions);
82         // Validate.
83         $this->assertEquals($regions, $this->blockmanager->get_regions(), '', 0, 10, true);
84     }
86     public function test_add_region_twice() {
87         // Exercise SUT.
88         $this->blockmanager->add_region('a-region-name');
89         $this->blockmanager->add_region('another-region');
90         // Validate.
91         $this->assertEquals(array('a-region-name', 'another-region'), $this->blockmanager->get_regions(), '', 0, 10, true);
92     }
94     /**
95      * @expectedException coding_exception
96      */
97     public function test_cannot_add_region_after_loaded() {
98         // Set up fixture.
99         $this->blockmanager->mark_loaded();
100         // Exercise SUT.
101         $this->blockmanager->add_region('too-late');
102     }
104     public function test_set_default_region() {
105         // Set up fixture.
106         $this->blockmanager->add_region('a-region-name');
107         // Exercise SUT.
108         $this->blockmanager->set_default_region('a-region-name');
109         // Validate.
110         $this->assertEquals('a-region-name', $this->blockmanager->get_default_region());
111     }
113     /**
114      * @expectedException coding_exception
115      */
116     public function test_cannot_set_unknown_region_as_default() {
117         // Exercise SUT.
118         $this->blockmanager->set_default_region('a-region-name');
119     }
121     /**
122      * @expectedException coding_exception
123      */
124     public function test_cannot_change_default_region_after_loaded() {
125         // Set up fixture.
126         $this->blockmanager->mark_loaded();
127         // Exercise SUT.
128         $this->blockmanager->set_default_region('too-late');
129     }
131     public function test_matching_page_type_patterns() {
132         $this->assertEquals(array('site-index', 'site-index-*', 'site-*', '*'),
133             matching_page_type_patterns('site-index'), '', 0, 10, true);
135         $this->assertEquals(array('mod-quiz-report-overview', 'mod-quiz-report-overview-*', 'mod-quiz-report-*', 'mod-quiz-*', 'mod-*', '*'),
136             matching_page_type_patterns('mod-quiz-report-overview'), '', 0, 10, true);
138         $this->assertEquals(array('mod-forum-view', 'mod-*-view', 'mod-forum-view-*', 'mod-forum-*', 'mod-*', '*'),
139             matching_page_type_patterns('mod-forum-view'), '', 0, 10, true);
141         $this->assertEquals(array('mod-forum-index', 'mod-*-index', 'mod-forum-index-*', 'mod-forum-*', 'mod-*', '*'),
142             matching_page_type_patterns('mod-forum-index'), '', 0, 10, true);
143     }
145     protected function get_a_page_and_block_manager($regions, $context, $pagetype, $subpage = '') {
146         $page = new moodle_page;
147         $page->set_context($context);
148         $page->set_pagetype($pagetype);
149         $page->set_subpage($subpage);
151         $blockmanager = new testable_block_manager($page);
152         $blockmanager->add_regions($regions);
153         $blockmanager->set_default_region($regions[0]);
155         return array($page, $blockmanager);
156     }
158     protected function get_a_known_block_type() {
159         global $DB;
160         $block = new stdClass;
161         $block->name = 'ablocktype';
162         $DB->insert_record('block', $block);
163         return $block->name;
164     }
166     protected function assertContainsBlocksOfType($typearray, $blockarray) {
167         if (!$this->assertEquals(count($typearray), count($blockarray), "Blocks array contains the wrong number of elements %s.")) {
168             return;
169         }
170         $types = array_values($typearray);
171         $i = 0;
172         foreach ($blockarray as $block) {
173             $blocktype = $types[$i];
174             $this->assertEquals($blocktype, $block->name(), "Block types do not match at postition $i %s.");
175             $i++;
176         }
177     }
179     public function test_empty_initially() {
180         $this->purge_blocks();
182         // Set up fixture.
183         list($page, $blockmanager) = $this->get_a_page_and_block_manager(array('a-region'),
184             context_system::instance(), 'page-type');
185         // Exercise SUT.
186         $blockmanager->load_blocks();
187         // Validate.
188         $blocks = $blockmanager->get_loaded_blocks();
189         $this->assertEquals(array('a-region' => array()), $blocks);
190     }
192     public function test_adding_and_retrieving_one_block() {
193         $this->purge_blocks();
195         // Set up fixture.
196         $regionname = 'a-region';
197         $blockname = $this->get_a_known_block_type();
198         $context = context_system::instance();
200         list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
201             $context, 'page-type');
203         // Exercise SUT.
204         $blockmanager->add_block($blockname, $regionname, 0, false);
205         $blockmanager->load_blocks();
206         // Validate.
207         $blocks = $blockmanager->get_blocks_for_region($regionname);
208         $this->assertContainsBlocksOfType(array($blockname), $blocks);
209     }
211     public function test_adding_and_retrieving_two_blocks() {
212         $this->purge_blocks();
214         // Set up fixture.
215         $regionname = 'a-region';
216         $blockname = $this->get_a_known_block_type();
217         $context = context_system::instance();
219         list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
220             $context, 'page-type');
222         // Exercise SUT.
223         $blockmanager->add_block($blockname, $regionname, 0, false);
224         $blockmanager->add_block($blockname, $regionname, 1, false);
225         $blockmanager->load_blocks();
226         // Validate.
227         $blocks = $blockmanager->get_blocks_for_region($regionname);
228         $this->assertContainsBlocksOfType(array($blockname, $blockname), $blocks);
229     }
231     public function test_block_not_included_in_different_context() {
232         $this->purge_blocks();
234         // Set up fixture.
235         $syscontext = context_system::instance();
236         $cat = $this->getDataGenerator()->create_category(array('name' => 'testcategory'));
237         $fakecontext = context_coursecat::instance($cat->id);
238         $regionname = 'a-region';
239         $blockname = $this->get_a_known_block_type();
241         list($addpage, $addbm) = $this->get_a_page_and_block_manager(array($regionname), $fakecontext, 'page-type');
242         list($viewpage, $viewbm) = $this->get_a_page_and_block_manager(array($regionname), $syscontext, 'page-type');
244         $addbm->add_block($blockname, $regionname, 0, false);
246         // Exercise SUT.
247         $viewbm->load_blocks();
248         // Validate.
249         $blocks = $viewbm->get_blocks_for_region($regionname);
250         $this->assertContainsBlocksOfType(array(), $blocks);
251     }
253     public function test_block_included_in_sub_context() {
254         $this->purge_blocks();
256         // Set up fixture.
257         $syscontext = context_system::instance();
258         $childcontext = context_coursecat::instance(1);
259         $regionname = 'a-region';
260         $blockname = $this->get_a_known_block_type();
262         list($addpage, $addbm) = $this->get_a_page_and_block_manager(array($regionname), $syscontext, 'page-type');
263         list($viewpage, $viewbm) = $this->get_a_page_and_block_manager(array($regionname), $childcontext, 'page-type');
265         $addbm->add_block($blockname, $regionname, 0, true);
267         // Exercise SUT.
268         $viewbm->load_blocks();
269         // Validate.
270         $blocks = $viewbm->get_blocks_for_region($regionname);
271         $this->assertContainsBlocksOfType(array($blockname), $blocks);
272     }
274     public function test_block_not_included_on_different_page_type() {
275         $this->purge_blocks();
277         // Set up fixture.
278         $syscontext = context_system::instance();
279         $regionname = 'a-region';
280         $blockname = $this->get_a_known_block_type();
282         list($addpage, $addbm) = $this->get_a_page_and_block_manager(array($regionname), $syscontext, 'page-type');
283         list($viewpage, $viewbm) = $this->get_a_page_and_block_manager(array($regionname), $syscontext, 'other-page-type');
285         $addbm->add_block($blockname, $regionname, 0, true);
287         // Exercise SUT.
288         $viewbm->load_blocks();
289         // Validate.
290         $blocks = $viewbm->get_blocks_for_region($regionname);
291         $this->assertContainsBlocksOfType(array(), $blocks);
292     }
294     public function test_block_not_included_on_different_sub_page() {
295         $this->purge_blocks();
297         // Set up fixture.
298         $regionname = 'a-region';
299         $blockname = $this->get_a_known_block_type();
300         $syscontext = context_system::instance();
302         list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
303             $syscontext, 'page-type', 'sub-page');
305         $blockmanager->add_block($blockname, $regionname, 0, true, $page->pagetype, 'other-sub-page');
307         // Exercise SUT.
308         $blockmanager->load_blocks();
309         // Validate.
310         $blocks = $blockmanager->get_blocks_for_region($regionname);
311         $this->assertContainsBlocksOfType(array(), $blocks);
312     }
314     public function test_block_included_with_explicit_sub_page() {
315         $this->purge_blocks();
317         // Set up fixture.
318         $regionname = 'a-region';
319         $blockname = $this->get_a_known_block_type();
320         $syscontext = context_system::instance();
322         list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
323             $syscontext, 'page-type', 'sub-page');
325         $blockmanager->add_block($blockname, $regionname, 0, true, $page->pagetype, $page->subpage);
327         // Exercise SUT.
328         $blockmanager->load_blocks();
329         // Validate.
330         $blocks = $blockmanager->get_blocks_for_region($regionname);
331         $this->assertContainsBlocksOfType(array($blockname), $blocks);
332     }
334     public function test_block_included_with_page_type_pattern() {
335         $this->purge_blocks();
337         // Set up fixture.
338         $regionname = 'a-region';
339         $blockname = $this->get_a_known_block_type();
340         $syscontext = context_system::instance();
342         list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
343             $syscontext, 'page-type', 'sub-page');
345         $blockmanager->add_block($blockname, $regionname, 0, true, 'page-*', $page->subpage);
347         // Exercise SUT.
348         $blockmanager->load_blocks();
349         // Validate.
350         $blocks = $blockmanager->get_blocks_for_region($regionname);
351         $this->assertContainsBlocksOfType(array($blockname), $blocks);
352     }
355 /**
356  * Test-specific subclass to make some protected things public.
357  */
358 class testable_block_manager extends block_manager {
360     public function mark_loaded() {
361         $this->birecordsbyregion = array();
362     }
363     public function get_loaded_blocks() {
364         return $this->birecordsbyregion;
365     }
368 /**
369  * Test-specific subclass to make some protected things public.
370  */
371 class block_ablocktype extends block_base {
372     public function init() {
373     }