MDL-28137 unit tests: Fixed up problem with block manager tests when running unit...
[moodle.git] / lib / simpletest / testblocklib_blockmanager.php
1 <?php
3 ///////////////////////////////////////////////////////////////////////////
4 //                                                                       //
5 // NOTICE OF COPYRIGHT                                                   //
6 //                                                                       //
7 // Moodle - Modular Object-Oriented Dynamic Learning Environment         //
8 //          http://moodle.org                                            //
9 //                                                                       //
10 // Copyright (C) 1999 onwards Martin Dougiamas  http://dougiamas.com     //
11 //                                                                       //
12 // This program is free software; you can redistribute it and/or modify  //
13 // it under the terms of the GNU General Public License as published by  //
14 // the Free Software Foundation; either version 2 of the License, or     //
15 // (at your option) any later version.                                   //
16 //                                                                       //
17 // This program is distributed in the hope that it will be useful,       //
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of        //
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         //
20 // GNU General Public License for more details:                          //
21 //                                                                       //
22 //          http://www.gnu.org/copyleft/gpl.html                         //
23 //                                                                       //
24 ///////////////////////////////////////////////////////////////////////////
26 /**
27  * Tests for the block_manager class in ../blocklib.php.
28  *
29  * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
30  * @package moodlecore
31  */
33 if (!defined('MOODLE_INTERNAL')) {
34     die('Direct access to this script is forbidden.');    ///  It must be included from a Moodle page
35 }
37 require_once($CFG->libdir . '/pagelib.php');
38 require_once($CFG->libdir . '/blocklib.php');
40 /** Test-specific subclass to make some protected things public. */
41 class testable_block_manager extends block_manager {
43     public function mark_loaded() {
44         $this->birecordsbyregion = array();
45     }
46     public function get_loaded_blocks() {
47         return $this->birecordsbyregion;
48     }
49 }
50 class block_ablocktype extends block_base {
51     public function init() {
52     }
53 }
55 /**
56  * Test functions that don't need to touch the database.
57  */
58 class moodle_block_manager_test extends UnitTestCase {
59     public  static $includecoverage = array('lib/pagelib.php', 'lib/blocklib.php');
60     protected $testpage;
61     protected $blockmanager;
63     public function setUp() {
64         $this->testpage = new moodle_page();
65         $this->testpage->set_context(get_context_instance(CONTEXT_SYSTEM));
66         $this->blockmanager = new testable_block_manager($this->testpage);
67     }
69     public function tearDown() {
70         $this->testpage = NULL;
71         $this->blockmanager = NULL;
72     }
74     public function test_no_regions_initially() {
75         // Exercise SUT & Validate
76         $this->assertEqual(array(), $this->blockmanager->get_regions());
77     }
79     public function test_add_region() {
80         // Exercise SUT.
81         $this->blockmanager->add_region('a-region-name');
82         // Validate
83         $this->assertEqual(array('a-region-name'), $this->blockmanager->get_regions());
84     }
86     public function test_add_regions() {
87         // Set up fixture.
88         $regions = array('a-region', 'another-region');
89         // Exercise SUT.
90         $this->blockmanager->add_regions($regions);
91         // Validate
92         $this->assert(new ArraysHaveSameValuesExpectation($regions), $this->blockmanager->get_regions());
93     }
95     public function test_add_region_twice() {
96         // Exercise SUT.
97         $this->blockmanager->add_region('a-region-name');
98         $this->blockmanager->add_region('another-region');
99         // Validate
100         $this->assert(new ArraysHaveSameValuesExpectation(array('a-region-name', 'another-region')),
101                 $this->blockmanager->get_regions());
102     }
104     public function test_cannot_add_region_after_loaded() {
105         // Set up fixture.
106         $this->blockmanager->mark_loaded();
107         // Set expectation
108         $this->expectException();
109         // Exercise SUT.
110         $this->blockmanager->add_region('too-late');
111     }
113     public function test_set_default_region() {
114         // Set up fixture.
115         $this->blockmanager->add_region('a-region-name');
116         // Exercise SUT.
117         $this->blockmanager->set_default_region('a-region-name');
118         // Validate
119         $this->assertEqual('a-region-name', $this->blockmanager->get_default_region());
120     }
122     public function test_cannot_set_unknown_region_as_default() {
123         // Set expectation
124         $this->expectException();
125         // Exercise SUT.
126         $this->blockmanager->set_default_region('a-region-name');
127     }
129     public function test_cannot_change_default_region_after_loaded() {
130         // Set up fixture.
131         $this->blockmanager->mark_loaded();
132         // Set expectation
133         $this->expectException();
134         // Exercise SUT.
135         $this->blockmanager->set_default_region('too-late');
136     }
138     public function test_matching_page_type_patterns() {
139         $this->assert(new ArraysHaveSameValuesExpectation(
140                 array('site-index', 'site-index-*', 'site-*', '*')),
141                 matching_page_type_patterns('site-index'));
143         $this->assert(new ArraysHaveSameValuesExpectation(
144                 array('mod-quiz-report-overview', 'mod-quiz-report-overview-*', 'mod-quiz-report-*', 'mod-quiz-*', 'mod-*', '*')),
145                 matching_page_type_patterns('mod-quiz-report-overview'));
147         $this->assert(new ArraysHaveSameValuesExpectation(
148                 array('mod-forum-view', 'mod-*-view', 'mod-forum-view-*', 'mod-forum-*', 'mod-*', '*')),
149                 matching_page_type_patterns('mod-forum-view'));
151         $this->assert(new ArraysHaveSameValuesExpectation(
152                 array('mod-forum-index', 'mod-*-index', 'mod-forum-index-*', 'mod-forum-*', 'mod-*', '*')),
153                 matching_page_type_patterns('mod-forum-index'));
154     }
157 /**
158  * Test methods that load and save data from block_instances and block_positions.
159  */
160 class moodle_block_manager_test_saving_loading extends UnitTestCaseUsingDatabase {
162     protected $isediting = null;
164     public function setUp() {
165         global $USER;
166         if (!empty($USER->editing)) {
167             // We want to avoid the capability checks associated with
168             // checking the user is editing.
169             $this->isediting = $USER->editing;
170             unset($USER->editing);
171         }
172         parent::setUp();
173         $this->create_test_tables(array('block', 'block_instances', 'block_positions', 'context'), 'lib');
174         $this->switch_to_test_db();
175     }
177     public function tearDown() {
178         global $USER;
179         if (!empty($this->isediting)) {
180             // Replace $USER->editing as it was there at setup.
181             $USER->editing = $this->isediting;
182             $this->isediting = null;
183         }
184         parent::tearDown();
185     }
187     /**
188      * Saves the context in the DB, setting $contextid.
189      * @param $context. Context. Path should be set to /parent/path/, that is with a traling /.
190      * This context's id will be appended.
191      */
192     protected function insert_context_in_db($context) {
193         $context->id = $this->testdb->insert_record('context', $context);
194         $context->path .= $context->id;
195         $this->testdb->set_field('context', 'path', $context->path, array('id' => $context->id));
196     }
198     protected function get_a_page_and_block_manager($regions, $context, $pagetype, $subpage = '') {
199         $page = new moodle_page;
200         $page->set_context($context);
201         $page->set_pagetype($pagetype);
202         $page->set_subpage($subpage);
204         $blockmanager = new testable_block_manager($page);
205         $blockmanager->add_regions($regions);
206         $blockmanager->set_default_region($regions[0]);
208         return array($page, $blockmanager);
209     }
211     protected function get_a_known_block_type() {
212         global $DB;
213         $block = new stdClass;
214         $block->name = 'ablocktype';
215         $this->testdb->insert_record('block', $block);
216         return $block->name;
217     }
219     protected function assertContainsBlocksOfType($typearray, $blockarray) {
220         if (!$this->assertEqual(count($typearray), count($blockarray), "Blocks array contains the wrong number of elements %s.")) {
221             return;
222         }
223         $types = array_values($typearray);
224         $i = 0;
225         foreach ($blockarray as $block) {
226             $blocktype = $types[$i];
227             $this->assertEqual($blocktype, $block->name(), "Block types do not match at postition $i %s.");
228             $i++;
229         }
230     }
232     public function test_empty_initially() {
233         // Set up fixture.
234         list($page, $blockmanager) = $this->get_a_page_and_block_manager(array('a-region'),
235                 get_context_instance(CONTEXT_SYSTEM), 'page-type');
236         // Exercise SUT.
237         $blockmanager->load_blocks();
238         // Validate.
239         $blocks = $blockmanager->get_loaded_blocks();
240         $this->assertEqual(array('a-region' => array()), $blocks);
241     }
243     public function test_adding_and_retrieving_one_block() {
244         // Set up fixture.
245         $regionname = 'a-region';
246         $blockname = $this->get_a_known_block_type();
247         $context = get_context_instance(CONTEXT_SYSTEM);
248         $context->path = '/';
249         $this->insert_context_in_db($context);
251         list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
252                 $context, 'page-type');
254         // Exercise SUT.
255         $blockmanager->add_block($blockname, $regionname, 0, false);
256         $blockmanager->load_blocks();
257         // Validate.
258         $blocks = $blockmanager->get_blocks_for_region($regionname);
259         $this->assertContainsBlocksOfType(array($blockname), $blocks);
260     }
262     public function test_adding_and_retrieving_two_blocks() {
263         // Set up fixture.
264         $regionname = 'a-region';
265         $blockname = $this->get_a_known_block_type();
266         $context = get_context_instance(CONTEXT_SYSTEM);
267         $context->path = '/';
268         $this->insert_context_in_db($context);
270         list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
271                 $context, 'page-type');
273         // Exercise SUT.
274         $blockmanager->add_block($blockname, $regionname, 0, false);
275         $blockmanager->add_block($blockname, $regionname, 1, false);
276         $blockmanager->load_blocks();
277         // Validate.
278         $blocks = $blockmanager->get_blocks_for_region($regionname);
279         $this->assertContainsBlocksOfType(array($blockname, $blockname), $blocks);
280     }
282     public function test_block_not_included_in_different_context() {
283         // Set up fixture.
284         $syscontext = get_context_instance(CONTEXT_SYSTEM);
285         $syscontext->path = '/';
286         $this->insert_context_in_db($syscontext);
287         $fakecontext = new stdClass;
288         $fakecontext->contextlevel = CONTEXT_COURSECAT;
289         $fakecontext->path = $syscontext->path . '/';
290         $this->insert_context_in_db($fakecontext);
291         $regionname = 'a-region';
292         $blockname = $this->get_a_known_block_type();
294         list($addpage, $addbm) = $this->get_a_page_and_block_manager(array($regionname), $fakecontext, 'page-type');
295         list($viewpage, $viewbm) = $this->get_a_page_and_block_manager(array($regionname), $syscontext, 'page-type');
297         $addbm->add_block($blockname, $regionname, 0, false);
299         // Exercise SUT.
300         $viewbm->load_blocks();
301         // Validate.
302         $blocks = $viewbm->get_blocks_for_region($regionname);
303         $this->assertContainsBlocksOfType(array(), $blocks);
304     }
306     public function test_block_included_in_sub_context() {
307         // Set up fixture.
308         $syscontext = get_context_instance(CONTEXT_SYSTEM);
309         $syscontext->path = '/';
310         $this->insert_context_in_db($syscontext);
311         $childcontext = new stdClass;
312         $childcontext->contextlevel = CONTEXT_COURSECAT;
313         $childcontext->path = $syscontext->path . '/';
314         $this->insert_context_in_db($childcontext);
315         $regionname = 'a-region';
316         $blockname = $this->get_a_known_block_type();
318         list($addpage, $addbm) = $this->get_a_page_and_block_manager(array($regionname), $syscontext, 'page-type');
319         list($viewpage, $viewbm) = $this->get_a_page_and_block_manager(array($regionname), $childcontext, 'page-type');
321         $addbm->add_block($blockname, $regionname, 0, true);
323         // Exercise SUT.
324         $viewbm->load_blocks();
325         // Validate.
326         $blocks = $viewbm->get_blocks_for_region($regionname);
327         $this->assertContainsBlocksOfType(array($blockname), $blocks);
328     }
330     public function test_block_not_included_on_different_page_type() {
331         // Set up fixture.
332         $syscontext = get_context_instance(CONTEXT_SYSTEM);
333         $syscontext->path = '/';
334         $this->insert_context_in_db($syscontext);
335         $regionname = 'a-region';
336         $blockname = $this->get_a_known_block_type();
338         list($addpage, $addbm) = $this->get_a_page_and_block_manager(array($regionname), $syscontext, 'page-type');
339         list($viewpage, $viewbm) = $this->get_a_page_and_block_manager(array($regionname), $syscontext, 'other-page-type');
341         $addbm->add_block($blockname, $regionname, 0, true);
343         // Exercise SUT.
344         $viewbm->load_blocks();
345         // Validate.
346         $blocks = $viewbm->get_blocks_for_region($regionname);
347         $this->assertContainsBlocksOfType(array(), $blocks);
348     }
350     public function test_block_not_included_on_different_sub_page() {
351         // Set up fixture.
352         $regionname = 'a-region';
353         $blockname = $this->get_a_known_block_type();
354         $syscontext = get_context_instance(CONTEXT_SYSTEM);
355         $syscontext->path = '/';
356         $this->insert_context_in_db($syscontext);
358         list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
359                 $syscontext, 'page-type', 'sub-page');
361         $blockmanager->add_block($blockname, $regionname, 0, true, $page->pagetype, 'other-sub-page');
363         // Exercise SUT.
364         $blockmanager->load_blocks();
365         // Validate.
366         $blocks = $blockmanager->get_blocks_for_region($regionname);
367         $this->assertContainsBlocksOfType(array(), $blocks);
368     }
370     public function test_block_included_with_explicit_sub_page() {
371         // Set up fixture.
372         $regionname = 'a-region';
373         $blockname = $this->get_a_known_block_type();
374         $syscontext = get_context_instance(CONTEXT_SYSTEM);
375         $syscontext->path = '/';
376         $this->insert_context_in_db($syscontext);
378         list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
379                 $syscontext, 'page-type', 'sub-page');
381         $blockmanager->add_block($blockname, $regionname, 0, true, $page->pagetype, $page->subpage);
383         // Exercise SUT.
384         $blockmanager->load_blocks();
385         // Validate.
386         $blocks = $blockmanager->get_blocks_for_region($regionname);
387         $this->assertContainsBlocksOfType(array($blockname), $blocks);
388     }
390     public function test_block_included_with_page_type_pattern() {
391         // Set up fixture.
392         $regionname = 'a-region';
393         $blockname = $this->get_a_known_block_type();
394         $syscontext = get_context_instance(CONTEXT_SYSTEM);
395         $syscontext->path = '/';
396         $this->insert_context_in_db($syscontext);
398         list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
399                 $syscontext, 'page-type', 'sub-page');
401         $blockmanager->add_block($blockname, $regionname, 0, true, 'page-*', $page->subpage);
403         // Exercise SUT.
404         $blockmanager->load_blocks();
405         // Validate.
406         $blocks = $blockmanager->get_blocks_for_region($regionname);
407         $this->assertContainsBlocksOfType(array($blockname), $blocks);
408     }