See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 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 * Test classes for handling embedded media. 19 * 20 * @package media_videojs 21 * @copyright 2016 Marina Glancy 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 namespace media_videojs; 26 27 use core_media_manager; 28 use html_writer; 29 use media_videojs_plugin; 30 use moodle_url; 31 32 /** 33 * Test script for media embedding. 34 * 35 * @package media_videojs 36 * @copyright 2016 Marina Glancy 37 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 38 */ 39 class player_test extends \advanced_testcase { 40 41 /** 42 * Pre-test setup. Preserves $CFG. 43 */ 44 public function setUp(): void { 45 parent::setUp(); 46 47 // Reset $CFG and $SERVER. 48 $this->resetAfterTest(); 49 50 // Consistent initial setup: all players disabled. 51 \core\plugininfo\media::set_enabled_plugins('videojs'); 52 53 // Pretend to be using Firefox browser (must support ogg for tests to work). 54 \core_useragent::instance(true, 'Mozilla/5.0 (X11; Linux x86_64; rv:46.0) Gecko/20100101 Firefox/46.0 '); 55 } 56 57 /** 58 * Test that plugin is returned as enabled media plugin. 59 */ 60 public function test_is_installed() { 61 $sortorder = \core\plugininfo\media::get_enabled_plugins(); 62 $this->assertEquals(['videojs' => 'videojs'], $sortorder); 63 } 64 65 /** 66 * Test method get_supported_extensions() 67 */ 68 public function test_supported_extensions() { 69 $supportedextensions = array_merge(file_get_typegroup('extension', 'html_video'), 70 file_get_typegroup('extension', 'html_audio'), file_get_typegroup('extension', 'media_source')); 71 72 // Make sure that the list of extensions from the setting is filtered to HTML5 natively supported extensions. 73 $player = new media_videojs_plugin(); 74 $this->assertTrue(in_array('.mp3', $player->get_supported_extensions())); 75 $this->assertEmpty(array_diff($player->get_supported_extensions(), $supportedextensions)); 76 77 // Try to set the audioextensions to something non-native (.ra) and make sure it is not returned as supported. 78 set_config('audioextensions', '.mp3,.wav,.ra', 'media_videojs'); 79 $player = new media_videojs_plugin(); 80 $this->assertNotEmpty($player->get_supported_extensions()); 81 $this->assertTrue(in_array('.mp3', $player->get_supported_extensions())); 82 $this->assertFalse(in_array('.ra', $player->get_supported_extensions())); 83 $this->assertEmpty(array_diff($player->get_supported_extensions(), $supportedextensions)); 84 85 // Check flash extensions are not returned as supported. 86 set_config('videoextensions', '.flv,.f4v', 'media_videojs'); 87 $player = new media_videojs_plugin(); 88 $this->assertFalse(in_array('.flv', $player->get_supported_extensions())); 89 $this->assertFalse(in_array('.f4v', $player->get_supported_extensions())); 90 } 91 92 /** 93 * Test embedding without media filter (for example for displaying file resorce). 94 */ 95 public function test_embed_url() { 96 global $CFG; 97 98 $url = new moodle_url('http://example.org/1.webm'); 99 100 $manager = core_media_manager::instance(); 101 $embedoptions = array( 102 core_media_manager::OPTION_TRUSTED => true, 103 core_media_manager::OPTION_BLOCK => true, 104 ); 105 106 $this->assertTrue($manager->can_embed_url($url, $embedoptions)); 107 $content = $manager->embed_url($url, 'Test & file', 0, 0, $embedoptions); 108 109 $this->assertMatchesRegularExpression('~mediaplugin_videojs~', $content); 110 $this->assertMatchesRegularExpression('~</video>~', $content); 111 $this->assertMatchesRegularExpression('~title="Test & file"~', $content); 112 $this->assertMatchesRegularExpression('~style="max-width:' . $CFG->media_default_width . 'px;~', $content); 113 114 // Repeat sending the specific size to the manager. 115 $content = $manager->embed_url($url, 'New file', 123, 50, $embedoptions); 116 $this->assertMatchesRegularExpression('~style="max-width:123px;~', $content); 117 118 // Repeat without sending the size and with unchecked setting to limit the video size. 119 set_config('limitsize', false, 'media_videojs'); 120 121 $manager = core_media_manager::instance(); 122 $content = $manager->embed_url($url, 'Test & file', 0, 0, $embedoptions); 123 $this->assertDoesNotMatchRegularExpression('~style="max-width:~', $content); 124 } 125 126 /** 127 * Test that mediaplugin filter replaces a link to the supported file with media tag. 128 * 129 * filter_mediaplugin is enabled by default. 130 */ 131 public function test_embed_link() { 132 global $CFG; 133 $url = new moodle_url('http://example.org/some_filename.mp4'); 134 $text = html_writer::link($url, 'Watch this one'); 135 $content = format_text($text, FORMAT_HTML); 136 137 $this->assertMatchesRegularExpression('~mediaplugin_videojs~', $content); 138 $this->assertMatchesRegularExpression('~</video>~', $content); 139 $this->assertMatchesRegularExpression('~title="Watch this one"~', $content); 140 $this->assertDoesNotMatchRegularExpression('~<track\b~i', $content); 141 $this->assertMatchesRegularExpression('~style="max-width:' . $CFG->media_default_width . 'px;~', $content); 142 } 143 144 /** 145 * Test that only supported URLs are listed as sources but all URLs are present in links fallbacks. 146 */ 147 public function test_fallback() { 148 149 $urls = [ 150 new moodle_url('http://example.org/1.rv'), // Not supported. 151 new moodle_url('http://example.org/2.webm'), // Supported. 152 new moodle_url('http://example.org/3.ogv'), // Supported. 153 ]; 154 155 $manager = core_media_manager::instance(); 156 $content = $manager->embed_alternatives($urls, '', 0, 0, []); 157 158 $this->assertMatchesRegularExpression('~mediaplugin_videojs~', $content); 159 $this->assertMatchesRegularExpression('~</video>~', $content); 160 // Title is taken from the name of the first supported file. 161 $this->assertMatchesRegularExpression('~title="2"~', $content); 162 // Only supported files are in <source>'s. 163 $this->assertDoesNotMatchRegularExpression('~<source src="http://example.org/1.rv"~', $content); 164 $this->assertMatchesRegularExpression('~<source src="http://example.org/2.webm"~', $content); 165 $this->assertMatchesRegularExpression('~<source src="http://example.org/3.ogv"~', $content); 166 // Links to all files are included. 167 $this->assertMatchesRegularExpression( 168 '~<a class="mediafallbacklink" href="http://example.org/1.rv">1.rv</a>~', $content); 169 $this->assertMatchesRegularExpression( 170 '~<a class="mediafallbacklink" href="http://example.org/2.webm">2.webm</a>~', $content); 171 $this->assertMatchesRegularExpression( 172 '~<a class="mediafallbacklink" href="http://example.org/3.ogv">3.ogv</a>~', $content); 173 } 174 175 /** 176 * Assert other players do not apply after videojs was applied. 177 */ 178 public function test_prevent_other_players() { 179 \core\plugininfo\media::set_enabled_plugins('videojs,html5video'); 180 $url = new moodle_url('http://example.org/some_filename.webm'); 181 $text = html_writer::link($url, 'Apply one player only'); 182 $content = format_text($text, FORMAT_HTML); 183 184 $this->assertMatchesRegularExpression('~mediaplugin_videojs~', $content); 185 $this->assertEquals(1, substr_count($content, '</video>')); 186 $this->assertDoesNotMatchRegularExpression('~mediaplugin_html5video~', $content); 187 $this->assertMatchesRegularExpression( 188 '~<a class="mediafallbacklink" href="http://example.org/some_filename.webm">Apply one player only</a>~', $content); 189 } 190 191 /** 192 * Test that mediaplugin filter adds player code on top of <video> tags. 193 * 194 * filter_mediaplugin is enabled by default. 195 */ 196 public function test_embed_media() { 197 global $CFG; 198 $url = new moodle_url('http://example.org/some_filename.mp4'); 199 $trackurl = new moodle_url('http://example.org/some_filename.vtt'); 200 $text = '<video controls="true"><source src="'.$url.'"/><source src="somethinginvalid"/>' . 201 '<track src="'.$trackurl.'">Unsupported text</video>'; 202 $content = format_text($text, FORMAT_HTML); 203 204 $this->assertMatchesRegularExpression('~mediaplugin_videojs~', $content); 205 $this->assertMatchesRegularExpression('~</video>~', $content); 206 $this->assertMatchesRegularExpression('~title="some_filename.mp4"~', $content); 207 $this->assertMatchesRegularExpression('~style="max-width:' . $CFG->media_default_width . 'px;~', $content); 208 // Unsupported text and tracks are preserved. 209 $this->assertMatchesRegularExpression('~Unsupported text~', $content); 210 $this->assertMatchesRegularExpression('~<track\b~i', $content); 211 // Invalid sources are removed. 212 $this->assertDoesNotMatchRegularExpression('~somethinginvalid~i', $content); 213 214 // Video with dimensions and source specified as src attribute without <source> tag. 215 $text = '<video controls="true" width="123" height="35" src="'.$url.'">Unsupported text</video>'; 216 $content = format_text($text, FORMAT_HTML); 217 $this->assertMatchesRegularExpression('~mediaplugin_videojs~', $content); 218 $this->assertMatchesRegularExpression('~</video>~', $content); 219 $this->assertMatchesRegularExpression('~<source\b~', $content); 220 $this->assertMatchesRegularExpression('~style="max-width:123px;~', $content); 221 $this->assertDoesNotMatchRegularExpression('~width="~', $content); 222 $this->assertDoesNotMatchRegularExpression('~height="~', $content); 223 224 // Audio tag. 225 $url = new moodle_url('http://example.org/some_filename.mp3'); 226 $trackurl = new moodle_url('http://example.org/some_filename.vtt'); 227 $text = '<audio controls="true"><source src="'.$url.'"/><source src="somethinginvalid"/>' . 228 '<track src="'.$trackurl.'">Unsupported text</audio>'; 229 $content = format_text($text, FORMAT_HTML); 230 231 $this->assertMatchesRegularExpression('~mediaplugin_videojs~', $content); 232 $this->assertDoesNotMatchRegularExpression('~</video>~', $content); 233 $this->assertMatchesRegularExpression('~</audio>~', $content); 234 $this->assertMatchesRegularExpression('~title="some_filename.mp3"~', $content); 235 $this->assertMatchesRegularExpression('~style="max-width:' . $CFG->media_default_width . 'px;~', $content); 236 // Unsupported text and tracks are preserved. 237 $this->assertMatchesRegularExpression('~Unsupported text~', $content); 238 $this->assertMatchesRegularExpression('~<track\b~i', $content); 239 // Invalid sources are removed. 240 $this->assertDoesNotMatchRegularExpression('~somethinginvalid~i', $content); 241 } 242 243 /** 244 * Helper function for testing youtube videos embedding. 245 * 246 * @param string $t output of core_media_manager::embed_url. 247 */ 248 protected function youtube_plugin_engaged($t) { 249 $this->assertStringContainsString('mediaplugin_videojs', $t); 250 $this->assertStringContainsString('data-setup-lazy="{"techOrder": ["youtube"]', $t); 251 } 252 253 /** 254 * Test that VideoJS can embed youtube videos. 255 */ 256 public function test_youtube() { 257 set_config('youtube', 1, 'media_videojs'); 258 259 $manager = core_media_manager::instance(); 260 261 // Format: youtube. 262 $url = new moodle_url('http://www.youtube.com/watch?v=vyrwMmsufJc'); 263 $t = $manager->embed_url($url); 264 $this->youtube_plugin_engaged($t); 265 $url = new moodle_url('http://www.youtube.com/v/vyrwMmsufJc'); 266 $t = $manager->embed_url($url); 267 $this->youtube_plugin_engaged($t); 268 269 // Format: youtube video within playlist - this will be played by video.js but without tracks selection. 270 $url = new moodle_url('https://www.youtube.com/watch?v=dv2f_xfmbD8&index=4&list=PLxcO_MFWQBDcyn9xpbmx601YSDlDcTcr0'); 271 $t = $manager->embed_url($url); 272 $this->youtube_plugin_engaged($t); 273 $this->assertStringContainsString('list=PLxcO_MFWQBDcyn9xpbmx601YSDlDcTcr0', $t); 274 275 // Format: youtube playlist - not supported. 276 $url = new moodle_url('http://www.youtube.com/view_play_list?p=PL6E18E2927047B662'); 277 $t = $manager->embed_url($url); 278 $this->assertStringNotContainsString('mediaplugin_videojs', $t); 279 $url = new moodle_url('http://www.youtube.com/playlist?list=PL6E18E2927047B662'); 280 $t = $manager->embed_url($url); 281 $this->assertStringNotContainsString('mediaplugin_videojs', $t); 282 $url = new moodle_url('http://www.youtube.com/p/PL6E18E2927047B662'); 283 $t = $manager->embed_url($url); 284 $this->assertStringNotContainsString('mediaplugin_videojs', $t); 285 } 286 287 /** 288 * Data provider for {@see test_youtube_start_time} 289 * 290 * @return array 291 */ 292 public function youtube_start_time_provider(): array { 293 return [ 294 ['https://www.youtube.com/watch?v=JNJMF1l3udM&t=1h11s', 3611], 295 ['https://www.youtube.com/watch?v=dv2f_xfmbD8&index=4&list=PLxcO_MFWQBDcyn9xpbmx601YSDlDcTcr0&t=1m5s', 65], 296 ['https://www.youtube.com/watch?v=JNJMF1l3udM&t=1h10m30s', 4230], 297 ['https://www.youtube.com/watch?v=JNJMF1l3udM&t=3m', 180], 298 ['https://www.youtube.com/watch?v=JNJMF1l3udM&t=43s', 43], 299 ['https://www.youtube.com/watch?v=JNJMF1l3udM&t=1234', 1234], 300 ['https://www.youtube.com/watch?v=JNJMF1l3udM&t=invalid', 0], 301 ]; 302 } 303 304 /** 305 * Test Youtube video embedding with URL's containing start time interval 306 * 307 * @param string $url 308 * @param int $expectedstart 309 * 310 * @dataProvider youtube_start_time_provider 311 */ 312 public function test_youtube_start_time(string $url, int $expectedstart) { 313 set_config('youtube', 1, 'media_videojs'); 314 315 $embedcode = core_media_manager::instance()->embed_url(new moodle_url($url)); 316 317 $this->youtube_plugin_engaged($embedcode); 318 $this->assertStringContainsString(""youtube": {"start": "{$expectedstart}"}", $embedcode); 319 } 320 321 /** 322 * Helper function for testing flash videos embedding. 323 * 324 * @param string $t output of core_media_manager::embed_url. 325 */ 326 protected function flash_plugin_engaged($t) { 327 $this->assertStringContainsString('mediaplugin_videojs', $t); 328 $this->assertStringContainsString('data-setup-lazy="{"techOrder": ["flash", "html5"]', $t); 329 } 330 331 /** 332 * Test that VideoJS can not embed flash videos. 333 */ 334 public function test_flash_behaviour() { 335 $manager = core_media_manager::instance(); 336 337 $url = new moodle_url('http://example.org/some_filename.flv'); 338 $t = $manager->embed_url($url); 339 $this->assertStringNotContainsString('mediaplugin_videojs', $t); 340 $this->assertMatchesRegularExpression( 341 '~<a class="mediafallbacklink" href="http://example.org/some_filename.flv">some_filename.flv</a>~', $t); 342 } 343 344 /** 345 * Test that VideoJS can not embed RTMP streams. 346 */ 347 public function test_rtmp_behaviour() { 348 $manager = core_media_manager::instance(); 349 350 $url = new moodle_url('rtmp://example.com/fms&mp4:path/to/file.mp4'); 351 $t = $manager->embed_url($url); 352 $this->assertStringNotContainsString('mediaplugin_videojs', $t); 353 $this->assertMatchesRegularExpression( 354 '~<a class="mediafallbacklink" href="rtmp://example.com/fms&mp4:path/to/file.mp4">file.mp4</a>~', $t); 355 } 356 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body