See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 400 and 401]
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 58 public function test_course_returns_site_before_set() { 59 global $SITE; 60 // Validated. 61 $this->assertSame($SITE, $this->testpage->course); 62 } 63 64 public function test_setting_course_works() { 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 74 public function test_global_course_and_page_course_are_same_with_global_page() { 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 86 public function test_global_course_not_changed_with_non_global_page() { 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 98 public function test_cannot_set_course_once_theme_set() { 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 108 public function test_cannot_set_category_once_theme_set() { 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 117 public function test_cannot_set_category_once_course_set() { 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 128 public function test_categories_array_empty_for_front_page() { 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 137 public function test_set_state_normal_path() { 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 154 public function test_set_state_cannot_skip_one() { 155 // Exercise SUT. 156 $this->expectException(\coding_exception::class); 157 $this->testpage->set_state(\moodle_page::STATE_IN_BODY); 158 } 159 160 public function test_header_printed_false_initially() { 161 // Validated. 162 $this->assertFalse($this->testpage->headerprinted); 163 } 164 165 public function test_header_printed_becomes_true() { 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 177 public function test_set_context() { 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 187 public function test_pagetype_defaults_to_script() { 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 195 public function test_set_pagetype() { 196 // Exercise SUT. 197 $this->testpage->set_pagetype('a-page-type'); 198 // Validated. 199 $this->assertSame('a-page-type', $this->testpage->pagetype); 200 } 201 202 public function test_initialise_default_pagetype() { 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 209 public function test_initialise_default_pagetype_fp() { 210 // Exercise SUT. 211 $this->testpage->initialise_default_pagetype('index.php'); 212 // Validated. 213 $this->assertSame('site-index', $this->testpage->pagetype); 214 } 215 216 public function test_get_body_classes_empty() { 217 // Validated. 218 $this->assertSame('', $this->testpage->bodyclasses); 219 } 220 221 public function test_get_body_classes_single() { 222 // Exercise SUT. 223 $this->testpage->add_body_class('aclassname'); 224 // Validated. 225 $this->assertSame('aclassname', $this->testpage->bodyclasses); 226 } 227 228 public function test_get_body_classes() { 229 // Exercise SUT. 230 $this->testpage->add_body_classes(array('aclassname', 'anotherclassname')); 231 // Validated. 232 $this->assertSame('aclassname anotherclassname', $this->testpage->bodyclasses); 233 } 234 235 public function test_url_to_class_name() { 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 242 public function test_set_docs_path() { 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 249 public function test_docs_path_defaults_from_pagetype() { 250 // Exercise SUT. 251 $this->testpage->set_pagetype('a-page-type'); 252 // Validated. 253 $this->assertSame('a/page/type', $this->testpage->docspath); 254 } 255 256 public function test_set_url_root() { 257 global $CFG; 258 // Exercise SUT. 259 $this->testpage->set_url('/'); 260 // Validated. 261 $this->assertSame($CFG->wwwroot . '/', $this->testpage->url->out()); 262 } 263 264 public function test_set_url_one_param() { 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 272 public function test_set_url_two_params() { 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&page=7', $this->testpage->url->out()); 278 } 279 280 public function test_set_url_using_moodle_url() { 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&method=manual', $this->testpage->url->out()); 288 } 289 290 public function test_set_url_sets_page_type() { 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 297 public function test_set_url_does_not_change_explicit_page_type() { 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 306 public function test_set_subpage() { 307 // Exercise SUT. 308 $this->testpage->set_subpage('somestring'); 309 // Validated. 310 $this->assertSame('somestring', $this->testpage->subpage); 311 } 312 313 public function test_set_heading() { 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('a heading <a href="#">edit</a><p>', false); 325 $this->assertSame('a heading <a href="#">edit</a><p></p>', $this->testpage->heading); 326 } 327 328 /** 329 * Data provider for {@see test_set_title}. 330 * 331 * @return array 332 */ 333 public function set_title_provider(): array { 334 return [ 335 'Do not append the site name' => [ 336 'shortname', false, '', false 337 ], 338 'Site not yet installed not configured defaults to site shortname' => [ 339 null, true, 'shortname' 340 ], 341 '$CFG->sitenameintitle not configured defaults to site shortname' => [ 342 null, true, 'shortname' 343 ], 344 '$CFG->sitenameintitle set to shortname' => [ 345 'shortname', true, 'shortname' 346 ], 347 '$CFG->sitenameintitle set to fullname' => [ 348 'fullname', true, 'fullname' 349 ], 350 ]; 351 } 352 353 /** 354 * Test for set_title 355 * 356 * @dataProvider set_title_provider 357 * @param string|null $config The config value for $CFG->sitenameintitle. 358 * @param bool $appendsitename The $appendsitename parameter 359 * @param string $expected The expected site name to be appended to the title. 360 * @param bool $sitenameset To simulate the absence of the site name being set in the site. 361 * @return void 362 * @covers ::set_title 363 */ 364 public function test_set_title(?string $config, bool $appendsitename, string $expected, bool $sitenameset = true): void { 365 global $CFG, $SITE; 366 367 if ($config !== null) { 368 $CFG->sitenameintitle = $config; 369 } 370 371 $title = "A title"; 372 if ($appendsitename) { 373 if ($sitenameset) { 374 $expectedtitle = $title . moodle_page::TITLE_SEPARATOR . $SITE->{$expected}; 375 } else { 376 // Simulate site fullname and shortname being empty for any reason. 377 $SITE->fullname = null; 378 $SITE->shortname = null; 379 $expectedtitle = $title . moodle_page::TITLE_SEPARATOR . 'Moodle'; 380 } 381 } else { 382 $expectedtitle = $title; 383 } 384 385 $this->testpage->set_title($title, $appendsitename); 386 // Validated. 387 $this->assertSame($expectedtitle, $this->testpage->title); 388 } 389 390 public function test_default_pagelayout() { 391 // Exercise SUT and Validate. 392 $this->assertSame('base', $this->testpage->pagelayout); 393 } 394 395 public function test_set_pagelayout() { 396 // Exercise SUT. 397 $this->testpage->set_pagelayout('type'); 398 // Validated. 399 $this->assertSame('type', $this->testpage->pagelayout); 400 } 401 402 public function test_setting_course_sets_context() { 403 // Setup fixture. 404 $course = $this->getDataGenerator()->create_course(); 405 $context = \context_course::instance($course->id); 406 407 // Exercise SUT. 408 $this->testpage->set_course($course); 409 410 // Validated. 411 $this->assertSame($context, $this->testpage->context); 412 } 413 414 public function test_set_category_top_level() { 415 global $DB; 416 // Setup fixture. 417 $cat = $this->getDataGenerator()->create_category(); 418 $catdbrecord = $DB->get_record('course_categories', array('id' => $cat->id)); 419 // Exercise SUT. 420 $this->testpage->set_category_by_id($cat->id); 421 // Validated. 422 $this->assertEquals($catdbrecord, $this->testpage->category); 423 $this->assertSame(\context_coursecat::instance($cat->id), $this->testpage->context); 424 } 425 426 public function test_set_nested_categories() { 427 global $DB; 428 // Setup fixture. 429 $topcat = $this->getDataGenerator()->create_category(); 430 $topcatdbrecord = $DB->get_record('course_categories', array('id' => $topcat->id)); 431 $subcat = $this->getDataGenerator()->create_category(array('parent'=>$topcat->id)); 432 $subcatdbrecord = $DB->get_record('course_categories', array('id' => $subcat->id)); 433 // Exercise SUT. 434 $this->testpage->set_category_by_id($subcat->id); 435 // Validated. 436 $categories = $this->testpage->categories; 437 $this->assertCount(2, $categories); 438 $this->assertEquals($topcatdbrecord, array_pop($categories)); 439 $this->assertEquals($subcatdbrecord, array_pop($categories)); 440 } 441 442 public function test_cm_null_initially() { 443 // Validated. 444 $this->assertNull($this->testpage->cm); 445 } 446 447 public function test_set_cm() { 448 // Setup fixture. 449 $course = $this->getDataGenerator()->create_course(); 450 $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id)); 451 $cm = get_coursemodule_from_id('forum', $forum->cmid); 452 // Exercise SUT. 453 $this->testpage->set_cm($cm); 454 // Validated. 455 $this->assertEquals($cm->id, $this->testpage->cm->id); 456 } 457 458 public function test_cannot_set_activity_record_before_cm() { 459 // Setup fixture. 460 $course = $this->getDataGenerator()->create_course(); 461 $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id)); 462 $cm = get_coursemodule_from_id('forum', $forum->cmid); 463 // Exercise SUT. 464 $this->expectException(\coding_exception::class); 465 $this->testpage->set_activity_record($forum); 466 } 467 468 public function test_setting_cm_sets_context() { 469 // Setup fixture. 470 $course = $this->getDataGenerator()->create_course(); 471 $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id)); 472 $cm = get_coursemodule_from_id('forum', $forum->cmid); 473 // Exercise SUT. 474 $this->testpage->set_cm($cm); 475 // Validated. 476 $this->assertSame(\context_module::instance($cm->id), $this->testpage->context); 477 } 478 479 public function test_activity_record_loaded_if_not_set() { 480 // Setup fixture. 481 $course = $this->getDataGenerator()->create_course(); 482 $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id)); 483 $cm = get_coursemodule_from_id('forum', $forum->cmid); 484 // Exercise SUT. 485 $this->testpage->set_cm($cm); 486 // Validated. 487 unset($forum->cmid); 488 $this->assertEquals($forum, $this->testpage->activityrecord); 489 } 490 491 public function test_set_activity_record() { 492 // Setup fixture. 493 $course = $this->getDataGenerator()->create_course(); 494 $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id)); 495 $cm = get_coursemodule_from_id('forum', $forum->cmid); 496 $this->testpage->set_cm($cm); 497 // Exercise SUT. 498 $this->testpage->set_activity_record($forum); 499 // Validated. 500 unset($forum->cmid); 501 $this->assertEquals($forum, $this->testpage->activityrecord); 502 } 503 504 public function test_cannot_set_inconsistent_activity_record_course() { 505 // Setup fixture. 506 $course = $this->getDataGenerator()->create_course(); 507 $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id)); 508 $cm = get_coursemodule_from_id('forum', $forum->cmid); 509 $this->testpage->set_cm($cm); 510 // Exercise SUT. 511 $forum->course = 13; 512 $this->expectException(\coding_exception::class); 513 $this->testpage->set_activity_record($forum); 514 } 515 516 public function test_cannot_set_inconsistent_activity_record_instance() { 517 // Setup fixture. 518 $course = $this->getDataGenerator()->create_course(); 519 $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id)); 520 $cm = get_coursemodule_from_id('forum', $forum->cmid); 521 $this->testpage->set_cm($cm); 522 // Exercise SUT. 523 $forum->id = 13; 524 $this->expectException(\coding_exception::class); 525 $this->testpage->set_activity_record($forum); 526 } 527 528 public function test_setting_cm_sets_course() { 529 // Setup fixture. 530 $course = $this->getDataGenerator()->create_course(); 531 $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id)); 532 $cm = get_coursemodule_from_id('forum', $forum->cmid); 533 // Exercise SUT. 534 $this->testpage->set_cm($cm); 535 // Validated. 536 $this->assertEquals($course->id, $this->testpage->course->id); 537 } 538 539 public function test_set_cm_with_course_and_activity_no_db() { 540 // Setup fixture. 541 $course = $this->getDataGenerator()->create_course(); 542 $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id)); 543 $cm = get_coursemodule_from_id('forum', $forum->cmid); 544 // This only works without db if we already have modinfo cache 545 // Exercise SUT. 546 $this->testpage->set_cm($cm, $course, $forum); 547 // Validated. 548 $this->assertEquals($cm->id, $this->testpage->cm->id); 549 $this->assertEquals($course->id, $this->testpage->course->id); 550 unset($forum->cmid); 551 $this->assertEquals($forum, $this->testpage->activityrecord); 552 } 553 554 public function test_cannot_set_cm_with_inconsistent_course() { 555 // Setup fixture. 556 $course = $this->getDataGenerator()->create_course(); 557 $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id)); 558 $cm = get_coursemodule_from_id('forum', $forum->cmid); 559 // Exercise SUT. 560 $cm->course = 13; 561 $this->expectException(\coding_exception::class); 562 $this->testpage->set_cm($cm, $course); 563 } 564 565 public function test_get_activity_name() { 566 // Setup fixture. 567 $course = $this->getDataGenerator()->create_course(); 568 $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id)); 569 $cm = get_coursemodule_from_id('forum', $forum->cmid); 570 // Exercise SUT. 571 $this->testpage->set_cm($cm, $course, $forum); 572 // Validated. 573 $this->assertSame('forum', $this->testpage->activityname); 574 } 575 576 public function test_user_is_editing_on() { 577 // We are relying on the fact that unit tests are always run by admin, to 578 // ensure the user_allows_editing call returns true. 579 580 // Setup fixture. 581 global $USER; 582 583 $this->testpage->set_context(\context_system::instance()); 584 $this->setAdminUser(); 585 586 $USER->editing = true; 587 // Validated. 588 $this->assertTrue($this->testpage->user_is_editing()); 589 } 590 591 public function test_user_is_editing_off() { 592 // We are relying on the fact that unit tests are always run by admin, to 593 // ensure the user_allows_editing call returns true. 594 595 // Setup fixture. 596 global $USER; 597 598 $this->testpage->set_context(\context_system::instance()); 599 $this->setAdminUser(); 600 601 $USER->editing = false; 602 // Validated. 603 $this->assertFalse($this->testpage->user_is_editing()); 604 } 605 606 public function test_default_editing_capabilities() { 607 $this->testpage->set_context(\context_system::instance()); 608 $this->setAdminUser(); 609 610 // Validated. 611 $this->assertEquals(array('moodle/site:manageblocks'), $this->testpage->all_editing_caps()); 612 } 613 614 public function test_other_block_editing_cap() { 615 $this->testpage->set_context(\context_system::instance()); 616 $this->setAdminUser(); 617 618 // Exercise SUT. 619 $this->testpage->set_blocks_editing_capability('moodle/my:manageblocks'); 620 // Validated. 621 $this->assertEquals(array('moodle/my:manageblocks'), $this->testpage->all_editing_caps()); 622 } 623 624 public function test_other_editing_cap() { 625 $this->testpage->set_context(\context_system::instance()); 626 $this->setAdminUser(); 627 628 // Exercise SUT. 629 $this->testpage->set_other_editing_capability('moodle/course:manageactivities'); 630 // Validated. 631 $actualcaps = $this->testpage->all_editing_caps(); 632 $expectedcaps = array('moodle/course:manageactivities', 'moodle/site:manageblocks'); 633 $this->assertEquals(array_values($expectedcaps), array_values($actualcaps)); 634 } 635 636 public function test_other_editing_caps() { 637 $this->testpage->set_context(\context_system::instance()); 638 $this->setAdminUser(); 639 640 // Exercise SUT. 641 $this->testpage->set_other_editing_capability(array('moodle/course:manageactivities', 'moodle/site:other')); 642 // Validated. 643 $actualcaps = $this->testpage->all_editing_caps(); 644 $expectedcaps = array('moodle/course:manageactivities', 'moodle/site:other', 'moodle/site:manageblocks'); 645 $this->assertEquals(array_values($expectedcaps), array_values($actualcaps)); 646 } 647 648 /** 649 * Test getting a renderer. 650 */ 651 public function test_get_renderer() { 652 global $OUTPUT, $PAGE; 653 $oldoutput = $OUTPUT; 654 $oldpage = $PAGE; 655 $PAGE = $this->testpage; 656 657 $this->testpage->set_pagelayout('standard'); 658 $this->assertEquals('standard', $this->testpage->pagelayout); 659 // Initialise theme and output for the next tests. 660 $this->testpage->initialise_theme_and_output(); 661 // Check the generated $OUTPUT object is a core renderer. 662 $this->assertInstanceOf('core_renderer', $OUTPUT); 663 // Check we can get a core renderer if we explicitly request one (no component). 664 $this->assertInstanceOf('core_renderer', $this->testpage->get_renderer('core')); 665 // Check we get a CLI renderer if we request a maintenance renderer. The CLI target should take precedence. 666 $this->assertInstanceOf('core_renderer_cli', 667 $this->testpage->get_renderer('core', null, RENDERER_TARGET_MAINTENANCE)); 668 669 // Check we can get a coures renderer if we explicitly request one (valid component). 670 $this->assertInstanceOf('core_course_renderer', $this->testpage->get_renderer('core', 'course')); 671 672 // Check a properly invalid component. 673 try { 674 $this->testpage->get_renderer('core', 'monkeys'); 675 $this->fail('Request for renderer with invalid component didn\'t throw expected exception.'); 676 } catch (\coding_exception $exception) { 677 $this->assertEquals('monkeys', $exception->debuginfo); 678 } 679 680 $PAGE = $oldpage; 681 $OUTPUT = $oldoutput; 682 } 683 684 /** 685 * Tests getting a renderer with a maintenance layout. 686 * 687 * This layout has special hacks in place in order to deliver a "maintenance" renderer. 688 */ 689 public function test_get_renderer_maintenance() { 690 global $OUTPUT, $PAGE; 691 $oldoutput = $OUTPUT; 692 $oldpage = $PAGE; 693 $PAGE = $this->testpage; 694 695 $this->testpage->set_pagelayout('maintenance'); 696 $this->assertEquals('maintenance', $this->testpage->pagelayout); 697 // Initialise theme and output for the next tests. 698 $this->testpage->initialise_theme_and_output(); 699 // Check the generated $OUTPUT object is a core cli renderer. 700 // It shouldn't be maintenance because there the cli target should take greater precedence. 701 $this->assertInstanceOf('core_renderer_cli', $OUTPUT); 702 // Check we can get a core renderer if we explicitly request one (no component). 703 $this->assertInstanceOf('core_renderer', $this->testpage->get_renderer('core')); 704 // Check we get a CLI renderer if we request a maintenance renderer. The CLI target should take precedence. 705 $this->assertInstanceOf('core_renderer_cli', 706 $this->testpage->get_renderer('core', null, RENDERER_TARGET_MAINTENANCE)); 707 // Check we can get a coures renderer if we explicitly request one (valid component). 708 $this->assertInstanceOf('core_course_renderer', $this->testpage->get_renderer('core', 'course')); 709 710 try { 711 $this->testpage->get_renderer('core', 'monkeys'); 712 $this->fail('Request for renderer with invalid component didn\'t throw expected exception.'); 713 } catch (\coding_exception $exception) { 714 $this->assertEquals('monkeys', $exception->debuginfo); 715 } 716 717 $PAGE = $oldpage; 718 $OUTPUT = $oldoutput; 719 } 720 721 public function test_render_to_cli() { 722 global $OUTPUT; 723 724 $footer = $OUTPUT->footer(); 725 $this->assertEmpty($footer, 'cli output does not have a footer.'); 726 } 727 728 /** 729 * Validate the theme value depending on the user theme and cohorts. 730 * 731 * @dataProvider get_user_theme_provider 732 */ 733 public function test_cohort_get_user_theme($usertheme, $sitetheme, $cohortthemes, $expected) { 734 global $DB, $PAGE, $USER; 735 736 $this->resetAfterTest(); 737 738 // Enable cohort themes. 739 set_config('allowuserthemes', 1); 740 set_config('allowcohortthemes', 1); 741 742 $systemctx = \context_system::instance(); 743 744 set_config('theme', $sitetheme); 745 // Create user. 746 $user = $this->getDataGenerator()->create_user(array('theme' => $usertheme)); 747 748 // Create cohorts and add user as member. 749 $cohorts = array(); 750 foreach ($cohortthemes as $cohorttheme) { 751 $cohort = $this->getDataGenerator()->create_cohort(array('contextid' => $systemctx->id, 'name' => 'Cohort', 752 'idnumber' => '', 'description' => '', 'theme' => $cohorttheme)); 753 $cohorts[] = $cohort; 754 cohort_add_member($cohort->id, $user->id); 755 } 756 757 // Get the theme and compare to the expected. 758 $this->setUser($user); 759 760 // Initialise user theme. 761 $USER = get_complete_user_data('id', $user->id); 762 763 // Initialise site theme. 764 $PAGE->reset_theme_and_output(); 765 $PAGE->initialise_theme_and_output(); 766 $result = $PAGE->theme->name; 767 $this->assertEquals($expected, $result); 768 } 769 770 /** 771 * Some user cases for validating the expected theme depending on the cohorts, site and user values. 772 * 773 * The result is an array of: 774 * 'User case description' => [ 775 * 'usertheme' => '', // User theme. 776 * 'sitetheme' => '', // Site theme. 777 * 'cohorts' => [], // Cohort themes. 778 * 'expected' => '', // Expected value returned by cohort_get_user_cohort_theme. 779 * ] 780 * 781 * @return array 782 */ 783 public function get_user_theme_provider() { 784 return [ 785 'User not a member of any cohort' => [ 786 'usertheme' => '', 787 'sitetheme' => 'boost', 788 'cohorts' => [], 789 'expected' => 'boost', 790 ], 791 'User member of one cohort which has a theme set' => [ 792 'usertheme' => '', 793 'sitetheme' => 'boost', 794 'cohorts' => [ 795 'classic', 796 ], 797 'expected' => 'classic', 798 ], 799 'User member of one cohort which has a theme set, and one without a theme' => [ 800 'usertheme' => '', 801 'sitetheme' => 'boost', 802 'cohorts' => [ 803 'classic', 804 '', 805 ], 806 'expected' => 'classic', 807 ], 808 'User member of one cohort which has a theme set, and one with a different theme' => [ 809 'usertheme' => '', 810 'sitetheme' => 'boost', 811 'cohorts' => [ 812 'classic', 813 'someother', 814 ], 815 'expected' => 'boost', 816 ], 817 'User with a theme but not a member of any cohort' => [ 818 'usertheme' => 'classic', 819 'sitetheme' => 'boost', 820 'cohorts' => [], 821 'expected' => 'classic', 822 ], 823 'User with a theme and member of one cohort which has a theme set' => [ 824 'usertheme' => 'classic', 825 'sitetheme' => 'boost', 826 'cohorts' => [ 827 'boost', 828 ], 829 'expected' => 'classic', 830 ], 831 ]; 832 } 833 834 /** 835 * Tests user_can_edit_blocks() returns the expected response. 836 * @covers ::user_can_edit_blocks() 837 */ 838 public function test_user_can_edit_blocks() { 839 global $DB; 840 841 $systemcontext = \context_system::instance(); 842 $this->testpage->set_context($systemcontext); 843 844 $user = $this->getDataGenerator()->create_user(); 845 $role = $DB->get_record('role', ['shortname' => 'teacher']); 846 role_assign($role->id, $user->id, $systemcontext->id); 847 $this->setUser($user); 848 849 // Confirm expected response (false) when user does not have access to edit blocks. 850 $capability = $this->testpage->all_editing_caps()[0]; 851 assign_capability($capability, CAP_PROHIBIT, $role->id, $systemcontext, true); 852 $this->assertFalse($this->testpage->user_can_edit_blocks()); 853 854 // Give capability and confirm expected response (true) now user has access to edit blocks. 855 assign_capability($capability, CAP_ALLOW, $role->id, $systemcontext, true); 856 $this->assertTrue($this->testpage->user_can_edit_blocks()); 857 } 858 859 /** 860 * Tests that calling force_lock_all_blocks() will cause user_can_edit_blocks() to return false, regardless of capabilities. 861 * @covers ::force_lock_all_blocks() 862 */ 863 public function test_force_lock_all_blocks() { 864 $this->testpage->set_context(\context_system::instance()); 865 $this->setAdminUser(); 866 867 // Confirm admin user has access to edit blocks. 868 $this->assertTrue($this->testpage->user_can_edit_blocks()); 869 870 // Force lock and confirm user can no longer edit, despite having the capability. 871 $this->testpage->force_lock_all_blocks(); 872 $this->assertFalse($this->testpage->user_can_edit_blocks()); 873 } 874 } 875 876 /** 877 * Test-specific subclass to make some protected things public. 878 */ 879 class testable_moodle_page extends moodle_page { 880 public function initialise_default_pagetype($script = null) { 881 parent::initialise_default_pagetype($script); 882 } 883 public function url_to_class_name($url) { 884 return parent::url_to_class_name($url); 885 } 886 public function all_editing_caps() { 887 return parent::all_editing_caps(); 888 } 889 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body