[ Index ] |
PHP Cross Reference of moodle-2.8 |
[Summary view] [Print] [Text view]
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 * Test classes for handling embedded media (audio/video). 19 * 20 * @package core_media 21 * @category phpunit 22 * @copyright 2012 The Open University 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 defined('MOODLE_INTERNAL') || die(); 27 28 global $CFG; 29 require_once($CFG->libdir . '/medialib.php'); 30 31 /** 32 * Test script for media embedding. 33 */ 34 class core_medialib_testcase extends advanced_testcase { 35 36 /** @var array Files covered by test */ 37 public static $includecoverage = array('lib/medialib.php', 'lib/outputrenderers.php'); 38 39 /** 40 * Pre-test setup. Preserves $CFG. 41 */ 42 public function setUp() { 43 global $CFG; 44 parent::setUp(); 45 46 // Reset $CFG and $SERVER. 47 $this->resetAfterTest(); 48 49 // Consistent initial setup: all players disabled. 50 $CFG->core_media_enable_html5video = false; 51 $CFG->core_media_enable_html5audio = false; 52 $CFG->core_media_enable_mp3 = false; 53 $CFG->core_media_enable_flv = false; 54 $CFG->core_media_enable_wmp = false; 55 $CFG->core_media_enable_qt = false; 56 $CFG->core_media_enable_rm = false; 57 $CFG->core_media_enable_youtube = false; 58 $CFG->core_media_enable_vimeo = false; 59 $CFG->core_media_enable_swf = false; 60 61 $_SERVER = array('HTTP_USER_AGENT' => ''); 62 $this->pretend_to_be_safari(); 63 } 64 65 /** 66 * Sets user agent to Safari. 67 */ 68 private function pretend_to_be_safari() { 69 // Pretend to be using Safari browser (must support mp4 for tests to work). 70 core_useragent::instance(true, 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; de-at) ' . 71 'AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1'); 72 } 73 74 /** 75 * Sets user agent to Firefox. 76 */ 77 private function pretend_to_be_firefox() { 78 // Pretend to be using Firefox browser (must support ogg for tests to work). 79 core_useragent::instance(true, 'Mozilla/5.0 (Windows NT 6.1; rv:8.0) Gecko/20100101 Firefox/8.0'); 80 } 81 82 /** 83 * Test for the core_media_player is_enabled. 84 */ 85 public function test_is_enabled() { 86 global $CFG; 87 88 // Test enabled: unset, 0, 1. 89 $test = new core_media_player_test; 90 $this->assertFalse($test->is_enabled()); 91 $CFG->core_media_enable_test = 0; 92 $this->assertFalse($test->is_enabled()); 93 $CFG->core_media_enable_test = 1; 94 $this->assertTrue($test->is_enabled()); 95 } 96 97 /** 98 * Test for core_media::get_filename. 99 */ 100 public function test_get_filename() { 101 $this->assertSame('frog.mp4', core_media::get_filename(new moodle_url( 102 '/pluginfile.php/312/mod_page/content/7/frog.mp4'))); 103 // This should work even though slasharguments is true, because we want 104 // it to support 'legacy' links if somebody toggles the option later. 105 $this->assertSame('frog.mp4', core_media::get_filename(new moodle_url( 106 '/pluginfile.php?file=/312/mod_page/content/7/frog.mp4'))); 107 } 108 109 /** 110 * Test for core_media::get_extension. 111 */ 112 public function test_get_extension() { 113 $this->assertSame('mp4', core_media::get_extension(new moodle_url( 114 '/pluginfile.php/312/mod_page/content/7/frog.mp4'))); 115 $this->assertSame('', core_media::get_extension(new moodle_url( 116 '/pluginfile.php/312/mod_page/content/7/frog'))); 117 $this->assertSame('mp4', core_media::get_extension(new moodle_url( 118 '/pluginfile.php?file=/312/mod_page/content/7/frog.mp4'))); 119 $this->assertSame('', core_media::get_extension(new moodle_url( 120 '/pluginfile.php?file=/312/mod_page/content/7/frog'))); 121 } 122 123 /** 124 * Test for the core_media_player list_supported_urls. 125 */ 126 public function test_list_supported_urls() { 127 global $CFG; 128 $test = new core_media_player_test; 129 130 // Some example URLs. 131 $supported1 = new moodle_url('http://example.org/1.test'); 132 $supported2 = new moodle_url('http://example.org/2.TST'); 133 $unsupported = new moodle_url('http://example.org/2.jpg'); 134 135 // No URLs => none. 136 $result = $test->list_supported_urls(array()); 137 $this->assertEquals(array(), $result); 138 139 // One supported URL => same. 140 $result = $test->list_supported_urls(array($supported1)); 141 $this->assertEquals(array($supported1), $result); 142 143 // Two supported URLS => same. 144 $result = $test->list_supported_urls(array($supported1, $supported2)); 145 $this->assertEquals(array($supported1, $supported2), $result); 146 147 // One unsupported => none. 148 $result = $test->list_supported_urls(array($unsupported)); 149 $this->assertEquals(array(), $result); 150 151 // Two supported and one unsupported => same. 152 $result = $test->list_supported_urls(array($supported2, $unsupported, $supported1)); 153 $this->assertEquals(array($supported2, $supported1), $result); 154 } 155 156 /** 157 * Test for core_media_renderer get_players 158 */ 159 public function test_get_players() { 160 global $CFG, $PAGE; 161 162 // All players are initially disabled (except link, which you can't). 163 $renderer = new core_media_renderer_test($PAGE, ''); 164 $this->assertSame('link', $renderer->get_players_test()); 165 166 // A couple enabled, check the order. 167 $CFG->core_media_enable_html5audio = true; 168 $CFG->core_media_enable_mp3 = true; 169 $renderer = new core_media_renderer_test($PAGE, ''); 170 $this->assertSame('mp3, html5audio, link', $renderer->get_players_test()); 171 } 172 173 /** 174 * Test for core_media_renderer can_embed_url 175 */ 176 public function test_can_embed_url() { 177 global $CFG, $PAGE; 178 179 // All players are initially disabled, so mp4 cannot be rendered. 180 $url = new moodle_url('http://example.org/test.mp4'); 181 $renderer = new core_media_renderer_test($PAGE, ''); 182 $this->assertFalse($renderer->can_embed_url($url)); 183 184 // Enable QT player. 185 $CFG->core_media_enable_qt = true; 186 $renderer = new core_media_renderer_test($PAGE, ''); 187 $this->assertTrue($renderer->can_embed_url($url)); 188 189 // QT + html5. 190 $CFG->core_media_enable_html5video = true; 191 $renderer = new core_media_renderer_test($PAGE, ''); 192 $this->assertTrue($renderer->can_embed_url($url)); 193 194 // Only html5. 195 $CFG->core_media_enable_qt = false; 196 $renderer = new core_media_renderer_test($PAGE, ''); 197 $this->assertTrue($renderer->can_embed_url($url)); 198 199 // Only WMP. 200 $CFG->core_media_enable_html5video = false; 201 $CFG->core_media_enable_wmp = true; 202 $renderer = new core_media_renderer_test($PAGE, ''); 203 $this->assertFalse($renderer->can_embed_url($url)); 204 } 205 206 /** 207 * Test for core_media_renderer embed_url. 208 * Checks multiple format/fallback support. 209 */ 210 public function test_embed_url_fallbacks() { 211 global $CFG, $PAGE; 212 213 $url = new moodle_url('http://example.org/test.mp4'); 214 215 // All plugins disabled, NOLINK option. 216 $renderer = new core_media_renderer_test($PAGE, ''); 217 $t = $renderer->embed_url($url, 0, 0, '', 218 array(core_media::OPTION_NO_LINK => true)); 219 // Completely empty. 220 $this->assertSame('', $t); 221 222 // All plugins disabled but not NOLINK. 223 $renderer = new core_media_renderer_test($PAGE, ''); 224 $t = $renderer->embed_url($url); 225 $this->assert_contents(false, false, true, $t); 226 227 // HTML5 plugin enabled. 228 $CFG->core_media_enable_html5video = true; 229 $renderer = new core_media_renderer_test($PAGE, ''); 230 $t = $renderer->embed_url($url); 231 $this->assert_contents(false, true, true, $t); 232 233 // QT plugin enabled as well. 234 $CFG->core_media_enable_qt = true; 235 $renderer = new core_media_renderer_test($PAGE, ''); 236 $t = $renderer->embed_url($url); 237 $this->assert_contents(true, true, true, $t); 238 239 // Nolink turned off, plugins still enabled. 240 $t = $renderer->embed_url($url, 0, 0, '', 241 array(core_media::OPTION_NO_LINK => true)); 242 $this->assert_contents(true, true, false, $t); 243 } 244 245 /** 246 * Checks the contents of the resulting HTML code to ensure it used the 247 * correct embed method(s). 248 * 249 * @param bool $hasqt True if it should have QT embed code 250 * @param bool $hashtml5 True if it should have HTML5 embed code 251 * @param bool $haslink True if it should have a fallback link 252 * @param string $text HTML content 253 */ 254 private function assert_contents($hasqt, $hashtml5, $haslink, $text) { 255 // I tried to avoid making it specific to the exact details of the html 256 // code, picking out only single key strings that would let it check 257 // whether final code contains the right things. 258 $qt = 'qtplugin.cab'; 259 $html5 = '</video>'; 260 $link = 'mediafallbacklink'; 261 262 if ($hasqt) { 263 $this->assertContains($qt, $text); 264 } else { 265 $this->assertNotContains($qt, $text); 266 } 267 268 if ($hashtml5) { 269 $this->assertContains($html5, $text); 270 } else { 271 $this->assertNotContains($html5, $text); 272 } 273 274 if ($haslink) { 275 $this->assertContains($link, $text); 276 } else { 277 $this->assertNotContains($link, $text); 278 } 279 } 280 281 /** 282 * Test for core_media_renderer embed_url. 283 * Check SWF works including the special option required to enable it 284 */ 285 public function test_embed_url_swf() { 286 global $CFG, $PAGE; 287 $CFG->core_media_enable_swf = true; 288 $renderer = new core_media_renderer_test($PAGE, ''); 289 290 // Without any options... 291 $url = new moodle_url('http://example.org/test.swf'); 292 $t = $renderer->embed_url($url); 293 $this->assertNotContains('</object>', $t); 294 295 // ...and with the 'no it's safe, I checked it' option. 296 $url = new moodle_url('http://example.org/test.swf'); 297 $t = $renderer->embed_url($url, '', 0, 0, array(core_media::OPTION_TRUSTED => true)); 298 $this->assertContains('</object>', $t); 299 } 300 301 /** 302 * Test for core_media_renderer embed_url. 303 * Exercises all the basic formats not covered elsewhere. 304 */ 305 public function test_embed_url_other_formats() { 306 global $CFG, $PAGE; 307 308 // Enable all players and get renderer. 309 $CFG->core_media_enable_html5audio = true; 310 $CFG->core_media_enable_mp3 = true; 311 $CFG->core_media_enable_flv = true; 312 $CFG->core_media_enable_wmp = true; 313 $CFG->core_media_enable_rm = true; 314 $CFG->core_media_enable_youtube = true; 315 $CFG->core_media_enable_vimeo = true; 316 $renderer = new core_media_renderer_test($PAGE, ''); 317 318 // Check each format one at a time. This is a basic check to be sure 319 // the HTML is included for files of the right type, not a test that 320 // the HTML itself is correct. 321 322 // Format: mp3. 323 $url = new moodle_url('http://example.org/test.mp3'); 324 $t = $renderer->embed_url($url); 325 $this->assertContains('core_media_mp3_', $t); 326 327 // Format: flv. 328 $url = new moodle_url('http://example.org/test.flv'); 329 $t = $renderer->embed_url($url); 330 $this->assertContains('core_media_flv_', $t); 331 332 // Format: wmp. 333 $url = new moodle_url('http://example.org/test.avi'); 334 $t = $renderer->embed_url($url); 335 $this->assertContains('6BF52A52-394A-11d3-B153-00C04F79FAA6', $t); 336 337 // Format: rm. 338 $url = new moodle_url('http://example.org/test.rm'); 339 $t = $renderer->embed_url($url); 340 $this->assertContains('CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA', $t); 341 342 // Format: youtube. 343 $url = new moodle_url('http://www.youtube.com/watch?v=vyrwMmsufJc'); 344 $t = $renderer->embed_url($url); 345 $this->assertContains('</iframe>', $t); 346 $url = new moodle_url('http://www.youtube.com/v/vyrwMmsufJc'); 347 $t = $renderer->embed_url($url); 348 $this->assertContains('</iframe>', $t); 349 350 // Format: youtube playlist. 351 $url = new moodle_url('http://www.youtube.com/view_play_list?p=PL6E18E2927047B662'); 352 $t = $renderer->embed_url($url); 353 $this->assertContains('</iframe>', $t); 354 $url = new moodle_url('http://www.youtube.com/playlist?list=PL6E18E2927047B662'); 355 $t = $renderer->embed_url($url); 356 $this->assertContains('</iframe>', $t); 357 $url = new moodle_url('http://www.youtube.com/p/PL6E18E2927047B662'); 358 $t = $renderer->embed_url($url); 359 $this->assertContains('</iframe>', $t); 360 361 // Format: vimeo. 362 $url = new moodle_url('http://vimeo.com/1176321'); 363 $t = $renderer->embed_url($url); 364 $this->assertContains('</iframe>', $t); 365 366 // Format: html5audio. 367 $this->pretend_to_be_firefox(); 368 $url = new moodle_url('http://example.org/test.ogg'); 369 $t = $renderer->embed_url($url); 370 $this->assertContains('</audio>', $t); 371 } 372 373 /** 374 * Same as test_embed_url MP3 test, but for slash arguments. 375 */ 376 public function test_slash_arguments() { 377 global $CFG, $PAGE; 378 379 // Again we do not turn slasharguments actually on, because it has to 380 // work regardless of the setting of that variable in case of handling 381 // links created using previous setting. 382 383 // Enable MP3 and get renderer. 384 $CFG->core_media_enable_mp3 = true; 385 $renderer = new core_media_renderer_test($PAGE, ''); 386 387 // Format: mp3. 388 $url = new moodle_url('http://example.org/pluginfile.php?file=x/y/z/test.mp3'); 389 $t = $renderer->embed_url($url); 390 $this->assertContains('core_media_mp3_', $t); 391 } 392 393 /** 394 * Test for core_media_renderer embed_url. 395 * Checks the EMBED_OR_BLANK option. 396 */ 397 public function test_embed_or_blank() { 398 global $CFG, $PAGE; 399 $CFG->core_media_enable_html5audio = true; 400 $this->pretend_to_be_firefox(); 401 402 $renderer = new core_media_renderer_test($PAGE, ''); 403 404 $options = array(core_media::OPTION_FALLBACK_TO_BLANK => true); 405 406 // Embed that does match something should still include the link too. 407 $url = new moodle_url('http://example.org/test.ogg'); 408 $t = $renderer->embed_url($url, '', 0, 0, $options); 409 $this->assertContains('</audio>', $t); 410 $this->assertContains('mediafallbacklink', $t); 411 412 // Embed that doesn't match something should be totally blank. 413 $url = new moodle_url('http://example.org/test.mp4'); 414 $t = $renderer->embed_url($url, '', 0, 0, $options); 415 $this->assertSame('', $t); 416 } 417 418 /** 419 * Test for core_media_renderer embed_url. 420 * Checks that size is passed through correctly to player objects and tests 421 * size support in html5video output. 422 */ 423 public function test_embed_url_size() { 424 global $CFG, $PAGE; 425 426 // Technically this could break in every format and they handle size 427 // in several different ways, but I'm too lazy to test it in every 428 // format, so let's just pick one to check the values get passed 429 // through. 430 $CFG->core_media_enable_html5video = true; 431 $renderer = new core_media_renderer_test($PAGE, ''); 432 $url = new moodle_url('http://example.org/test.mp4'); 433 434 // HTML5 default size - specifies core width and does not specify height. 435 $t = $renderer->embed_url($url); 436 $this->assertContains('width="' . CORE_MEDIA_VIDEO_WIDTH . '"', $t); 437 $this->assertNotContains('height', $t); 438 439 // HTML5 specified size - specifies both. 440 $t = $renderer->embed_url($url, '', '666', '101'); 441 $this->assertContains('width="666"', $t); 442 $this->assertContains('height="101"', $t); 443 444 // HTML5 size specified in url, overrides call. 445 $url = new moodle_url('http://example.org/test.mp4?d=123x456'); 446 $t = $renderer->embed_url($url, '', '666', '101'); 447 $this->assertContains('width="123"', $t); 448 $this->assertContains('height="456"', $t); 449 } 450 451 /** 452 * Test for core_media_renderer embed_url. 453 * Checks that name is passed through correctly to player objects and tests 454 * name support in html5video output. 455 */ 456 public function test_embed_url_name() { 457 global $CFG, $PAGE; 458 459 // As for size this could break in every format but I'm only testing 460 // html5video. 461 $CFG->core_media_enable_html5video = true; 462 $renderer = new core_media_renderer_test($PAGE, ''); 463 $url = new moodle_url('http://example.org/test.mp4'); 464 465 // HTML5 default name - use filename. 466 $t = $renderer->embed_url($url); 467 $this->assertContains('title="test.mp4"', $t); 468 469 // HTML5 specified name - check escaping. 470 $t = $renderer->embed_url($url, 'frog & toad'); 471 $this->assertContains('title="frog & toad"', $t); 472 } 473 474 /** 475 * Test for core_media_renderer split_alternatives. 476 */ 477 public function test_split_alternatives() { 478 // Single URL - identical moodle_url. 479 $mp4 = 'http://example.org/test.mp4'; 480 $result = core_media::split_alternatives($mp4, $w, $h); 481 $this->assertEquals($mp4, $result[0]->out(false)); 482 483 // Width and height weren't specified. 484 $this->assertEquals(0, $w); 485 $this->assertEquals(0, $h); 486 487 // Two URLs - identical moodle_urls. 488 $webm = 'http://example.org/test.webm'; 489 $result = core_media::split_alternatives("$mp4#$webm", $w, $h); 490 $this->assertEquals($mp4, $result[0]->out(false)); 491 $this->assertEquals($webm, $result[1]->out(false)); 492 493 // Two URLs plus dimensions. 494 $size = 'd=400x280'; 495 $result = core_media::split_alternatives("$mp4#$webm#$size", $w, $h); 496 $this->assertEquals($mp4, $result[0]->out(false)); 497 $this->assertEquals($webm, $result[1]->out(false)); 498 $this->assertEquals(400, $w); 499 $this->assertEquals(280, $h); 500 501 // Two URLs plus legacy dimensions (use last one). 502 $result = core_media::split_alternatives("$mp4?d=1x1#$webm?$size", $w, $h); 503 $this->assertEquals($mp4, $result[0]->out(false)); 504 $this->assertEquals($webm, $result[1]->out(false)); 505 $this->assertEquals(400, $w); 506 $this->assertEquals(280, $h); 507 } 508 509 /** 510 * Test for core_media_renderer embed_alternatives (with multiple urls) 511 */ 512 public function test_embed_alternatives() { 513 global $PAGE, $CFG; 514 515 // Most aspects of this are same as single player so let's just try 516 // a single typical / complicated scenario. 517 518 // MP3, WebM and FLV. 519 $urls = array( 520 new moodle_url('http://example.org/test.mp4'), 521 new moodle_url('http://example.org/test.webm'), 522 new moodle_url('http://example.org/test.flv'), 523 ); 524 525 // Enable html5 and flv. 526 $CFG->core_media_enable_html5video = true; 527 $CFG->core_media_enable_flv = true; 528 $renderer = new core_media_renderer_test($PAGE, ''); 529 530 // Result should contain HTML5 with two sources + FLV. 531 $t = $renderer->embed_alternatives($urls); 532 533 // HTML5 sources - mp4, not flv or webm (not supported in Safari). 534 $this->assertContains('<source src="http://example.org/test.mp4"', $t); 535 $this->assertNotContains('<source src="http://example.org/test.webm"', $t); 536 $this->assertNotContains('<source src="http://example.org/test.flv"', $t); 537 538 // FLV is before the video tag (indicating html5 is used as fallback to flv 539 // and not vice versa). 540 $this->assertTrue((bool)preg_match('~core_media_flv_.*<video~s', $t)); 541 542 // Do same test with firefox and check we get the webm and not mp4. 543 $this->pretend_to_be_firefox(); 544 $t = $renderer->embed_alternatives($urls); 545 546 // HTML5 sources - webm, not not flv or mp4 (not supported in Firefox). 547 $this->assertNotContains('<source src="http://example.org/test.mp4"', $t); 548 $this->assertContains('<source src="http://example.org/test.webm"', $t); 549 $this->assertNotContains('<source src="http://example.org/test.flv"', $t); 550 } 551 552 /** 553 * Converts moodle_url array into a single comma-separated string for 554 * easier testing. 555 * 556 * @param array $urls Array of moodle_urls 557 * @return string String containing those URLs, comma-separated 558 */ 559 public static function string_urls($urls) { 560 $out = array(); 561 foreach ($urls as $url) { 562 $out[] = $url->out(false); 563 } 564 return implode(',', $out); 565 } 566 567 /** 568 * Converts associative array into a semicolon-separated string for easier 569 * testing. 570 * 571 * @param array $options Associative array 572 * @return string String of form 'a=b;c=d' 573 */ 574 public static function string_options($options) { 575 $out = ''; 576 foreach ($options as $key => $value) { 577 if ($out) { 578 $out .= ';'; 579 } 580 $out .= "$key=$value"; 581 } 582 return $out; 583 } 584 } 585 586 /** 587 * Media player stub for testing purposes. 588 */ 589 class core_media_player_test extends core_media_player { 590 /** @var array Array of supported extensions */ 591 public $ext; 592 /** @var int Player rank */ 593 public $rank; 594 /** @var int Arbitrary number */ 595 public $num; 596 597 /** 598 * @param int $num Number (used in output) 599 * @param int $rank Player rank 600 * @param array $ext Array of supported extensions 601 */ 602 public function __construct($num = 1, $rank = 13, $ext = array('tst', 'test')) { 603 $this->ext = $ext; 604 $this->rank = $rank; 605 $this->num = $num; 606 } 607 608 public function embed($urls, $name, $width, $height, $options) { 609 return $this->num . ':' . medialib_test::string_urls($urls) . 610 ",$name,$width,$height,<!--FALLBACK-->," . medialib_test::string_options($options); 611 } 612 613 public function get_supported_extensions() { 614 return $this->ext; 615 } 616 617 public function get_rank() { 618 return $this->rank; 619 } 620 } 621 622 /** 623 * Media renderer override for testing purposes. 624 */ 625 class core_media_renderer_test extends core_media_renderer { 626 /** 627 * Access list of players as string, shortening it by getting rid of 628 * repeated text. 629 * @return string Comma-separated list of players 630 */ 631 public function get_players_test() { 632 $players = $this->get_players(); 633 $out = ''; 634 foreach ($players as $player) { 635 if ($out) { 636 $out .= ', '; 637 } 638 $out .= str_replace('core_media_player_', '', get_class($player)); 639 } 640 return $out; 641 } 642 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:29:05 2014 | Cross-referenced by PHPXref 0.7.1 |