MDL-41551 blocks: added tracking and recognition of custom block regions
[moodle.git] / lib / tests / blocklib_test.php
CommitLineData
a3d5830a
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 * 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 */
25
26defined('MOODLE_INTERNAL') || die();
27
28global $CFG;
29require_once($CFG->libdir . '/pagelib.php');
30require_once($CFG->libdir . '/blocklib.php');
31require_once($CFG->dirroot . '/blocks/moodleblock.class.php');
32
33
a3d5830a 34/**
3e654ea2 35 * Test various block related classes.
a3d5830a 36 */
3e654ea2 37class core_blocklib_testcase extends advanced_testcase {
a3d5830a
PS
38 protected $testpage;
39 protected $blockmanager;
3e654ea2 40 protected $isediting = null;
a3d5830a 41
1cbf2a20 42 protected function setUp() {
a3d5830a
PS
43 parent::setUp();
44 $this->testpage = new moodle_page();
b0c6dc1c 45 $this->testpage->set_context(context_system::instance());
292dcf04 46 $this->testpage->set_pagetype('phpunit-block-test');
a3d5830a
PS
47 $this->blockmanager = new testable_block_manager($this->testpage);
48 }
49
1cbf2a20 50 protected function tearDown() {
a3d5830a
PS
51 $this->testpage = null;
52 $this->blockmanager = null;
53 parent::tearDown();
54 }
55
3e654ea2
PS
56 protected function purge_blocks() {
57 global $DB;
58 $this->resetAfterTest();
59
60 $bis = $DB->get_records('block_instances');
61 foreach ($bis as $instance) {
62 blocks_delete_instance($instance);
63 }
64 }
65
a3d5830a 66 public function test_no_regions_initially() {
3e654ea2 67 // Exercise SUT & Validate.
a3d5830a
PS
68 $this->assertEquals(array(), $this->blockmanager->get_regions());
69 }
70
71 public function test_add_region() {
72 // Exercise SUT.
292dcf04 73 $this->blockmanager->add_region('a-region-name', false);
3e654ea2 74 // Validate.
a3d5830a
PS
75 $this->assertEquals(array('a-region-name'), $this->blockmanager->get_regions());
76 }
77
78 public function test_add_regions() {
79 // Set up fixture.
80 $regions = array('a-region', 'another-region');
81 // Exercise SUT.
292dcf04 82 $this->blockmanager->add_regions($regions, false);
3e654ea2 83 // Validate.
a3d5830a
PS
84 $this->assertEquals($regions, $this->blockmanager->get_regions(), '', 0, 10, true);
85 }
86
87 public function test_add_region_twice() {
88 // Exercise SUT.
292dcf04
SH
89 $this->blockmanager->add_region('a-region-name', false);
90 $this->blockmanager->add_region('another-region', false);
3e654ea2 91 // Validate.
a3d5830a
PS
92 $this->assertEquals(array('a-region-name', 'another-region'), $this->blockmanager->get_regions(), '', 0, 10, true);
93 }
94
95 /**
96 * @expectedException coding_exception
a3d5830a
PS
97 */
98 public function test_cannot_add_region_after_loaded() {
292dcf04
SH
99 // Set up fixture.
100 $this->blockmanager->mark_loaded();
101 // Exercise SUT.
102 $this->blockmanager->add_region('too-late', false);
103 }
104
105 /**
106 * Testing adding a custom region.
107 */
108 public function test_add_custom_region() {
109 global $SESSION;
110 // Exercise SUT.
111 $this->blockmanager->add_region('a-custom-region-name');
112 // Validate.
113 $this->assertEquals(array('a-custom-region-name'), $this->blockmanager->get_regions());
114 $this->assertTrue(isset($SESSION->custom_block_regions));
115 $this->assertArrayHasKey('phpunit-block-test', $SESSION->custom_block_regions);
116 $this->assertTrue(in_array('a-custom-region-name', $SESSION->custom_block_regions['phpunit-block-test']));
117
118 }
119
120 /**
121 * Test adding two custom regions using add_regions method.
122 */
123 public function test_add_custom_regions() {
124 global $SESSION;
125 // Set up fixture.
126 $regions = array('a-region', 'another-custom-region');
127 // Exercise SUT.
128 $this->blockmanager->add_regions($regions);
129 // Validate.
130 $this->assertEquals($regions, $this->blockmanager->get_regions(), '', 0, 10, true);
131 $this->assertTrue(isset($SESSION->custom_block_regions));
132 $this->assertArrayHasKey('phpunit-block-test', $SESSION->custom_block_regions);
133 $this->assertTrue(in_array('another-custom-region', $SESSION->custom_block_regions['phpunit-block-test']));
134 }
135
136 /**
137 * Test adding two custom block regions.
138 */
139 public function test_add_custom_region_twice() {
140 // Exercise SUT.
141 $this->blockmanager->add_region('a-custom-region-name');
142 $this->blockmanager->add_region('another-custom-region');
143 // Validate.
144 $this->assertEquals(
145 array('a-custom-region-name', 'another-custom-region'),
146 $this->blockmanager->get_regions(),
147 '', 0, 10, true
148 );
149 }
150
151 /**
152 * Test to ensure that we cannot add a region after the blocks have been loaded.
153 * @expectedException coding_exception
154 */
155 public function test_cannot_add_custom_region_after_loaded() {
a3d5830a
PS
156 // Set up fixture.
157 $this->blockmanager->mark_loaded();
158 // Exercise SUT.
159 $this->blockmanager->add_region('too-late');
160 }
161
162 public function test_set_default_region() {
163 // Set up fixture.
292dcf04 164 $this->blockmanager->add_region('a-region-name', false);
a3d5830a
PS
165 // Exercise SUT.
166 $this->blockmanager->set_default_region('a-region-name');
3e654ea2 167 // Validate.
a3d5830a
PS
168 $this->assertEquals('a-region-name', $this->blockmanager->get_default_region());
169 }
170
171 /**
172 * @expectedException coding_exception
a3d5830a
PS
173 */
174 public function test_cannot_set_unknown_region_as_default() {
175 // Exercise SUT.
176 $this->blockmanager->set_default_region('a-region-name');
177 }
178
179 /**
180 * @expectedException coding_exception
a3d5830a
PS
181 */
182 public function test_cannot_change_default_region_after_loaded() {
183 // Set up fixture.
184 $this->blockmanager->mark_loaded();
185 // Exercise SUT.
186 $this->blockmanager->set_default_region('too-late');
187 }
188
189 public function test_matching_page_type_patterns() {
190 $this->assertEquals(array('site-index', 'site-index-*', 'site-*', '*'),
191 matching_page_type_patterns('site-index'), '', 0, 10, true);
192
193 $this->assertEquals(array('mod-quiz-report-overview', 'mod-quiz-report-overview-*', 'mod-quiz-report-*', 'mod-quiz-*', 'mod-*', '*'),
194 matching_page_type_patterns('mod-quiz-report-overview'), '', 0, 10, true);
195
196 $this->assertEquals(array('mod-forum-view', 'mod-*-view', 'mod-forum-view-*', 'mod-forum-*', 'mod-*', '*'),
197 matching_page_type_patterns('mod-forum-view'), '', 0, 10, true);
198
199 $this->assertEquals(array('mod-forum-index', 'mod-*-index', 'mod-forum-index-*', 'mod-forum-*', 'mod-*', '*'),
200 matching_page_type_patterns('mod-forum-index'), '', 0, 10, true);
201 }
a3d5830a
PS
202
203 protected function get_a_page_and_block_manager($regions, $context, $pagetype, $subpage = '') {
204 $page = new moodle_page;
205 $page->set_context($context);
206 $page->set_pagetype($pagetype);
207 $page->set_subpage($subpage);
208
209 $blockmanager = new testable_block_manager($page);
292dcf04 210 $blockmanager->add_regions($regions, false);
a3d5830a
PS
211 $blockmanager->set_default_region($regions[0]);
212
213 return array($page, $blockmanager);
214 }
215
216 protected function get_a_known_block_type() {
217 global $DB;
218 $block = new stdClass;
219 $block->name = 'ablocktype';
220 $DB->insert_record('block', $block);
221 return $block->name;
222 }
223
224 protected function assertContainsBlocksOfType($typearray, $blockarray) {
225 if (!$this->assertEquals(count($typearray), count($blockarray), "Blocks array contains the wrong number of elements %s.")) {
226 return;
227 }
228 $types = array_values($typearray);
229 $i = 0;
230 foreach ($blockarray as $block) {
231 $blocktype = $types[$i];
232 $this->assertEquals($blocktype, $block->name(), "Block types do not match at postition $i %s.");
233 $i++;
234 }
235 }
236
237 public function test_empty_initially() {
238 $this->purge_blocks();
239
240 // Set up fixture.
241 list($page, $blockmanager) = $this->get_a_page_and_block_manager(array('a-region'),
b0c6dc1c 242 context_system::instance(), 'page-type');
a3d5830a
PS
243 // Exercise SUT.
244 $blockmanager->load_blocks();
245 // Validate.
246 $blocks = $blockmanager->get_loaded_blocks();
247 $this->assertEquals(array('a-region' => array()), $blocks);
248 }
249
250 public function test_adding_and_retrieving_one_block() {
251 $this->purge_blocks();
252
253 // Set up fixture.
254 $regionname = 'a-region';
255 $blockname = $this->get_a_known_block_type();
b0c6dc1c 256 $context = context_system::instance();
a3d5830a
PS
257
258 list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
259 $context, 'page-type');
260
261 // Exercise SUT.
262 $blockmanager->add_block($blockname, $regionname, 0, false);
263 $blockmanager->load_blocks();
264 // Validate.
265 $blocks = $blockmanager->get_blocks_for_region($regionname);
266 $this->assertContainsBlocksOfType(array($blockname), $blocks);
267 }
268
269 public function test_adding_and_retrieving_two_blocks() {
270 $this->purge_blocks();
271
272 // Set up fixture.
273 $regionname = 'a-region';
274 $blockname = $this->get_a_known_block_type();
b0c6dc1c 275 $context = context_system::instance();
a3d5830a
PS
276
277 list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
278 $context, 'page-type');
279
280 // Exercise SUT.
281 $blockmanager->add_block($blockname, $regionname, 0, false);
282 $blockmanager->add_block($blockname, $regionname, 1, false);
283 $blockmanager->load_blocks();
284 // Validate.
285 $blocks = $blockmanager->get_blocks_for_region($regionname);
286 $this->assertContainsBlocksOfType(array($blockname, $blockname), $blocks);
287 }
288
289 public function test_block_not_included_in_different_context() {
a3d5830a
PS
290 $this->purge_blocks();
291
292 // Set up fixture.
b0c6dc1c 293 $syscontext = context_system::instance();
b28bb7e8
MG
294 $cat = $this->getDataGenerator()->create_category(array('name' => 'testcategory'));
295 $fakecontext = context_coursecat::instance($cat->id);
a3d5830a
PS
296 $regionname = 'a-region';
297 $blockname = $this->get_a_known_block_type();
298
299 list($addpage, $addbm) = $this->get_a_page_and_block_manager(array($regionname), $fakecontext, 'page-type');
300 list($viewpage, $viewbm) = $this->get_a_page_and_block_manager(array($regionname), $syscontext, 'page-type');
301
302 $addbm->add_block($blockname, $regionname, 0, false);
303
304 // Exercise SUT.
305 $viewbm->load_blocks();
306 // Validate.
307 $blocks = $viewbm->get_blocks_for_region($regionname);
308 $this->assertContainsBlocksOfType(array(), $blocks);
309 }
310
311 public function test_block_included_in_sub_context() {
312 $this->purge_blocks();
313
314 // Set up fixture.
b0c6dc1c 315 $syscontext = context_system::instance();
a3d5830a
PS
316 $childcontext = context_coursecat::instance(1);
317 $regionname = 'a-region';
318 $blockname = $this->get_a_known_block_type();
319
320 list($addpage, $addbm) = $this->get_a_page_and_block_manager(array($regionname), $syscontext, 'page-type');
321 list($viewpage, $viewbm) = $this->get_a_page_and_block_manager(array($regionname), $childcontext, 'page-type');
322
323 $addbm->add_block($blockname, $regionname, 0, true);
324
325 // Exercise SUT.
326 $viewbm->load_blocks();
327 // Validate.
328 $blocks = $viewbm->get_blocks_for_region($regionname);
329 $this->assertContainsBlocksOfType(array($blockname), $blocks);
330 }
331
332 public function test_block_not_included_on_different_page_type() {
333 $this->purge_blocks();
334
335 // Set up fixture.
b0c6dc1c 336 $syscontext = context_system::instance();
a3d5830a
PS
337 $regionname = 'a-region';
338 $blockname = $this->get_a_known_block_type();
339
340 list($addpage, $addbm) = $this->get_a_page_and_block_manager(array($regionname), $syscontext, 'page-type');
341 list($viewpage, $viewbm) = $this->get_a_page_and_block_manager(array($regionname), $syscontext, 'other-page-type');
342
343 $addbm->add_block($blockname, $regionname, 0, true);
344
345 // Exercise SUT.
346 $viewbm->load_blocks();
347 // Validate.
348 $blocks = $viewbm->get_blocks_for_region($regionname);
349 $this->assertContainsBlocksOfType(array(), $blocks);
350 }
351
352 public function test_block_not_included_on_different_sub_page() {
353 $this->purge_blocks();
354
355 // Set up fixture.
356 $regionname = 'a-region';
357 $blockname = $this->get_a_known_block_type();
b0c6dc1c 358 $syscontext = context_system::instance();
a3d5830a
PS
359
360 list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
361 $syscontext, 'page-type', 'sub-page');
362
363 $blockmanager->add_block($blockname, $regionname, 0, true, $page->pagetype, 'other-sub-page');
364
365 // Exercise SUT.
366 $blockmanager->load_blocks();
367 // Validate.
368 $blocks = $blockmanager->get_blocks_for_region($regionname);
369 $this->assertContainsBlocksOfType(array(), $blocks);
370 }
371
372 public function test_block_included_with_explicit_sub_page() {
373 $this->purge_blocks();
374
375 // Set up fixture.
376 $regionname = 'a-region';
377 $blockname = $this->get_a_known_block_type();
b0c6dc1c 378 $syscontext = context_system::instance();
a3d5830a
PS
379
380 list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
381 $syscontext, 'page-type', 'sub-page');
382
383 $blockmanager->add_block($blockname, $regionname, 0, true, $page->pagetype, $page->subpage);
384
385 // Exercise SUT.
386 $blockmanager->load_blocks();
387 // Validate.
388 $blocks = $blockmanager->get_blocks_for_region($regionname);
389 $this->assertContainsBlocksOfType(array($blockname), $blocks);
390 }
391
392 public function test_block_included_with_page_type_pattern() {
393 $this->purge_blocks();
394
395 // Set up fixture.
396 $regionname = 'a-region';
397 $blockname = $this->get_a_known_block_type();
b0c6dc1c 398 $syscontext = context_system::instance();
a3d5830a
PS
399
400 list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
401 $syscontext, 'page-type', 'sub-page');
402
403 $blockmanager->add_block($blockname, $regionname, 0, true, 'page-*', $page->subpage);
404
405 // Exercise SUT.
406 $blockmanager->load_blocks();
407 // Validate.
408 $blocks = $blockmanager->get_blocks_for_region($regionname);
409 $this->assertContainsBlocksOfType(array($blockname), $blocks);
410 }
411}
412
3e654ea2
PS
413/**
414 * Test-specific subclass to make some protected things public.
415 */
416class testable_block_manager extends block_manager {
417
418 public function mark_loaded() {
419 $this->birecordsbyregion = array();
420 }
421 public function get_loaded_blocks() {
422 return $this->birecordsbyregion;
423 }
424}
425
426/**
427 * Test-specific subclass to make some protected things public.
428 */
429class block_ablocktype extends block_base {
430 public function init() {
431 }
432}