Merge branch 'MDL-49360-28' of git://github.com/lameze/moodle into MOODLE_28_STABLE
[moodle.git] / lib / tests / blocklib_test.php
blob38e3790c0f647633129ee704f828d6f20aead594
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.
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.
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
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.
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->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;
53 parent::tearDown();
56 protected function purge_blocks() {
57 global $DB;
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() {
72 // Exercise SUT.
73 $this->blockmanager->add_region('a-region-name', false);
74 // Validate.
75 $this->assertEquals(array('a-region-name'), $this->blockmanager->get_regions());
78 public function test_add_regions() {
79 // Set up fixture.
80 $regions = array('a-region', 'another-region');
81 // Exercise SUT.
82 $this->blockmanager->add_regions($regions, false);
83 // Validate.
84 $this->assertEquals($regions, $this->blockmanager->get_regions(), '', 0, 10, true);
87 public function test_add_region_twice() {
88 // Exercise SUT.
89 $this->blockmanager->add_region('a-region-name', false);
90 $this->blockmanager->add_region('another-region', false);
91 // Validate.
92 $this->assertEquals(array('a-region-name', 'another-region'), $this->blockmanager->get_regions(), '', 0, 10, true);
95 /**
96 * @expectedException coding_exception
98 public function test_cannot_add_region_after_loaded() {
99 // Set up fixture.
100 $this->blockmanager->mark_loaded();
101 // Exercise SUT.
102 $this->blockmanager->add_region('too-late', false);
106 * Testing adding a custom region.
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']));
121 * Test adding two custom regions using add_regions method.
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']));
137 * Test adding two custom block regions.
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
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() {
156 // Set up fixture.
157 $this->blockmanager->mark_loaded();
158 // Exercise SUT.
159 $this->blockmanager->add_region('too-late');
162 public function test_set_default_region() {
163 // Set up fixture.
164 $this->blockmanager->add_region('a-region-name', false);
165 // Exercise SUT.
166 $this->blockmanager->set_default_region('a-region-name');
167 // Validate.
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() {
175 // Exercise SUT.
176 $this->blockmanager->set_default_region('a-region-name');
180 * @expectedException coding_exception
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');
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() {
217 global $DB;
218 $block = new stdClass;
219 $block->name = 'ablocktype';
220 $DB->insert_record('block', $block);
221 return $block->name;
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;
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++;
237 public function test_empty_initially() {
238 $this->purge_blocks();
240 // Set up fixture.
241 list($page, $blockmanager) = $this->get_a_page_and_block_manager(array('a-region'),
242 context_system::instance(), 'page-type');
243 // Exercise SUT.
244 $blockmanager->load_blocks();
245 // Validate.
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();
253 // Set up fixture.
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');
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);
269 public function test_adding_and_retrieving_two_blocks() {
270 $this->purge_blocks();
272 // Set up fixture.
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');
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);
289 public function test_adding_blocks() {
290 $this->purge_blocks();
292 // Set up fixture.
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();
312 // Set up fixture.
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);
324 // Exercise SUT.
325 $viewbm->load_blocks();
326 // Validate.
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();
334 // Set up fixture.
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);
345 // Exercise SUT.
346 $viewbm->load_blocks();
347 // Validate.
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();
355 // Set up fixture.
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);
365 // Exercise SUT.
366 $viewbm->load_blocks();
367 // Validate.
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();
375 // Set up fixture.
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');
385 // Exercise SUT.
386 $blockmanager->load_blocks();
387 // Validate.
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();
395 // Set up fixture.
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);
405 // Exercise SUT.
406 $blockmanager->load_blocks();
407 // Validate.
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();
415 // Set up fixture.
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);
425 // Exercise SUT.
426 $blockmanager->load_blocks();
427 // Validate.
428 $blocks = $blockmanager->get_blocks_for_region($regionname);
429 $this->assertContainsBlocksOfType(array($blockname), $blocks);
432 public function test_matching_page_type_patterns_from_pattern() {
433 $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() {