Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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
namespace core;
18
 
19
defined('MOODLE_INTERNAL') || die();
20
 
21
global $CFG;
22
require_once($CFG->libdir . '/pagelib.php');
23
require_once($CFG->libdir . '/blocklib.php');
24
require_once($CFG->dirroot . '/blocks/moodleblock.class.php');
25
require_once(__DIR__ . '/fixtures/block_ablocktype.php');
26
require_once(__DIR__ . '/fixtures/testable_block_manager.php');
27
 
28
/**
29
 * Tests for the block_manager class in ../blocklib.php.
30
 *
31
 * @package   core
32
 * @category  test
33
 * @copyright 2009 Tim Hunt
34
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
35
 */
36
class blocklib_test extends \advanced_testcase {
37
    protected $testpage;
38
    protected $blockmanager;
39
    protected $isediting = null;
40
 
41
    protected function setUp(): void {
42
        parent::setUp();
43
        $this->testpage = new \moodle_page();
44
        $this->testpage->set_context(\context_system::instance());
45
        $this->testpage->set_pagetype('phpunit-block-test');
46
        $this->blockmanager = new \testable_block_manager($this->testpage);
47
    }
48
 
49
    protected function tearDown(): void {
50
        $this->testpage = null;
51
        $this->blockmanager = null;
52
        parent::tearDown();
53
    }
54
 
55
    protected function purge_blocks() {
56
        global $DB;
57
        $this->resetAfterTest();
58
 
59
        $bis = $DB->get_records('block_instances');
60
        foreach ($bis as $instance) {
61
            blocks_delete_instance($instance);
62
        }
63
    }
64
 
65
    /**
66
     * Gets the last block created.
67
     *
68
     * @return stdClass a record from block_instances
69
     */
70
    protected function get_last_created_block() {
71
        global $DB;
72
        // The newest block should be the record with the highest id.
73
        $records = $DB->get_records('block_instances', [], 'id DESC', '*', 0, 1);
74
        $return = null;
75
        foreach ($records as $record) {
76
            // There should only be one.
77
            $return = $record;
78
        }
79
        return $return;
80
    }
81
 
11 efrain 82
    public function test_no_regions_initially(): void {
1 efrain 83
        // Exercise SUT & Validate.
84
        $this->assertEquals(array(), $this->blockmanager->get_regions());
85
    }
86
 
11 efrain 87
    public function test_add_region(): void {
1 efrain 88
        // Exercise SUT.
89
        $this->blockmanager->add_region('a-region-name', false);
90
        // Validate.
91
        $this->assertEquals(array('a-region-name'), $this->blockmanager->get_regions());
92
    }
93
 
11 efrain 94
    public function test_add_regions(): void {
1 efrain 95
        // Set up fixture.
96
        $regions = array('a-region', 'another-region');
97
        // Exercise SUT.
98
        $this->blockmanager->add_regions($regions, false);
99
        // Validate.
100
        $this->assertEqualsCanonicalizing($regions, $this->blockmanager->get_regions());
101
    }
102
 
11 efrain 103
    public function test_add_region_twice(): void {
1 efrain 104
        // Exercise SUT.
105
        $this->blockmanager->add_region('a-region-name', false);
106
        $this->blockmanager->add_region('another-region', false);
107
        // Validate.
108
        $this->assertEqualsCanonicalizing(array('a-region-name', 'another-region'), $this->blockmanager->get_regions());
109
    }
110
 
11 efrain 111
    public function test_cannot_add_region_after_loaded(): void {
1 efrain 112
        // Set up fixture.
113
        $this->blockmanager->mark_loaded();
114
        // Exercise SUT.
115
        $this->expectException(\coding_exception::class);
116
        $this->blockmanager->add_region('too-late', false);
117
    }
118
 
119
    /**
120
     * Testing adding a custom region.
121
     */
11 efrain 122
    public function test_add_custom_region(): void {
1 efrain 123
        global $SESSION;
124
        // Exercise SUT.
125
        $this->blockmanager->add_region('a-custom-region-name');
126
        // Validate.
127
        $this->assertEquals(array('a-custom-region-name'), $this->blockmanager->get_regions());
128
        $this->assertTrue(isset($SESSION->custom_block_regions));
129
        $this->assertArrayHasKey('phpunit-block-test', $SESSION->custom_block_regions);
130
        $this->assertTrue(in_array('a-custom-region-name', $SESSION->custom_block_regions['phpunit-block-test']));
131
 
132
    }
133
 
134
    /**
135
     * Test adding two custom regions using add_regions method.
136
     */
11 efrain 137
    public function test_add_custom_regions(): void {
1 efrain 138
        global $SESSION;
139
        // Set up fixture.
140
        $regions = array('a-region', 'another-custom-region');
141
        // Exercise SUT.
142
        $this->blockmanager->add_regions($regions);
143
        // Validate.
144
        $this->assertEqualsCanonicalizing($regions, $this->blockmanager->get_regions());
145
        $this->assertTrue(isset($SESSION->custom_block_regions));
146
        $this->assertArrayHasKey('phpunit-block-test', $SESSION->custom_block_regions);
147
        $this->assertTrue(in_array('another-custom-region', $SESSION->custom_block_regions['phpunit-block-test']));
148
    }
149
 
150
    /**
151
     * Test adding two custom block regions.
152
     */
11 efrain 153
    public function test_add_custom_region_twice(): void {
1 efrain 154
        // Exercise SUT.
155
        $this->blockmanager->add_region('a-custom-region-name');
156
        $this->blockmanager->add_region('another-custom-region');
157
        // Validate.
158
        $this->assertEqualsCanonicalizing(
159
            array('a-custom-region-name', 'another-custom-region'),
160
            $this->blockmanager->get_regions());
161
    }
162
 
163
    /**
164
     * Test to ensure that we cannot add a region after the blocks have been loaded.
165
     */
11 efrain 166
    public function test_cannot_add_custom_region_after_loaded(): void {
1 efrain 167
        // Set up fixture.
168
        $this->blockmanager->mark_loaded();
169
        // Exercise SUT.
170
        $this->expectException(\coding_exception::class);
171
        $this->blockmanager->add_region('too-late');
172
    }
173
 
11 efrain 174
    public function test_set_default_region(): void {
1 efrain 175
        // Set up fixture.
176
        $this->blockmanager->add_region('a-region-name', false);
177
        // Exercise SUT.
178
        $this->blockmanager->set_default_region('a-region-name');
179
        // Validate.
180
        $this->assertEquals('a-region-name', $this->blockmanager->get_default_region());
181
    }
182
 
11 efrain 183
    public function test_cannot_set_unknown_region_as_default(): void {
1 efrain 184
        // Exercise SUT.
185
        $this->expectException(\coding_exception::class);
186
        $this->blockmanager->set_default_region('a-region-name');
187
    }
188
 
11 efrain 189
    public function test_cannot_change_default_region_after_loaded(): void {
1 efrain 190
        // Set up fixture.
191
        $this->blockmanager->mark_loaded();
192
        // Exercise SUT.
193
        $this->expectException(\coding_exception::class);
194
        $this->blockmanager->set_default_region('too-late');
195
    }
196
 
11 efrain 197
    public function test_matching_page_type_patterns(): void {
1 efrain 198
        $this->assertEqualsCanonicalizing(array('site-index', 'site-index-*', 'site-*', '*'),
199
            matching_page_type_patterns('site-index'));
200
 
201
        $this->assertEqualsCanonicalizing(array('mod-quiz-report-overview', 'mod-quiz-report-overview-*', 'mod-quiz-report-*', 'mod-quiz-*', 'mod-*', '*'),
202
            matching_page_type_patterns('mod-quiz-report-overview'));
203
 
204
        $this->assertEqualsCanonicalizing(array('mod-forum-view', 'mod-*-view', 'mod-forum-view-*', 'mod-forum-*', 'mod-*', '*'),
205
            matching_page_type_patterns('mod-forum-view'));
206
 
207
        $this->assertEqualsCanonicalizing(array('mod-forum-index', 'mod-*-index', 'mod-forum-index-*', 'mod-forum-*', 'mod-*', '*'),
208
            matching_page_type_patterns('mod-forum-index'));
209
    }
210
 
211
    protected function get_a_page_and_block_manager($regions, $context, $pagetype, $subpage = '') {
212
        $page = new \moodle_page;
213
        $page->set_context($context);
214
        $page->set_pagetype($pagetype);
215
        $page->set_subpage($subpage);
216
        $page->set_url(new \moodle_url('/'));
217
 
218
        $blockmanager = new \testable_block_manager($page);
219
        $blockmanager->add_regions($regions, false);
220
        $blockmanager->set_default_region($regions[0]);
221
 
222
        return array($page, $blockmanager);
223
    }
224
 
225
    protected function get_a_known_block_type() {
226
        global $DB;
227
        $block = new \stdClass;
228
        $block->name = 'ablocktype';
229
        $DB->insert_record('block', $block);
230
        return $block->name;
231
    }
232
 
233
    protected function assertContainsBlocksOfType($typearray, $blockarray) {
234
        if (!$this->assertEquals(count($typearray), count($blockarray), "Blocks array contains the wrong number of elements %s.")) {
235
            return;
236
        }
237
        $types = array_values($typearray);
238
        $i = 0;
239
        foreach ($blockarray as $block) {
240
            $blocktype = $types[$i];
241
            $this->assertEquals($blocktype, $block->name(), "Block types do not match at postition $i %s.");
242
            $i++;
243
        }
244
    }
245
 
11 efrain 246
    public function test_empty_initially(): void {
1 efrain 247
        $this->purge_blocks();
248
 
249
        // Set up fixture.
250
        list($page, $blockmanager) = $this->get_a_page_and_block_manager(array('a-region'),
251
            \context_system::instance(), 'page-type');
252
        // Exercise SUT.
253
        $blockmanager->load_blocks();
254
        // Validate.
255
        $blocks = $blockmanager->get_loaded_blocks();
256
        $this->assertEquals(array('a-region' => array()), $blocks);
257
    }
258
 
11 efrain 259
    public function test_adding_and_retrieving_one_block(): void {
1 efrain 260
        $this->purge_blocks();
261
 
262
        // Set up fixture.
263
        $regionname = 'a-region';
264
        $blockname = $this->get_a_known_block_type();
265
        $context = \context_system::instance();
266
 
267
        list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
268
            $context, 'page-type');
269
 
270
        // Exercise SUT.
271
        $blockmanager->add_block($blockname, $regionname, 0, false);
272
        $blockmanager->load_blocks();
273
        // Validate.
274
        $blocks = $blockmanager->get_blocks_for_region($regionname);
275
        $this->assertContainsBlocksOfType(array($blockname), $blocks);
276
    }
277
 
11 efrain 278
    public function test_adding_and_retrieving_two_blocks(): void {
1 efrain 279
        $this->purge_blocks();
280
 
281
        // Set up fixture.
282
        $regionname = 'a-region';
283
        $blockname = $this->get_a_known_block_type();
284
        $context = \context_system::instance();
285
 
286
        list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
287
            $context, 'page-type');
288
 
289
        // Exercise SUT.
290
        $blockmanager->add_block($blockname, $regionname, 0, false);
291
        $blockmanager->add_block($blockname, $regionname, 1, false);
292
        $blockmanager->load_blocks();
293
        // Validate.
294
        $blocks = $blockmanager->get_blocks_for_region($regionname);
295
        $this->assertContainsBlocksOfType(array($blockname, $blockname), $blocks);
296
    }
297
 
11 efrain 298
    public function test_adding_blocks(): void {
1 efrain 299
        $this->purge_blocks();
300
 
301
        // Set up fixture.
302
        $regionname = 'a-region';
303
        $blockname = $this->get_a_known_block_type();
304
        $context = \context_system::instance();
305
 
306
        list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
307
            $context, 'page-type');
308
 
309
        $blockmanager->add_blocks(array($regionname => array($blockname, $blockname)), null, null, false, 3);
310
        $blockmanager->load_blocks();
311
 
312
        $blocks = $blockmanager->get_blocks_for_region($regionname);
313
 
314
        $this->assertEquals('3', $blocks[0]->instance->weight);
315
        $this->assertEquals('4', $blocks[1]->instance->weight);
316
    }
317
 
318
    /**
319
     * Test block instances.
320
     *
321
     * @return null
322
     */
11 efrain 323
    public function test_block_instances(): void {
1 efrain 324
        $this->purge_blocks();
325
 
326
        // Set up fixture.
327
        $regionname = 'a-region';
328
        $blockname = $this->get_a_known_block_type();
329
        $context = \context_system::instance();
330
 
331
        list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
332
            $context, 'page-type');
333
 
334
        $blockmanager->add_blocks(array($regionname => array($blockname, $blockname)), null, null, false, 3);
335
        $blockmanager->load_blocks();
336
 
337
        $blocks = $blockmanager->get_blocks_for_region($regionname);
338
 
339
        $this->assertInstanceOf('\block_base', block_instance($blockname, $blocks[0]->instance));
340
        $this->assertInstanceOf('\block_base', block_instance_by_id($blocks[0]->instance->id));
341
    }
342
 
11 efrain 343
    public function test_block_not_included_in_different_context(): void {
1 efrain 344
        $this->purge_blocks();
345
 
346
        // Set up fixture.
347
        $syscontext = \context_system::instance();
348
        $cat = $this->getDataGenerator()->create_category(array('name' => 'testcategory'));
349
        $fakecontext = \context_coursecat::instance($cat->id);
350
        $regionname = 'a-region';
351
        $blockname = $this->get_a_known_block_type();
352
 
353
        list($addpage, $addbm) = $this->get_a_page_and_block_manager(array($regionname), $fakecontext, 'page-type');
354
        list($viewpage, $viewbm) = $this->get_a_page_and_block_manager(array($regionname), $syscontext, 'page-type');
355
 
356
        $addbm->add_block($blockname, $regionname, 0, false);
357
 
358
        // Exercise SUT.
359
        $viewbm->load_blocks();
360
        // Validate.
361
        $blocks = $viewbm->get_blocks_for_region($regionname);
362
        $this->assertContainsBlocksOfType(array(), $blocks);
363
    }
364
 
11 efrain 365
    public function test_block_included_in_sub_context(): void {
1 efrain 366
        $this->purge_blocks();
367
 
368
        // Set up fixture.
369
        $syscontext = \context_system::instance();
370
        $childcontext = \context_coursecat::instance(1);
371
        $regionname = 'a-region';
372
        $blockname = $this->get_a_known_block_type();
373
 
374
        list($addpage, $addbm) = $this->get_a_page_and_block_manager(array($regionname), $syscontext, 'page-type');
375
        list($viewpage, $viewbm) = $this->get_a_page_and_block_manager(array($regionname), $childcontext, 'page-type');
376
 
377
        $addbm->add_block($blockname, $regionname, 0, true);
378
 
379
        // Exercise SUT.
380
        $viewbm->load_blocks();
381
        // Validate.
382
        $blocks = $viewbm->get_blocks_for_region($regionname);
383
        $this->assertContainsBlocksOfType(array($blockname), $blocks);
384
    }
385
 
11 efrain 386
    public function test_block_not_included_on_different_page_type(): void {
1 efrain 387
        $this->purge_blocks();
388
 
389
        // Set up fixture.
390
        $syscontext = \context_system::instance();
391
        $regionname = 'a-region';
392
        $blockname = $this->get_a_known_block_type();
393
 
394
        list($addpage, $addbm) = $this->get_a_page_and_block_manager(array($regionname), $syscontext, 'page-type');
395
        list($viewpage, $viewbm) = $this->get_a_page_and_block_manager(array($regionname), $syscontext, 'other-page-type');
396
 
397
        $addbm->add_block($blockname, $regionname, 0, true);
398
 
399
        // Exercise SUT.
400
        $viewbm->load_blocks();
401
        // Validate.
402
        $blocks = $viewbm->get_blocks_for_region($regionname);
403
        $this->assertContainsBlocksOfType(array(), $blocks);
404
    }
405
 
11 efrain 406
    public function test_block_not_included_on_different_sub_page(): void {
1 efrain 407
        $this->purge_blocks();
408
 
409
        // Set up fixture.
410
        $regionname = 'a-region';
411
        $blockname = $this->get_a_known_block_type();
412
        $syscontext = \context_system::instance();
413
 
414
        list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
415
            $syscontext, 'page-type', 'sub-page');
416
 
417
        $blockmanager->add_block($blockname, $regionname, 0, true, $page->pagetype, 'other-sub-page');
418
 
419
        // Exercise SUT.
420
        $blockmanager->load_blocks();
421
        // Validate.
422
        $blocks = $blockmanager->get_blocks_for_region($regionname);
423
        $this->assertContainsBlocksOfType(array(), $blocks);
424
    }
425
 
11 efrain 426
    public function test_block_included_with_explicit_sub_page(): void {
1 efrain 427
        $this->purge_blocks();
428
 
429
        // Set up fixture.
430
        $regionname = 'a-region';
431
        $blockname = $this->get_a_known_block_type();
432
        $syscontext = \context_system::instance();
433
 
434
        list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
435
            $syscontext, 'page-type', 'sub-page');
436
 
437
        $blockmanager->add_block($blockname, $regionname, 0, true, $page->pagetype, $page->subpage);
438
 
439
        // Exercise SUT.
440
        $blockmanager->load_blocks();
441
        // Validate.
442
        $blocks = $blockmanager->get_blocks_for_region($regionname);
443
        $this->assertContainsBlocksOfType(array($blockname), $blocks);
444
    }
445
 
11 efrain 446
    public function test_block_included_with_page_type_pattern(): void {
1 efrain 447
        $this->purge_blocks();
448
 
449
        // Set up fixture.
450
        $regionname = 'a-region';
451
        $blockname = $this->get_a_known_block_type();
452
        $syscontext = \context_system::instance();
453
 
454
        list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
455
            $syscontext, 'page-type', 'sub-page');
456
 
457
        $blockmanager->add_block($blockname, $regionname, 0, true, 'page-*', $page->subpage);
458
 
459
        // Exercise SUT.
460
        $blockmanager->load_blocks();
461
        // Validate.
462
        $blocks = $blockmanager->get_blocks_for_region($regionname);
463
        $this->assertContainsBlocksOfType(array($blockname), $blocks);
464
    }
465
 
11 efrain 466
    public function test_matching_page_type_patterns_from_pattern(): void {
1 efrain 467
        $pattern = '*';
468
        $expected = array('*');
469
        $this->assertEquals($expected, array_values(matching_page_type_patterns_from_pattern($pattern)));
470
 
471
        $pattern = 'admin-*';
472
        $expected = array('admin-*', 'admin', '*');
473
        $this->assertEquals($expected, array_values(matching_page_type_patterns_from_pattern($pattern)));
474
 
475
        $pattern = 'blog-index';
476
        $expected = array('blog-index', 'blog-index-*', 'blog-*', '*');
477
        $this->assertEquals($expected, array_values(matching_page_type_patterns_from_pattern($pattern)));
478
 
479
        $pattern = 'course-index-*';
480
        $expected = array('course-index-*', 'course-index', 'course-*', '*');
481
        $this->assertEquals($expected, array_values(matching_page_type_patterns_from_pattern($pattern)));
482
 
483
        $pattern = 'course-index-category';
484
        $expected = array('course-index-category', 'course-index-category-*', 'course-index-*', 'course-*', '*');
485
        $this->assertEquals($expected, array_values(matching_page_type_patterns_from_pattern($pattern)));
486
 
487
        $pattern = 'mod-assign-view';
488
        $expected = array('mod-assign-view', 'mod-*-view', 'mod-assign-view-*', 'mod-assign-*', 'mod-*', '*');
489
        $this->assertEquals($expected, array_values(matching_page_type_patterns_from_pattern($pattern)));
490
 
491
        $pattern = 'mod-assign-index';
492
        $expected = array('mod-assign-index', 'mod-*-index', 'mod-assign-index-*', 'mod-assign-*', 'mod-*', '*');
493
        $this->assertEquals($expected, array_values(matching_page_type_patterns_from_pattern($pattern)));
494
 
495
        $pattern = 'mod-forum-*';
496
        $expected = array('mod-forum-*', 'mod-forum', 'mod-*', '*');
497
        $this->assertEquals($expected, array_values(matching_page_type_patterns_from_pattern($pattern)));
498
 
499
        $pattern = 'mod-*-view';
500
        $expected = array('mod-*-view', 'mod', 'mod-*', '*');
501
        $this->assertEquals($expected, array_values(matching_page_type_patterns_from_pattern($pattern)));
502
 
503
        $pattern = 'mod-*-index';
504
        $expected = array('mod-*-index', 'mod', 'mod-*', '*');
505
        $this->assertEquals($expected, array_values(matching_page_type_patterns_from_pattern($pattern)));
506
 
507
        $pattern = 'my-index';
508
        $expected = array('my-index', 'my-index-*', 'my-*', '*');
509
        $this->assertEquals($expected, array_values(matching_page_type_patterns_from_pattern($pattern)));
510
 
511
        $pattern = 'user-profile';
512
        $expected = array('user-profile', 'user-profile-*', 'user-*', '*');
513
        $this->assertEquals($expected, array_values(matching_page_type_patterns_from_pattern($pattern)));
514
    }
515
 
11 efrain 516
    public function test_delete_instances(): void {
1 efrain 517
        global $DB;
518
        $this->purge_blocks();
519
        $this->setAdminUser();
520
 
521
        $regionname = 'a-region';
522
        $blockname = $this->get_a_known_block_type();
523
        $context = \context_system::instance();
524
 
525
        list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
526
            $context, 'page-type');
527
 
528
        $blockmanager->add_blocks(array($regionname => array($blockname, $blockname, $blockname)), null, null, false, 3);
529
        $blockmanager->load_blocks();
530
 
531
        $blocks = $blockmanager->get_blocks_for_region($regionname);
532
        $blockids = array();
533
        $preferences = array();
534
 
535
        // Create block related data.
536
        foreach ($blocks as $block) {
537
            $instance = $block->instance;
538
            $pref = 'block' . $instance->id . 'hidden';
539
            set_user_preference($pref, '123', 123);
540
            $preferences[] = $pref;
541
            $pref = 'docked_block_instance_' . $instance->id;
542
            set_user_preference($pref, '123', 123);
543
            $preferences[] = $pref;
544
            blocks_set_visibility($instance, $page, 1);
545
            $blockids[] = $instance->id;
546
        }
547
 
548
        // Confirm what has been set.
549
        $this->assertCount(3, $blockids);
550
        list($insql, $inparams) = $DB->get_in_or_equal($blockids);
551
        $this->assertEquals(3, $DB->count_records_select('block_positions', "blockinstanceid $insql", $inparams));
552
        list($insql, $inparams) = $DB->get_in_or_equal($preferences);
553
        $this->assertEquals(6, $DB->count_records_select('user_preferences', "name $insql", $inparams));
554
 
555
        // Keep a block on the side.
556
        $allblockids = $blockids;
557
        $tokeep = array_pop($blockids);
558
 
559
        // Delete and confirm what should have happened.
560
        blocks_delete_instances($blockids);
561
 
562
        // Reload the manager.
563
        list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
564
            $context, 'page-type');
565
        $blockmanager->load_blocks();
566
        $blocks = $blockmanager->get_blocks_for_region($regionname);
567
 
568
        $this->assertCount(1, $blocks);
569
        list($insql, $inparams) = $DB->get_in_or_equal($allblockids);
570
        $this->assertEquals(1, $DB->count_records_select('block_positions', "blockinstanceid $insql", $inparams));
571
        list($insql, $inparams) = $DB->get_in_or_equal($preferences);
572
        $this->assertEquals(2, $DB->count_records_select('user_preferences', "name $insql", $inparams));
573
 
574
        $this->assertFalse(\context_block::instance($blockids[0], IGNORE_MISSING));
575
        $this->assertFalse(\context_block::instance($blockids[1], IGNORE_MISSING));
576
        \context_block::instance($tokeep);   // Would throw an exception if it was deleted.
577
    }
578
 
11 efrain 579
    public function test_create_all_block_instances(): void {
1 efrain 580
        global $CFG, $PAGE, $DB;
581
 
582
        $this->setAdminUser();
583
        $this->resetAfterTest();
584
        $regionname = 'side-pre';
585
        $context = \context_system::instance();
586
 
587
        $PAGE->reset_theme_and_output();
588
        $CFG->theme = 'boost';
589
 
590
        list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
591
            $context, 'page-type');
592
        $blockmanager->load_blocks();
593
        $blockmanager->create_all_block_instances();
594
        $blocks = $blockmanager->get_blocks_for_region($regionname);
595
        // Assert that we no auto created blocks in boost by default.
596
        $this->assertEmpty($blocks);
597
        // There should be no blocks in the DB.
598
 
599
        $PAGE->reset_theme_and_output();
600
        // Change to a theme with undeletable blocks.
601
        $CFG->theme = 'classic';
602
 
603
        list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
604
            $context, 'page-type');
605
 
606
        $blockmanager->show_only_fake_blocks(true);
607
        $blockmanager->load_blocks();
608
        $blockmanager->create_all_block_instances();
609
        $blocks = $blockmanager->get_blocks_for_region($regionname);
610
        // Assert that we no auto created blocks when viewing a fake blocks only page.
611
        $this->assertEmpty($blocks);
612
 
613
        $PAGE->reset_theme_and_output();
614
        list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
615
            $context, 'page-type');
616
 
617
        $blockmanager->show_only_fake_blocks(false);
618
        $blockmanager->load_blocks();
619
        $blockmanager->create_all_block_instances();
620
        $blocks = $blockmanager->get_blocks_for_region($regionname);
621
        // Assert that we get the required block for this theme auto-created.
622
        $this->assertCount(2, $blocks);
623
 
624
        $PAGE->reset_theme_and_output();
625
        list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
626
            $context, 'page-type');
627
 
628
        $blockmanager->protect_block('html');
629
        $blockmanager->load_blocks();
630
        $blockmanager->create_all_block_instances();
631
        $blocks = $blockmanager->get_blocks_for_region($regionname);
632
        // Assert that protecting a block does not make it auto-created.
633
        $this->assertCount(2, $blocks);
634
 
635
        $requiredbytheme = $blockmanager->get_required_by_theme_block_types();
636
        foreach ($requiredbytheme as $blockname) {
637
            $instance = $DB->get_record('block_instances', array('blockname' => $blockname));
638
            $this->assertEquals(1, $instance->requiredbytheme);
639
        }
640
 
641
        // Switch back and those auto blocks should not be returned.
642
        $PAGE->reset_theme_and_output();
643
        $CFG->theme = 'boost';
644
 
645
        list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
646
            $context, 'page-type');
647
        $blockmanager->load_blocks();
648
        $blockmanager->create_all_block_instances();
649
        $blocks = $blockmanager->get_blocks_for_region($regionname);
650
        // Assert that we do not return requiredbytheme blocks when they are not required.
651
        $this->assertEmpty($blocks);
652
        // But they should exist in the DB.
653
        foreach ($requiredbytheme as $blockname) {
654
            $count = $DB->count_records('block_instances', array('blockname' => $blockname));
655
            $this->assertEquals(1, $count);
656
        }
657
    }
658
 
659
    /**
660
     * Test the block instance time fields (timecreated, timemodified).
661
     */
11 efrain 662
    public function test_block_instance_times(): void {
1 efrain 663
        global $DB;
664
 
665
        $this->purge_blocks();
666
 
667
        // Set up fixture.
668
        $regionname = 'a-region';
669
        $blockname = 'html';
670
        $context = \context_system::instance();
671
 
672
        list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
673
                $context, 'page-type');
674
 
675
        // Add block to page.
676
        $before = time();
677
        $blockmanager->add_block($blockname, $regionname, 0, false);
678
        $after = time();
679
 
680
        // Check database table to ensure it contains created/modified times.
681
        $blockdata = $DB->get_record('block_instances', ['blockname' => 'html']);
682
        $this->assertTrue($blockdata->timemodified >= $before && $blockdata->timemodified <= $after);
683
        $this->assertTrue($blockdata->timecreated >= $before && $blockdata->timecreated <= $after);
684
 
685
        // Get block from manager.
686
        $blockmanager->load_blocks();
687
        $blocks = $blockmanager->get_blocks_for_region($regionname);
688
        $block = reset($blocks);
689
 
690
        // Wait until at least the next second.
691
        while (time() === $after) {
692
            usleep(100000);
693
        }
694
 
695
        // Update block settings.
696
        $this->setAdminUser();
697
        $data = (object)['text' => ['text' => 'New text', 'itemid' => 0, 'format' => FORMAT_HTML]];
698
        $before = time();
699
        $block->instance_config_save($data);
700
        $after = time();
701
 
702
        // Check time modified updated, but time created didn't.
703
        $newblockdata = $DB->get_record('block_instances', ['blockname' => 'html']);
704
        $this->assertTrue(
705
                $newblockdata->timemodified >= $before &&
706
                $newblockdata->timemodified <= $after &&
707
                $newblockdata->timemodified > $blockdata->timemodified);
708
        $this->assertEquals($blockdata->timecreated, $newblockdata->timecreated);
709
 
710
        // Also try repositioning the block.
711
        while (time() === $after) {
712
            usleep(100000);
713
        }
714
        $before = time();
715
        $blockmanager->reposition_block($blockdata->id, $regionname, 10);
716
        $after = time();
717
        $blockdata = $newblockdata;
718
        $newblockdata = $DB->get_record('block_instances', ['blockname' => 'html']);
719
        $this->assertTrue(
720
                $newblockdata->timemodified >= $before &&
721
                $newblockdata->timemodified <= $after &&
722
                $newblockdata->timemodified > $blockdata->timemodified);
723
        $this->assertEquals($blockdata->timecreated, $newblockdata->timecreated);
724
    }
725
 
726
    /**
727
     * Tests that dashboard pages get their blocks loaded correctly.
728
     */
11 efrain 729
    public function test_default_dashboard(): void {
1 efrain 730
        global $CFG, $PAGE, $DB;
731
        $storedpage = $PAGE;
732
        require_once($CFG->dirroot . '/my/lib.php');
733
        $this->purge_blocks();
734
        $regionname = 'a-region';
735
        $blockname = $this->get_a_known_block_type();
736
        $user = self::getDataGenerator()->create_user();
737
        $syscontext = \context_system::instance();
738
        $usercontext = \context_user::instance($user->id);
739
        // Add sitewide 'sticky' blocks. The page is not setup exactly as a site page would be...
740
        // but it does seem to mean that the bloacks are added correctly.
741
        list($sitepage, $sitebm) = $this->get_a_page_and_block_manager(array($regionname), $syscontext, 'site-index');
742
        $sitebm->add_block($blockname, $regionname, 0, true, '*');
743
        $sitestickyblock1 = $this->get_last_created_block();
744
        $sitebm->add_block($blockname, $regionname, 1, true, '*');
745
        $sitestickyblock2 = $this->get_last_created_block();
746
        $sitebm->add_block($blockname, $regionname, 8, true, '*');
747
        $sitestickyblock3 = $this->get_last_created_block();
748
        // Blocks that should not be picked up by any other pages in this unit test.
749
        $sitebm->add_block($blockname, $regionname, -8, true, 'site-index-*');
750
        $sitebm->add_block($blockname, $regionname, -9, true, 'site-index');
751
        $sitebm->load_blocks();
752
        // This repositioning should not be picked up.
753
        $sitebm->reposition_block($sitestickyblock3->id, $regionname, 9);
754
        // Setup the default dashboard page. This adds the blocks with the correct parameters, but seems to not be
755
        // an exact page/blockmanager setup for the default dashboard setup page.
756
        $defaultmy = my_get_page(null, MY_PAGE_PRIVATE);
757
        list($defaultmypage, $defaultmybm) = $this->get_a_page_and_block_manager(array($regionname), null, 'my-index', $defaultmy->id);
758
        $PAGE = $defaultmypage;
759
        $defaultmybm->add_block($blockname, $regionname, -2, false, $defaultmypage->pagetype, $defaultmypage->subpage);
760
        $defaultblock1 = $this->get_last_created_block();
761
        $defaultmybm->add_block($blockname, $regionname, 3, false, $defaultmypage->pagetype, $defaultmypage->subpage);
762
        $defaultblock2 = $this->get_last_created_block();
763
        $defaultmybm->load_blocks();
764
        $defaultmybm->reposition_block($sitestickyblock1->id, $regionname, 4);
765
        // Setup the user's dashboard.
766
        $usermy = my_copy_page($user->id);
767
        list($mypage, $mybm) = $this->get_a_page_and_block_manager(array($regionname), $usercontext, 'my-index', $usermy->id);
768
        $PAGE = $mypage;
769
        $mybm->add_block($blockname, $regionname, 5, false, $mypage->pagetype, $mypage->subpage);
770
        $block1 = $this->get_last_created_block();
771
        $mybm->load_blocks();
772
        $mybm->reposition_block($sitestickyblock2->id, $regionname, -1);
773
        // Reload the blocks in the managers.
774
        \context_helper::reset_caches();
775
        $defaultmybm->reset_caches();
776
        $this->assertNull($defaultmybm->get_loaded_blocks());
777
        $defaultmybm->load_blocks();
778
        $this->assertNotNull($defaultmybm->get_loaded_blocks());
779
        $defaultbr = $defaultmybm->get_blocks_for_region($regionname);
780
        $mybm->reset_caches();
781
        $this->assertNull($mybm->get_loaded_blocks());
782
        $mybm->load_blocks();
783
        $this->assertNotNull($mybm->get_loaded_blocks());
784
        $mybr = $mybm->get_blocks_for_region($regionname);
785
        // Test that a user dashboard when forced to use the default finds the correct blocks.
786
        list($forcedmypage, $forcedmybm) = $this->get_a_page_and_block_manager(array($regionname), $usercontext, 'my-index', $defaultmy->id);
787
        $forcedmybm->load_blocks();
788
        $forcedmybr = $forcedmybm->get_blocks_for_region($regionname);
789
        // Check that the default page is in the expected order.
790
        $this->assertCount(5, $defaultbr);
791
        $this->assertEquals($defaultblock1->id, $defaultbr[0]->instance->id);
792
        $this->assertEquals('-2', $defaultbr[0]->instance->weight);
793
        $this->assertEquals($sitestickyblock2->id, $defaultbr[1]->instance->id);
794
        $this->assertEquals('1', $defaultbr[1]->instance->weight);
795
        $this->assertEquals($defaultblock2->id, $defaultbr[2]->instance->id);
796
        $this->assertEquals('3', $defaultbr[2]->instance->weight);
797
        $this->assertEquals($sitestickyblock1->id, $defaultbr[3]->instance->id);
798
        $this->assertEquals('4', $defaultbr[3]->instance->weight);
799
        $this->assertEquals($sitestickyblock3->id, $defaultbr[4]->instance->id);
800
        $this->assertEquals('8', $defaultbr[4]->instance->weight);
801
        // Check that the correct block are present in the expected order for a.
802
        $this->assertCount(5, $forcedmybr);
803
        $this->assertEquals($defaultblock1->id, $forcedmybr[0]->instance->id);
804
        $this->assertEquals('-2', $forcedmybr[0]->instance->weight);
805
        $this->assertEquals($sitestickyblock2->id, $forcedmybr[1]->instance->id);
806
        $this->assertEquals('1', $forcedmybr[1]->instance->weight);
807
        $this->assertEquals($defaultblock2->id, $forcedmybr[2]->instance->id);
808
        $this->assertEquals('3', $forcedmybr[2]->instance->weight);
809
        $this->assertEquals($sitestickyblock1->id, $forcedmybr[3]->instance->id);
810
        $this->assertEquals('4', $forcedmybr[3]->instance->weight);
811
        $this->assertEquals($sitestickyblock3->id, $forcedmybr[4]->instance->id);
812
        $this->assertEquals('8', $forcedmybr[4]->instance->weight);
813
        // Check that the correct blocks are present in the standard my page.
814
        $this->assertCount(6, $mybr);
815
        $this->assertEquals('-2', $mybr[0]->instance->weight);
816
        $this->assertEquals($sitestickyblock2->id, $mybr[1]->instance->id);
817
        $this->assertEquals('-1', $mybr[1]->instance->weight);
818
        $this->assertEquals('3', $mybr[2]->instance->weight);
819
        // Test the override on the first sticky block was copied and picked up.
820
        $this->assertEquals($sitestickyblock1->id, $mybr[3]->instance->id);
821
        $this->assertEquals('4', $mybr[3]->instance->weight);
822
        $this->assertEquals($block1->id, $mybr[4]->instance->id);
823
        $this->assertEquals('5', $mybr[4]->instance->weight);
824
        $this->assertEquals($sitestickyblock3->id, $mybr[5]->instance->id);
825
        $this->assertEquals('8', $mybr[5]->instance->weight);
826
        $PAGE = $storedpage;
827
    }
828
 
829
    /**
830
     * Test get_unaddable_by_theme_block_types() method to return expected result depending on the theme.
831
     *
832
     * @covers \block_manager::get_unaddable_by_theme_block_types
833
     */
834
    public function test_get_unaddable_by_theme_block_types(): void {
835
        global $CFG, $PAGE;
836
 
837
        $this->setAdminUser();
838
        $this->resetAfterTest();
839
        $regionname = 'side-pre';
840
        $context = \context_system::instance();
841
 
842
        $PAGE->reset_theme_and_output();
843
        $CFG->theme = 'boost';
844
 
845
        list($page, $blockmanager) = $this->get_a_page_and_block_manager([$regionname], $context, 'page-type');
846
        $blockmanager->load_blocks();
847
        $blocks = $blockmanager->get_unaddable_by_theme_block_types();
848
        // Assert that a few blocks are excluded for boost theme.
849
        $this->assertCount(4, $blocks);
850
        $this->assertContains('navigation', $blocks);
851
        $this->assertContains('settings', $blocks);
852
        $this->assertContains('course_list', $blocks);
853
        $this->assertContains('section_links', $blocks);
854
 
855
        // Change to a theme without unaddable blocks.
856
        $PAGE->reset_theme_and_output();
857
        $CFG->theme = 'classic';
858
 
859
        list($page, $blockmanager) = $this->get_a_page_and_block_manager([$regionname], $context, 'page-type');
860
        $blockmanager->load_blocks();
861
        $blocks = $blockmanager->get_unaddable_by_theme_block_types();
862
        // Assert that no blocks are excluded for classic theme.
863
        $this->assertEmpty($blocks);
864
    }
865
}