2 // This file is part of Moodle - http://moodle.org/
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.
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.
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/>.
18 * Tests for the block_manager class in ../blocklib.php.
22 * @copyright 2009 Tim Hunt
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26 defined('MOODLE_INTERNAL') ||
die();
29 require_once($CFG->libdir
. '/pagelib.php');
30 require_once($CFG->libdir
. '/blocklib.php');
31 require_once($CFG->dirroot
. '/blocks/moodleblock.class.php');
35 * Test various block related classes.
37 class core_blocklib_testcase
extends advanced_testcase
{
39 protected $blockmanager;
40 protected $isediting = null;
42 protected function setUp() {
44 $this->testpage
= new moodle_page();
45 $this->testpage
->set_context(context_system
::instance());
46 $this->testpage
->set_pagetype('phpunit-block-test');
47 $this->blockmanager
= new testable_block_manager($this->testpage
);
50 protected function tearDown() {
51 $this->testpage
= null;
52 $this->blockmanager
= null;
56 protected function purge_blocks() {
58 $this->resetAfterTest();
60 $bis = $DB->get_records('block_instances');
61 foreach ($bis as $instance) {
62 blocks_delete_instance($instance);
66 public function test_no_regions_initially() {
67 // Exercise SUT & Validate.
68 $this->assertEquals(array(), $this->blockmanager
->get_regions());
71 public function test_add_region() {
73 $this->blockmanager
->add_region('a-region-name', false);
75 $this->assertEquals(array('a-region-name'), $this->blockmanager
->get_regions());
78 public function test_add_regions() {
80 $regions = array('a-region', 'another-region');
82 $this->blockmanager
->add_regions($regions, false);
84 $this->assertEquals($regions, $this->blockmanager
->get_regions(), '', 0, 10, true);
87 public function test_add_region_twice() {
89 $this->blockmanager
->add_region('a-region-name', false);
90 $this->blockmanager
->add_region('another-region', false);
92 $this->assertEquals(array('a-region-name', 'another-region'), $this->blockmanager
->get_regions(), '', 0, 10, true);
96 * @expectedException coding_exception
98 public function test_cannot_add_region_after_loaded() {
100 $this->blockmanager
->mark_loaded();
102 $this->blockmanager
->add_region('too-late', false);
106 * Testing adding a custom region.
108 public function test_add_custom_region() {
111 $this->blockmanager
->add_region('a-custom-region-name');
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']));
121 * Test adding two custom regions using add_regions method.
123 public function test_add_custom_regions() {
126 $regions = array('a-region', 'another-custom-region');
128 $this->blockmanager
->add_regions($regions);
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']));
137 * Test adding two custom block regions.
139 public function test_add_custom_region_twice() {
141 $this->blockmanager
->add_region('a-custom-region-name');
142 $this->blockmanager
->add_region('another-custom-region');
145 array('a-custom-region-name', 'another-custom-region'),
146 $this->blockmanager
->get_regions(),
152 * Test to ensure that we cannot add a region after the blocks have been loaded.
153 * @expectedException coding_exception
155 public function test_cannot_add_custom_region_after_loaded() {
157 $this->blockmanager
->mark_loaded();
159 $this->blockmanager
->add_region('too-late');
162 public function test_set_default_region() {
164 $this->blockmanager
->add_region('a-region-name', false);
166 $this->blockmanager
->set_default_region('a-region-name');
168 $this->assertEquals('a-region-name', $this->blockmanager
->get_default_region());
172 * @expectedException coding_exception
174 public function test_cannot_set_unknown_region_as_default() {
176 $this->blockmanager
->set_default_region('a-region-name');
180 * @expectedException coding_exception
182 public function test_cannot_change_default_region_after_loaded() {
184 $this->blockmanager
->mark_loaded();
186 $this->blockmanager
->set_default_region('too-late');
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);
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);
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);
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);
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);
209 $blockmanager = new testable_block_manager($page);
210 $blockmanager->add_regions($regions, false);
211 $blockmanager->set_default_region($regions[0]);
213 return array($page, $blockmanager);
216 protected function get_a_known_block_type() {
218 $block = new stdClass
;
219 $block->name
= 'ablocktype';
220 $DB->insert_record('block', $block);
224 protected function assertContainsBlocksOfType($typearray, $blockarray) {
225 if (!$this->assertEquals(count($typearray), count($blockarray), "Blocks array contains the wrong number of elements %s.")) {
228 $types = array_values($typearray);
230 foreach ($blockarray as $block) {
231 $blocktype = $types[$i];
232 $this->assertEquals($blocktype, $block->name(), "Block types do not match at postition $i %s.");
237 public function test_empty_initially() {
238 $this->purge_blocks();
241 list($page, $blockmanager) = $this->get_a_page_and_block_manager(array('a-region'),
242 context_system
::instance(), 'page-type');
244 $blockmanager->load_blocks();
246 $blocks = $blockmanager->get_loaded_blocks();
247 $this->assertEquals(array('a-region' => array()), $blocks);
250 public function test_adding_and_retrieving_one_block() {
251 $this->purge_blocks();
254 $regionname = 'a-region';
255 $blockname = $this->get_a_known_block_type();
256 $context = context_system
::instance();
258 list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
259 $context, 'page-type');
262 $blockmanager->add_block($blockname, $regionname, 0, false);
263 $blockmanager->load_blocks();
265 $blocks = $blockmanager->get_blocks_for_region($regionname);
266 $this->assertContainsBlocksOfType(array($blockname), $blocks);
269 public function test_adding_and_retrieving_two_blocks() {
270 $this->purge_blocks();
273 $regionname = 'a-region';
274 $blockname = $this->get_a_known_block_type();
275 $context = context_system
::instance();
277 list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
278 $context, 'page-type');
281 $blockmanager->add_block($blockname, $regionname, 0, false);
282 $blockmanager->add_block($blockname, $regionname, 1, false);
283 $blockmanager->load_blocks();
285 $blocks = $blockmanager->get_blocks_for_region($regionname);
286 $this->assertContainsBlocksOfType(array($blockname, $blockname), $blocks);
289 public function test_adding_blocks() {
290 $this->purge_blocks();
293 $regionname = 'a-region';
294 $blockname = $this->get_a_known_block_type();
295 $context = context_system
::instance();
297 list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
298 $context, 'page-type');
300 $blockmanager->add_blocks(array($regionname => array($blockname, $blockname)), null, null, false, 3);
301 $blockmanager->load_blocks();
303 $blocks = $blockmanager->get_blocks_for_region($regionname);
305 $this->assertEquals('3', $blocks[0]->instance
->weight
);
306 $this->assertEquals('4', $blocks[1]->instance
->weight
);
309 public function test_block_not_included_in_different_context() {
310 $this->purge_blocks();
313 $syscontext = context_system
::instance();
314 $cat = $this->getDataGenerator()->create_category(array('name' => 'testcategory'));
315 $fakecontext = context_coursecat
::instance($cat->id
);
316 $regionname = 'a-region';
317 $blockname = $this->get_a_known_block_type();
319 list($addpage, $addbm) = $this->get_a_page_and_block_manager(array($regionname), $fakecontext, 'page-type');
320 list($viewpage, $viewbm) = $this->get_a_page_and_block_manager(array($regionname), $syscontext, 'page-type');
322 $addbm->add_block($blockname, $regionname, 0, false);
325 $viewbm->load_blocks();
327 $blocks = $viewbm->get_blocks_for_region($regionname);
328 $this->assertContainsBlocksOfType(array(), $blocks);
331 public function test_block_included_in_sub_context() {
332 $this->purge_blocks();
335 $syscontext = context_system
::instance();
336 $childcontext = context_coursecat
::instance(1);
337 $regionname = 'a-region';
338 $blockname = $this->get_a_known_block_type();
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), $childcontext, 'page-type');
343 $addbm->add_block($blockname, $regionname, 0, true);
346 $viewbm->load_blocks();
348 $blocks = $viewbm->get_blocks_for_region($regionname);
349 $this->assertContainsBlocksOfType(array($blockname), $blocks);
352 public function test_block_not_included_on_different_page_type() {
353 $this->purge_blocks();
356 $syscontext = context_system
::instance();
357 $regionname = 'a-region';
358 $blockname = $this->get_a_known_block_type();
360 list($addpage, $addbm) = $this->get_a_page_and_block_manager(array($regionname), $syscontext, 'page-type');
361 list($viewpage, $viewbm) = $this->get_a_page_and_block_manager(array($regionname), $syscontext, 'other-page-type');
363 $addbm->add_block($blockname, $regionname, 0, true);
366 $viewbm->load_blocks();
368 $blocks = $viewbm->get_blocks_for_region($regionname);
369 $this->assertContainsBlocksOfType(array(), $blocks);
372 public function test_block_not_included_on_different_sub_page() {
373 $this->purge_blocks();
376 $regionname = 'a-region';
377 $blockname = $this->get_a_known_block_type();
378 $syscontext = context_system
::instance();
380 list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
381 $syscontext, 'page-type', 'sub-page');
383 $blockmanager->add_block($blockname, $regionname, 0, true, $page->pagetype
, 'other-sub-page');
386 $blockmanager->load_blocks();
388 $blocks = $blockmanager->get_blocks_for_region($regionname);
389 $this->assertContainsBlocksOfType(array(), $blocks);
392 public function test_block_included_with_explicit_sub_page() {
393 $this->purge_blocks();
396 $regionname = 'a-region';
397 $blockname = $this->get_a_known_block_type();
398 $syscontext = context_system
::instance();
400 list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
401 $syscontext, 'page-type', 'sub-page');
403 $blockmanager->add_block($blockname, $regionname, 0, true, $page->pagetype
, $page->subpage
);
406 $blockmanager->load_blocks();
408 $blocks = $blockmanager->get_blocks_for_region($regionname);
409 $this->assertContainsBlocksOfType(array($blockname), $blocks);
412 public function test_block_included_with_page_type_pattern() {
413 $this->purge_blocks();
416 $regionname = 'a-region';
417 $blockname = $this->get_a_known_block_type();
418 $syscontext = context_system
::instance();
420 list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
421 $syscontext, 'page-type', 'sub-page');
423 $blockmanager->add_block($blockname, $regionname, 0, true, 'page-*', $page->subpage
);
426 $blockmanager->load_blocks();
428 $blocks = $blockmanager->get_blocks_for_region($regionname);
429 $this->assertContainsBlocksOfType(array($blockname), $blocks);
432 public function test_matching_page_type_patterns_from_pattern() {
434 $expected = array('*');
435 $this->assertEquals($expected, array_values(matching_page_type_patterns_from_pattern($pattern)));
437 $pattern = 'admin-*';
438 $expected = array('admin-*', 'admin', '*');
439 $this->assertEquals($expected, array_values(matching_page_type_patterns_from_pattern($pattern)));
441 $pattern = 'blog-index';
442 $expected = array('blog-index', 'blog-index-*', 'blog-*', '*');
443 $this->assertEquals($expected, array_values(matching_page_type_patterns_from_pattern($pattern)));
445 $pattern = 'course-index-*';
446 $expected = array('course-index-*', 'course-index', 'course-*', '*');
447 $this->assertEquals($expected, array_values(matching_page_type_patterns_from_pattern($pattern)));
449 $pattern = 'course-index-category';
450 $expected = array('course-index-category', 'course-index-category-*', 'course-index-*', 'course-*', '*');
451 $this->assertEquals($expected, array_values(matching_page_type_patterns_from_pattern($pattern)));
453 $pattern = 'mod-assign-view';
454 $expected = array('mod-assign-view', 'mod-*-view', 'mod-assign-view-*', 'mod-assign-*', 'mod-*', '*');
455 $this->assertEquals($expected, array_values(matching_page_type_patterns_from_pattern($pattern)));
457 $pattern = 'mod-assign-index';
458 $expected = array('mod-assign-index', 'mod-*-index', 'mod-assign-index-*', 'mod-assign-*', 'mod-*', '*');
459 $this->assertEquals($expected, array_values(matching_page_type_patterns_from_pattern($pattern)));
461 $pattern = 'mod-forum-*';
462 $expected = array('mod-forum-*', 'mod-forum', 'mod-*', '*');
463 $this->assertEquals($expected, array_values(matching_page_type_patterns_from_pattern($pattern)));
465 $pattern = 'mod-*-view';
466 $expected = array('mod-*-view', 'mod', 'mod-*', '*');
467 $this->assertEquals($expected, array_values(matching_page_type_patterns_from_pattern($pattern)));
469 $pattern = 'mod-*-index';
470 $expected = array('mod-*-index', 'mod', 'mod-*', '*');
471 $this->assertEquals($expected, array_values(matching_page_type_patterns_from_pattern($pattern)));
473 $pattern = 'my-index';
474 $expected = array('my-index', 'my-index-*', 'my-*', '*');
475 $this->assertEquals($expected, array_values(matching_page_type_patterns_from_pattern($pattern)));
477 $pattern = 'user-profile';
478 $expected = array('user-profile', 'user-profile-*', 'user-*', '*');
479 $this->assertEquals($expected, array_values(matching_page_type_patterns_from_pattern($pattern)));
484 * Test-specific subclass to make some protected things public.
486 class testable_block_manager
extends block_manager
{
488 public function mark_loaded() {
489 $this->birecordsbyregion
= array();
491 public function get_loaded_blocks() {
492 return $this->birecordsbyregion
;
497 * Test-specific subclass to make some protected things public.
499 class block_ablocktype
extends block_base
{
500 public function init() {