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
/**
18
 * Tests for the moodle_page class.
19
 *
20
 * @package   core
21
 * @category  test
22
 * @copyright 2009 Tim Hunt
23
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24
 */
25
 
26
namespace core;
27
 
28
use moodle_page;
29
 
30
defined('MOODLE_INTERNAL') || die();
31
 
32
global $CFG;
33
require_once($CFG->libdir . '/pagelib.php');
34
require_once($CFG->libdir . '/blocklib.php');
35
 
36
/**
37
 * Tests for the moodle_page class.
38
 *
39
 * @package   core
40
 * @category  test
41
 * @copyright 2009 Tim Hunt
42
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
43
 * @coversDefaultClass \moodle_page
44
 */
45
class moodle_page_test extends \advanced_testcase {
46
 
47
    /**
48
     * @var testable_moodle_page
49
     */
50
    protected $testpage;
51
 
52
    public function setUp(): void {
53
        parent::setUp();
54
        $this->resetAfterTest();
55
        $this->testpage = new testable_moodle_page();
56
    }
57
 
11 efrain 58
    public function test_course_returns_site_before_set(): void {
1 efrain 59
        global $SITE;
60
        // Validated.
61
        $this->assertSame($SITE, $this->testpage->course);
62
    }
63
 
11 efrain 64
    public function test_setting_course_works(): void {
1 efrain 65
        // Setup fixture.
66
        $course = $this->getDataGenerator()->create_course();
67
        $this->testpage->set_context(\context_system::instance()); // Avoid trying to set the context.
68
        // Exercise SUT.
69
        $this->testpage->set_course($course);
70
        // Validated.
71
        $this->assertEquals($course, $this->testpage->course);
72
    }
73
 
11 efrain 74
    public function test_global_course_and_page_course_are_same_with_global_page(): void {
1 efrain 75
        global $COURSE, $PAGE;
76
        // Setup fixture.
77
        $course = $this->getDataGenerator()->create_course();
78
        $this->testpage->set_context(\context_system::instance()); // Avoid trying to set the context.
79
        $PAGE = $this->testpage;
80
        // Exercise SUT.
81
        $this->testpage->set_course($course);
82
        // Validated.
83
        $this->assertSame($COURSE, $this->testpage->course);
84
    }
85
 
11 efrain 86
    public function test_global_course_not_changed_with_non_global_page(): void {
1 efrain 87
        global $COURSE;
88
        $originalcourse = $COURSE;
89
        // Setup fixture.
90
        $course = $this->getDataGenerator()->create_course();
91
        $this->testpage->set_context(\context_system::instance()); // Avoid trying to set the context.
92
        // Exercise SUT.
93
        $this->testpage->set_course($course);
94
        // Validated.
95
        $this->assertSame($originalcourse, $COURSE);
96
    }
97
 
11 efrain 98
    public function test_cannot_set_course_once_theme_set(): void {
1 efrain 99
        // Setup fixture.
100
        $this->testpage->force_theme(\theme_config::DEFAULT_THEME);
101
        $course = $this->getDataGenerator()->create_course();
102
 
103
        // Exercise SUT.
104
        $this->expectException(\coding_exception::class);
105
        $this->testpage->set_course($course);
106
    }
107
 
11 efrain 108
    public function test_cannot_set_category_once_theme_set(): void {
1 efrain 109
        // Setup fixture.
110
        $this->testpage->force_theme(\theme_config::DEFAULT_THEME);
111
 
112
        // Exercise SUT.
113
        $this->expectException(\coding_exception::class);
114
        $this->testpage->set_category_by_id(123);
115
    }
116
 
11 efrain 117
    public function test_cannot_set_category_once_course_set(): void {
1 efrain 118
        // Setup fixture.
119
        $course = $this->getDataGenerator()->create_course();
120
        $this->testpage->set_context(\context_system::instance()); // Avoid trying to set the context.
121
        $this->testpage->set_course($course);
122
 
123
        // Exercise SUT.
124
        $this->expectException(\coding_exception::class);
125
        $this->testpage->set_category_by_id(123);
126
    }
127
 
11 efrain 128
    public function test_categories_array_empty_for_front_page(): void {
1 efrain 129
        global $SITE;
130
        // Setup fixture.
131
        $this->testpage->set_context(\context_system::instance()); // Avoid trying to set the context.
132
        $this->testpage->set_course($SITE);
133
        // Exercise SUT and validate.
134
        $this->assertEquals(array(), $this->testpage->categories);
135
    }
136
 
11 efrain 137
    public function test_set_state_normal_path(): void {
1 efrain 138
        $course = $this->getDataGenerator()->create_course();
139
        $this->testpage->set_context(\context_system::instance());
140
        $this->testpage->set_course($course);
141
 
142
        $this->assertEquals(\moodle_page::STATE_BEFORE_HEADER, $this->testpage->state);
143
 
144
        $this->testpage->set_state(\moodle_page::STATE_PRINTING_HEADER);
145
        $this->assertEquals(\moodle_page::STATE_PRINTING_HEADER, $this->testpage->state);
146
 
147
        $this->testpage->set_state(\moodle_page::STATE_IN_BODY);
148
        $this->assertEquals(\moodle_page::STATE_IN_BODY, $this->testpage->state);
149
 
150
        $this->testpage->set_state(\moodle_page::STATE_DONE);
151
        $this->assertEquals(\moodle_page::STATE_DONE, $this->testpage->state);
152
    }
153
 
11 efrain 154
    public function test_set_state_cannot_skip_one(): void {
1 efrain 155
        // Exercise SUT.
156
        $this->expectException(\coding_exception::class);
157
        $this->testpage->set_state(\moodle_page::STATE_IN_BODY);
158
    }
159
 
11 efrain 160
    public function test_header_printed_false_initially(): void {
1 efrain 161
        // Validated.
162
        $this->assertFalse($this->testpage->headerprinted);
163
    }
164
 
11 efrain 165
    public function test_header_printed_becomes_true(): void {
1 efrain 166
        $course = $this->getDataGenerator()->create_course();
167
        $this->testpage->set_context(\context_system::instance());
168
        $this->testpage->set_course($course);
169
 
170
        // Exercise SUT.
171
        $this->testpage->set_state(\moodle_page::STATE_PRINTING_HEADER);
172
        $this->testpage->set_state(\moodle_page::STATE_IN_BODY);
173
        // Validated.
174
        $this->assertTrue($this->testpage->headerprinted);
175
    }
176
 
11 efrain 177
    public function test_set_context(): void {
1 efrain 178
        // Setup fixture.
179
        $course = $this->getDataGenerator()->create_course();
180
        $context = \context_course::instance($course->id);
181
        // Exercise SUT.
182
        $this->testpage->set_context($context);
183
        // Validated.
184
        $this->assertSame($context, $this->testpage->context);
185
    }
186
 
11 efrain 187
    public function test_pagetype_defaults_to_script(): void {
1 efrain 188
        global $SCRIPT;
189
        // Exercise SUT and validate.
190
        $SCRIPT = '/index.php';
191
        $this->testpage->initialise_default_pagetype();
192
        $this->assertSame('site-index', $this->testpage->pagetype);
193
    }
194
 
11 efrain 195
    public function test_set_pagetype(): void {
1 efrain 196
        // Exercise SUT.
197
        $this->testpage->set_pagetype('a-page-type');
198
        // Validated.
199
        $this->assertSame('a-page-type', $this->testpage->pagetype);
200
    }
201
 
11 efrain 202
    public function test_initialise_default_pagetype(): void {
1 efrain 203
        // Exercise SUT.
204
        $this->testpage->initialise_default_pagetype('admin/tool/unittest/index.php');
205
        // Validated.
206
        $this->assertSame('admin-tool-unittest-index', $this->testpage->pagetype);
207
    }
208
 
11 efrain 209
    public function test_initialise_default_pagetype_fp(): void {
1 efrain 210
        // Exercise SUT.
211
        $this->testpage->initialise_default_pagetype('index.php');
212
        // Validated.
213
        $this->assertSame('site-index', $this->testpage->pagetype);
214
    }
215
 
11 efrain 216
    public function test_get_body_classes_empty(): void {
1 efrain 217
        // Validated.
218
        $this->assertSame('', $this->testpage->bodyclasses);
219
    }
220
 
11 efrain 221
    public function test_get_body_classes_single(): void {
1 efrain 222
        // Exercise SUT.
223
        $this->testpage->add_body_class('aclassname');
224
        // Validated.
225
        $this->assertSame('aclassname', $this->testpage->bodyclasses);
226
    }
227
 
11 efrain 228
    public function test_get_body_classes(): void {
1 efrain 229
        // Exercise SUT.
230
        $this->testpage->add_body_classes(array('aclassname', 'anotherclassname'));
231
        // Validated.
232
        $this->assertSame('aclassname anotherclassname', $this->testpage->bodyclasses);
233
    }
234
 
11 efrain 235
    public function test_url_to_class_name(): void {
1 efrain 236
        $this->assertSame('example-com', $this->testpage->url_to_class_name('http://example.com'));
237
        $this->assertSame('example-com--80', $this->testpage->url_to_class_name('http://example.com:80'));
238
        $this->assertSame('example-com--moodle', $this->testpage->url_to_class_name('https://example.com/moodle'));
239
        $this->assertSame('example-com--8080--nested-moodle', $this->testpage->url_to_class_name('https://example.com:8080/nested/moodle'));
240
    }
241
 
11 efrain 242
    public function test_set_docs_path(): void {
1 efrain 243
        // Exercise SUT.
244
        $this->testpage->set_docs_path('a/file/path');
245
        // Validated.
246
        $this->assertSame('a/file/path', $this->testpage->docspath);
247
    }
248
 
11 efrain 249
    public function test_docs_path_defaults_from_pagetype(): void {
1 efrain 250
        // Exercise SUT.
251
        $this->testpage->set_pagetype('a-page-type');
252
        // Validated.
253
        $this->assertSame('a/page/type', $this->testpage->docspath);
254
    }
255
 
11 efrain 256
    public function test_set_url_root(): void {
1 efrain 257
        global $CFG;
258
        // Exercise SUT.
259
        $this->testpage->set_url('/');
260
        // Validated.
261
        $this->assertSame($CFG->wwwroot . '/', $this->testpage->url->out());
262
    }
263
 
11 efrain 264
    public function test_set_url_one_param(): void {
1 efrain 265
        global $CFG;
266
        // Exercise SUT.
267
        $this->testpage->set_url('/mod/quiz/attempt.php', array('attempt' => 123));
268
        // Validated.
269
        $this->assertSame($CFG->wwwroot . '/mod/quiz/attempt.php?attempt=123', $this->testpage->url->out());
270
    }
271
 
11 efrain 272
    public function test_set_url_two_params(): void {
1 efrain 273
        global $CFG;
274
        // Exercise SUT.
275
        $this->testpage->set_url('/mod/quiz/attempt.php', array('attempt' => 123, 'page' => 7));
276
        // Validated.
277
        $this->assertSame($CFG->wwwroot . '/mod/quiz/attempt.php?attempt=123&amp;page=7', $this->testpage->url->out());
278
    }
279
 
11 efrain 280
    public function test_set_url_using_moodle_url(): void {
1 efrain 281
        global $CFG;
282
        // Fixture setup.
283
        $url = new \moodle_url('/mod/workshop/allocation.php', array('cmid' => 29, 'method' => 'manual'));
284
        // Exercise SUT.
285
        $this->testpage->set_url($url);
286
        // Validated.
287
        $this->assertSame($CFG->wwwroot . '/mod/workshop/allocation.php?cmid=29&amp;method=manual', $this->testpage->url->out());
288
    }
289
 
11 efrain 290
    public function test_set_url_sets_page_type(): void {
1 efrain 291
        // Exercise SUT.
292
        $this->testpage->set_url('/mod/quiz/attempt.php', array('attempt' => 123, 'page' => 7));
293
        // Validated.
294
        $this->assertSame('mod-quiz-attempt', $this->testpage->pagetype);
295
    }
296
 
11 efrain 297
    public function test_set_url_does_not_change_explicit_page_type(): void {
1 efrain 298
        // Setup fixture.
299
        $this->testpage->set_pagetype('a-page-type');
300
        // Exercise SUT.
301
        $this->testpage->set_url('/mod/quiz/attempt.php', array('attempt' => 123, 'page' => 7));
302
        // Validated.
303
        $this->assertSame('a-page-type', $this->testpage->pagetype);
304
    }
305
 
11 efrain 306
    public function test_set_subpage(): void {
1 efrain 307
        // Exercise SUT.
308
        $this->testpage->set_subpage('somestring');
309
        // Validated.
310
        $this->assertSame('somestring', $this->testpage->subpage);
311
    }
312
 
11 efrain 313
    public function test_set_heading(): void {
1 efrain 314
        // Exercise SUT.
315
        $this->testpage->set_heading('a heading');
316
        // Validated.
317
        $this->assertSame('a heading', $this->testpage->heading);
318
 
319
        // By default formatting is applied and tags are removed.
320
        $this->testpage->set_heading('a heading <a href="#">edit</a><p>');
321
        $this->assertSame('a heading edit', $this->testpage->heading);
322
 
323
        // Without formatting the tags are preserved but cleaned.
324
        $this->testpage->set_heading('<div data-param1="value1">a heading <a href="#">edit</a><p></div>', false);
325
        $this->assertSame('<div>a heading <a href="#">edit</a><p></p></div>', $this->testpage->heading);
326
 
327
        // Without formatting nor clean.
328
        $this->testpage->set_heading('<div data-param1="value1">a heading <a href="#">edit</a><p></div>', false, false);
329
        $this->assertSame('<div data-param1="value1">a heading <a href="#">edit</a><p></div>', $this->testpage->heading);
330
    }
331
 
332
    /**
333
     * Data provider for {@see test_set_title}.
334
     *
335
     * @return array
336
     */
337
    public function set_title_provider(): array {
338
        return [
339
            'Do not append the site name' => [
340
                'shortname', false, '', false
341
            ],
342
            'Site not yet installed not configured defaults to site shortname' => [
343
                null, true, 'shortname'
344
            ],
345
            '$CFG->sitenameintitle not configured defaults to site shortname' => [
346
                null, true, 'shortname'
347
            ],
348
            '$CFG->sitenameintitle set to shortname' => [
349
                'shortname', true, 'shortname'
350
            ],
351
            '$CFG->sitenameintitle set to fullname' => [
352
                'fullname', true, 'fullname'
353
            ],
354
        ];
355
    }
356
 
357
    /**
358
     * Test for set_title
359
     *
360
     * @dataProvider set_title_provider
361
     * @param string|null $config The config value for $CFG->sitenameintitle.
362
     * @param bool $appendsitename The $appendsitename parameter
363
     * @param string $expected The expected site name to be appended to the title.
364
     * @param bool $sitenameset To simulate the absence of the site name being set in the site.
365
     * @return void
366
     * @covers ::set_title
367
     */
368
    public function test_set_title(?string $config, bool $appendsitename, string $expected, bool $sitenameset = true): void {
369
        global $CFG, $SITE;
370
 
371
        if ($config !== null) {
372
            $CFG->sitenameintitle = $config;
373
        }
374
 
375
        $title = "A title";
376
        if ($appendsitename) {
377
            if ($sitenameset) {
378
                $expectedtitle = $title . moodle_page::TITLE_SEPARATOR . $SITE->{$expected};
379
            } else {
380
                // Simulate site fullname and shortname being empty for any reason.
381
                $SITE->fullname = null;
382
                $SITE->shortname = null;
383
                $expectedtitle = $title . moodle_page::TITLE_SEPARATOR . 'Moodle';
384
            }
385
        } else {
386
            $expectedtitle = $title;
387
        }
388
 
389
        $this->testpage->set_title($title, $appendsitename);
390
        // Validated.
391
        $this->assertSame($expectedtitle, $this->testpage->title);
392
    }
393
 
11 efrain 394
    public function test_default_pagelayout(): void {
1 efrain 395
        // Exercise SUT and Validate.
396
        $this->assertSame('base', $this->testpage->pagelayout);
397
    }
398
 
11 efrain 399
    public function test_set_pagelayout(): void {
1 efrain 400
        // Exercise SUT.
401
        $this->testpage->set_pagelayout('type');
402
        // Validated.
403
        $this->assertSame('type', $this->testpage->pagelayout);
404
    }
405
 
11 efrain 406
    public function test_setting_course_sets_context(): void {
1 efrain 407
        // Setup fixture.
408
        $course = $this->getDataGenerator()->create_course();
409
        $context = \context_course::instance($course->id);
410
 
411
        // Exercise SUT.
412
        $this->testpage->set_course($course);
413
 
414
        // Validated.
415
        $this->assertSame($context, $this->testpage->context);
416
    }
417
 
11 efrain 418
    public function test_set_category_top_level(): void {
1 efrain 419
        global $DB;
420
        // Setup fixture.
421
        $cat = $this->getDataGenerator()->create_category();
422
        $catdbrecord = $DB->get_record('course_categories', array('id' => $cat->id));
423
        // Exercise SUT.
424
        $this->testpage->set_category_by_id($cat->id);
425
        // Validated.
426
        $this->assertEquals($catdbrecord, $this->testpage->category);
427
        $this->assertSame(\context_coursecat::instance($cat->id), $this->testpage->context);
428
    }
429
 
11 efrain 430
    public function test_set_nested_categories(): void {
1 efrain 431
        global $DB;
432
        // Setup fixture.
433
        $topcat = $this->getDataGenerator()->create_category();
434
        $topcatdbrecord = $DB->get_record('course_categories', array('id' => $topcat->id));
435
        $subcat = $this->getDataGenerator()->create_category(array('parent'=>$topcat->id));
436
        $subcatdbrecord = $DB->get_record('course_categories', array('id' => $subcat->id));
437
        // Exercise SUT.
438
        $this->testpage->set_category_by_id($subcat->id);
439
        // Validated.
440
        $categories = $this->testpage->categories;
441
        $this->assertCount(2, $categories);
442
        $this->assertEquals($topcatdbrecord, array_pop($categories));
443
        $this->assertEquals($subcatdbrecord, array_pop($categories));
444
    }
445
 
11 efrain 446
    public function test_cm_null_initially(): void {
1 efrain 447
        // Validated.
448
        $this->assertNull($this->testpage->cm);
449
    }
450
 
11 efrain 451
    public function test_set_cm(): void {
1 efrain 452
        // Setup fixture.
453
        $course = $this->getDataGenerator()->create_course();
454
        $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id));
455
        $cm = get_coursemodule_from_id('forum', $forum->cmid);
456
        // Exercise SUT.
457
        $this->testpage->set_cm($cm);
458
        // Validated.
459
        $this->assertEquals($cm->id, $this->testpage->cm->id);
460
    }
461
 
11 efrain 462
    public function test_cannot_set_activity_record_before_cm(): void {
1 efrain 463
        // Setup fixture.
464
        $course = $this->getDataGenerator()->create_course();
465
        $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id));
466
        $cm = get_coursemodule_from_id('forum', $forum->cmid);
467
        // Exercise SUT.
468
        $this->expectException(\coding_exception::class);
469
        $this->testpage->set_activity_record($forum);
470
    }
471
 
11 efrain 472
    public function test_setting_cm_sets_context(): void {
1 efrain 473
        // Setup fixture.
474
        $course = $this->getDataGenerator()->create_course();
475
        $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id));
476
        $cm = get_coursemodule_from_id('forum', $forum->cmid);
477
        // Exercise SUT.
478
        $this->testpage->set_cm($cm);
479
        // Validated.
480
        $this->assertSame(\context_module::instance($cm->id), $this->testpage->context);
481
    }
482
 
11 efrain 483
    public function test_activity_record_loaded_if_not_set(): void {
1 efrain 484
        // Setup fixture.
485
        $course = $this->getDataGenerator()->create_course();
486
        $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id));
487
        $cm = get_coursemodule_from_id('forum', $forum->cmid);
488
        // Exercise SUT.
489
        $this->testpage->set_cm($cm);
490
        // Validated.
491
        unset($forum->cmid);
492
        $this->assertEquals($forum, $this->testpage->activityrecord);
493
    }
494
 
11 efrain 495
    public function test_set_activity_record(): void {
1 efrain 496
        // Setup fixture.
497
        $course = $this->getDataGenerator()->create_course();
498
        $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id));
499
        $cm = get_coursemodule_from_id('forum', $forum->cmid);
500
        $this->testpage->set_cm($cm);
501
        // Exercise SUT.
502
        $this->testpage->set_activity_record($forum);
503
        // Validated.
504
        unset($forum->cmid);
505
        $this->assertEquals($forum, $this->testpage->activityrecord);
506
    }
507
 
11 efrain 508
    public function test_cannot_set_inconsistent_activity_record_course(): void {
1 efrain 509
        // Setup fixture.
510
        $course = $this->getDataGenerator()->create_course();
511
        $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id));
512
        $cm = get_coursemodule_from_id('forum', $forum->cmid);
513
        $this->testpage->set_cm($cm);
514
        // Exercise SUT.
515
        $forum->course = 13;
516
        $this->expectException(\coding_exception::class);
517
        $this->testpage->set_activity_record($forum);
518
    }
519
 
11 efrain 520
    public function test_cannot_set_inconsistent_activity_record_instance(): void {
1 efrain 521
        // Setup fixture.
522
        $course = $this->getDataGenerator()->create_course();
523
        $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id));
524
        $cm = get_coursemodule_from_id('forum', $forum->cmid);
525
        $this->testpage->set_cm($cm);
526
        // Exercise SUT.
527
        $forum->id = 13;
528
        $this->expectException(\coding_exception::class);
529
        $this->testpage->set_activity_record($forum);
530
    }
531
 
11 efrain 532
    public function test_setting_cm_sets_course(): void {
1 efrain 533
        // Setup fixture.
534
        $course = $this->getDataGenerator()->create_course();
535
        $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id));
536
        $cm = get_coursemodule_from_id('forum', $forum->cmid);
537
        // Exercise SUT.
538
        $this->testpage->set_cm($cm);
539
        // Validated.
540
        $this->assertEquals($course->id, $this->testpage->course->id);
541
    }
542
 
11 efrain 543
    public function test_set_cm_with_course_and_activity_no_db(): void {
1 efrain 544
        // Setup fixture.
545
        $course = $this->getDataGenerator()->create_course();
546
        $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id));
547
        $cm = get_coursemodule_from_id('forum', $forum->cmid);
548
        // This only works without db if we already have modinfo cache
549
        // Exercise SUT.
550
        $this->testpage->set_cm($cm, $course, $forum);
551
        // Validated.
552
        $this->assertEquals($cm->id, $this->testpage->cm->id);
553
        $this->assertEquals($course->id, $this->testpage->course->id);
554
        unset($forum->cmid);
555
        $this->assertEquals($forum, $this->testpage->activityrecord);
556
    }
557
 
11 efrain 558
    public function test_cannot_set_cm_with_inconsistent_course(): void {
1 efrain 559
        // Setup fixture.
560
        $course = $this->getDataGenerator()->create_course();
561
        $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id));
562
        $cm = get_coursemodule_from_id('forum', $forum->cmid);
563
        // Exercise SUT.
564
        $cm->course = 13;
565
        $this->expectException(\coding_exception::class);
566
        $this->testpage->set_cm($cm, $course);
567
    }
568
 
11 efrain 569
    public function test_get_activity_name(): void {
1 efrain 570
        // Setup fixture.
571
        $course = $this->getDataGenerator()->create_course();
572
        $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id));
573
        $cm = get_coursemodule_from_id('forum', $forum->cmid);
574
        // Exercise SUT.
575
        $this->testpage->set_cm($cm, $course, $forum);
576
        // Validated.
577
        $this->assertSame('forum', $this->testpage->activityname);
578
    }
579
 
11 efrain 580
    public function test_user_is_editing_on(): void {
1 efrain 581
        // We are relying on the fact that unit tests are always run by admin, to
582
        // ensure the user_allows_editing call returns true.
583
 
584
        // Setup fixture.
585
        global $USER;
586
 
587
        $this->testpage->set_context(\context_system::instance());
588
        $this->setAdminUser();
589
 
590
        $USER->editing = true;
591
        // Validated.
592
        $this->assertTrue($this->testpage->user_is_editing());
593
    }
594
 
11 efrain 595
    public function test_user_is_editing_off(): void {
1 efrain 596
        // We are relying on the fact that unit tests are always run by admin, to
597
        // ensure the user_allows_editing call returns true.
598
 
599
        // Setup fixture.
600
        global $USER;
601
 
602
        $this->testpage->set_context(\context_system::instance());
603
        $this->setAdminUser();
604
 
605
        $USER->editing = false;
606
        // Validated.
607
        $this->assertFalse($this->testpage->user_is_editing());
608
    }
609
 
11 efrain 610
    public function test_default_editing_capabilities(): void {
1 efrain 611
        $this->testpage->set_context(\context_system::instance());
612
        $this->setAdminUser();
613
 
614
        // Validated.
615
        $this->assertEquals(array('moodle/site:manageblocks'), $this->testpage->all_editing_caps());
616
    }
617
 
11 efrain 618
    public function test_other_block_editing_cap(): void {
1 efrain 619
        $this->testpage->set_context(\context_system::instance());
620
        $this->setAdminUser();
621
 
622
        // Exercise SUT.
623
        $this->testpage->set_blocks_editing_capability('moodle/my:manageblocks');
624
        // Validated.
625
        $this->assertEquals(array('moodle/my:manageblocks'), $this->testpage->all_editing_caps());
626
    }
627
 
11 efrain 628
    public function test_other_editing_cap(): void {
1 efrain 629
        $this->testpage->set_context(\context_system::instance());
630
        $this->setAdminUser();
631
 
632
        // Exercise SUT.
633
        $this->testpage->set_other_editing_capability('moodle/course:manageactivities');
634
        // Validated.
635
        $actualcaps = $this->testpage->all_editing_caps();
636
        $expectedcaps = array('moodle/course:manageactivities', 'moodle/site:manageblocks');
637
        $this->assertEquals(array_values($expectedcaps), array_values($actualcaps));
638
    }
639
 
11 efrain 640
    public function test_other_editing_caps(): void {
1 efrain 641
        $this->testpage->set_context(\context_system::instance());
642
        $this->setAdminUser();
643
 
644
        // Exercise SUT.
645
        $this->testpage->set_other_editing_capability(array('moodle/course:manageactivities', 'moodle/site:other'));
646
        // Validated.
647
        $actualcaps = $this->testpage->all_editing_caps();
648
        $expectedcaps = array('moodle/course:manageactivities', 'moodle/site:other', 'moodle/site:manageblocks');
649
        $this->assertEquals(array_values($expectedcaps), array_values($actualcaps));
650
    }
651
 
652
    /**
653
     * Test getting a renderer.
654
     */
11 efrain 655
    public function test_get_renderer(): void {
1 efrain 656
        global $OUTPUT, $PAGE;
657
        $oldoutput = $OUTPUT;
658
        $oldpage = $PAGE;
659
        $PAGE = $this->testpage;
660
 
661
        $this->testpage->set_pagelayout('standard');
662
        $this->assertEquals('standard', $this->testpage->pagelayout);
663
        // Initialise theme and output for the next tests.
664
        $this->testpage->initialise_theme_and_output();
665
        // Check the generated $OUTPUT object is a core renderer.
666
        $this->assertInstanceOf('core_renderer', $OUTPUT);
667
        // Check we can get a core renderer if we explicitly request one (no component).
668
        $this->assertInstanceOf('core_renderer', $this->testpage->get_renderer('core'));
669
        // Check we get a CLI renderer if we request a maintenance renderer. The CLI target should take precedence.
670
        $this->assertInstanceOf('core_renderer_cli',
671
            $this->testpage->get_renderer('core', null, RENDERER_TARGET_MAINTENANCE));
672
 
673
        // Check we can get a coures renderer if we explicitly request one (valid component).
674
        $this->assertInstanceOf('core_course_renderer', $this->testpage->get_renderer('core', 'course'));
675
 
676
        // Check a properly invalid component.
677
        try {
678
            $this->testpage->get_renderer('core', 'monkeys');
679
            $this->fail('Request for renderer with invalid component didn\'t throw expected exception.');
680
        } catch (\coding_exception $exception) {
681
            $this->assertEquals('monkeys', $exception->debuginfo);
682
        }
683
 
684
        $PAGE = $oldpage;
685
        $OUTPUT = $oldoutput;
686
    }
687
 
688
    /**
689
     * Tests getting a renderer with a maintenance layout.
690
     *
691
     * This layout has special hacks in place in order to deliver a "maintenance" renderer.
692
     */
11 efrain 693
    public function test_get_renderer_maintenance(): void {
1 efrain 694
        global $OUTPUT, $PAGE;
695
        $oldoutput = $OUTPUT;
696
        $oldpage = $PAGE;
697
        $PAGE = $this->testpage;
698
 
699
        $this->testpage->set_pagelayout('maintenance');
700
        $this->assertEquals('maintenance', $this->testpage->pagelayout);
701
        // Initialise theme and output for the next tests.
702
        $this->testpage->initialise_theme_and_output();
703
        // Check the generated $OUTPUT object is a core cli renderer.
704
        // It shouldn't be maintenance because there the cli target should take greater precedence.
705
        $this->assertInstanceOf('core_renderer_cli', $OUTPUT);
706
        // Check we can get a core renderer if we explicitly request one (no component).
707
        $this->assertInstanceOf('core_renderer', $this->testpage->get_renderer('core'));
708
        // Check we get a CLI renderer if we request a maintenance renderer. The CLI target should take precedence.
709
        $this->assertInstanceOf('core_renderer_cli',
710
            $this->testpage->get_renderer('core', null, RENDERER_TARGET_MAINTENANCE));
711
        // Check we can get a coures renderer if we explicitly request one (valid component).
712
        $this->assertInstanceOf('core_course_renderer', $this->testpage->get_renderer('core', 'course'));
713
 
714
        try {
715
            $this->testpage->get_renderer('core', 'monkeys');
716
            $this->fail('Request for renderer with invalid component didn\'t throw expected exception.');
717
        } catch (\coding_exception $exception) {
718
            $this->assertEquals('monkeys', $exception->debuginfo);
719
        }
720
 
721
        $PAGE = $oldpage;
722
        $OUTPUT = $oldoutput;
723
    }
724
 
11 efrain 725
    public function test_render_to_cli(): void {
1 efrain 726
        global $OUTPUT;
727
 
728
        $footer = $OUTPUT->footer();
729
        $this->assertEmpty($footer, 'cli output does not have a footer.');
730
    }
731
 
732
    /**
733
     * Validate the theme value depending on the user theme and cohorts.
734
     *
735
     * @dataProvider get_user_theme_provider
736
     */
11 efrain 737
    public function test_cohort_get_user_theme($usertheme, $sitetheme, $cohortthemes, $expected): void {
1 efrain 738
        global $DB, $PAGE, $USER;
739
 
740
        $this->resetAfterTest();
741
 
742
        // Enable cohort themes.
743
        set_config('allowuserthemes', 1);
744
        set_config('allowcohortthemes', 1);
745
 
746
        $systemctx = \context_system::instance();
747
 
748
        set_config('theme', $sitetheme);
749
        // Create user.
750
        $user = $this->getDataGenerator()->create_user(array('theme' => $usertheme));
751
 
752
        // Create cohorts and add user as member.
753
        $cohorts = array();
754
        foreach ($cohortthemes as $cohorttheme) {
755
            $cohort = $this->getDataGenerator()->create_cohort(array('contextid' => $systemctx->id, 'name' => 'Cohort',
756
                'idnumber' => '', 'description' => '', 'theme' => $cohorttheme));
757
            $cohorts[] = $cohort;
758
            cohort_add_member($cohort->id, $user->id);
759
        }
760
 
761
        // Get the theme and compare to the expected.
762
        $this->setUser($user);
763
 
764
        // Initialise user theme.
765
        $USER = get_complete_user_data('id', $user->id);
766
 
767
        // Initialise site theme.
768
        $PAGE->reset_theme_and_output();
769
        $PAGE->initialise_theme_and_output();
770
        $result = $PAGE->theme->name;
771
        $this->assertEquals($expected, $result);
772
    }
773
 
774
    /**
775
     * Some user cases for validating the expected theme depending on the cohorts, site and user values.
776
     *
777
     * The result is an array of:
778
     *     'User case description' => [
779
     *      'usertheme' => '', // User theme.
780
     *      'sitetheme' => '', // Site theme.
781
     *      'cohorts' => [],   // Cohort themes.
782
     *      'expected' => '',  // Expected value returned by cohort_get_user_cohort_theme.
783
     *    ]
784
     *
785
     * @return array
786
     */
787
    public function get_user_theme_provider() {
788
        return [
789
            'User not a member of any cohort' => [
790
                'usertheme' => '',
791
                'sitetheme' => 'boost',
792
                'cohorts' => [],
793
                'expected' => 'boost',
794
            ],
795
            'User member of one cohort which has a theme set' => [
796
                'usertheme' => '',
797
                'sitetheme' => 'boost',
798
                'cohorts' => [
799
                    'classic',
800
                ],
801
                'expected' => 'classic',
802
            ],
803
            'User member of one cohort which has a theme set, and one without a theme' => [
804
                'usertheme' => '',
805
                'sitetheme' => 'boost',
806
                'cohorts' => [
807
                    'classic',
808
                    '',
809
                ],
810
                'expected' => 'classic',
811
            ],
812
            'User member of one cohort which has a theme set, and one with a different theme' => [
813
                'usertheme' => '',
814
                'sitetheme' => 'boost',
815
                'cohorts' => [
816
                    'classic',
817
                    'someother',
818
                ],
819
                'expected' => 'boost',
820
            ],
821
            'User with a theme but not a member of any cohort' => [
822
                'usertheme' => 'classic',
823
                'sitetheme' => 'boost',
824
                'cohorts' => [],
825
                'expected' => 'classic',
826
            ],
827
            'User with a theme and member of one cohort which has a theme set' => [
828
                'usertheme' => 'classic',
829
                'sitetheme' => 'boost',
830
                'cohorts' => [
831
                    'boost',
832
                ],
833
                'expected' => 'classic',
834
            ],
835
        ];
836
    }
837
 
838
    /**
839
     * Tests user_can_edit_blocks() returns the expected response.
840
     * @covers ::user_can_edit_blocks()
841
     */
11 efrain 842
    public function test_user_can_edit_blocks(): void {
1 efrain 843
        global $DB;
844
 
845
        $systemcontext = \context_system::instance();
846
        $this->testpage->set_context($systemcontext);
847
 
848
        $user = $this->getDataGenerator()->create_user();
849
        $role = $DB->get_record('role', ['shortname' => 'teacher']);
850
        role_assign($role->id, $user->id, $systemcontext->id);
851
        $this->setUser($user);
852
 
853
        // Confirm expected response (false) when user does not have access to edit blocks.
854
        $capability = $this->testpage->all_editing_caps()[0];
855
        assign_capability($capability, CAP_PROHIBIT, $role->id, $systemcontext, true);
856
        $this->assertFalse($this->testpage->user_can_edit_blocks());
857
 
858
        // Give capability and confirm expected response (true) now user has access to edit blocks.
859
        assign_capability($capability, CAP_ALLOW, $role->id, $systemcontext, true);
860
        $this->assertTrue($this->testpage->user_can_edit_blocks());
861
    }
862
 
863
    /**
864
     * Tests that calling force_lock_all_blocks() will cause user_can_edit_blocks() to return false, regardless of capabilities.
865
     * @covers ::force_lock_all_blocks()
866
     */
11 efrain 867
    public function test_force_lock_all_blocks(): void {
1 efrain 868
        $this->testpage->set_context(\context_system::instance());
869
        $this->setAdminUser();
870
 
871
        // Confirm admin user has access to edit blocks.
872
        $this->assertTrue($this->testpage->user_can_edit_blocks());
873
 
874
        // Force lock and confirm user can no longer edit, despite having the capability.
875
        $this->testpage->force_lock_all_blocks();
876
        $this->assertFalse($this->testpage->user_can_edit_blocks());
877
    }
878
 
879
    /**
880
     * Test the method to set and retrieve the show_course_index property.
881
     *
882
     * @covers ::set_show_course_index
883
     * @covers ::get_show_course_index
884
     * @return void
885
     */
886
    public function test_show_course_index(): void {
887
        $page = new \moodle_page();
888
        $page->set_show_course_index(false);
889
        $this->assertFalse($page->get_show_course_index());
890
    }
891
}
892
 
893
/**
894
 * Test-specific subclass to make some protected things public.
895
 */
896
class testable_moodle_page extends moodle_page {
897
    public function initialise_default_pagetype($script = null) {
898
        parent::initialise_default_pagetype($script);
899
    }
900
    public function url_to_class_name($url) {
901
        return parent::url_to_class_name($url);
902
    }
903
    public function all_editing_caps() {
904
        return parent::all_editing_caps();
905
    }
906
}