3 class FileRepoFileTest
extends MediaWikiMediaTestCase
{
5 * @dataProvider getThumbnailBucketProvider
6 * @covers File::getThumbnailBucket
8 public function testGetThumbnailBucket( $data ) {
9 $this->setMwGlobals( 'wgThumbnailBuckets', $data['buckets'] );
10 $this->setMwGlobals( 'wgThumbnailMinimumBucketDistance', $data['minimumBucketDistance'] );
12 $fileMock = $this->getMockBuilder( 'File' )
13 ->setConstructorArgs( array( 'fileMock', false ) )
14 ->setMethods( array( 'getWidth' ) )
15 ->getMockForAbstractClass();
17 $fileMock->expects( $this->any() )->method( 'getWidth' )->will(
18 $this->returnValue( $data['width'] ) );
21 $data['expectedBucket'],
22 $fileMock->getThumbnailBucket( $data['requestedWidth'] ),
26 public function getThumbnailBucketProvider() {
27 $defaultBuckets = array( 256, 512, 1024, 2048, 4096 );
31 'buckets' => $defaultBuckets,
32 'minimumBucketDistance' => 0,
34 'requestedWidth' => 120,
35 'expectedBucket' => 256,
36 'message' => 'Picking bucket bigger than requested size'
39 'buckets' => $defaultBuckets,
40 'minimumBucketDistance' => 0,
42 'requestedWidth' => 300,
43 'expectedBucket' => 512,
44 'message' => 'Picking bucket bigger than requested size'
47 'buckets' => $defaultBuckets,
48 'minimumBucketDistance' => 0,
50 'requestedWidth' => 1024,
51 'expectedBucket' => 2048,
52 'message' => 'Picking bucket bigger than requested size'
55 'buckets' => $defaultBuckets,
56 'minimumBucketDistance' => 0,
58 'requestedWidth' => 2048,
59 'expectedBucket' => false,
60 'message' => 'Picking no bucket because none is bigger than the requested size'
63 'buckets' => $defaultBuckets,
64 'minimumBucketDistance' => 0,
66 'requestedWidth' => 3500,
67 'expectedBucket' => false,
68 'message' => 'Picking no bucket because requested size is bigger than original'
71 'buckets' => array( 1024 ),
72 'minimumBucketDistance' => 0,
74 'requestedWidth' => 1024,
75 'expectedBucket' => false,
76 'message' => 'Picking no bucket because requested size equals biggest bucket'
80 'minimumBucketDistance' => 0,
82 'requestedWidth' => 1024,
83 'expectedBucket' => false,
84 'message' => 'Picking no bucket because no buckets have been specified'
87 'buckets' => array( 256, 512 ),
88 'minimumBucketDistance' => 10,
90 'requestedWidth' => 245,
91 'expectedBucket' => 256,
92 'message' => 'Requested width is distant enough from next bucket for it to be picked'
95 'buckets' => array( 256, 512 ),
96 'minimumBucketDistance' => 10,
98 'requestedWidth' => 246,
99 'expectedBucket' => 512,
100 'message' => 'Requested width is too close to next bucket, picking next one'
106 * @dataProvider getThumbnailSourceProvider
107 * @covers File::getThumbnailSource
109 public function testGetThumbnailSource( $data ) {
110 $backendMock = $this->getMockBuilder( 'FSFileBackend' )
111 ->setConstructorArgs( array( array( 'name' => 'backendMock', 'wikiId' => wfWikiId() ) ) )
114 $repoMock = $this->getMockBuilder( 'FileRepo' )
115 ->setConstructorArgs( array( array( 'name' => 'repoMock', 'backend' => $backendMock ) ) )
116 ->setMethods( array( 'fileExists', 'getLocalReference' ) )
119 $fsFile = new FSFile( 'fsFilePath' );
121 $repoMock->expects( $this->any() )->method( 'fileExists' )->will(
122 $this->returnValue( true ) );
124 $repoMock->expects( $this->any() )->method( 'getLocalReference' )->will(
125 $this->returnValue( $fsFile ) );
127 $handlerMock = $this->getMock( 'BitmapHandler', array( 'supportsBucketing' ) );
128 $handlerMock->expects( $this->any() )->method( 'supportsBucketing' )->will(
129 $this->returnValue( $data['supportsBucketing'] ) );
131 $fileMock = $this->getMockBuilder( 'File' )
132 ->setConstructorArgs( array( 'fileMock', $repoMock ) )
133 ->setMethods( array( 'getThumbnailBucket', 'getLocalRefPath', 'getHandler' ) )
134 ->getMockForAbstractClass();
136 $fileMock->expects( $this->any() )->method( 'getThumbnailBucket' )->will(
137 $this->returnValue( $data['thumbnailBucket'] ) );
139 $fileMock->expects( $this->any() )->method( 'getLocalRefPath' )->will(
140 $this->returnValue( 'localRefPath' ) );
142 $fileMock->expects( $this->any() )->method( 'getHandler' )->will(
143 $this->returnValue( $handlerMock ) );
145 $reflection = new ReflectionClass( $fileMock );
146 $reflection_property = $reflection->getProperty( 'handler' );
147 $reflection_property->setAccessible( true );
148 $reflection_property->setValue( $fileMock, $handlerMock );
150 if ( !is_null( $data['tmpBucketedThumbCache'] ) ) {
151 $reflection_property = $reflection->getProperty( 'tmpBucketedThumbCache' );
152 $reflection_property->setAccessible( true );
153 $reflection_property->setValue( $fileMock, $data['tmpBucketedThumbCache'] );
156 $result = $fileMock->getThumbnailSource(
157 array( 'physicalWidth' => $data['physicalWidth'] ) );
159 $this->assertEquals( $data['expectedPath'], $result['path'], $data['message'] );
162 public function getThumbnailSourceProvider() {
165 'supportsBucketing' => true,
166 'tmpBucketedThumbCache' => null,
167 'thumbnailBucket' => 1024,
168 'physicalWidth' => 2048,
169 'expectedPath' => 'fsFilePath',
170 'message' => 'Path downloaded from storage'
173 'supportsBucketing' => true,
174 'tmpBucketedThumbCache' => array( 1024 => '/tmp/shouldnotexist' +
rand() ),
175 'thumbnailBucket' => 1024,
176 'physicalWidth' => 2048,
177 'expectedPath' => 'fsFilePath',
178 'message' => 'Path downloaded from storage because temp file is missing'
181 'supportsBucketing' => true,
182 'tmpBucketedThumbCache' => array( 1024 => '/tmp' ),
183 'thumbnailBucket' => 1024,
184 'physicalWidth' => 2048,
185 'expectedPath' => '/tmp',
186 'message' => 'Temporary path because temp file was found'
189 'supportsBucketing' => false,
190 'tmpBucketedThumbCache' => null,
191 'thumbnailBucket' => 1024,
192 'physicalWidth' => 2048,
193 'expectedPath' => 'localRefPath',
194 'message' => 'Original file path because bucketing is unsupported by handler'
197 'supportsBucketing' => true,
198 'tmpBucketedThumbCache' => null,
199 'thumbnailBucket' => false,
200 'physicalWidth' => 2048,
201 'expectedPath' => 'localRefPath',
202 'message' => 'Original file path because no width provided'
208 * @dataProvider generateBucketsIfNeededProvider
209 * @covers File::generateBucketsIfNeeded
211 public function testGenerateBucketsIfNeeded( $data ) {
212 $this->setMwGlobals( 'wgThumbnailBuckets', $data['buckets'] );
214 $backendMock = $this->getMockBuilder( 'FSFileBackend' )
215 ->setConstructorArgs( array( array( 'name' => 'backendMock', 'wikiId' => wfWikiId() ) ) )
218 $repoMock = $this->getMockBuilder( 'FileRepo' )
219 ->setConstructorArgs( array( array( 'name' => 'repoMock', 'backend' => $backendMock ) ) )
220 ->setMethods( array( 'fileExists', 'getLocalReference' ) )
223 $fileMock = $this->getMockBuilder( 'File' )
224 ->setConstructorArgs( array( 'fileMock', $repoMock ) )
225 ->setMethods( array( 'getWidth', 'getBucketThumbPath', 'makeTransformTmpFile', 'generateAndSaveThumb', 'getHandler' ) )
226 ->getMockForAbstractClass();
228 $handlerMock = $this->getMock( 'JpegHandler', array( 'supportsBucketing' ) );
229 $handlerMock->expects( $this->any() )->method( 'supportsBucketing' )->will(
230 $this->returnValue( true ) );
232 $fileMock->expects( $this->any() )->method( 'getHandler' )->will(
233 $this->returnValue( $handlerMock ) );
235 $reflectionMethod = new ReflectionMethod( 'File', 'generateBucketsIfNeeded' );
236 $reflectionMethod->setAccessible( true );
238 $fileMock->expects( $this->any() )
239 ->method( 'getWidth' )
240 ->will( $this->returnValue( $data['width'] ) );
242 $fileMock->expects( $data['expectedGetBucketThumbPathCalls'] )
243 ->method( 'getBucketThumbPath' );
245 $repoMock->expects( $data['expectedFileExistsCalls'] )
246 ->method( 'fileExists' )
247 ->will( $this->returnValue( $data['fileExistsReturn'] ) );
249 $fileMock->expects( $data['expectedMakeTransformTmpFile'] )
250 ->method( 'makeTransformTmpFile' )
251 ->will( $this->returnValue( $data['makeTransformTmpFileReturn'] ) );
253 $fileMock->expects( $data['expectedGenerateAndSaveThumb'] )
254 ->method( 'generateAndSaveThumb' )
255 ->will( $this->returnValue( $data['generateAndSaveThumbReturn'] ) );
257 $this->assertEquals( $data['expectedResult'],
258 $reflectionMethod->invoke(
261 'physicalWidth' => $data['physicalWidth'],
262 'physicalHeight' => $data['physicalHeight'] )
267 public function generateBucketsIfNeededProvider() {
268 $defaultBuckets = array( 256, 512, 1024, 2048, 4096 );
272 'buckets' => $defaultBuckets,
274 'physicalWidth' => 256,
275 'physicalHeight' => 100,
276 'expectedGetBucketThumbPathCalls' => $this->never(),
277 'expectedFileExistsCalls' => $this->never(),
278 'fileExistsReturn' => null,
279 'expectedMakeTransformTmpFile' => $this->never(),
280 'makeTransformTmpFileReturn' => false,
281 'expectedGenerateAndSaveThumb' => $this->never(),
282 'generateAndSaveThumbReturn' => false,
283 'expectedResult' => false,
284 'message' => 'No bucket found, nothing to generate'
287 'buckets' => $defaultBuckets,
289 'physicalWidth' => 300,
290 'physicalHeight' => 200,
291 'expectedGetBucketThumbPathCalls' => $this->once(),
292 'expectedFileExistsCalls' => $this->once(),
293 'fileExistsReturn' => true,
294 'expectedMakeTransformTmpFile' => $this->never(),
295 'makeTransformTmpFileReturn' => false,
296 'expectedGenerateAndSaveThumb' => $this->never(),
297 'generateAndSaveThumbReturn' => false,
298 'expectedResult' => false,
299 'message' => 'File already exists, no reason to generate buckets'
302 'buckets' => $defaultBuckets,
304 'physicalWidth' => 300,
305 'physicalHeight' => 200,
306 'expectedGetBucketThumbPathCalls' => $this->once(),
307 'expectedFileExistsCalls' => $this->once(),
308 'fileExistsReturn' => false,
309 'expectedMakeTransformTmpFile' => $this->once(),
310 'makeTransformTmpFileReturn' => false,
311 'expectedGenerateAndSaveThumb' => $this->never(),
312 'generateAndSaveThumbReturn' => false,
313 'expectedResult' => false,
314 'message' => 'Cannot generate temp file for bucket'
317 'buckets' => $defaultBuckets,
319 'physicalWidth' => 300,
320 'physicalHeight' => 200,
321 'expectedGetBucketThumbPathCalls' => $this->once(),
322 'expectedFileExistsCalls' => $this->once(),
323 'fileExistsReturn' => false,
324 'expectedMakeTransformTmpFile' => $this->once(),
325 'makeTransformTmpFileReturn' => new TempFSFile( '/tmp/foo' ),
326 'expectedGenerateAndSaveThumb' => $this->once(),
327 'generateAndSaveThumbReturn' => false,
328 'expectedResult' => false,
329 'message' => 'Bucket image could not be generated'
332 'buckets' => $defaultBuckets,
334 'physicalWidth' => 300,
335 'physicalHeight' => 200,
336 'expectedGetBucketThumbPathCalls' => $this->once(),
337 'expectedFileExistsCalls' => $this->once(),
338 'fileExistsReturn' => false,
339 'expectedMakeTransformTmpFile' => $this->once(),
340 'makeTransformTmpFileReturn' => new TempFSFile( '/tmp/foo' ),
341 'expectedGenerateAndSaveThumb' => $this->once(),
342 'generateAndSaveThumbReturn' => new ThumbnailImage( false, 'bar', false, false ),
343 'expectedResult' => true,
344 'message' => 'Bucket image could not be generated'