Differences Between: [Versions 310 and 402] [Versions 311 and 402] [Versions 39 and 402] [Versions 400 and 402] [Versions 401 and 402]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 namespace core; 18 19 defined('MOODLE_INTERNAL') || die(); 20 21 global $CFG; 22 require_once($CFG->libdir . '/outputrequirementslib.php'); 23 24 25 /** 26 * Unit tests for lib/outputrequirementslibphp. 27 * 28 * @package core 29 * @category test 30 * @copyright 2012 Petr Škoda 31 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 32 */ 33 class outputrequirementslib_test extends \advanced_testcase { 34 public function test_string_for_js() { 35 $this->resetAfterTest(); 36 37 $page = new \moodle_page(); 38 $page->requires->string_for_js('course', 'moodle', 1); 39 $page->requires->string_for_js('course', 'moodle', 1); 40 $this->expectException('coding_exception'); 41 $page->requires->string_for_js('course', 'moodle', 2); 42 43 // Note: we can not switch languages in phpunit yet, 44 // it would be nice to test that the strings are actually fetched in the footer. 45 } 46 47 public function test_one_time_output_normal_case() { 48 $page = new \moodle_page(); 49 $this->assertTrue($page->requires->should_create_one_time_item_now('test_item')); 50 $this->assertFalse($page->requires->should_create_one_time_item_now('test_item')); 51 } 52 53 public function test_one_time_output_repeat_output_throws() { 54 $page = new \moodle_page(); 55 $page->requires->set_one_time_item_created('test_item'); 56 $this->expectException('coding_exception'); 57 $page->requires->set_one_time_item_created('test_item'); 58 } 59 60 public function test_one_time_output_different_pages_independent() { 61 $firstpage = new \moodle_page(); 62 $secondpage = new \moodle_page(); 63 $this->assertTrue($firstpage->requires->should_create_one_time_item_now('test_item')); 64 $this->assertTrue($secondpage->requires->should_create_one_time_item_now('test_item')); 65 } 66 67 /** 68 * Test for the jquery_plugin method. 69 * 70 * Test to make sure that backslashes are not generated with either slasharguments set to on or off. 71 */ 72 public function test_jquery_plugin() { 73 global $CFG, $PAGE; 74 75 $this->resetAfterTest(); 76 77 // With slasharguments on. 78 $CFG->slasharguments = 1; 79 80 $page = new \moodle_page(); 81 $requirements = $page->requires; 82 // Assert successful method call. 83 $this->assertTrue($requirements->jquery_plugin('jquery')); 84 $this->assertTrue($requirements->jquery_plugin('ui')); 85 86 // Get the code containing the required jquery plugins. 87 $renderer = $PAGE->get_renderer('core', null, RENDERER_TARGET_MAINTENANCE); 88 $requirecode = $requirements->get_top_of_body_code($renderer); 89 // Make sure that the generated code does not contain backslashes. 90 $this->assertFalse(strpos($requirecode, '\\'), "Output contains backslashes: " . $requirecode); 91 92 // With slasharguments off. 93 $CFG->slasharguments = 0; 94 95 $page = new \moodle_page(); 96 $requirements = $page->requires; 97 // Assert successful method call. 98 $this->assertTrue($requirements->jquery_plugin('jquery')); 99 $this->assertTrue($requirements->jquery_plugin('ui')); 100 101 // Get the code containing the required jquery plugins. 102 $requirecode = $requirements->get_top_of_body_code($renderer); 103 // Make sure that the generated code does not contain backslashes. 104 $this->assertFalse(strpos($requirecode, '\\'), "Output contains backslashes: " . $requirecode); 105 } 106 107 /** 108 * Test AMD modules loading. 109 */ 110 public function test_js_call_amd() { 111 112 $page = new \moodle_page(); 113 114 // Load an AMD module without a function call. 115 $page->requires->js_call_amd('theme_foobar/lightbox'); 116 117 // Load an AMD module and call its function without parameters. 118 $page->requires->js_call_amd('theme_foobar/demo_one', 'init'); 119 120 // Load an AMD module and call its function with some parameters. 121 $page->requires->js_call_amd('theme_foobar/demo_two', 'init', [ 122 'foo', 123 'keyWillIgnored' => 'baz', 124 [42, 'xyz'], 125 ]); 126 127 $html = $page->requires->get_end_code(); 128 129 $modname = 'theme_foobar/lightbox'; 130 $this->assertStringContainsString("M.util.js_pending('{$modname}'); require(['{$modname}'], function(amd) {M.util.js_complete('{$modname}');});", $html); 131 132 $modname = 'theme_foobar/demo_one'; 133 $this->assertStringContainsString("M.util.js_pending('{$modname}'); require(['{$modname}'], function(amd) {amd.init(); M.util.js_complete('{$modname}');});", $html); 134 135 $modname = 'theme_foobar/demo_two'; 136 $this->assertStringContainsString("M.util.js_pending('{$modname}'); require(['{$modname}'], function(amd) {amd.init(\"foo\", \"baz\", [42,\"xyz\"]); M.util.js_complete('{$modname}');});", $html); 137 } 138 139 /** 140 * Test the actual URL through which a JavaScript file is served. 141 * 142 * @param \moodle_url $moodleurl The <u>moodle_url</u> instance pointing to a web resource. 143 * @param int $cfgslashargs The value to force $CFG->slasharguments. 144 * @param string $expected The expected output URL. 145 * @throws ReflectionException if the class does not exist. 146 * @see \page_requirements_manager::js_fix_url() 147 * @see \moodle_url 148 * @covers \page_requirements_manager::js_fix_url 149 * @dataProvider js_fix_url_moodle_url_provider 150 */ 151 public function test_js_fix_url_moodle_url(\moodle_url $moodleurl, int $cfgslashargs, string $expected) { 152 global $CFG; 153 $defaultslashargs = $CFG->slasharguments; 154 155 $CFG->slasharguments = $cfgslashargs; 156 $rc = new \ReflectionClass(\page_requirements_manager::class); 157 $rcm = $rc->getMethod('js_fix_url'); 158 $rcm->setAccessible(true); 159 $requires = new \page_requirements_manager(); 160 $actualmoodleurl = $rcm->invokeArgs($requires, [$moodleurl]); 161 $this->assertEquals($expected, $actualmoodleurl->out(false)); 162 163 $CFG->slasharguments = $defaultslashargs; 164 } 165 166 /** 167 * Data provider for JavaScript proper Handler using a <u>\moodle_url</url>. 168 * 169 * @return array 170 * @see \page_requirements_manager::js_fix_url() 171 * @see \moodle_url 172 */ 173 public function js_fix_url_moodle_url_provider() { 174 global $CFG; 175 $wwwroot = rtrim($CFG->wwwroot, '/'); 176 $libdir = rtrim($CFG->libdir, '/'); 177 $admin = "/{$CFG->admin}/"; // Deprecated, just for coverage purposes. 178 179 // Note: $CFG->slasharguments is enabled by default; it will be a forced setting one day (MDL-62640). 180 return [ 181 'Environment XML file' => [ 182 new \moodle_url('/admin/environment.xml'), 183 0, 184 $wwwroot . $admin . 'environment.xml' 185 ], 186 'Google Maps CDN (HTTPS)' => [ 187 new \moodle_url('https://maps.googleapis.com/maps/api/js', ['key' => 'googlemapkey3', 'sensor' => 'false']), 188 1, 189 'https://maps.googleapis.com/maps/api/js?key=googlemapkey3&sensor=false' 190 ], 191 'Google Maps CDN (HTTP)' => [ 192 new \moodle_url('http://maps.googleapis.com/maps/api/js', ['key' => 'googlemapkey3', 'sensor' => 'false']), 193 0, 194 'http://maps.googleapis.com/maps/api/js?key=googlemapkey3&sensor=false' 195 ], 196 'H5P JS internal resource (slasharguments on)' => [ 197 new \moodle_url('/h5p/js/embed.js'), 198 1, 199 $wwwroot . '/lib/javascript.php/1/h5p/js/embed.js' 200 ], 201 'H5P JS internal resource (slasharguments off)' => [ 202 new \moodle_url('/h5p/js/embed.js'), 203 0, 204 $wwwroot . '/lib/javascript.php?rev=1&jsfile=%2Fh5p%2Fjs%2Fembed.js' 205 ], 206 'A custom Moodle CSS Handler' => [ 207 new \moodle_url('/mod/data/css.php?d=1234567890'), 208 1, 209 $wwwroot . '/mod/data/css.php?d=1234567890' 210 ], 211 'A custom Moodle JS Handler (slasharguments on)' => [ 212 new \moodle_url('/mod/data/js.php?d=1234567890'), 213 1, 214 $wwwroot . '/mod/data/js.php?d=1234567890' 215 ], 216 'A custom Moodle JS Handler (slasharguments off)' => [ 217 new \moodle_url('/mod/data/js.php?d=1234567890'), 218 0, 219 $wwwroot . '/mod/data/js.php?d=1234567890' 220 ], 221 ]; 222 } 223 224 /** 225 * Test the actual url through which a JavaScript file is served. 226 * 227 * @param string $url The URL pointing to a web resource. 228 * @param int $cfgslashargs The value to force $CFG->slasharguments. 229 * @param string $expected The expected output URL. 230 * @throws ReflectionException if the class does not exist. 231 * @see \page_requirements_manager::js_fix_url() 232 * @covers \page_requirements_manager::js_fix_url 233 * @dataProvider js_fix_url_plain_string_provider 234 */ 235 public function test_js_fix_url_plain_string(string $url, int $cfgslashargs, string $expected) { 236 global $CFG; 237 $defaultslashargs = $CFG->slasharguments; 238 239 $CFG->slasharguments = $cfgslashargs; 240 $rc = new \ReflectionClass(\page_requirements_manager::class); 241 $rcm = $rc->getMethod('js_fix_url'); 242 $rcm->setAccessible(true); 243 $requires = new \page_requirements_manager(); 244 $actualmoodleurl = $rcm->invokeArgs($requires, [$url]); 245 $this->assertEquals($expected, $actualmoodleurl->out(false)); 246 247 $CFG->slasharguments = $defaultslashargs; 248 } 249 250 /** 251 * Data provider for JavaScript proper Handler using a plain relative string. 252 * 253 * @return array 254 * @see \page_requirements_manager::js_fix_url() 255 */ 256 public function js_fix_url_plain_string_provider() { 257 global $CFG; 258 $wwwroot = rtrim($CFG->wwwroot, '/'); 259 $admin = "/{$CFG->admin}/"; // Deprecated, just for coverage purposes. 260 261 // Note: $CFG->slasharguments is enabled by default; it will be a forced setting one day (MDL-62640). 262 return [ 263 'Environment XML file' => [ 264 '/admin/environment.xml', 265 0, 266 $wwwroot . $admin . 'environment.xml' 267 ], 268 'Course Format JS (slasharguments on)' => [ 269 '/course/format/topics/format.js', 270 1, 271 $wwwroot . '/lib/javascript.php/1/course/format/topics/format.js' 272 ], 273 'Course Format JS (slasharguments off)' => [ 274 '/course/format/topics/format.js', 275 0, 276 $wwwroot . '/lib/javascript.php?rev=1&jsfile=%2Fcourse%2Fformat%2Ftopics%2Fformat.js' 277 ], 278 'Data JS' => [ 279 '/mod/data/data.js', 280 1, 281 $wwwroot . '/lib/javascript.php/1/mod/data/data.js' 282 ], 283 'SCORM Request JS' => [ 284 '/mod/scorm/request.js', 285 1, 286 $wwwroot . '/lib/javascript.php/1/mod/scorm/request.js' 287 ], 288 'Wiki Editors Buttons JS' => [ 289 '/mod/wiki/editors/wiki/buttons.js', 290 1, 291 $wwwroot . '/lib/javascript.php/1/mod/wiki/editors/wiki/buttons.js' 292 ], 293 'A non-JS internal resource' => [ 294 '/theme/boost/pix/favicon.ico', 295 0, 296 $wwwroot . '/theme/boost/pix/favicon.ico' 297 ], 298 'A custom Moodle CSS Handler' => [ 299 '/mod/data/css.php?d=1234567890', 300 1, 301 $wwwroot . '/mod/data/css.php?d=1234567890' 302 ], 303 'A custom Moodle JS Handler (slasharguments on)' => [ 304 '/mod/data/js.php?d=1234567890', 305 1, 306 $wwwroot . '/mod/data/js.php?d=1234567890' 307 ], 308 'A custom Moodle JS Handler (slasharguments off)' => [ 309 '/mod/data/js.php?d=1234567890', 310 0, 311 $wwwroot . '/mod/data/js.php?d=1234567890' 312 ], 313 ]; 314 } 315 316 /** 317 * Test the coding exceptions when trying to get the actual URL through which a JavaScript file is served. 318 * 319 * @param moodle_url|string|null $url The URL pointing to a web resource. 320 * @param string $exmessage The expected output URL. 321 * @throws ReflectionException if the class does not exist. 322 * @see \page_requirements_manager::js_fix_url() 323 * @covers \page_requirements_manager::js_fix_url 324 * @dataProvider js_fix_url_coding_exception_provider 325 */ 326 public function test_js_fix_url_coding_exception($url, string $exmessage) { 327 $rc = new \ReflectionClass(\page_requirements_manager::class); 328 $rcm = $rc->getMethod('js_fix_url'); 329 $rcm->setAccessible(true); 330 $requires = new \page_requirements_manager(); 331 $this->expectException(\coding_exception::class); 332 $this->expectExceptionMessage($exmessage); 333 $actualmoodleurl = $rcm->invokeArgs($requires, [$url]); 334 } 335 336 /** 337 * Data provider for throwing coding exceptions in <u>\page_requirements_manager::js_fix_url()</u>. 338 * 339 * @return array 340 * @see \page_requirements_manager::js_fix_url() 341 */ 342 public function js_fix_url_coding_exception_provider() { 343 global $CFG; 344 $wwwroot = rtrim($CFG->wwwroot, '/'); 345 346 return [ 347 'Provide a null argument' => [ 348 null, 349 'Coding error detected, it must be fixed by a programmer: ' 350 . 'Invalid JS url, it has to be shortened url starting with / or moodle_url instance.' 351 ], 352 'Provide an internal absolute URL' => [ 353 $wwwroot . '/lib/javascript.php/1/h5p/js/embed.js', 354 'Coding error detected, it must be fixed by a programmer: ' 355 . 'Invalid JS url, it has to be shortened url starting with / or moodle_url instance. ' 356 . '(' . $wwwroot . '/lib/javascript.php/1/h5p/js/embed.js)' 357 ], 358 'Provide an external absolute URL' => [ 359 'https://maps.googleapis.com/maps/api/js?key=googlemapkey3&sensor=false', 360 'Coding error detected, it must be fixed by a programmer: ' 361 . 'Invalid JS url, it has to be shortened url starting with / or moodle_url instance. ' 362 . '(https://maps.googleapis.com/maps/api/js?key=googlemapkey3&sensor=false)' 363 ], 364 'A non-JS internal resource using an absolute URL' => [ 365 $wwwroot . '/theme/boost/pix/favicon.ico', 366 'Coding error detected, it must be fixed by a programmer: ' 367 . 'Invalid JS url, it has to be shortened url starting with / or moodle_url instance. (' 368 . $wwwroot . '/theme/boost/pix/favicon.ico)' 369 ], 370 'A non-existant internal resource using an absolute URL' => [ 371 $wwwroot . '/path/to/file.ext', 372 'Coding error detected, it must be fixed by a programmer: ' 373 . 'Invalid JS url, it has to be shortened url starting with / or moodle_url instance. (' 374 . $wwwroot . '/path/to/file.ext)' 375 ], 376 'A non-existant internal resource. WARN the developer!' => [ 377 '/path/to/file1.ext', 378 'Coding error detected, it must be fixed by a programmer: ' 379 . 'Attempt to require a JavaScript file that does not exist. (/path/to/file1.ext)' 380 ], 381 'A non-existant internal resource using moodle_url. WARN the developer!' => [ 382 new \moodle_url('/path/to/file2.ext'), 383 'Coding error detected, it must be fixed by a programmer: ' 384 . 'Attempt to require a JavaScript file that does not exist. (/path/to/file2.ext)' 385 ], 386 ]; 387 } 388 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body