1 <?php 2 // This file is part of Moodle - https://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 <https://www.gnu.org/licenses/>. 16 17 namespace core\hook\navigation; 18 19 /** 20 * Test hook for primary navigation. 21 * 22 * @coversDefaultClass \core\hook\navigation\primary_extend 23 * 24 * @package core 25 * @author Petr Skoda 26 * @copyright 2023 Open LMS 27 * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 28 */ 29 class primary_extend_test extends \advanced_testcase { 30 /** 31 * Test stoppable_trait. 32 * @covers ::stop_propagation 33 */ 34 public function test_stop_propagation() { 35 global $PAGE; 36 $this->resetAfterTest(); 37 38 $PAGE = new \moodle_page(); 39 $PAGE->set_url('/'); 40 $primarynav = new \core\navigation\views\primary($PAGE); 41 42 $hook = new primary_extend($primarynav); 43 $this->assertInstanceOf('Psr\EventDispatcher\StoppableEventInterface', $hook); 44 $this->assertFalse($hook->isPropagationStopped()); 45 46 $hook->stop_propagation(); 47 $this->assertTrue($hook->isPropagationStopped()); 48 } 49 50 /** 51 * Test hook is triggered when initialising primary navigation menu. 52 * @covers \core\navigation\views\primary::initialise 53 */ 54 public function test_trigggering() { 55 global $PAGE; 56 $this->resetAfterTest(); 57 58 $PAGE = new \moodle_page(); 59 $PAGE->set_url('/'); 60 61 $count = 0; 62 $receivedhook = null; 63 $testcallback = function(primary_extend $hook) use (&$receivedhook, &$count): void { 64 $count++; 65 $receivedhook = $hook; 66 }; 67 $this->redirectHook(primary_extend::class, $testcallback); 68 69 $primarynav = new \core\navigation\views\primary($PAGE); 70 $this->assertSame(0, $count); 71 $this->assertNull($receivedhook); 72 73 $primarynav->initialise(); 74 $this->assertSame(1, $count); 75 $this->assertInstanceOf(primary_extend::class, $receivedhook); 76 } 77 78 /** 79 * Verify that nothing except this hook modifies the primary menu. 80 * @covers \core\navigation\views\primary::initialise 81 */ 82 public function test_unsupported_hacks() { 83 global $PAGE; 84 $this->resetAfterTest(); 85 86 $PAGE = new \moodle_page(); 87 $PAGE->set_url('/'); 88 89 $testcallback = function(primary_extend $hook): void { 90 // Nothing to do, propagation is stopped by hook redirection. 91 }; 92 $this->redirectHook(primary_extend::class, $testcallback); 93 94 $primarynav = new \core\navigation\views\primary($PAGE); 95 $primarynav->initialise(); 96 $this->assertSame(['home'], $primarynav->get_children_key_list(), 97 'Unsupported primary menu modification detected, use new primary_extend hook instead.'); 98 99 $this->setAdminUser(); 100 $primarynav = new \core\navigation\views\primary($PAGE); 101 $primarynav->initialise(); 102 $this->assertSame(['home', 'myhome', 'mycourses'], $primarynav->get_children_key_list(), 103 'Unsupported primary menu modification detected, use new primary_extend hook instead.'); 104 } 105 106 /** 107 * Test adding of primary menu items via hook. 108 * @covers \core\navigation\views\primary::initialise 109 */ 110 public function test_primary_menu_extending() { 111 global $PAGE; 112 $this->resetAfterTest(); 113 114 $PAGE = new \moodle_page(); 115 $PAGE->set_url('/'); 116 117 $testcallback = function(primary_extend $hook): void { 118 $primaryview = $hook->get_primaryview(); 119 $primaryview->add('Pokus', null); 120 }; 121 $this->redirectHook(primary_extend::class, $testcallback); 122 123 $primarynav = new \core\navigation\views\primary($PAGE); 124 $primarynav->initialise(); 125 $keys = $primarynav->get_children_key_list(); 126 $this->assertCount(2, $keys); 127 $firstkey = array_shift($keys); 128 $this->assertSame('home', $firstkey); 129 $secondkey = array_shift($keys); 130 /** @var \navigation_node $pokus */ 131 $pokus = $primarynav->get($secondkey); 132 $this->assertInstanceOf(\navigation_node::class, $pokus); 133 $this->assertSame('Pokus', $pokus->text); 134 } 135 136 /** 137 * Test replacing of the whole primary menu. 138 * @covers \core\navigation\views\primary::initialise 139 */ 140 public function test_primary_menu_replacing() { 141 global $PAGE; 142 $this->resetAfterTest(); 143 144 $PAGE = new \moodle_page(); 145 $PAGE->set_url('/'); 146 147 $testcallback = function(primary_extend $hook): void { 148 $primaryview = $hook->get_primaryview(); 149 $keys = $primaryview->get_children_key_list(); 150 foreach ($keys as $key) { 151 $item = $primaryview->get($key); 152 $item->remove(); 153 } 154 $primaryview->add('Pokus', null); 155 // Technically we do not need to stop because observers are overridden, 156 // but this can be used as an example for plugin that wants to stop 157 // adding of primary menu items from plugins. 158 $hook->stop_propagation(); 159 }; 160 $this->redirectHook(primary_extend::class, $testcallback); 161 162 $primarynav = new \core\navigation\views\primary($PAGE); 163 $primarynav->initialise(); 164 $keys = $primarynav->get_children_key_list(); 165 $this->assertCount(1, $keys); 166 $firstkey = array_shift($keys); 167 /** @var \navigation_node $pokus */ 168 $pokus = $primarynav->get($firstkey); 169 $this->assertInstanceOf(\navigation_node::class, $pokus); 170 $this->assertSame('Pokus', $pokus->text); 171 } 172 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body