MediaWiki  REL1_24
FileTest.php
Go to the documentation of this file.
00001 <?php
00002 
00003 class FileTest extends MediaWikiMediaTestCase {
00004 
00010     function testCanAnimateThumbIfAppropriate( $filename, $expected ) {
00011         $this->setMwGlobals( 'wgMaxAnimatedGifArea', 9000 );
00012         $file = $this->dataFile( $filename );
00013         $this->assertEquals( $file->canAnimateThumbIfAppropriate(), $expected );
00014     }
00015 
00016     function providerCanAnimate() {
00017         return array(
00018             array( 'nonanimated.gif', true ),
00019             array( 'jpeg-comment-utf.jpg', true ),
00020             array( 'test.tiff', true ),
00021             array( 'Animated_PNG_example_bouncing_beach_ball.png', false ),
00022             array( 'greyscale-png.png', true ),
00023             array( 'Toll_Texas_1.svg', true ),
00024             array( 'LoremIpsum.djvu', true ),
00025             array( '80x60-2layers.xcf', true ),
00026             array( 'Soccer_ball_animated.svg', false ),
00027             array( 'Bishzilla_blink.gif', false ),
00028             array( 'animated.gif', true ),
00029         );
00030     }
00031 
00036     public function testGetThumbnailBucket( $data ) {
00037         $this->setMwGlobals( 'wgThumbnailBuckets', $data['buckets'] );
00038         $this->setMwGlobals( 'wgThumbnailMinimumBucketDistance', $data['minimumBucketDistance'] );
00039 
00040         $fileMock = $this->getMockBuilder( 'File' )
00041             ->setConstructorArgs( array( 'fileMock', false ) )
00042             ->setMethods( array( 'getWidth' ) )
00043             ->getMockForAbstractClass();
00044 
00045         $fileMock->expects( $this->any() )
00046             ->method( 'getWidth' )
00047             ->will( $this->returnValue( $data['width'] ) );
00048 
00049         $this->assertEquals(
00050             $data['expectedBucket'],
00051             $fileMock->getThumbnailBucket( $data['requestedWidth'] ),
00052             $data['message'] );
00053     }
00054 
00055     public function getThumbnailBucketProvider() {
00056         $defaultBuckets = array( 256, 512, 1024, 2048, 4096 );
00057 
00058         return array(
00059             array( array(
00060                 'buckets' => $defaultBuckets,
00061                 'minimumBucketDistance' => 0,
00062                 'width' => 3000,
00063                 'requestedWidth' => 120,
00064                 'expectedBucket' => 256,
00065                 'message' => 'Picking bucket bigger than requested size'
00066             ) ),
00067             array( array(
00068                 'buckets' => $defaultBuckets,
00069                 'minimumBucketDistance' => 0,
00070                 'width' => 3000,
00071                 'requestedWidth' => 300,
00072                 'expectedBucket' => 512,
00073                 'message' => 'Picking bucket bigger than requested size'
00074             ) ),
00075             array( array(
00076                 'buckets' => $defaultBuckets,
00077                 'minimumBucketDistance' => 0,
00078                 'width' => 3000,
00079                 'requestedWidth' => 1024,
00080                 'expectedBucket' => 2048,
00081                 'message' => 'Picking bucket bigger than requested size'
00082             ) ),
00083             array( array(
00084                 'buckets' => $defaultBuckets,
00085                 'minimumBucketDistance' => 0,
00086                 'width' => 3000,
00087                 'requestedWidth' => 2048,
00088                 'expectedBucket' => false,
00089                 'message' => 'Picking no bucket because none is bigger than the requested size'
00090             ) ),
00091             array( array(
00092                 'buckets' => $defaultBuckets,
00093                 'minimumBucketDistance' => 0,
00094                 'width' => 3000,
00095                 'requestedWidth' => 3500,
00096                 'expectedBucket' => false,
00097                 'message' => 'Picking no bucket because requested size is bigger than original'
00098             ) ),
00099             array( array(
00100                 'buckets' => array( 1024 ),
00101                 'minimumBucketDistance' => 0,
00102                 'width' => 3000,
00103                 'requestedWidth' => 1024,
00104                 'expectedBucket' => false,
00105                 'message' => 'Picking no bucket because requested size equals biggest bucket'
00106             ) ),
00107             array( array(
00108                 'buckets' => null,
00109                 'minimumBucketDistance' => 0,
00110                 'width' => 3000,
00111                 'requestedWidth' => 1024,
00112                 'expectedBucket' => false,
00113                 'message' => 'Picking no bucket because no buckets have been specified'
00114             ) ),
00115             array( array(
00116                 'buckets' => array( 256, 512 ),
00117                 'minimumBucketDistance' => 10,
00118                 'width' => 3000,
00119                 'requestedWidth' => 245,
00120                 'expectedBucket' => 256,
00121                 'message' => 'Requested width is distant enough from next bucket for it to be picked'
00122             ) ),
00123             array( array(
00124                 'buckets' => array( 256, 512 ),
00125                 'minimumBucketDistance' => 10,
00126                 'width' => 3000,
00127                 'requestedWidth' => 246,
00128                 'expectedBucket' => 512,
00129                 'message' => 'Requested width is too close to next bucket, picking next one'
00130             ) ),
00131         );
00132     }
00133 
00138     public function testGetThumbnailSource( $data ) {
00139         $backendMock = $this->getMockBuilder( 'FSFileBackend' )
00140             ->setConstructorArgs( array( array( 'name' => 'backendMock', 'wikiId' => wfWikiId() ) ) )
00141             ->getMock();
00142 
00143         $repoMock = $this->getMockBuilder( 'FileRepo' )
00144             ->setConstructorArgs( array( array( 'name' => 'repoMock', 'backend' => $backendMock ) ) )
00145             ->setMethods( array( 'fileExists', 'getLocalReference' ) )
00146             ->getMock();
00147 
00148         $fsFile = new FSFile( 'fsFilePath' );
00149 
00150         $repoMock->expects( $this->any() )
00151             ->method( 'fileExists' )
00152             ->will( $this->returnValue( true ) );
00153 
00154         $repoMock->expects( $this->any() )
00155             ->method( 'getLocalReference' )
00156             ->will( $this->returnValue( $fsFile ) );
00157 
00158         $handlerMock = $this->getMock( 'BitmapHandler', array( 'supportsBucketing' ) );
00159         $handlerMock->expects( $this->any() )
00160             ->method( 'supportsBucketing' )
00161             ->will( $this->returnValue( $data['supportsBucketing'] ) );
00162 
00163         $fileMock = $this->getMockBuilder( 'File' )
00164             ->setConstructorArgs( array( 'fileMock', $repoMock ) )
00165             ->setMethods( array( 'getThumbnailBucket', 'getLocalRefPath', 'getHandler' ) )
00166             ->getMockForAbstractClass();
00167 
00168         $fileMock->expects( $this->any() )
00169             ->method( 'getThumbnailBucket' )
00170             ->will( $this->returnValue( $data['thumbnailBucket'] ) );
00171 
00172         $fileMock->expects( $this->any() )
00173             ->method( 'getLocalRefPath' )
00174             ->will( $this->returnValue( 'localRefPath' ) );
00175 
00176         $fileMock->expects( $this->any() )
00177             ->method( 'getHandler' )
00178             ->will( $this->returnValue( $handlerMock ) );
00179 
00180         $reflection = new ReflectionClass( $fileMock );
00181         $reflection_property = $reflection->getProperty( 'handler' );
00182         $reflection_property->setAccessible( true );
00183         $reflection_property->setValue( $fileMock, $handlerMock );
00184 
00185         if ( !is_null( $data['tmpBucketedThumbCache'] ) ) {
00186             $reflection_property = $reflection->getProperty( 'tmpBucketedThumbCache' );
00187             $reflection_property->setAccessible( true );
00188             $reflection_property->setValue( $fileMock, $data['tmpBucketedThumbCache'] );
00189         }
00190 
00191         $result = $fileMock->getThumbnailSource(
00192             array( 'physicalWidth' => $data['physicalWidth'] ) );
00193 
00194         $this->assertEquals( $data['expectedPath'], $result['path'], $data['message'] );
00195     }
00196 
00197     public function getThumbnailSourceProvider() {
00198         return array(
00199             array( array(
00200                 'supportsBucketing' => true,
00201                 'tmpBucketedThumbCache' => null,
00202                 'thumbnailBucket' => 1024,
00203                 'physicalWidth' => 2048,
00204                 'expectedPath' => 'fsFilePath',
00205                 'message' => 'Path downloaded from storage'
00206             ) ),
00207             array( array(
00208                 'supportsBucketing' => true,
00209                 'tmpBucketedThumbCache' => array( 1024 => '/tmp/shouldnotexist' + rand() ),
00210                 'thumbnailBucket' => 1024,
00211                 'physicalWidth' => 2048,
00212                 'expectedPath' => 'fsFilePath',
00213                 'message' => 'Path downloaded from storage because temp file is missing'
00214             ) ),
00215             array( array(
00216                 'supportsBucketing' => true,
00217                 'tmpBucketedThumbCache' => array( 1024 => '/tmp' ),
00218                 'thumbnailBucket' => 1024,
00219                 'physicalWidth' => 2048,
00220                 'expectedPath' => '/tmp',
00221                 'message' => 'Temporary path because temp file was found'
00222             ) ),
00223             array( array(
00224                 'supportsBucketing' => false,
00225                 'tmpBucketedThumbCache' => null,
00226                 'thumbnailBucket' => 1024,
00227                 'physicalWidth' => 2048,
00228                 'expectedPath' => 'localRefPath',
00229                 'message' => 'Original file path because bucketing is unsupported by handler'
00230             ) ),
00231             array( array(
00232                 'supportsBucketing' => true,
00233                 'tmpBucketedThumbCache' => null,
00234                 'thumbnailBucket' => false,
00235                 'physicalWidth' => 2048,
00236                 'expectedPath' => 'localRefPath',
00237                 'message' => 'Original file path because no width provided'
00238             ) ),
00239         );
00240     }
00241 
00246     public function testGenerateBucketsIfNeeded( $data ) {
00247         $this->setMwGlobals( 'wgThumbnailBuckets', $data['buckets'] );
00248 
00249         $backendMock = $this->getMockBuilder( 'FSFileBackend' )
00250             ->setConstructorArgs( array( array( 'name' => 'backendMock', 'wikiId' => wfWikiId() ) ) )
00251             ->getMock();
00252 
00253         $repoMock = $this->getMockBuilder( 'FileRepo' )
00254             ->setConstructorArgs( array( array( 'name' => 'repoMock', 'backend' => $backendMock ) ) )
00255             ->setMethods( array( 'fileExists', 'getLocalReference' ) )
00256             ->getMock();
00257 
00258         $fileMock = $this->getMockBuilder( 'File' )
00259             ->setConstructorArgs( array( 'fileMock', $repoMock ) )
00260             ->setMethods( array( 'getWidth', 'getBucketThumbPath', 'makeTransformTmpFile',
00261                 'generateAndSaveThumb', 'getHandler' ) )
00262             ->getMockForAbstractClass();
00263 
00264         $handlerMock = $this->getMock( 'JpegHandler', array( 'supportsBucketing' ) );
00265         $handlerMock->expects( $this->any() )
00266             ->method( 'supportsBucketing' )
00267             ->will( $this->returnValue( true ) );
00268 
00269         $fileMock->expects( $this->any() )
00270             ->method( 'getHandler' )
00271             ->will( $this->returnValue( $handlerMock ) );
00272 
00273         $reflectionMethod = new ReflectionMethod( 'File', 'generateBucketsIfNeeded' );
00274         $reflectionMethod->setAccessible( true );
00275 
00276         $fileMock->expects( $this->any() )
00277             ->method( 'getWidth' )
00278             ->will( $this->returnValue( $data['width'] ) );
00279 
00280         $fileMock->expects( $data['expectedGetBucketThumbPathCalls'] )
00281             ->method( 'getBucketThumbPath' );
00282 
00283         $repoMock->expects( $data['expectedFileExistsCalls'] )
00284             ->method( 'fileExists' )
00285             ->will( $this->returnValue( $data['fileExistsReturn'] ) );
00286 
00287         $fileMock->expects( $data['expectedMakeTransformTmpFile'] )
00288             ->method( 'makeTransformTmpFile' )
00289             ->will( $this->returnValue( $data['makeTransformTmpFileReturn'] ) );
00290 
00291         $fileMock->expects( $data['expectedGenerateAndSaveThumb'] )
00292             ->method( 'generateAndSaveThumb' )
00293             ->will( $this->returnValue( $data['generateAndSaveThumbReturn'] ) );
00294 
00295         $this->assertEquals( $data['expectedResult'],
00296             $reflectionMethod->invoke(
00297                 $fileMock,
00298                 array(
00299                     'physicalWidth' => $data['physicalWidth'],
00300                     'physicalHeight' => $data['physicalHeight'] )
00301                 ),
00302                 $data['message'] );
00303     }
00304 
00305     public function generateBucketsIfNeededProvider() {
00306         $defaultBuckets = array( 256, 512, 1024, 2048, 4096 );
00307 
00308         return array(
00309             array( array(
00310                 'buckets' => $defaultBuckets,
00311                 'width' => 256,
00312                 'physicalWidth' => 256,
00313                 'physicalHeight' => 100,
00314                 'expectedGetBucketThumbPathCalls' => $this->never(),
00315                 'expectedFileExistsCalls' => $this->never(),
00316                 'fileExistsReturn' => null,
00317                 'expectedMakeTransformTmpFile' => $this->never(),
00318                 'makeTransformTmpFileReturn' => false,
00319                 'expectedGenerateAndSaveThumb' => $this->never(),
00320                 'generateAndSaveThumbReturn' => false,
00321                 'expectedResult' => false,
00322                 'message' => 'No bucket found, nothing to generate'
00323             ) ),
00324             array( array(
00325                 'buckets' => $defaultBuckets,
00326                 'width' => 5000,
00327                 'physicalWidth' => 300,
00328                 'physicalHeight' => 200,
00329                 'expectedGetBucketThumbPathCalls' => $this->once(),
00330                 'expectedFileExistsCalls' => $this->once(),
00331                 'fileExistsReturn' => true,
00332                 'expectedMakeTransformTmpFile' => $this->never(),
00333                 'makeTransformTmpFileReturn' => false,
00334                 'expectedGenerateAndSaveThumb' => $this->never(),
00335                 'generateAndSaveThumbReturn' => false,
00336                 'expectedResult' => false,
00337                 'message' => 'File already exists, no reason to generate buckets'
00338             ) ),
00339             array( array(
00340                 'buckets' => $defaultBuckets,
00341                 'width' => 5000,
00342                 'physicalWidth' => 300,
00343                 'physicalHeight' => 200,
00344                 'expectedGetBucketThumbPathCalls' => $this->once(),
00345                 'expectedFileExistsCalls' => $this->once(),
00346                 'fileExistsReturn' => false,
00347                 'expectedMakeTransformTmpFile' => $this->once(),
00348                 'makeTransformTmpFileReturn' => false,
00349                 'expectedGenerateAndSaveThumb' => $this->never(),
00350                 'generateAndSaveThumbReturn' => false,
00351                 'expectedResult' => false,
00352                 'message' => 'Cannot generate temp file for bucket'
00353             ) ),
00354             array( array(
00355                 'buckets' => $defaultBuckets,
00356                 'width' => 5000,
00357                 'physicalWidth' => 300,
00358                 'physicalHeight' => 200,
00359                 'expectedGetBucketThumbPathCalls' => $this->once(),
00360                 'expectedFileExistsCalls' => $this->once(),
00361                 'fileExistsReturn' => false,
00362                 'expectedMakeTransformTmpFile' => $this->once(),
00363                 'makeTransformTmpFileReturn' => new TempFSFile( '/tmp/foo' ),
00364                 'expectedGenerateAndSaveThumb' => $this->once(),
00365                 'generateAndSaveThumbReturn' => false,
00366                 'expectedResult' => false,
00367                 'message' => 'Bucket image could not be generated'
00368             ) ),
00369             array( array(
00370                 'buckets' => $defaultBuckets,
00371                 'width' => 5000,
00372                 'physicalWidth' => 300,
00373                 'physicalHeight' => 200,
00374                 'expectedGetBucketThumbPathCalls' => $this->once(),
00375                 'expectedFileExistsCalls' => $this->once(),
00376                 'fileExistsReturn' => false,
00377                 'expectedMakeTransformTmpFile' => $this->once(),
00378                 'makeTransformTmpFileReturn' => new TempFSFile( '/tmp/foo' ),
00379                 'expectedGenerateAndSaveThumb' => $this->once(),
00380                 'generateAndSaveThumbReturn' => new ThumbnailImage( false, 'bar', false, false ),
00381                 'expectedResult' => true,
00382                 'message' => 'Bucket image could not be generated'
00383             ) ),
00384         );
00385     }
00386 }