summaryrefslogtreecommitdiff
path: root/extensions/TimedMediaHandler/tests/phpunit
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/TimedMediaHandler/tests/phpunit')
-rw-r--r--extensions/TimedMediaHandler/tests/phpunit/ApiTestCaseVideoUpload.php130
-rw-r--r--extensions/TimedMediaHandler/tests/phpunit/README11
-rw-r--r--extensions/TimedMediaHandler/tests/phpunit/TestApiUploadVideo.php34
-rw-r--r--extensions/TimedMediaHandler/tests/phpunit/TestOggHandler.php67
-rw-r--r--extensions/TimedMediaHandler/tests/phpunit/TestTimeParsing.php42
-rw-r--r--extensions/TimedMediaHandler/tests/phpunit/TestTimedMediaHandler.php47
-rw-r--r--extensions/TimedMediaHandler/tests/phpunit/TestTimedMediaTransformOutput.php142
-rw-r--r--extensions/TimedMediaHandler/tests/phpunit/TestVideoThumbnail.php80
-rw-r--r--extensions/TimedMediaHandler/tests/phpunit/TestVideoTranscode.php121
-rw-r--r--extensions/TimedMediaHandler/tests/phpunit/TestWebMHandler.php52
-rw-r--r--extensions/TimedMediaHandler/tests/phpunit/media/README38
-rw-r--r--extensions/TimedMediaHandler/tests/phpunit/media/VP9-tractor.webmbin0 -> 179277 bytes
-rw-r--r--extensions/TimedMediaHandler/tests/phpunit/media/bear-vp9-opus.webmbin0 -> 101414 bytes
-rw-r--r--extensions/TimedMediaHandler/tests/phpunit/media/broken-file.oggbin0 -> 11424 bytes
-rw-r--r--extensions/TimedMediaHandler/tests/phpunit/media/doubleTag.ogabin0 -> 11423 bytes
-rw-r--r--extensions/TimedMediaHandler/tests/phpunit/media/shuttle10seconds.1080x608.webmbin0 -> 699018 bytes
-rw-r--r--extensions/TimedMediaHandler/tests/phpunit/media/test5seconds.electricsheep.300x400.ogvbin0 -> 299761 bytes
17 files changed, 764 insertions, 0 deletions
diff --git a/extensions/TimedMediaHandler/tests/phpunit/ApiTestCaseVideoUpload.php b/extensions/TimedMediaHandler/tests/phpunit/ApiTestCaseVideoUpload.php
new file mode 100644
index 00000000..9dd4cb52
--- /dev/null
+++ b/extensions/TimedMediaHandler/tests/phpunit/ApiTestCaseVideoUpload.php
@@ -0,0 +1,130 @@
+<?php
+/**
+ * Abstract test class to support Video Tests with video uploads
+ * @author dale
+ */
+
+if ( !defined( 'MEDIAWIKI' ) ) {
+ exit;
+}
+
+// Include core class ApiTestCaseUpload ( not part of base autoLoader )
+global $IP;
+require_once( "$IP/tests/phpunit/includes/api/ApiTestCaseUpload.php" );
+
+abstract class ApiTestCaseVideoUpload extends ApiTestCaseUpload {
+ /**
+ * @return Array set of test files with associated metadata
+ */
+ static function mediaFilesProvider(){
+ return array(
+ array(
+ // Double wrap the file array to match phpunit data provider conventions
+ array(
+ 'mime' => 'application/ogg',
+ 'filePath' => dirname( __FILE__ ) . '/media/test5seconds.electricsheep.300x400.ogv',
+ "size" => 301477,
+ "width" => 400,
+ "height" => 300,
+ "mediatype" => "VIDEO",
+ "bandwidth" => 452216,
+ "framerate" => 30
+ )
+ ),
+ array(
+ array(
+ 'mime' => 'video/webm',
+ 'filePath' => dirname( __FILE__ ) . '/media/shuttle10seconds.1080x608.webm',
+ "size" => 699018,
+ "width" => 1080,
+ "height" => 608,
+ "mediatype" => "VIDEO",
+ "bandwidth" => 522142,
+ "framerate" => 29.97
+ )
+ )
+ );
+ }
+ /**
+ * Fixture -- run after every test
+ * Clean up temporary files etc.
+ *
+ */
+ protected function tearDown() {
+ parent::tearDown();
+
+ $testMediaFiles = $this->mediaFilesProvider();
+ foreach( $testMediaFiles as $file ){
+ $file = $file[0];
+ // Clean up and delete all files
+ $this->deleteFileByFilename( $file['filePath'] );
+ }
+ }
+
+ /**
+ * Do login
+ */
+ protected function doLogin( $user = 'sysop' ) {
+ $user = self::$users['uploader'];
+
+ $params = array(
+ 'action' => 'login',
+ 'lgname' => $user->username,
+ 'lgpassword' => $user->password
+ );
+ list( $result, , $session ) = $this->doApiRequest( $params );
+ $token = $result['login']['token'];
+
+ $params = array(
+ 'action' => 'login',
+ 'lgtoken' => $token,
+ 'lgname' => $user->username,
+ 'lgpassword' => $user->password
+ );
+ list( $result, , $session ) = $this->doApiRequest( $params, $session );
+ return $session;
+ }
+
+ /**
+ * uploads a file:
+ */
+ public function uploadFile( $file ){
+ global $wgUser;
+ // get a session object
+ $session = $this->doLogin();
+ // Update the global user:
+ $wgUser = self::$users['uploader']->getUser();
+
+ // Upload the media file:
+ $fileName = basename( $file['filePath'] );
+
+ // remove if already in thd db:
+ $this->deleteFileByFileName( $fileName );
+ $this->deleteFileByContent( $file['filePath'] );
+
+ if ( !$this->fakeUploadFile( 'file', $fileName, $file['mime'], $file['filePath'] ) ) {
+ $this->markTestIncomplete( "Couldn't upload file!\n" );
+ }
+
+ $params = array(
+ 'action' => 'upload',
+ 'filename' => $fileName,
+ 'file' => 'dummy content',
+ 'comment' => 'dummy comment',
+ 'text' => "This is the page text for $fileName",
+ // This uploadFile function supports video tests not a test upload warnings
+ 'ignorewarnings' => true
+ );
+
+ try{
+ list( $result, , ) = $this->doApiRequestWithToken( $params, $session );
+ } catch( Exception $e ) {
+ // Could not upload mark test that called uploadFile as incomplete
+ $this->markTestIncomplete( $e->getMessage() );
+ }
+
+ return $result;
+
+ }
+
+}
diff --git a/extensions/TimedMediaHandler/tests/phpunit/README b/extensions/TimedMediaHandler/tests/phpunit/README
new file mode 100644
index 00000000..dd9eba39
--- /dev/null
+++ b/extensions/TimedMediaHandler/tests/phpunit/README
@@ -0,0 +1,11 @@
+
+Some TimedMediaHandler testing notes:
+
+ We have a base class ApiTestCaseVideoUpload that establishes the uploads. Actual uploading
+ is tested in the core uploading support so we focus these tests on timed media handler functionality
+
+ We sometimes combine a few tests because fixtures don't play well with dataProvider
+ since the mediawiki test framework nukes the db every time you run the next test in
+ a given dataProvider data set.
+
+
diff --git a/extensions/TimedMediaHandler/tests/phpunit/TestApiUploadVideo.php b/extensions/TimedMediaHandler/tests/phpunit/TestApiUploadVideo.php
new file mode 100644
index 00000000..ebc38ddf
--- /dev/null
+++ b/extensions/TimedMediaHandler/tests/phpunit/TestApiUploadVideo.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * TestApiUploadVideo test case.
+ *
+ * NOTE: This build heavily on ApiUploadTest ( would need to refactor ApiUploadTest for this to work better )
+ *
+ * @ingroup timedmedia
+ * @since 0.2
+ * @author Michael Dale
+ */
+
+/**
+ * @group Database
+ * @group Destructive
+ * @group medium
+ */
+class TestApiUploadVideo extends ApiTestCaseVideoUpload {
+
+ /**
+ * @dataProvider mediaFilesProvider
+ */
+ public function testUploadVideoFiles( $file ){
+
+ $result = $this->uploadFile( $file );
+
+ // Run asserts
+ $this->assertTrue( isset( $result['upload'] ) );
+ $this->assertEquals( 'Success', $result['upload']['result'] );
+ $this->assertEquals( filesize( $file['filePath'] ), ( int )$result['upload']['imageinfo']['size'] );
+ $this->assertEquals( $file['mime'], $result['upload']['imageinfo']['mime'] );
+
+ }
+
+}
diff --git a/extensions/TimedMediaHandler/tests/phpunit/TestOggHandler.php b/extensions/TimedMediaHandler/tests/phpunit/TestOggHandler.php
new file mode 100644
index 00000000..3c058974
--- /dev/null
+++ b/extensions/TimedMediaHandler/tests/phpunit/TestOggHandler.php
@@ -0,0 +1,67 @@
+<?php
+class TestOggHandler extends MediaWikiMediaTestCase {
+
+ /** @var OggHandlerTMH */
+ private $handler;
+
+ function getFilePath() {
+ return __DIR__ . '/media';
+ }
+
+ function setUp() {
+ parent::setUp();
+ $this->handler = new OggHandlerTMH;
+ }
+
+ /**
+ * @dataProvider providerGetCommonMetaArray
+ * @param $filename String name of file
+ * @param $expected Array
+ */
+ function testGetCommonMetaArray( $filename, $expected ) {
+ $testFile = $this->dataFile( $filename, 'application/ogg' );
+ $this->assertEquals( $expected, $this->handler->getCommonMetaArray( $testFile ) );
+ }
+
+ function providerGetCommonMetaArray() {
+ return array(
+ array( 'test5seconds.electricsheep.300x400.ogv',
+ array(
+ 'Software' => array( 'Lavf53.21.1' ),
+ 'ObjectName' => array( 'Electric Sheep' ),
+ 'UserComment' => array( '🐑' )
+ )
+ ),
+ array( 'doubleTag.oga',
+ array(
+ 'Artist' => array( 'Brian', 'Bawolff' ),
+ 'Software' => array( 'Lavf55.10.2' )
+ )
+ ),
+ array( 'broken-file.ogg',
+ array()
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider providerGetWebType
+ * @param $filename String name of file
+ * @param $expected String Mime type (including codecs)
+ */
+ function testGetWebType( $filename, $expected ) {
+ $testFile = $this->dataFile( $filename, 'application/ogg' );
+ $this->assertEquals( $expected, $this->handler->getWebType( $testFile ) );
+ }
+
+ function providerGetWebType() {
+ return array(
+ array( 'test5seconds.electricsheep.300x400.ogv', 'video/ogg; codecs="theora"' ),
+ array( 'doubleTag.oga', 'audio/ogg; codecs="vorbis"' ),
+ // XXX: This behaviour is somewhat questionable. It perhaps should be
+ // application/ogg in this case.
+ array( 'broken-file.ogg', 'audio/ogg' ),
+ );
+ }
+
+}
diff --git a/extensions/TimedMediaHandler/tests/phpunit/TestTimeParsing.php b/extensions/TimedMediaHandler/tests/phpunit/TestTimeParsing.php
new file mode 100644
index 00000000..b4ec6ba9
--- /dev/null
+++ b/extensions/TimedMediaHandler/tests/phpunit/TestTimeParsing.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * TestTimeParsing test .
+ *
+ * @ingroup timedmedia
+ * @since 0.2
+ * @author Michael Dale
+ */
+
+
+class TestTimeParsing extends PHPUnit_Framework_TestCase {
+ /**
+ * Test time string to np2
+ */
+ function testSeconds2NptFormat() {
+ // Some time conversions:
+ $this->assertEquals( TimedMediaHandler::seconds2npt( 100 ), '0:1:40' );
+ $this->assertEquals( TimedMediaHandler::seconds2npt( 0 ), '0:0:0' );
+ $this->assertEquals( TimedMediaHandler::seconds2npt( 3601 ), '1:0:1' );
+
+ // Test failures:
+ $this->assertEquals( TimedMediaHandler::seconds2npt( 'foo' ), false );
+ $this->assertEquals( TimedMediaHandler::seconds2npt( -1 ), false );
+ }
+
+ /**
+ * Test time parsing to seconds
+ */
+ function testParseTimeString() {
+ // Some time conversions:
+ $this->assertEquals( TimedMediaHandler::parseTimeString( 100 ), 100 );
+ $this->assertEquals( TimedMediaHandler::parseTimeString( '1:0:0' ), 3600 );
+ $this->assertEquals( TimedMediaHandler::parseTimeString( -1 ), 0 );
+ // Test longer than duration check ( should return time -1 )
+ $this->assertEquals( TimedMediaHandler::parseTimeString( 10, 9 ), 8 );
+
+ // Test failures:
+ $this->assertEquals( TimedMediaHandler::parseTimeString( '1:1:1:1' ), false );
+ $this->assertEquals( TimedMediaHandler::parseTimeString( 'abc' ), false );
+
+ }
+} \ No newline at end of file
diff --git a/extensions/TimedMediaHandler/tests/phpunit/TestTimedMediaHandler.php b/extensions/TimedMediaHandler/tests/phpunit/TestTimedMediaHandler.php
new file mode 100644
index 00000000..2ca350a0
--- /dev/null
+++ b/extensions/TimedMediaHandler/tests/phpunit/TestTimedMediaHandler.php
@@ -0,0 +1,47 @@
+<?php
+class TestTimedMediaHandler extends MediaWikiTestCase {
+
+ /** @var TimedMediaHandler */
+ private $handler;
+
+ function setUp() {
+ $this->handler = new TimedMediaHandler;
+ parent::setUp();
+ }
+
+ /**
+ * @dataProvider providerParseParamString
+ * @param $str String a thumbnail parameter string
+ * @param $expected Array Expected thumbnailing parameters
+ */
+ function testParseParamString( $str, $expected ) {
+ $result = $this->handler->parseParamString( $str );
+ $this->assertEquals( $result, $expected );
+ }
+
+ function providerParseParamString() {
+ return array(
+ array(
+ 'mid',
+ array(),
+ ),
+ array(
+ '220px-',
+ array( 'width' => 220 ),
+ ),
+ array(
+ 'seek=30',
+ array( 'thumbtime' => 30.0 ),
+ ),
+ array(
+ 'seek=15.72',
+ array( 'thumbtime' => 15.72 ),
+ ),
+ array(
+ '180px-seek=15',
+ array( 'thumbtime' => 15, 'width' => 180 ),
+ ),
+ );
+
+ }
+}
diff --git a/extensions/TimedMediaHandler/tests/phpunit/TestTimedMediaTransformOutput.php b/extensions/TimedMediaHandler/tests/phpunit/TestTimedMediaTransformOutput.php
new file mode 100644
index 00000000..9bcc89fb
--- /dev/null
+++ b/extensions/TimedMediaHandler/tests/phpunit/TestTimedMediaTransformOutput.php
@@ -0,0 +1,142 @@
+<?php
+class TestTimedMediaTransformOutput extends MediaWikiMediaTestCase {
+
+ private $sortMethod;
+ private $thumbObj;
+
+ function getFilePath() {
+ return __DIR__ . '/media';
+ }
+
+ protected function setUp() {
+ parent::setUp();
+
+ // Disable video thumbnail generation. Not needed for this test.
+ $reflection = new ReflectionClass( $this->repo );
+ $reflectionProperty = $reflection->getProperty( 'transformVia404' );
+ $reflectionProperty->setAccessible( true );
+ $reflectionProperty->setValue( $this->repo, true );
+
+ $this->setMWGlobals( 'wgMinimumVideoPlayerSize', '400' );
+ }
+
+ /**
+ * @param $width int The requested width of the thumbnail
+ * @param $minVideoSize int The min width a non-pop up video is acceptable
+ * @param $expectPopup boolean Do we expect a pop up video
+ *
+ * @dataProvider providerIsPopUp
+ */
+ function testIsPopUp( $width, $minVideoSize, $expectPopup ) {
+ $this->setMwGlobals( 'wgMinimumVideoPlayerSize', $minVideoSize );
+
+ // Note this file has a width of 400px and a height of 300px
+ $file = $this->dataFile( 'test5seconds.electricsheep.300x400.ogv', 'application/ogg' );
+ $thumbnail = $file->transform( array( 'width' => $width ) );
+ $this->assertTrue( $thumbnail && !$thumbnail->isError() );
+
+ $reflection = new ReflectionClass( $thumbnail );
+ $reflMethod = $reflection->getMethod( 'useImagePopUp' );
+ $reflMethod->setAccessible( true );
+
+ $actual = $reflMethod->invoke( $thumbnail );
+ $this->assertEquals( $actual, $expectPopup );
+
+ }
+
+ function providerIsPopUp() {
+ return array(
+ array( 400, 800, false ),
+ array( 300, 800, true ),
+ array( 300, 200, false ),
+ array( 300, 300, false )
+ );
+ }
+
+ /**
+ * @param $thumbWidth int Requested width
+ * @param $sources array
+ * @param $sortedSources array
+ * @dataProvider providerSortMediaByBandwidth
+ */
+ function testSortMediaByBandwidth( $thumbWidth, $sources, $sortedSources ) {
+ $params = array(
+ 'width' => $thumbWidth,
+ 'height' => $thumbWidth * 9 / 16,
+ 'isVideo' => true,
+ 'fillwindow' => false,
+ 'file' => new FakeDimensionFile( array( 1820, 1024 ) )
+ );
+ $this->thumbObj = new TimedMediaTransformOutput( $params );
+
+ $reflection = new ReflectionClass( $this->thumbObj );
+ $this->sortMethod = $reflection->getMethod( 'sortMediaByBandwidth' );
+ $this->sortMethod->setAccessible( true );
+
+ usort( $sources, array( $this, 'callSortMethodHelper' ) );
+ $this->assertEquals( $sortedSources, $sources );
+ }
+
+ public function callSortMethodHelper( $a, $b ) {
+ return $this->sortMethod->invoke( $this->thumbObj, $a, $b );
+ }
+
+
+ function providerSortMediaByBandwidth() {
+ return array(
+ array(
+ 600,
+ array(
+ array( 'width' => 1000, 'bandwidth' => 2000 ),
+ array( 'width' => 1000, 'bandwidth' => 7000 ),
+ array( 'width' => 1000, 'bandwidth' => 1000 ),
+ ),
+ array(
+ array( 'width' => 1000, 'bandwidth' => 1000 ),
+ array( 'width' => 1000, 'bandwidth' => 2000 ),
+ array( 'width' => 1000, 'bandwidth' => 7000 ),
+ ),
+ ),
+ array(
+ 600,
+ array(
+ array( 'width' => 200, 'bandwidth' => 2000 ),
+ array( 'width' => 1000, 'bandwidth' => 7000 ),
+ array( 'width' => 200, 'bandwidth' => 1000 ),
+ ),
+ array(
+ array( 'width' => 1000, 'bandwidth' => 7000 ),
+ array( 'width' => 200, 'bandwidth' => 1000 ),
+ array( 'width' => 200, 'bandwidth' => 2000 ),
+ ),
+ ),
+ array(
+ /* Pop up viewer in this case */
+ 100,
+ array(
+ array( 'width' => 700, 'bandwidth' => 2000 ),
+ array( 'width' => 1000, 'bandwidth' => 7000 ),
+ array( 'width' => 700, 'bandwidth' => 1000 ),
+ ),
+ array(
+ array( 'width' => 1000, 'bandwidth' => 7000 ),
+ array( 'width' => 700, 'bandwidth' => 1000 ),
+ array( 'width' => 700, 'bandwidth' => 2000 ),
+ ),
+ ),
+ array(
+ 600,
+ array(
+ array( 'width' => 700, 'bandwidth' => 2000 ),
+ array( 'width' => 800, 'bandwidth' => 7000 ),
+ array( 'width' => 1000, 'bandwidth' => 1000 ),
+ ),
+ array(
+ array( 'width' => 1000, 'bandwidth' => 1000 ),
+ array( 'width' => 700, 'bandwidth' => 2000 ),
+ array( 'width' => 800, 'bandwidth' => 7000 ),
+ ),
+ ),
+ );
+ }
+}
diff --git a/extensions/TimedMediaHandler/tests/phpunit/TestVideoThumbnail.php b/extensions/TimedMediaHandler/tests/phpunit/TestVideoThumbnail.php
new file mode 100644
index 00000000..b3c9ef87
--- /dev/null
+++ b/extensions/TimedMediaHandler/tests/phpunit/TestVideoThumbnail.php
@@ -0,0 +1,80 @@
+<?php
+/**
+ * @ingroup timedmedia
+ * @author dale
+ * @group medium
+ */
+class TestVideoThumbnail extends ApiTestCaseVideoUpload {
+
+ /**
+ * Once video files are uploaded test thumbnail generating
+ *
+ * @dataProvider mediaFilesProvider
+ * Broken as per bug 61877
+ * @group Broken
+ */
+ function testApiThumbnails( $file ){
+ // Upload the file to the mediaWiki system
+ $result = $this->uploadFile( $file);
+
+ // Do a API request and check for valid thumbnails:
+ $fileName = basename( $file['filePath'] );
+ $params = array(
+ 'action' => 'query',
+ 'titles' => 'File:' . $fileName,
+ 'prop' => 'imageinfo',
+ 'iiprop' => "url|size|thumbmime",
+ );
+
+ // Do a request for a small ( 200px ) thumbnail
+ list($result,,) = $this->doApiRequest(
+ array_merge( $params, array(
+ 'iiurlwidth' => '200'
+ )
+ )
+ );
+
+ // Check The thumbnail output:
+ $this->assertTrue( isset( $result['query'] ) );
+
+ $page = current( $result['query']['pages'] );
+ $this->assertTrue( isset( $page['imageinfo'] ) );
+
+ $imageInfo = current( $page['imageinfo'] );
+
+ // Make sure we got a 200 wide pixel image:
+ $this->assertEquals( 200, ( int )$imageInfo['thumbwidth'] );
+
+ // Thumbnails should be image/jpeg:
+ $this->assertEquals( 'image/jpeg', $imageInfo['thumbmime'] );
+
+ // Make sure the thumbnail url is valid and the correct size ( assuming php has getimagesize function)
+ if( function_exists( 'getimagesize' ) ){
+ list($width ,,,) = getimagesize ( $imageInfo[ 'thumburl'] );
+ $this->assertEquals( 200, $width );
+ }
+
+ /**
+ * We combine tests because fixtures don't play well with dataProvider
+ * see README for more info
+ */
+
+ // Test a larger thumbnail with 1 second time offset
+ list( $result,, ) = $this->doApiRequest(
+ array_merge( $params, array(
+ 'iiurlwidth' => '600',
+ 'iiurlparam' => '1'
+ )
+ )
+ );
+ $page = current( $result['query']['pages'] );
+ $imageInfo = current( $page['imageinfo'] );
+ // Thumb should max out at source size ( no upscale )
+ $targetWidth = ( ( int )$file['width'] < 600 ) ? ( int )$file['width'] : 600;
+ $this->assertEquals( $targetWidth, ( int )$imageInfo['thumbwidth'] );
+ if( function_exists( 'getimagesize' ) ){
+ list( $srcImageWidth ,,,) = getimagesize ( $imageInfo[ 'thumburl'] );
+ $this->assertEquals( $targetWidth, $srcImageWidth );
+ }
+ }
+}
diff --git a/extensions/TimedMediaHandler/tests/phpunit/TestVideoTranscode.php b/extensions/TimedMediaHandler/tests/phpunit/TestVideoTranscode.php
new file mode 100644
index 00000000..af0e6f1f
--- /dev/null
+++ b/extensions/TimedMediaHandler/tests/phpunit/TestVideoTranscode.php
@@ -0,0 +1,121 @@
+<?php
+/**
+ * @ingroup timedmedia
+ * @author michael dale
+ * @group medium
+ */
+class TestVideoTranscode extends ApiTestCaseVideoUpload {
+
+ /**
+ * Once video files are uploaded test transcoding
+ *
+ * Test if a transcode job is added for a file once requested
+ *
+ * @dataProvider mediaFilesProvider
+ * Broken as per bug 61878
+ * @group Broken
+ */
+ function testTranscodeJobs( $file ){
+ // Upload the file to the mediaWiki system
+ $result = $this->uploadFile( $file );
+
+ // Check for derivatives ( should trigger adding jobs )
+ $fileName = basename( $file['filePath'] );
+ $params = array(
+ 'action' => 'query',
+ 'titles' => 'File:' . $fileName,
+ 'prop' => 'videoinfo',
+ 'viprop' => "derivatives",
+ );
+ list($result,,) = $this->doApiRequest( $params );
+
+ // Get the $derivatives:
+ $derivatives = $this->getDerivativesFromResult( $result );
+ // Only the "source" asset will be present at first:
+ $source = current( $derivatives );
+
+ // Check that the source matches the api bandwidth property:
+ $this->assertEquals( $file['bandwidth'], $source['bandwidth'] );
+
+ // Check if the transcode jobs were added:
+ // get results: query jobs table
+ $db = wfGetDB( DB_MASTER );
+ $res = $db->select( 'transcode', '*', array(
+ 'transcode_image_name' => ucfirst( $fileName )
+ ) );
+ // Make sure we target at least one ogg and one webm:
+ $hasOgg = $hasWebM = false;
+ $targetEncodes = array();
+ foreach( $res as $row ){
+ $codec = WebVideoTranscode::$derivativeSettings[ $row->transcode_key ]['videoCodec'];
+ if( $codec == 'theora' ){
+ $hasOgg = true;
+ }
+ if( $codec == 'vp8' ){
+ $hasWebM = true;
+ }
+ $targetEncodes[ $row->transcode_key ] = $row;
+ };
+ // Make sure we have ogg and webm:
+ $this->assertTrue( $hasOgg && $hasWebM );
+
+ // Now run the transcode job queue
+ $this->runTranscodeJobs();
+
+ $res = $db->select( 'transcode', '*', array(
+ 'transcode_image_name' => ucfirst( $fileName )
+ ) );
+
+ // Now check if the derivatives were created:
+ list($result,,) = $this->doApiRequest( $params );
+ $derivatives = $this->getDerivativesFromResult( $result );
+
+ // Check that every requested encode was encoded:
+ foreach( $targetEncodes as $transcodeKey => $row ){
+ $targetEncodeFound = false;
+ foreach( $derivatives as $derv ){
+ // The transcode key is always the last part of the file name:
+ if( substr( $derv['src'], -1 * strlen( $transcodeKey ) ) == $transcodeKey ){
+ $targetEncodeFound = true;
+ }
+ }
+ // Test that target encode was found:
+ $this->assertTrue( $targetEncodeFound );
+ }
+
+ }
+
+ // Run Transcode job
+ function runTranscodeJobs(){
+ $dbw = wfGetDB( DB_MASTER );
+ $type = 'webVideoTranscode';
+ // Set the condition to only run the webVideoTranscode
+ $conds = array( "job_cmd" => $type );
+
+ while ( $dbw->selectField( 'job', 'job_id', $conds, 'runJobs.php' ) ) {
+ for ( ; ; ) {
+ $job = Job::pop_type( $type );
+ if ( !$job )
+ break;
+
+ wfWaitForSlaves( 5 );
+ $t = microtime( true );
+ $offset = $job->id;
+ $status = $job->run();
+ $t = microtime( true ) - $t;
+ $timeMs = intval( $t * 1000 );
+ }
+ }
+ }
+
+ function getDerivativesFromResult( $result ){
+ // Only the source should be listed initially:
+ $this->assertTrue( isset( $result['query']['pages'] ) );
+ $page = current( $result['query']['pages'] );
+
+ $videoInfo = current( $page['videoinfo'] );
+ $this->assertTrue( isset( $videoInfo['derivatives'] ) );
+
+ return $videoInfo['derivatives'];
+ }
+}
diff --git a/extensions/TimedMediaHandler/tests/phpunit/TestWebMHandler.php b/extensions/TimedMediaHandler/tests/phpunit/TestWebMHandler.php
new file mode 100644
index 00000000..2d73f46d
--- /dev/null
+++ b/extensions/TimedMediaHandler/tests/phpunit/TestWebMHandler.php
@@ -0,0 +1,52 @@
+<?php
+class TestOggHandler extends MediaWikiMediaTestCase {
+
+ /** @var OggHandlerTMH */
+ private $handler;
+
+ function getFilePath() {
+ return __DIR__ . '/media';
+ }
+
+ function setUp() {
+ parent::setUp();
+ $this->handler = new WebMHandler;
+ }
+
+ /**
+ * @dataProvider providerGetStreamTypes
+ * @param $filename String name of file
+ * @param $expected array List of codecs in file
+ */
+ function testGetStreamTypes( $filename, $expected ) {
+ $testFile = $this->dataFile( $filename, 'video/webm' );
+ $this->assertEquals( $expected, $this->handler->getStreamTypes( $testFile ) );
+ }
+
+ function providerGetStreamTypes() {
+ return array(
+ array( 'shuttle10seconds.1080x608.webm', array( 'VP8' ) ),
+ array( 'VP9-tractor.webm', array( 'VP9' ) ),
+ array( 'bear-vp9-opus.webm', array( 'Opus', 'VP9' ) )
+ );
+ }
+
+
+ /**
+ * @dataProvider providerGetWebType
+ * @param $filename String name of file
+ * @param $expected String Mime type
+ */
+ function testGetWebType( $filename, $expected ) {
+ $testFile = $this->dataFile( $filename, 'video/webm' );
+ $this->assertEquals( $expected, $this->handler->getWebType( $testFile ) );
+ }
+
+ function providerGetWebType() {
+ return array(
+ array( 'shuttle10seconds.1080x608.webm', 'video/webm; codecs="vp8"' ),
+ array( 'VP9-tractor.webm', 'video/webm; codecs="vp9"' ),
+ array( 'bear-vp9-opus.webm', 'video/webm; codecs="opus, vp9"' )
+ );
+ }
+}
diff --git a/extensions/TimedMediaHandler/tests/phpunit/media/README b/extensions/TimedMediaHandler/tests/phpunit/media/README
new file mode 100644
index 00000000..b21871ea
--- /dev/null
+++ b/extensions/TimedMediaHandler/tests/phpunit/media/README
@@ -0,0 +1,38 @@
+doubleTag.oga and broken-file.ogg were created by Brian Wolff and is released into the public domain
+
+VP9-tractor.webm is from http://base-n.de/webm/VP9%20Sample.html and was encoded from a public domain
+file located at http://media.xiph.org/video/derf/y4m/
+
+bear-vp9-opus.webm comes from the chromnium project at the url
+http://code.metager.de/source/raw/chromium/media/test/data/bear-vp9-opus.webm
+which has the following copyright notice:
+
+1 // Copyright 2014 The Chromium Authors. All rights reserved.
+2 //
+3 // Redistribution and use in source and binary forms, with or without
+4 // modification, are permitted provided that the following conditions are
+5 // met:
+6 //
+7 // * Redistributions of source code must retain the above copyright
+8 // notice, this list of conditions and the following disclaimer.
+9 // * Redistributions in binary form must reproduce the above
+10 // copyright notice, this list of conditions and the following disclaimer
+11 // in the documentation and/or other materials provided with the
+12 // distribution.
+13 // * Neither the name of Google Inc. nor the names of its
+14 // contributors may be used to endorse or promote products derived from
+15 // this software without specific prior written permission.
+16 //
+17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
diff --git a/extensions/TimedMediaHandler/tests/phpunit/media/VP9-tractor.webm b/extensions/TimedMediaHandler/tests/phpunit/media/VP9-tractor.webm
new file mode 100644
index 00000000..bbe96f5d
--- /dev/null
+++ b/extensions/TimedMediaHandler/tests/phpunit/media/VP9-tractor.webm
Binary files differ
diff --git a/extensions/TimedMediaHandler/tests/phpunit/media/bear-vp9-opus.webm b/extensions/TimedMediaHandler/tests/phpunit/media/bear-vp9-opus.webm
new file mode 100644
index 00000000..80355cfa
--- /dev/null
+++ b/extensions/TimedMediaHandler/tests/phpunit/media/bear-vp9-opus.webm
Binary files differ
diff --git a/extensions/TimedMediaHandler/tests/phpunit/media/broken-file.ogg b/extensions/TimedMediaHandler/tests/phpunit/media/broken-file.ogg
new file mode 100644
index 00000000..c9fc4fd5
--- /dev/null
+++ b/extensions/TimedMediaHandler/tests/phpunit/media/broken-file.ogg
Binary files differ
diff --git a/extensions/TimedMediaHandler/tests/phpunit/media/doubleTag.oga b/extensions/TimedMediaHandler/tests/phpunit/media/doubleTag.oga
new file mode 100644
index 00000000..f7fac168
--- /dev/null
+++ b/extensions/TimedMediaHandler/tests/phpunit/media/doubleTag.oga
Binary files differ
diff --git a/extensions/TimedMediaHandler/tests/phpunit/media/shuttle10seconds.1080x608.webm b/extensions/TimedMediaHandler/tests/phpunit/media/shuttle10seconds.1080x608.webm
new file mode 100644
index 00000000..a7b865b1
--- /dev/null
+++ b/extensions/TimedMediaHandler/tests/phpunit/media/shuttle10seconds.1080x608.webm
Binary files differ
diff --git a/extensions/TimedMediaHandler/tests/phpunit/media/test5seconds.electricsheep.300x400.ogv b/extensions/TimedMediaHandler/tests/phpunit/media/test5seconds.electricsheep.300x400.ogv
new file mode 100644
index 00000000..a73ec5bf
--- /dev/null
+++ b/extensions/TimedMediaHandler/tests/phpunit/media/test5seconds.electricsheep.300x400.ogv
Binary files differ