Differences Between: [Versions 310 and 400] [Versions 311 and 400] [Versions 39 and 400] [Versions 400 and 401] [Versions 400 and 402] [Versions 400 and 403]
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 public function test_set_title() { 329 // Exercise SUT. 330 $this->testpage->set_title('a title'); 331 // Validated. 332 $this->assertSame('a title', $this->testpage->title); 333 } 334 335 public function test_default_pagelayout() { 336 // Exercise SUT and Validate. 337 $this->assertSame('base', $this->testpage->pagelayout); 338 } 339 340 public function test_set_pagelayout() { 341 // Exercise SUT. 342 $this->testpage->set_pagelayout('type'); 343 // Validated. 344 $this->assertSame('type', $this->testpage->pagelayout); 345 } 346 347 public function test_setting_course_sets_context() { 348 // Setup fixture. 349 $course = $this->getDataGenerator()->create_course(); 350 $context = \context_course::instance($course->id); 351 352 // Exercise SUT. 353 $this->testpage->set_course($course); 354 355 // Validated. 356 $this->assertSame($context, $this->testpage->context); 357 } 358 359 public function test_set_category_top_level() { 360 global $DB; 361 // Setup fixture. 362 $cat = $this->getDataGenerator()->create_category(); 363 $catdbrecord = $DB->get_record('course_categories', array('id' => $cat->id)); 364 // Exercise SUT. 365 $this->testpage->set_category_by_id($cat->id); 366 // Validated. 367 $this->assertEquals($catdbrecord, $this->testpage->category); 368 $this->assertSame(\context_coursecat::instance($cat->id), $this->testpage->context); 369 } 370 371 public function test_set_nested_categories() { 372 global $DB; 373 // Setup fixture. 374 $topcat = $this->getDataGenerator()->create_category(); 375 $topcatdbrecord = $DB->get_record('course_categories', array('id' => $topcat->id)); 376 $subcat = $this->getDataGenerator()->create_category(array('parent'=>$topcat->id)); 377 $subcatdbrecord = $DB->get_record('course_categories', array('id' => $subcat->id)); 378 // Exercise SUT. 379 $this->testpage->set_category_by_id($subcat->id); 380 // Validated. 381 $categories = $this->testpage->categories; 382 $this->assertCount(2, $categories); 383 $this->assertEquals($topcatdbrecord, array_pop($categories)); 384 $this->assertEquals($subcatdbrecord, array_pop($categories)); 385 } 386 387 public function test_cm_null_initially() { 388 // Validated. 389 $this->assertNull($this->testpage->cm); 390 } 391 392 public function test_set_cm() { 393 // Setup fixture. 394 $course = $this->getDataGenerator()->create_course(); 395 $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id)); 396 $cm = get_coursemodule_from_id('forum', $forum->cmid); 397 // Exercise SUT. 398 $this->testpage->set_cm($cm); 399 // Validated. 400 $this->assertEquals($cm->id, $this->testpage->cm->id); 401 } 402 403 public function test_cannot_set_activity_record_before_cm() { 404 // Setup fixture. 405 $course = $this->getDataGenerator()->create_course(); 406 $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id)); 407 $cm = get_coursemodule_from_id('forum', $forum->cmid); 408 // Exercise SUT. 409 $this->expectException(\coding_exception::class); 410 $this->testpage->set_activity_record($forum); 411 } 412 413 public function test_setting_cm_sets_context() { 414 // Setup fixture. 415 $course = $this->getDataGenerator()->create_course(); 416 $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id)); 417 $cm = get_coursemodule_from_id('forum', $forum->cmid); 418 // Exercise SUT. 419 $this->testpage->set_cm($cm); 420 // Validated. 421 $this->assertSame(\context_module::instance($cm->id), $this->testpage->context); 422 } 423 424 public function test_activity_record_loaded_if_not_set() { 425 // Setup fixture. 426 $course = $this->getDataGenerator()->create_course(); 427 $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id)); 428 $cm = get_coursemodule_from_id('forum', $forum->cmid); 429 // Exercise SUT. 430 $this->testpage->set_cm($cm); 431 // Validated. 432 unset($forum->cmid); 433 $this->assertEquals($forum, $this->testpage->activityrecord); 434 } 435 436 public function test_set_activity_record() { 437 // Setup fixture. 438 $course = $this->getDataGenerator()->create_course(); 439 $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id)); 440 $cm = get_coursemodule_from_id('forum', $forum->cmid); 441 $this->testpage->set_cm($cm); 442 // Exercise SUT. 443 $this->testpage->set_activity_record($forum); 444 // Validated. 445 unset($forum->cmid); 446 $this->assertEquals($forum, $this->testpage->activityrecord); 447 } 448 449 public function test_cannot_set_inconsistent_activity_record_course() { 450 // Setup fixture. 451 $course = $this->getDataGenerator()->create_course(); 452 $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id)); 453 $cm = get_coursemodule_from_id('forum', $forum->cmid); 454 $this->testpage->set_cm($cm); 455 // Exercise SUT. 456 $forum->course = 13; 457 $this->expectException(\coding_exception::class); 458 $this->testpage->set_activity_record($forum); 459 } 460 461 public function test_cannot_set_inconsistent_activity_record_instance() { 462 // Setup fixture. 463 $course = $this->getDataGenerator()->create_course(); 464 $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id)); 465 $cm = get_coursemodule_from_id('forum', $forum->cmid); 466 $this->testpage->set_cm($cm); 467 // Exercise SUT. 468 $forum->id = 13; 469 $this->expectException(\coding_exception::class); 470 $this->testpage->set_activity_record($forum); 471 } 472 473 public function test_setting_cm_sets_course() { 474 // Setup fixture. 475 $course = $this->getDataGenerator()->create_course(); 476 $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id)); 477 $cm = get_coursemodule_from_id('forum', $forum->cmid); 478 // Exercise SUT. 479 $this->testpage->set_cm($cm); 480 // Validated. 481 $this->assertEquals($course->id, $this->testpage->course->id); 482 } 483 484 public function test_set_cm_with_course_and_activity_no_db() { 485 // Setup fixture. 486 $course = $this->getDataGenerator()->create_course(); 487 $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id)); 488 $cm = get_coursemodule_from_id('forum', $forum->cmid); 489 // This only works without db if we already have modinfo cache 490 // Exercise SUT. 491 $this->testpage->set_cm($cm, $course, $forum); 492 // Validated. 493 $this->assertEquals($cm->id, $this->testpage->cm->id); 494 $this->assertEquals($course->id, $this->testpage->course->id); 495 unset($forum->cmid); 496 $this->assertEquals($forum, $this->testpage->activityrecord); 497 } 498 499 public function test_cannot_set_cm_with_inconsistent_course() { 500 // Setup fixture. 501 $course = $this->getDataGenerator()->create_course(); 502 $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id)); 503 $cm = get_coursemodule_from_id('forum', $forum->cmid); 504 // Exercise SUT. 505 $cm->course = 13; 506 $this->expectException(\coding_exception::class); 507 $this->testpage->set_cm($cm, $course); 508 } 509 510 public function test_get_activity_name() { 511 // Setup fixture. 512 $course = $this->getDataGenerator()->create_course(); 513 $forum = $this->getDataGenerator()->create_module('forum', array('course'=>$course->id)); 514 $cm = get_coursemodule_from_id('forum', $forum->cmid); 515 // Exercise SUT. 516 $this->testpage->set_cm($cm, $course, $forum); 517 // Validated. 518 $this->assertSame('forum', $this->testpage->activityname); 519 } 520 521 public function test_user_is_editing_on() { 522 // We are relying on the fact that unit tests are always run by admin, to 523 // ensure the user_allows_editing call returns true. 524 525 // Setup fixture. 526 global $USER; 527 528 $this->testpage->set_context(\context_system::instance()); 529 $this->setAdminUser(); 530 531 $USER->editing = true; 532 // Validated. 533 $this->assertTrue($this->testpage->user_is_editing()); 534 } 535 536 public function test_user_is_editing_off() { 537 // We are relying on the fact that unit tests are always run by admin, to 538 // ensure the user_allows_editing call returns true. 539 540 // Setup fixture. 541 global $USER; 542 543 $this->testpage->set_context(\context_system::instance()); 544 $this->setAdminUser(); 545 546 $USER->editing = false; 547 // Validated. 548 $this->assertFalse($this->testpage->user_is_editing()); 549 } 550 551 public function test_default_editing_capabilities() { 552 $this->testpage->set_context(\context_system::instance()); 553 $this->setAdminUser(); 554 555 // Validated. 556 $this->assertEquals(array('moodle/site:manageblocks'), $this->testpage->all_editing_caps()); 557 } 558 559 public function test_other_block_editing_cap() { 560 $this->testpage->set_context(\context_system::instance()); 561 $this->setAdminUser(); 562 563 // Exercise SUT. 564 $this->testpage->set_blocks_editing_capability('moodle/my:manageblocks'); 565 // Validated. 566 $this->assertEquals(array('moodle/my:manageblocks'), $this->testpage->all_editing_caps()); 567 } 568 569 public function test_other_editing_cap() { 570 $this->testpage->set_context(\context_system::instance()); 571 $this->setAdminUser(); 572 573 // Exercise SUT. 574 $this->testpage->set_other_editing_capability('moodle/course:manageactivities'); 575 // Validated. 576 $actualcaps = $this->testpage->all_editing_caps(); 577 $expectedcaps = array('moodle/course:manageactivities', 'moodle/site:manageblocks'); 578 $this->assertEquals(array_values($expectedcaps), array_values($actualcaps)); 579 } 580 581 public function test_other_editing_caps() { 582 $this->testpage->set_context(\context_system::instance()); 583 $this->setAdminUser(); 584 585 // Exercise SUT. 586 $this->testpage->set_other_editing_capability(array('moodle/course:manageactivities', 'moodle/site:other')); 587 // Validated. 588 $actualcaps = $this->testpage->all_editing_caps(); 589 $expectedcaps = array('moodle/course:manageactivities', 'moodle/site:other', 'moodle/site:manageblocks'); 590 $this->assertEquals(array_values($expectedcaps), array_values($actualcaps)); 591 } 592 593 /** 594 * Test getting a renderer. 595 */ 596 public function test_get_renderer() { 597 global $OUTPUT, $PAGE; 598 $oldoutput = $OUTPUT; 599 $oldpage = $PAGE; 600 $PAGE = $this->testpage; 601 602 $this->testpage->set_pagelayout('standard'); 603 $this->assertEquals('standard', $this->testpage->pagelayout); 604 // Initialise theme and output for the next tests. 605 $this->testpage->initialise_theme_and_output(); 606 // Check the generated $OUTPUT object is a core renderer. 607 $this->assertInstanceOf('core_renderer', $OUTPUT); 608 // Check we can get a core renderer if we explicitly request one (no component). 609 $this->assertInstanceOf('core_renderer', $this->testpage->get_renderer('core')); 610 // Check we get a CLI renderer if we request a maintenance renderer. The CLI target should take precedence. 611 $this->assertInstanceOf('core_renderer_cli', 612 $this->testpage->get_renderer('core', null, RENDERER_TARGET_MAINTENANCE)); 613 614 // Check we can get a coures renderer if we explicitly request one (valid component). 615 $this->assertInstanceOf('core_course_renderer', $this->testpage->get_renderer('core', 'course')); 616 617 // Check a properly invalid component. 618 try { 619 $this->testpage->get_renderer('core', 'monkeys'); 620 $this->fail('Request for renderer with invalid component didn\'t throw expected exception.'); 621 } catch (\coding_exception $exception) { 622 $this->assertEquals('monkeys', $exception->debuginfo); 623 } 624 625 $PAGE = $oldpage; 626 $OUTPUT = $oldoutput; 627 } 628 629 /** 630 * Tests getting a renderer with a maintenance layout. 631 * 632 * This layout has special hacks in place in order to deliver a "maintenance" renderer. 633 */ 634 public function test_get_renderer_maintenance() { 635 global $OUTPUT, $PAGE; 636 $oldoutput = $OUTPUT; 637 $oldpage = $PAGE; 638 $PAGE = $this->testpage; 639 640 $this->testpage->set_pagelayout('maintenance'); 641 $this->assertEquals('maintenance', $this->testpage->pagelayout); 642 // Initialise theme and output for the next tests. 643 $this->testpage->initialise_theme_and_output(); 644 // Check the generated $OUTPUT object is a core cli renderer. 645 // It shouldn't be maintenance because there the cli target should take greater precedence. 646 $this->assertInstanceOf('core_renderer_cli', $OUTPUT); 647 // Check we can get a core renderer if we explicitly request one (no component). 648 $this->assertInstanceOf('core_renderer', $this->testpage->get_renderer('core')); 649 // Check we get a CLI renderer if we request a maintenance renderer. The CLI target should take precedence. 650 $this->assertInstanceOf('core_renderer_cli', 651 $this->testpage->get_renderer('core', null, RENDERER_TARGET_MAINTENANCE)); 652 // Check we can get a coures renderer if we explicitly request one (valid component). 653 $this->assertInstanceOf('core_course_renderer', $this->testpage->get_renderer('core', 'course')); 654 655 try { 656 $this->testpage->get_renderer('core', 'monkeys'); 657 $this->fail('Request for renderer with invalid component didn\'t throw expected exception.'); 658 } catch (\coding_exception $exception) { 659 $this->assertEquals('monkeys', $exception->debuginfo); 660 } 661 662 $PAGE = $oldpage; 663 $OUTPUT = $oldoutput; 664 } 665 666 public function test_render_to_cli() { 667 global $OUTPUT; 668 669 $footer = $OUTPUT->footer(); 670 $this->assertEmpty($footer, 'cli output does not have a footer.'); 671 } 672 673 /** 674 * Validate the theme value depending on the user theme and cohorts. 675 * 676 * @dataProvider get_user_theme_provider 677 */ 678 public function test_cohort_get_user_theme($usertheme, $sitetheme, $cohortthemes, $expected) { 679 global $DB, $PAGE, $USER; 680 681 $this->resetAfterTest(); 682 683 // Enable cohort themes. 684 set_config('allowuserthemes', 1); 685 set_config('allowcohortthemes', 1); 686 687 $systemctx = \context_system::instance(); 688 689 set_config('theme', $sitetheme); 690 // Create user. 691 $user = $this->getDataGenerator()->create_user(array('theme' => $usertheme)); 692 693 // Create cohorts and add user as member. 694 $cohorts = array(); 695 foreach ($cohortthemes as $cohorttheme) { 696 $cohort = $this->getDataGenerator()->create_cohort(array('contextid' => $systemctx->id, 'name' => 'Cohort', 697 'idnumber' => '', 'description' => '', 'theme' => $cohorttheme)); 698 $cohorts[] = $cohort; 699 cohort_add_member($cohort->id, $user->id); 700 } 701 702 // Get the theme and compare to the expected. 703 $this->setUser($user); 704 705 // Initialise user theme. 706 $USER = get_complete_user_data('id', $user->id); 707 708 // Initialise site theme. 709 $PAGE->reset_theme_and_output(); 710 $PAGE->initialise_theme_and_output(); 711 $result = $PAGE->theme->name; 712 $this->assertEquals($expected, $result); 713 } 714 715 /** 716 * Some user cases for validating the expected theme depending on the cohorts, site and user values. 717 * 718 * The result is an array of: 719 * 'User case description' => [ 720 * 'usertheme' => '', // User theme. 721 * 'sitetheme' => '', // Site theme. 722 * 'cohorts' => [], // Cohort themes. 723 * 'expected' => '', // Expected value returned by cohort_get_user_cohort_theme. 724 * ] 725 * 726 * @return array 727 */ 728 public function get_user_theme_provider() { 729 return [ 730 'User not a member of any cohort' => [ 731 'usertheme' => '', 732 'sitetheme' => 'boost', 733 'cohorts' => [], 734 'expected' => 'boost', 735 ], 736 'User member of one cohort which has a theme set' => [ 737 'usertheme' => '', 738 'sitetheme' => 'boost', 739 'cohorts' => [ 740 'classic', 741 ], 742 'expected' => 'classic', 743 ], 744 'User member of one cohort which has a theme set, and one without a theme' => [ 745 'usertheme' => '', 746 'sitetheme' => 'boost', 747 'cohorts' => [ 748 'classic', 749 '', 750 ], 751 'expected' => 'classic', 752 ], 753 'User member of one cohort which has a theme set, and one with a different theme' => [ 754 'usertheme' => '', 755 'sitetheme' => 'boost', 756 'cohorts' => [ 757 'classic', 758 'someother', 759 ], 760 'expected' => 'boost', 761 ], 762 'User with a theme but not a member of any cohort' => [ 763 'usertheme' => 'classic', 764 'sitetheme' => 'boost', 765 'cohorts' => [], 766 'expected' => 'classic', 767 ], 768 'User with a theme and member of one cohort which has a theme set' => [ 769 'usertheme' => 'classic', 770 'sitetheme' => 'boost', 771 'cohorts' => [ 772 'boost', 773 ], 774 'expected' => 'classic', 775 ], 776 ]; 777 } 778 779 /** 780 * Tests user_can_edit_blocks() returns the expected response. 781 * @covers ::user_can_edit_blocks() 782 */ 783 public function test_user_can_edit_blocks() { 784 global $DB; 785 786 $systemcontext = \context_system::instance(); 787 $this->testpage->set_context($systemcontext); 788 789 $user = $this->getDataGenerator()->create_user(); 790 $role = $DB->get_record('role', ['shortname' => 'teacher']); 791 role_assign($role->id, $user->id, $systemcontext->id); 792 $this->setUser($user); 793 794 // Confirm expected response (false) when user does not have access to edit blocks. 795 $capability = $this->testpage->all_editing_caps()[0]; 796 assign_capability($capability, CAP_PROHIBIT, $role->id, $systemcontext, true); 797 $this->assertFalse($this->testpage->user_can_edit_blocks()); 798 799 // Give capability and confirm expected response (true) now user has access to edit blocks. 800 assign_capability($capability, CAP_ALLOW, $role->id, $systemcontext, true); 801 $this->assertTrue($this->testpage->user_can_edit_blocks()); 802 } 803 804 /** 805 * Tests that calling force_lock_all_blocks() will cause user_can_edit_blocks() to return false, regardless of capabilities. 806 * @covers ::force_lock_all_blocks() 807 */ 808 public function test_force_lock_all_blocks() { 809 $this->testpage->set_context(\context_system::instance()); 810 $this->setAdminUser(); 811 812 // Confirm admin user has access to edit blocks. 813 $this->assertTrue($this->testpage->user_can_edit_blocks()); 814 815 // Force lock and confirm user can no longer edit, despite having the capability. 816 $this->testpage->force_lock_all_blocks(); 817 $this->assertFalse($this->testpage->user_can_edit_blocks()); 818 } 819 } 820 821 /** 822 * Test-specific subclass to make some protected things public. 823 */ 824 class testable_moodle_page extends moodle_page { 825 public function initialise_default_pagetype($script = null) { 826 parent::initialise_default_pagetype($script); 827 } 828 public function url_to_class_name($url) { 829 return parent::url_to_class_name($url); 830 } 831 public function all_editing_caps() { 832 return parent::all_editing_caps(); 833 } 834 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body