summaryrefslogtreecommitdiff
path: root/www/wiki/tests/phpunit/includes/filerepo/file
diff options
context:
space:
mode:
Diffstat (limited to 'www/wiki/tests/phpunit/includes/filerepo/file')
-rw-r--r--www/wiki/tests/phpunit/includes/filerepo/file/FileTest.php389
-rw-r--r--www/wiki/tests/phpunit/includes/filerepo/file/LocalFileTest.php183
2 files changed, 572 insertions, 0 deletions
diff --git a/www/wiki/tests/phpunit/includes/filerepo/file/FileTest.php b/www/wiki/tests/phpunit/includes/filerepo/file/FileTest.php
new file mode 100644
index 00000000..3f4e46b5
--- /dev/null
+++ b/www/wiki/tests/phpunit/includes/filerepo/file/FileTest.php
@@ -0,0 +1,389 @@
+<?php
+
+class FileTest extends MediaWikiMediaTestCase {
+
+ /**
+ * @param string $filename
+ * @param bool $expected
+ * @dataProvider providerCanAnimate
+ * @covers File::canAnimateThumbIfAppropriate
+ */
+ function testCanAnimateThumbIfAppropriate( $filename, $expected ) {
+ $this->setMwGlobals( 'wgMaxAnimatedGifArea', 9000 );
+ $file = $this->dataFile( $filename );
+ $this->assertEquals( $file->canAnimateThumbIfAppropriate(), $expected );
+ }
+
+ function providerCanAnimate() {
+ return [
+ [ 'nonanimated.gif', true ],
+ [ 'jpeg-comment-utf.jpg', true ],
+ [ 'test.tiff', true ],
+ [ 'Animated_PNG_example_bouncing_beach_ball.png', false ],
+ [ 'greyscale-png.png', true ],
+ [ 'Toll_Texas_1.svg', true ],
+ [ 'LoremIpsum.djvu', true ],
+ [ '80x60-2layers.xcf', true ],
+ [ 'Soccer_ball_animated.svg', false ],
+ [ 'Bishzilla_blink.gif', false ],
+ [ 'animated.gif', true ],
+ ];
+ }
+
+ /**
+ * @dataProvider getThumbnailBucketProvider
+ * @covers File::getThumbnailBucket
+ */
+ public function testGetThumbnailBucket( $data ) {
+ $this->setMwGlobals( 'wgThumbnailBuckets', $data['buckets'] );
+ $this->setMwGlobals( 'wgThumbnailMinimumBucketDistance', $data['minimumBucketDistance'] );
+
+ $fileMock = $this->getMockBuilder( File::class )
+ ->setConstructorArgs( [ 'fileMock', false ] )
+ ->setMethods( [ 'getWidth' ] )
+ ->getMockForAbstractClass();
+
+ $fileMock->expects( $this->any() )
+ ->method( 'getWidth' )
+ ->will( $this->returnValue( $data['width'] ) );
+
+ $this->assertEquals(
+ $data['expectedBucket'],
+ $fileMock->getThumbnailBucket( $data['requestedWidth'] ),
+ $data['message'] );
+ }
+
+ public function getThumbnailBucketProvider() {
+ $defaultBuckets = [ 256, 512, 1024, 2048, 4096 ];
+
+ return [
+ [ [
+ 'buckets' => $defaultBuckets,
+ 'minimumBucketDistance' => 0,
+ 'width' => 3000,
+ 'requestedWidth' => 120,
+ 'expectedBucket' => 256,
+ 'message' => 'Picking bucket bigger than requested size'
+ ] ],
+ [ [
+ 'buckets' => $defaultBuckets,
+ 'minimumBucketDistance' => 0,
+ 'width' => 3000,
+ 'requestedWidth' => 300,
+ 'expectedBucket' => 512,
+ 'message' => 'Picking bucket bigger than requested size'
+ ] ],
+ [ [
+ 'buckets' => $defaultBuckets,
+ 'minimumBucketDistance' => 0,
+ 'width' => 3000,
+ 'requestedWidth' => 1024,
+ 'expectedBucket' => 2048,
+ 'message' => 'Picking bucket bigger than requested size'
+ ] ],
+ [ [
+ 'buckets' => $defaultBuckets,
+ 'minimumBucketDistance' => 0,
+ 'width' => 3000,
+ 'requestedWidth' => 2048,
+ 'expectedBucket' => false,
+ 'message' => 'Picking no bucket because none is bigger than the requested size'
+ ] ],
+ [ [
+ 'buckets' => $defaultBuckets,
+ 'minimumBucketDistance' => 0,
+ 'width' => 3000,
+ 'requestedWidth' => 3500,
+ 'expectedBucket' => false,
+ 'message' => 'Picking no bucket because requested size is bigger than original'
+ ] ],
+ [ [
+ 'buckets' => [ 1024 ],
+ 'minimumBucketDistance' => 0,
+ 'width' => 3000,
+ 'requestedWidth' => 1024,
+ 'expectedBucket' => false,
+ 'message' => 'Picking no bucket because requested size equals biggest bucket'
+ ] ],
+ [ [
+ 'buckets' => null,
+ 'minimumBucketDistance' => 0,
+ 'width' => 3000,
+ 'requestedWidth' => 1024,
+ 'expectedBucket' => false,
+ 'message' => 'Picking no bucket because no buckets have been specified'
+ ] ],
+ [ [
+ 'buckets' => [ 256, 512 ],
+ 'minimumBucketDistance' => 10,
+ 'width' => 3000,
+ 'requestedWidth' => 245,
+ 'expectedBucket' => 256,
+ 'message' => 'Requested width is distant enough from next bucket for it to be picked'
+ ] ],
+ [ [
+ 'buckets' => [ 256, 512 ],
+ 'minimumBucketDistance' => 10,
+ 'width' => 3000,
+ 'requestedWidth' => 246,
+ 'expectedBucket' => 512,
+ 'message' => 'Requested width is too close to next bucket, picking next one'
+ ] ],
+ ];
+ }
+
+ /**
+ * @dataProvider getThumbnailSourceProvider
+ * @covers File::getThumbnailSource
+ */
+ public function testGetThumbnailSource( $data ) {
+ $backendMock = $this->getMockBuilder( FSFileBackend::class )
+ ->setConstructorArgs( [ [ 'name' => 'backendMock', 'wikiId' => wfWikiID() ] ] )
+ ->getMock();
+
+ $repoMock = $this->getMockBuilder( FileRepo::class )
+ ->setConstructorArgs( [ [ 'name' => 'repoMock', 'backend' => $backendMock ] ] )
+ ->setMethods( [ 'fileExists', 'getLocalReference' ] )
+ ->getMock();
+
+ $fsFile = new FSFile( 'fsFilePath' );
+
+ $repoMock->expects( $this->any() )
+ ->method( 'fileExists' )
+ ->will( $this->returnValue( true ) );
+
+ $repoMock->expects( $this->any() )
+ ->method( 'getLocalReference' )
+ ->will( $this->returnValue( $fsFile ) );
+
+ $handlerMock = $this->getMockBuilder( BitmapHandler::class )
+ ->setMethods( [ 'supportsBucketing' ] )->getMock();
+ $handlerMock->expects( $this->any() )
+ ->method( 'supportsBucketing' )
+ ->will( $this->returnValue( $data['supportsBucketing'] ) );
+
+ $fileMock = $this->getMockBuilder( File::class )
+ ->setConstructorArgs( [ 'fileMock', $repoMock ] )
+ ->setMethods( [ 'getThumbnailBucket', 'getLocalRefPath', 'getHandler' ] )
+ ->getMockForAbstractClass();
+
+ $fileMock->expects( $this->any() )
+ ->method( 'getThumbnailBucket' )
+ ->will( $this->returnValue( $data['thumbnailBucket'] ) );
+
+ $fileMock->expects( $this->any() )
+ ->method( 'getLocalRefPath' )
+ ->will( $this->returnValue( 'localRefPath' ) );
+
+ $fileMock->expects( $this->any() )
+ ->method( 'getHandler' )
+ ->will( $this->returnValue( $handlerMock ) );
+
+ $reflection = new ReflectionClass( $fileMock );
+ $reflection_property = $reflection->getProperty( 'handler' );
+ $reflection_property->setAccessible( true );
+ $reflection_property->setValue( $fileMock, $handlerMock );
+
+ if ( !is_null( $data['tmpBucketedThumbCache'] ) ) {
+ $reflection_property = $reflection->getProperty( 'tmpBucketedThumbCache' );
+ $reflection_property->setAccessible( true );
+ $reflection_property->setValue( $fileMock, $data['tmpBucketedThumbCache'] );
+ }
+
+ $result = $fileMock->getThumbnailSource(
+ [ 'physicalWidth' => $data['physicalWidth'] ] );
+
+ $this->assertEquals( $data['expectedPath'], $result['path'], $data['message'] );
+ }
+
+ public function getThumbnailSourceProvider() {
+ return [
+ [ [
+ 'supportsBucketing' => true,
+ 'tmpBucketedThumbCache' => null,
+ 'thumbnailBucket' => 1024,
+ 'physicalWidth' => 2048,
+ 'expectedPath' => 'fsFilePath',
+ 'message' => 'Path downloaded from storage'
+ ] ],
+ [ [
+ 'supportsBucketing' => true,
+ 'tmpBucketedThumbCache' => [ 1024 => '/tmp/shouldnotexist' . rand() ],
+ 'thumbnailBucket' => 1024,
+ 'physicalWidth' => 2048,
+ 'expectedPath' => 'fsFilePath',
+ 'message' => 'Path downloaded from storage because temp file is missing'
+ ] ],
+ [ [
+ 'supportsBucketing' => true,
+ 'tmpBucketedThumbCache' => [ 1024 => '/tmp' ],
+ 'thumbnailBucket' => 1024,
+ 'physicalWidth' => 2048,
+ 'expectedPath' => '/tmp',
+ 'message' => 'Temporary path because temp file was found'
+ ] ],
+ [ [
+ 'supportsBucketing' => false,
+ 'tmpBucketedThumbCache' => null,
+ 'thumbnailBucket' => 1024,
+ 'physicalWidth' => 2048,
+ 'expectedPath' => 'localRefPath',
+ 'message' => 'Original file path because bucketing is unsupported by handler'
+ ] ],
+ [ [
+ 'supportsBucketing' => true,
+ 'tmpBucketedThumbCache' => null,
+ 'thumbnailBucket' => false,
+ 'physicalWidth' => 2048,
+ 'expectedPath' => 'localRefPath',
+ 'message' => 'Original file path because no width provided'
+ ] ],
+ ];
+ }
+
+ /**
+ * @dataProvider generateBucketsIfNeededProvider
+ * @covers File::generateBucketsIfNeeded
+ */
+ public function testGenerateBucketsIfNeeded( $data ) {
+ $this->setMwGlobals( 'wgThumbnailBuckets', $data['buckets'] );
+
+ $backendMock = $this->getMockBuilder( FSFileBackend::class )
+ ->setConstructorArgs( [ [ 'name' => 'backendMock', 'wikiId' => wfWikiID() ] ] )
+ ->getMock();
+
+ $repoMock = $this->getMockBuilder( FileRepo::class )
+ ->setConstructorArgs( [ [ 'name' => 'repoMock', 'backend' => $backendMock ] ] )
+ ->setMethods( [ 'fileExists', 'getLocalReference' ] )
+ ->getMock();
+
+ $fileMock = $this->getMockBuilder( File::class )
+ ->setConstructorArgs( [ 'fileMock', $repoMock ] )
+ ->setMethods( [ 'getWidth', 'getBucketThumbPath', 'makeTransformTmpFile',
+ 'generateAndSaveThumb', 'getHandler' ] )
+ ->getMockForAbstractClass();
+
+ $handlerMock = $this->getMockBuilder( JpegHandler::class )
+ ->setMethods( [ 'supportsBucketing' ] )->getMock();
+ $handlerMock->expects( $this->any() )
+ ->method( 'supportsBucketing' )
+ ->will( $this->returnValue( true ) );
+
+ $fileMock->expects( $this->any() )
+ ->method( 'getHandler' )
+ ->will( $this->returnValue( $handlerMock ) );
+
+ $reflectionMethod = new ReflectionMethod( File::class, 'generateBucketsIfNeeded' );
+ $reflectionMethod->setAccessible( true );
+
+ $fileMock->expects( $this->any() )
+ ->method( 'getWidth' )
+ ->will( $this->returnValue( $data['width'] ) );
+
+ $fileMock->expects( $data['expectedGetBucketThumbPathCalls'] )
+ ->method( 'getBucketThumbPath' );
+
+ $repoMock->expects( $data['expectedFileExistsCalls'] )
+ ->method( 'fileExists' )
+ ->will( $this->returnValue( $data['fileExistsReturn'] ) );
+
+ $fileMock->expects( $data['expectedMakeTransformTmpFile'] )
+ ->method( 'makeTransformTmpFile' )
+ ->will( $this->returnValue( $data['makeTransformTmpFileReturn'] ) );
+
+ $fileMock->expects( $data['expectedGenerateAndSaveThumb'] )
+ ->method( 'generateAndSaveThumb' )
+ ->will( $this->returnValue( $data['generateAndSaveThumbReturn'] ) );
+
+ $this->assertEquals( $data['expectedResult'],
+ $reflectionMethod->invoke(
+ $fileMock,
+ [
+ 'physicalWidth' => $data['physicalWidth'],
+ 'physicalHeight' => $data['physicalHeight'] ]
+ ),
+ $data['message'] );
+ }
+
+ public function generateBucketsIfNeededProvider() {
+ $defaultBuckets = [ 256, 512, 1024, 2048, 4096 ];
+
+ return [
+ [ [
+ 'buckets' => $defaultBuckets,
+ 'width' => 256,
+ 'physicalWidth' => 256,
+ 'physicalHeight' => 100,
+ 'expectedGetBucketThumbPathCalls' => $this->never(),
+ 'expectedFileExistsCalls' => $this->never(),
+ 'fileExistsReturn' => null,
+ 'expectedMakeTransformTmpFile' => $this->never(),
+ 'makeTransformTmpFileReturn' => false,
+ 'expectedGenerateAndSaveThumb' => $this->never(),
+ 'generateAndSaveThumbReturn' => false,
+ 'expectedResult' => false,
+ 'message' => 'No bucket found, nothing to generate'
+ ] ],
+ [ [
+ 'buckets' => $defaultBuckets,
+ 'width' => 5000,
+ 'physicalWidth' => 300,
+ 'physicalHeight' => 200,
+ 'expectedGetBucketThumbPathCalls' => $this->once(),
+ 'expectedFileExistsCalls' => $this->once(),
+ 'fileExistsReturn' => true,
+ 'expectedMakeTransformTmpFile' => $this->never(),
+ 'makeTransformTmpFileReturn' => false,
+ 'expectedGenerateAndSaveThumb' => $this->never(),
+ 'generateAndSaveThumbReturn' => false,
+ 'expectedResult' => false,
+ 'message' => 'File already exists, no reason to generate buckets'
+ ] ],
+ [ [
+ 'buckets' => $defaultBuckets,
+ 'width' => 5000,
+ 'physicalWidth' => 300,
+ 'physicalHeight' => 200,
+ 'expectedGetBucketThumbPathCalls' => $this->once(),
+ 'expectedFileExistsCalls' => $this->once(),
+ 'fileExistsReturn' => false,
+ 'expectedMakeTransformTmpFile' => $this->once(),
+ 'makeTransformTmpFileReturn' => false,
+ 'expectedGenerateAndSaveThumb' => $this->never(),
+ 'generateAndSaveThumbReturn' => false,
+ 'expectedResult' => false,
+ 'message' => 'Cannot generate temp file for bucket'
+ ] ],
+ [ [
+ 'buckets' => $defaultBuckets,
+ 'width' => 5000,
+ 'physicalWidth' => 300,
+ 'physicalHeight' => 200,
+ 'expectedGetBucketThumbPathCalls' => $this->once(),
+ 'expectedFileExistsCalls' => $this->once(),
+ 'fileExistsReturn' => false,
+ 'expectedMakeTransformTmpFile' => $this->once(),
+ 'makeTransformTmpFileReturn' => new TempFSFile( '/tmp/foo' ),
+ 'expectedGenerateAndSaveThumb' => $this->once(),
+ 'generateAndSaveThumbReturn' => false,
+ 'expectedResult' => false,
+ 'message' => 'Bucket image could not be generated'
+ ] ],
+ [ [
+ 'buckets' => $defaultBuckets,
+ 'width' => 5000,
+ 'physicalWidth' => 300,
+ 'physicalHeight' => 200,
+ 'expectedGetBucketThumbPathCalls' => $this->once(),
+ 'expectedFileExistsCalls' => $this->once(),
+ 'fileExistsReturn' => false,
+ 'expectedMakeTransformTmpFile' => $this->once(),
+ 'makeTransformTmpFileReturn' => new TempFSFile( '/tmp/foo' ),
+ 'expectedGenerateAndSaveThumb' => $this->once(),
+ 'generateAndSaveThumbReturn' => new ThumbnailImage( false, 'bar', false, false ),
+ 'expectedResult' => true,
+ 'message' => 'Bucket image could not be generated'
+ ] ],
+ ];
+ }
+}
diff --git a/www/wiki/tests/phpunit/includes/filerepo/file/LocalFileTest.php b/www/wiki/tests/phpunit/includes/filerepo/file/LocalFileTest.php
new file mode 100644
index 00000000..e25e6064
--- /dev/null
+++ b/www/wiki/tests/phpunit/includes/filerepo/file/LocalFileTest.php
@@ -0,0 +1,183 @@
+<?php
+
+/**
+ * These tests should work regardless of $wgCapitalLinks
+ * @todo Split tests into providers and test methods
+ */
+
+class LocalFileTest extends MediaWikiTestCase {
+
+ protected function setUp() {
+ parent::setUp();
+
+ $this->setMwGlobals( 'wgCapitalLinks', true );
+
+ $info = [
+ 'name' => 'test',
+ 'directory' => '/testdir',
+ 'url' => '/testurl',
+ 'hashLevels' => 2,
+ 'transformVia404' => false,
+ 'backend' => new FSFileBackend( [
+ 'name' => 'local-backend',
+ 'wikiId' => wfWikiID(),
+ 'containerPaths' => [
+ 'cont1' => "/testdir/local-backend/tempimages/cont1",
+ 'cont2' => "/testdir/local-backend/tempimages/cont2"
+ ]
+ ] )
+ ];
+ $this->repo_hl0 = new LocalRepo( [ 'hashLevels' => 0 ] + $info );
+ $this->repo_hl2 = new LocalRepo( [ 'hashLevels' => 2 ] + $info );
+ $this->repo_lc = new LocalRepo( [ 'initialCapital' => false ] + $info );
+ $this->file_hl0 = $this->repo_hl0->newFile( 'test!' );
+ $this->file_hl2 = $this->repo_hl2->newFile( 'test!' );
+ $this->file_lc = $this->repo_lc->newFile( 'test!' );
+ }
+
+ /**
+ * @covers File::getHashPath
+ */
+ public function testGetHashPath() {
+ $this->assertEquals( '', $this->file_hl0->getHashPath() );
+ $this->assertEquals( 'a/a2/', $this->file_hl2->getHashPath() );
+ $this->assertEquals( 'c/c4/', $this->file_lc->getHashPath() );
+ }
+
+ /**
+ * @covers File::getRel
+ */
+ public function testGetRel() {
+ $this->assertEquals( 'Test!', $this->file_hl0->getRel() );
+ $this->assertEquals( 'a/a2/Test!', $this->file_hl2->getRel() );
+ $this->assertEquals( 'c/c4/test!', $this->file_lc->getRel() );
+ }
+
+ /**
+ * @covers File::getUrlRel
+ */
+ public function testGetUrlRel() {
+ $this->assertEquals( 'Test%21', $this->file_hl0->getUrlRel() );
+ $this->assertEquals( 'a/a2/Test%21', $this->file_hl2->getUrlRel() );
+ $this->assertEquals( 'c/c4/test%21', $this->file_lc->getUrlRel() );
+ }
+
+ /**
+ * @covers File::getArchivePath
+ */
+ public function testGetArchivePath() {
+ $this->assertEquals(
+ 'mwstore://local-backend/test-public/archive',
+ $this->file_hl0->getArchivePath()
+ );
+ $this->assertEquals(
+ 'mwstore://local-backend/test-public/archive/a/a2',
+ $this->file_hl2->getArchivePath()
+ );
+ $this->assertEquals(
+ 'mwstore://local-backend/test-public/archive/!',
+ $this->file_hl0->getArchivePath( '!' )
+ );
+ $this->assertEquals(
+ 'mwstore://local-backend/test-public/archive/a/a2/!',
+ $this->file_hl2->getArchivePath( '!' )
+ );
+ }
+
+ /**
+ * @covers File::getThumbPath
+ */
+ public function testGetThumbPath() {
+ $this->assertEquals(
+ 'mwstore://local-backend/test-thumb/Test!',
+ $this->file_hl0->getThumbPath()
+ );
+ $this->assertEquals(
+ 'mwstore://local-backend/test-thumb/a/a2/Test!',
+ $this->file_hl2->getThumbPath()
+ );
+ $this->assertEquals(
+ 'mwstore://local-backend/test-thumb/Test!/x',
+ $this->file_hl0->getThumbPath( 'x' )
+ );
+ $this->assertEquals(
+ 'mwstore://local-backend/test-thumb/a/a2/Test!/x',
+ $this->file_hl2->getThumbPath( 'x' )
+ );
+ }
+
+ /**
+ * @covers File::getArchiveUrl
+ */
+ public function testGetArchiveUrl() {
+ $this->assertEquals( '/testurl/archive', $this->file_hl0->getArchiveUrl() );
+ $this->assertEquals( '/testurl/archive/a/a2', $this->file_hl2->getArchiveUrl() );
+ $this->assertEquals( '/testurl/archive/%21', $this->file_hl0->getArchiveUrl( '!' ) );
+ $this->assertEquals( '/testurl/archive/a/a2/%21', $this->file_hl2->getArchiveUrl( '!' ) );
+ }
+
+ /**
+ * @covers File::getThumbUrl
+ */
+ public function testGetThumbUrl() {
+ $this->assertEquals( '/testurl/thumb/Test%21', $this->file_hl0->getThumbUrl() );
+ $this->assertEquals( '/testurl/thumb/a/a2/Test%21', $this->file_hl2->getThumbUrl() );
+ $this->assertEquals( '/testurl/thumb/Test%21/x', $this->file_hl0->getThumbUrl( 'x' ) );
+ $this->assertEquals( '/testurl/thumb/a/a2/Test%21/x', $this->file_hl2->getThumbUrl( 'x' ) );
+ }
+
+ /**
+ * @covers File::getArchiveVirtualUrl
+ */
+ public function testGetArchiveVirtualUrl() {
+ $this->assertEquals( 'mwrepo://test/public/archive', $this->file_hl0->getArchiveVirtualUrl() );
+ $this->assertEquals(
+ 'mwrepo://test/public/archive/a/a2',
+ $this->file_hl2->getArchiveVirtualUrl()
+ );
+ $this->assertEquals(
+ 'mwrepo://test/public/archive/%21',
+ $this->file_hl0->getArchiveVirtualUrl( '!' )
+ );
+ $this->assertEquals(
+ 'mwrepo://test/public/archive/a/a2/%21',
+ $this->file_hl2->getArchiveVirtualUrl( '!' )
+ );
+ }
+
+ /**
+ * @covers File::getThumbVirtualUrl
+ */
+ public function testGetThumbVirtualUrl() {
+ $this->assertEquals( 'mwrepo://test/thumb/Test%21', $this->file_hl0->getThumbVirtualUrl() );
+ $this->assertEquals( 'mwrepo://test/thumb/a/a2/Test%21', $this->file_hl2->getThumbVirtualUrl() );
+ $this->assertEquals(
+ 'mwrepo://test/thumb/Test%21/%21',
+ $this->file_hl0->getThumbVirtualUrl( '!' )
+ );
+ $this->assertEquals(
+ 'mwrepo://test/thumb/a/a2/Test%21/%21',
+ $this->file_hl2->getThumbVirtualUrl( '!' )
+ );
+ }
+
+ /**
+ * @covers File::getUrl
+ */
+ public function testGetUrl() {
+ $this->assertEquals( '/testurl/Test%21', $this->file_hl0->getUrl() );
+ $this->assertEquals( '/testurl/a/a2/Test%21', $this->file_hl2->getUrl() );
+ }
+
+ /**
+ * @covers ::wfLocalFile
+ */
+ public function testWfLocalFile() {
+ $file = wfLocalFile( "File:Some_file_that_probably_doesn't exist.png" );
+ $this->assertThat(
+ $file,
+ $this->isInstanceOf( LocalFile::class ),
+ 'wfLocalFile() returns LocalFile for valid Titles'
+ );
+ }
+}