Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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
use core_media_manager;
20
use media_test_plugin;
21
 
22
defined('MOODLE_INTERNAL') || die();
23
require_once(__DIR__ . '/fixtures/testable_core_media_player.php');
24
 
25
/**
26
 * Test classes for handling embedded media (audio/video).
27
 *
28
 * @package   core
29
 * @category  test
30
 * @copyright 2012 The Open University
31
 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
32
 */
33
class medialib_test extends \advanced_testcase {
34
 
35
    /**
36
     * Pre-test setup. Preserves $CFG.
37
     */
38
    public function setUp(): void {
39
        parent::setUp();
40
 
41
        // Reset $CFG and $SERVER.
42
        $this->resetAfterTest();
43
 
44
        // "Install" a fake plugin for testing.
45
        set_config('version', '2016101400', 'media_test');
46
 
47
        // Consistent initial setup: all players disabled.
48
        \core\plugininfo\media::set_enabled_plugins('');
49
 
50
        $_SERVER = array('HTTP_USER_AGENT' => '');
51
        $this->pretend_to_be_safari();
52
    }
53
 
54
    /**
55
     * Sets user agent to Safari.
56
     */
57
    private function pretend_to_be_safari() {
58
        // Pretend to be using Safari browser (must support mp4 for tests to work).
59
        \core_useragent::instance(true, 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; de-at) ' .
60
                'AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1');
61
    }
62
 
63
    /**
64
     * Sets user agent to Firefox.
65
     */
66
    private function pretend_to_be_firefox() {
67
        // Pretend to be using Firefox browser (must support ogg for tests to work).
68
        \core_useragent::instance(true, 'Mozilla/5.0 (X11; Linux x86_64; rv:46.0) Gecko/20100101 Firefox/46.0 ');
69
    }
70
 
71
    /**
72
     * Test for core_media::get_filename.
73
     */
11 efrain 74
    public function test_get_filename(): void {
1 efrain 75
        $manager = core_media_manager::instance();
76
 
77
        $this->assertSame('frog.mp4', $manager->get_filename(new \moodle_url(
78
                '/pluginfile.php/312/mod_page/content/7/frog.mp4')));
79
        // This should work even though slasharguments is true, because we want
80
        // it to support 'legacy' links if somebody toggles the option later.
81
        $this->assertSame('frog.mp4', $manager->get_filename(new \moodle_url(
82
                '/pluginfile.php?file=/312/mod_page/content/7/frog.mp4')));
83
    }
84
 
85
    /**
86
     * Test for core_media::get_extension.
87
     */
11 efrain 88
    public function test_get_extension(): void {
1 efrain 89
        $manager = core_media_manager::instance();
90
 
91
        $this->assertSame('mp4', $manager->get_extension(new \moodle_url(
92
                '/pluginfile.php/312/mod_page/content/7/frog.mp4')));
93
        $this->assertSame('', $manager->get_extension(new \moodle_url(
94
                '/pluginfile.php/312/mod_page/content/7/frog')));
95
        $this->assertSame('mp4', $manager->get_extension(new \moodle_url(
96
                '/pluginfile.php?file=/312/mod_page/content/7/frog.mp4')));
97
        $this->assertSame('', $manager->get_extension(new \moodle_url(
98
                '/pluginfile.php?file=/312/mod_page/content/7/frog')));
99
    }
100
 
101
    /**
102
     * Test for the core_media_player list_supported_urls.
103
     */
11 efrain 104
    public function test_list_supported_urls(): void {
1 efrain 105
        $test = new media_test_plugin(1, 13, ['tst', 'test']);
106
 
107
        // Some example URLs.
108
        $supported1 = new \moodle_url('http://example.org/1.test');
109
        $supported2 = new \moodle_url('http://example.org/2.TST');
110
        $unsupported = new \moodle_url('http://example.org/2.jpg');
111
 
112
        // No URLs => none.
113
        $result = $test->list_supported_urls(array());
114
        $this->assertEquals(array(), $result);
115
 
116
        // One supported URL => same.
117
        $result = $test->list_supported_urls(array($supported1));
118
        $this->assertEquals(array($supported1), $result);
119
 
120
        // Two supported URLS => same.
121
        $result = $test->list_supported_urls(array($supported1, $supported2));
122
        $this->assertEquals(array($supported1, $supported2), $result);
123
 
124
        // One unsupported => none.
125
        $result = $test->list_supported_urls(array($unsupported));
126
        $this->assertEquals(array(), $result);
127
 
128
        // Two supported and one unsupported => same.
129
        $result = $test->list_supported_urls(array($supported2, $unsupported, $supported1));
130
        $this->assertEquals(array($supported2, $supported1), $result);
131
    }
132
 
133
    /**
134
     * Test for get_players
135
     */
11 efrain 136
    public function test_get_players(): void {
1 efrain 137
        // All players are initially disabled (except link, which you can't).
138
        $manager = core_media_manager::instance();
139
        $this->assertEmpty($this->get_players_test($manager));
140
 
141
        // A couple enabled, check the order.
142
        \core\plugininfo\media::set_enabled_plugins('youtube,html5audio');
143
        $manager = core_media_manager::instance();
144
        $this->assertSame('youtube, html5audio', $this->get_players_test($manager));
145
 
146
        // Test HTML5 media order.
147
        \core\plugininfo\media::set_enabled_plugins('html5video,html5audio');
148
        $manager = core_media_manager::instance();
149
        $this->assertSame('html5video, html5audio', $this->get_players_test($manager));
150
 
151
        // Make sure that our test plugin is considered installed.
152
        \core\plugininfo\media::set_enabled_plugins('test,html5video');
153
        $manager = core_media_manager::instance();
154
        $this->assertSame('test, html5video', $this->get_players_test($manager));
155
 
156
        // Make sure that non-existing plugin is NOT considered installed.
157
        \core\plugininfo\media::set_enabled_plugins('nonexistingplugin,html5video');
158
        $manager = core_media_manager::instance();
159
        $this->assertSame('html5video', $this->get_players_test($manager));
160
    }
161
 
162
    /**
163
     * Test for can_embed_url
164
     */
11 efrain 165
    public function test_can_embed_url(): void {
1 efrain 166
        // All players are initially disabled, so mp4 cannot be rendered.
167
        $url = new \moodle_url('http://example.org/test.mp4');
168
        $manager = core_media_manager::instance();
169
        $this->assertFalse($manager->can_embed_url($url));
170
 
171
        // Enable VideoJS player.
172
        \core\plugininfo\media::set_enabled_plugins('videojs');
173
        $manager = core_media_manager::instance();
174
        $this->assertTrue($manager->can_embed_url($url));
175
 
176
        // VideoJS + html5.
177
        \core\plugininfo\media::set_enabled_plugins('videojs,html5video');
178
        $manager = core_media_manager::instance();
179
        $this->assertTrue($manager->can_embed_url($url));
180
 
181
        // Only html5.
182
        \core\plugininfo\media::set_enabled_plugins('html5video');
183
        $manager = core_media_manager::instance();
184
        $this->assertTrue($manager->can_embed_url($url));
185
    }
186
 
187
    /**
188
     * Test for embed_url.
189
     * Checks multiple format/fallback support.
190
     */
11 efrain 191
    public function test_embed_url_fallbacks(): void {
1 efrain 192
 
193
        // Key strings in the embed code that identify with the media formats being tested.
194
        $html5video = '</video>';
195
        $html5audio = '</audio>';
196
        $link = 'mediafallbacklink';
197
        $test = 'mediaplugin_test';
198
 
199
        $url = new \moodle_url('http://example.org/test.mp4');
200
 
201
        // All plugins disabled, NOLINK option.
202
        \core\plugininfo\media::set_enabled_plugins('');
203
        $manager = core_media_manager::instance();
204
        $t = $manager->embed_url($url, 0, 0, '',
205
                array(core_media_manager::OPTION_NO_LINK => true));
206
        // Completely empty.
207
        $this->assertSame('', $t);
208
 
209
        // All plugins disabled but not NOLINK.
210
        \core\plugininfo\media::set_enabled_plugins('');
211
        $manager = core_media_manager::instance();
212
        $t = $manager->embed_url($url);
213
        $this->assertStringContainsString($link, $t);
214
 
215
        // Enable media players that can play the same media formats. (ie. test & html5audio for mp3 files, etc.)
216
        \core\plugininfo\media::set_enabled_plugins('test,html5video,html5audio');
217
        $manager = core_media_manager::instance();
218
 
219
        // Test media formats that can be played by 2 or more players.
220
        $mediaformats = array('mp3', 'mp4');
221
 
222
        foreach ($mediaformats as $format) {
223
            $url = new \moodle_url('http://example.org/test.' . $format);
224
            $textwithlink = $manager->embed_url($url);
225
            $textwithoutlink = $manager->embed_url($url, 0, 0, '', array(core_media_manager::OPTION_NO_LINK => true));
226
 
227
            switch ($format) {
228
                case 'mp3':
229
                    $this->assertStringContainsString($test, $textwithlink);
230
                    $this->assertStringNotContainsString($html5video, $textwithlink);
231
                    $this->assertStringContainsString($html5audio, $textwithlink);
232
                    $this->assertStringContainsString($link, $textwithlink);
233
 
234
                    $this->assertStringContainsString($test, $textwithoutlink);
235
                    $this->assertStringNotContainsString($html5video, $textwithoutlink);
236
                    $this->assertStringContainsString($html5audio, $textwithoutlink);
237
                    $this->assertStringNotContainsString($link, $textwithoutlink);
238
                    break;
239
 
240
                case 'mp4':
241
                    $this->assertStringContainsString($test, $textwithlink);
242
                    $this->assertStringContainsString($html5video, $textwithlink);
243
                    $this->assertStringNotContainsString($html5audio, $textwithlink);
244
                    $this->assertStringContainsString($link, $textwithlink);
245
 
246
                    $this->assertStringContainsString($test, $textwithoutlink);
247
                    $this->assertStringContainsString($html5video, $textwithoutlink);
248
                    $this->assertStringNotContainsString($html5audio, $textwithoutlink);
249
                    $this->assertStringNotContainsString($link, $textwithoutlink);
250
                    break;
251
 
252
                default:
253
                    break;
254
            }
255
        }
256
    }
257
 
258
    /**
259
     * Test for embed_url.
260
     * SWF shouldn't be converted to objects because media_swf has been removed.
261
     */
11 efrain 262
    public function test_embed_url_swf(): void {
1 efrain 263
        $manager = core_media_manager::instance();
264
 
265
        // Without any options...
266
        $url = new \moodle_url('http://example.org/test.swf');
267
        $t = $manager->embed_url($url);
268
        $this->assertStringNotContainsString('</object>', $t);
269
 
270
        // ...and with the 'no it's safe, I checked it' option.
271
        $url = new \moodle_url('http://example.org/test.swf');
272
        $t = $manager->embed_url($url, '', 0, 0, array(core_media_manager::OPTION_TRUSTED => true));
273
        $this->assertStringNotContainsString('</object>', $t);
274
    }
275
 
276
    /**
277
     * Same as test_embed_url MP3 test, but for slash arguments.
278
     */
11 efrain 279
    public function test_slash_arguments(): void {
1 efrain 280
 
281
        // Again we do not turn slasharguments actually on, because it has to
282
        // work regardless of the setting of that variable in case of handling
283
        // links created using previous setting.
284
 
285
        // Enable player.
286
        \core\plugininfo\media::set_enabled_plugins('html5audio');
287
        $manager = core_media_manager::instance();
288
 
289
        // Format: mp3.
290
        $url = new \moodle_url('http://example.org/pluginfile.php?file=x/y/z/test.mp3');
291
        $t = $manager->embed_url($url);
292
        $this->assertStringContainsString('</audio>', $t);
293
    }
294
 
295
    /**
296
     * Test for embed_url.
297
     * Checks the EMBED_OR_BLANK option.
298
     */
11 efrain 299
    public function test_embed_or_blank(): void {
1 efrain 300
        \core\plugininfo\media::set_enabled_plugins('html5audio');
301
        $manager = core_media_manager::instance();
302
        $this->pretend_to_be_firefox();
303
 
304
        $options = array(core_media_manager::OPTION_FALLBACK_TO_BLANK => true);
305
 
306
        // Embed that does match something should still include the link too.
307
        $url = new \moodle_url('http://example.org/test.ogg');
308
        $t = $manager->embed_url($url, '', 0, 0, $options);
309
        $this->assertStringContainsString('</audio>', $t);
310
        $this->assertStringContainsString('mediafallbacklink', $t);
311
 
312
        // Embed that doesn't match something should be totally blank.
313
        $url = new \moodle_url('http://example.org/test.mp4');
314
        $t = $manager->embed_url($url, '', 0, 0, $options);
315
        $this->assertSame('', $t);
316
    }
317
 
318
    /**
319
     * Test for embed_url.
320
     * Checks that size is passed through correctly to player objects and tests
321
     * size support in html5video output.
322
     */
11 efrain 323
    public function test_embed_url_size(): void {
1 efrain 324
        global $CFG;
325
 
326
        // Technically this could break in every format and they handle size
327
        // in several different ways, but I'm too lazy to test it in every
328
        // format, so let's just pick one to check the values get passed
329
        // through.
330
        \core\plugininfo\media::set_enabled_plugins('html5video');
331
        $manager = core_media_manager::instance();
332
        $url = new \moodle_url('http://example.org/test.mp4');
333
 
334
        // HTML5 default size - specifies core width and does not specify height.
335
        $t = $manager->embed_url($url);
336
        $this->assertStringContainsString('width="' . $CFG->media_default_width . '"', $t);
337
        $this->assertStringNotContainsString('height', $t);
338
 
339
        // HTML5 specified size - specifies both.
340
        $t = $manager->embed_url($url, '', '666', '101');
341
        $this->assertStringContainsString('width="666"', $t);
342
        $this->assertStringContainsString('height="101"', $t);
343
 
344
        // HTML5 size specified in url, overrides call.
345
        $url = new \moodle_url('http://example.org/test.mp4?d=123x456');
346
        $t = $manager->embed_url($url, '', '666', '101');
347
        $this->assertStringContainsString('width="123"', $t);
348
        $this->assertStringContainsString('height="456"', $t);
349
    }
350
 
351
    /**
352
     * Test for embed_url.
353
     * Checks that name is passed through correctly to player objects and tests
354
     * name support in html5video output.
355
     */
11 efrain 356
    public function test_embed_url_name(): void {
1 efrain 357
        // As for size this could break in every format but I'm only testing
358
        // html5video.
359
        \core\plugininfo\media::set_enabled_plugins('html5video');
360
        $manager = core_media_manager::instance();
361
        $url = new \moodle_url('http://example.org/test.mp4');
362
 
363
        // HTML5 default name - use filename.
364
        $t = $manager->embed_url($url);
365
        $this->assertStringContainsString('title="test.mp4"', $t);
366
 
367
        // HTML5 specified name - check escaping.
368
        $t = $manager->embed_url($url, 'frog & toad');
369
        $this->assertStringContainsString('title="frog &amp; toad"', $t);
370
    }
371
 
372
    /**
373
     * Test for split_alternatives.
374
     */
11 efrain 375
    public function test_split_alternatives(): void {
1 efrain 376
        $mediamanager = core_media_manager::instance();
377
 
378
        // Single URL - identical moodle_url.
379
        $mp4 = 'http://example.org/test.mp4';
380
        $result = $mediamanager->split_alternatives($mp4, $w, $h);
381
        $this->assertEquals($mp4, $result[0]->out(false));
382
 
383
        // Width and height weren't specified.
384
        $this->assertEquals(0, $w);
385
        $this->assertEquals(0, $h);
386
 
387
        // Two URLs - identical moodle_urls.
388
        $webm = 'http://example.org/test.webm';
389
        $result = $mediamanager->split_alternatives("$mp4#$webm", $w, $h);
390
        $this->assertEquals($mp4, $result[0]->out(false));
391
        $this->assertEquals($webm, $result[1]->out(false));
392
 
393
        // Two URLs plus dimensions.
394
        $size = 'd=400x280';
395
        $result = $mediamanager->split_alternatives("$mp4#$webm#$size", $w, $h);
396
        $this->assertEquals($mp4, $result[0]->out(false));
397
        $this->assertEquals($webm, $result[1]->out(false));
398
        $this->assertEquals(400, $w);
399
        $this->assertEquals(280, $h);
400
 
401
        // Two URLs plus legacy dimensions (use last one).
402
        $result = $mediamanager->split_alternatives("$mp4?d=1x1#$webm?$size", $w, $h);
403
        $this->assertEquals($mp4, $result[0]->out(false));
404
        $this->assertEquals($webm, $result[1]->out(false));
405
        $this->assertEquals(400, $w);
406
        $this->assertEquals(280, $h);
407
    }
408
 
409
    /**
410
     * Test for embed_alternatives (with multiple urls)
411
     */
11 efrain 412
    public function test_embed_alternatives(): void {
1 efrain 413
        // Most aspects of this are same as single player so let's just try
414
        // a single typical / complicated scenario.
415
 
416
        // MP4, OGV, WebM and FLV.
417
        $urls = array(
418
            new \moodle_url('http://example.org/test.mp4'),
419
            new \moodle_url('http://example.org/test.ogv'),
420
            new \moodle_url('http://example.org/test.webm'),
421
            new \moodle_url('http://example.org/test.flv'),
422
        );
423
 
424
        // Enable html5 and "test" ("test" first).
425
        \core\plugininfo\media::set_enabled_plugins('test,html5video');
426
        $manager = core_media_manager::instance();
427
 
428
        // Result should contain HTML5 with two sources + FLV.
429
        $t = $manager->embed_alternatives($urls);
430
 
431
        // HTML5 sources - mp4, but not ogv, flv or webm (not supported in Safari).
432
        $this->assertStringContainsString('<source src="http://example.org/test.mp4"', $t);
433
        $this->assertStringNotContainsString('<source src="http://example.org/test.ogv"', $t);
434
        $this->assertStringNotContainsString('<source src="http://example.org/test.webm"', $t);
435
        $this->assertStringNotContainsString('<source src="http://example.org/test.flv"', $t);
436
 
437
        // FLV is before the video tag (indicating html5 is used as fallback to flv
438
        // and not vice versa).
439
        $this->assertTrue((bool)preg_match('~mediaplugin_test.*<video~s', $t));
440
 
441
        // Do same test with firefox and check we get the webm and not mp4.
442
        $this->pretend_to_be_firefox();
443
        $t = $manager->embed_alternatives($urls);
444
 
445
        // HTML5 sources - mp4, ogv and webm, but not flv.
446
        $this->assertStringContainsString('<source src="http://example.org/test.mp4"', $t);
447
        $this->assertStringContainsString('<source src="http://example.org/test.ogv"', $t);
448
        $this->assertStringContainsString('<source src="http://example.org/test.webm"', $t);
449
        $this->assertStringNotContainsString('<source src="http://example.org/test.flv"', $t);
450
    }
451
 
452
    /**
453
     * Make sure the instance() method returns singleton for the same page and different object for another page
454
     */
11 efrain 455
    public function test_initialise(): void {
1 efrain 456
        $moodlepage1 = new \moodle_page();
457
 
458
        $mediamanager1 = core_media_manager::instance($moodlepage1);
459
        $mediamanager2 = core_media_manager::instance($moodlepage1);
460
 
461
        $this->assertSame($mediamanager1, $mediamanager2);
462
 
463
        $moodlepage3 = new \moodle_page();
464
        $mediamanager3 = core_media_manager::instance($moodlepage3);
465
 
466
        $this->assertNotSame($mediamanager1, $mediamanager3);
467
    }
468
 
469
 
470
    /**
471
     * Access list of players as string, shortening it by getting rid of
472
     * repeated text.
473
     * @param core_media_manager $manager The core_media_manager instance
474
     * @return string Comma-separated list of players
475
     */
476
    public function get_players_test($manager) {
477
        $method = new \ReflectionMethod("core_media_manager", "get_players");
478
        $players = $method->invoke($manager);
479
        $out = '';
480
        foreach ($players as $player) {
481
            if ($out) {
482
                $out .= ', ';
483
            }
484
            $out .= str_replace('core_media_player_', '', preg_replace('/^media_(.*)_plugin$/', '$1', get_class($player)));
485
        }
486
        return $out;
487
    }
488
}