MDL-28137 unit tests: Fixed up problem with block manager tests when running unit...
[moodle.git] / lib / simpletest / testblocklib_blockmanager.php
CommitLineData
8926f844 1<?php
86b5ea0f 2
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///////////////////////////////////////////////////////////////////////////
25
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 */
32
33if (!defined('MOODLE_INTERNAL')) {
34 die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page
35}
36
37require_once($CFG->libdir . '/pagelib.php');
38require_once($CFG->libdir . '/blocklib.php');
39
40/** Test-specific subclass to make some protected things public. */
41class testable_block_manager extends block_manager {
081a63a9 42
86b5ea0f 43 public function mark_loaded() {
bb46a4fa 44 $this->birecordsbyregion = array();
08eab897 45 }
46 public function get_loaded_blocks() {
bb46a4fa 47 return $this->birecordsbyregion;
08eab897 48 }
86b5ea0f 49}
bb46a4fa 50class block_ablocktype extends block_base {
51 public function init() {
52 }
53}
86b5ea0f 54
55/**
56 * Test functions that don't need to touch the database.
57 */
08eab897 58class moodle_block_manager_test extends UnitTestCase {
081a63a9 59 public static $includecoverage = array('lib/pagelib.php', 'lib/blocklib.php');
86b5ea0f 60 protected $testpage;
61 protected $blockmanager;
62
63 public function setUp() {
64 $this->testpage = new moodle_page();
50999f14 65 $this->testpage->set_context(get_context_instance(CONTEXT_SYSTEM));
86b5ea0f 66 $this->blockmanager = new testable_block_manager($this->testpage);
67 }
68
69 public function tearDown() {
70 $this->testpage = NULL;
71 $this->blockmanager = NULL;
72 }
73
74 public function test_no_regions_initially() {
75 // Exercise SUT & Validate
76 $this->assertEqual(array(), $this->blockmanager->get_regions());
77 }
78
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 }
85
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 }
94
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 }
103
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 }
112
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 }
121
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 }
128
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 }
137
08eab897 138 public function test_matching_page_type_patterns() {
139 $this->assert(new ArraysHaveSameValuesExpectation(
140 array('site-index', 'site-index-*', 'site-*', '*')),
1d13c75c 141 matching_page_type_patterns('site-index'));
08eab897 142
143 $this->assert(new ArraysHaveSameValuesExpectation(
144 array('mod-quiz-report-overview', 'mod-quiz-report-overview-*', 'mod-quiz-report-*', 'mod-quiz-*', 'mod-*', '*')),
1d13c75c 145 matching_page_type_patterns('mod-quiz-report-overview'));
08eab897 146
147 $this->assert(new ArraysHaveSameValuesExpectation(
148 array('mod-forum-view', 'mod-*-view', 'mod-forum-view-*', 'mod-forum-*', 'mod-*', '*')),
1d13c75c 149 matching_page_type_patterns('mod-forum-view'));
08eab897 150
151 $this->assert(new ArraysHaveSameValuesExpectation(
152 array('mod-forum-index', 'mod-*-index', 'mod-forum-index-*', 'mod-forum-*', 'mod-*', '*')),
1d13c75c 153 matching_page_type_patterns('mod-forum-index'));
08eab897 154 }
86b5ea0f 155}
156
08eab897 157/**
158 * Test methods that load and save data from block_instances and block_positions.
159 */
160class moodle_block_manager_test_saving_loading extends UnitTestCaseUsingDatabase {
161
f50243ed
SH
162 protected $isediting = null;
163
08eab897 164 public function setUp() {
f50243ed
SH
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 }
08eab897 172 parent::setUp();
485e4661 173 $this->create_test_tables(array('block', 'block_instances', 'block_positions', 'context'), 'lib');
08eab897 174 $this->switch_to_test_db();
175 }
176
177 public function tearDown() {
f50243ed
SH
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 }
08eab897 184 parent::tearDown();
185 }
186
485e4661 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 }
197
08eab897 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);
203
204 $blockmanager = new testable_block_manager($page);
205 $blockmanager->add_regions($regions);
206 $blockmanager->set_default_region($regions[0]);
207
208 return array($page, $blockmanager);
209 }
210
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 }
218
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];
bb46a4fa 227 $this->assertEqual($blocktype, $block->name(), "Block types do not match at postition $i %s.");
08eab897 228 $i++;
229 }
230 }
231
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 }
242
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();
485e4661 247 $context = get_context_instance(CONTEXT_SYSTEM);
248 $context->path = '/';
249 $this->insert_context_in_db($context);
08eab897 250
251 list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
485e4661 252 $context, 'page-type');
08eab897 253
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 }
261
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();
485e4661 266 $context = get_context_instance(CONTEXT_SYSTEM);
267 $context->path = '/';
268 $this->insert_context_in_db($context);
08eab897 269
270 list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
485e4661 271 $context, 'page-type');
08eab897 272
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 }
281
282 public function test_block_not_included_in_different_context() {
283 // Set up fixture.
284 $syscontext = get_context_instance(CONTEXT_SYSTEM);
485e4661 285 $syscontext->path = '/';
286 $this->insert_context_in_db($syscontext);
08eab897 287 $fakecontext = new stdClass;
73af8b11 288 $fakecontext->contextlevel = CONTEXT_COURSECAT;
485e4661 289 $fakecontext->path = $syscontext->path . '/';
290 $this->insert_context_in_db($fakecontext);
08eab897 291 $regionname = 'a-region';
292 $blockname = $this->get_a_known_block_type();
293
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');
296
297 $addbm->add_block($blockname, $regionname, 0, false);
298
299 // Exercise SUT.
300 $viewbm->load_blocks();
301 // Validate.
302 $blocks = $viewbm->get_blocks_for_region($regionname);
303 $this->assertContainsBlocksOfType(array(), $blocks);
304 }
305
306 public function test_block_included_in_sub_context() {
307 // Set up fixture.
308 $syscontext = get_context_instance(CONTEXT_SYSTEM);
485e4661 309 $syscontext->path = '/';
310 $this->insert_context_in_db($syscontext);
08eab897 311 $childcontext = new stdClass;
485e4661 312 $childcontext->contextlevel = CONTEXT_COURSECAT;
313 $childcontext->path = $syscontext->path . '/';
314 $this->insert_context_in_db($childcontext);
08eab897 315 $regionname = 'a-region';
316 $blockname = $this->get_a_known_block_type();
317
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');
320
321 $addbm->add_block($blockname, $regionname, 0, true);
322
323 // Exercise SUT.
324 $viewbm->load_blocks();
325 // Validate.
326 $blocks = $viewbm->get_blocks_for_region($regionname);
327 $this->assertContainsBlocksOfType(array($blockname), $blocks);
328 }
329
330 public function test_block_not_included_on_different_page_type() {
331 // Set up fixture.
332 $syscontext = get_context_instance(CONTEXT_SYSTEM);
485e4661 333 $syscontext->path = '/';
334 $this->insert_context_in_db($syscontext);
08eab897 335 $regionname = 'a-region';
336 $blockname = $this->get_a_known_block_type();
337
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');
340
341 $addbm->add_block($blockname, $regionname, 0, true);
342
343 // Exercise SUT.
344 $viewbm->load_blocks();
345 // Validate.
346 $blocks = $viewbm->get_blocks_for_region($regionname);
347 $this->assertContainsBlocksOfType(array(), $blocks);
348 }
349
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();
485e4661 354 $syscontext = get_context_instance(CONTEXT_SYSTEM);
355 $syscontext->path = '/';
356 $this->insert_context_in_db($syscontext);
08eab897 357
358 list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
485e4661 359 $syscontext, 'page-type', 'sub-page');
08eab897 360
361 $blockmanager->add_block($blockname, $regionname, 0, true, $page->pagetype, 'other-sub-page');
362
363 // Exercise SUT.
364 $blockmanager->load_blocks();
365 // Validate.
366 $blocks = $blockmanager->get_blocks_for_region($regionname);
367 $this->assertContainsBlocksOfType(array(), $blocks);
368 }
369
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();
485e4661 374 $syscontext = get_context_instance(CONTEXT_SYSTEM);
375 $syscontext->path = '/';
376 $this->insert_context_in_db($syscontext);
08eab897 377
378 list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
485e4661 379 $syscontext, 'page-type', 'sub-page');
08eab897 380
381 $blockmanager->add_block($blockname, $regionname, 0, true, $page->pagetype, $page->subpage);
382
383 // Exercise SUT.
384 $blockmanager->load_blocks();
385 // Validate.
386 $blocks = $blockmanager->get_blocks_for_region($regionname);
387 $this->assertContainsBlocksOfType(array($blockname), $blocks);
388 }
389
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();
485e4661 394 $syscontext = get_context_instance(CONTEXT_SYSTEM);
395 $syscontext->path = '/';
396 $this->insert_context_in_db($syscontext);
08eab897 397
398 list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
485e4661 399 $syscontext, 'page-type', 'sub-page');
08eab897 400
401 $blockmanager->add_block($blockname, $regionname, 0, true, 'page-*', $page->subpage);
402
403 // Exercise SUT.
404 $blockmanager->load_blocks();
405 // Validate.
406 $blocks = $blockmanager->get_blocks_for_region($regionname);
407 $this->assertContainsBlocksOfType(array($blockname), $blocks);
408 }
409}
8926f844 410