Merge "phpunit: Avoid use of deprecated getMock for PHPUnit 5 compat"
[lhc/web/wiklou.git] / tests / phpunit / includes / filerepo / file / FileTest.php
1 <?php
2
3 class FileTest extends MediaWikiMediaTestCase {
4
5 /**
6 * @param string $filename
7 * @param bool $expected
8 * @dataProvider providerCanAnimate
9 */
10 function testCanAnimateThumbIfAppropriate( $filename, $expected ) {
11 $this->setMwGlobals( 'wgMaxAnimatedGifArea', 9000 );
12 $file = $this->dataFile( $filename );
13 $this->assertEquals( $file->canAnimateThumbIfAppropriate(), $expected );
14 }
15
16 function providerCanAnimate() {
17 return [
18 [ 'nonanimated.gif', true ],
19 [ 'jpeg-comment-utf.jpg', true ],
20 [ 'test.tiff', true ],
21 [ 'Animated_PNG_example_bouncing_beach_ball.png', false ],
22 [ 'greyscale-png.png', true ],
23 [ 'Toll_Texas_1.svg', true ],
24 [ 'LoremIpsum.djvu', true ],
25 [ '80x60-2layers.xcf', true ],
26 [ 'Soccer_ball_animated.svg', false ],
27 [ 'Bishzilla_blink.gif', false ],
28 [ 'animated.gif', true ],
29 ];
30 }
31
32 /**
33 * @dataProvider getThumbnailBucketProvider
34 * @covers File::getThumbnailBucket
35 */
36 public function testGetThumbnailBucket( $data ) {
37 $this->setMwGlobals( 'wgThumbnailBuckets', $data['buckets'] );
38 $this->setMwGlobals( 'wgThumbnailMinimumBucketDistance', $data['minimumBucketDistance'] );
39
40 $fileMock = $this->getMockBuilder( 'File' )
41 ->setConstructorArgs( [ 'fileMock', false ] )
42 ->setMethods( [ 'getWidth' ] )
43 ->getMockForAbstractClass();
44
45 $fileMock->expects( $this->any() )
46 ->method( 'getWidth' )
47 ->will( $this->returnValue( $data['width'] ) );
48
49 $this->assertEquals(
50 $data['expectedBucket'],
51 $fileMock->getThumbnailBucket( $data['requestedWidth'] ),
52 $data['message'] );
53 }
54
55 public function getThumbnailBucketProvider() {
56 $defaultBuckets = [ 256, 512, 1024, 2048, 4096 ];
57
58 return [
59 [ [
60 'buckets' => $defaultBuckets,
61 'minimumBucketDistance' => 0,
62 'width' => 3000,
63 'requestedWidth' => 120,
64 'expectedBucket' => 256,
65 'message' => 'Picking bucket bigger than requested size'
66 ] ],
67 [ [
68 'buckets' => $defaultBuckets,
69 'minimumBucketDistance' => 0,
70 'width' => 3000,
71 'requestedWidth' => 300,
72 'expectedBucket' => 512,
73 'message' => 'Picking bucket bigger than requested size'
74 ] ],
75 [ [
76 'buckets' => $defaultBuckets,
77 'minimumBucketDistance' => 0,
78 'width' => 3000,
79 'requestedWidth' => 1024,
80 'expectedBucket' => 2048,
81 'message' => 'Picking bucket bigger than requested size'
82 ] ],
83 [ [
84 'buckets' => $defaultBuckets,
85 'minimumBucketDistance' => 0,
86 'width' => 3000,
87 'requestedWidth' => 2048,
88 'expectedBucket' => false,
89 'message' => 'Picking no bucket because none is bigger than the requested size'
90 ] ],
91 [ [
92 'buckets' => $defaultBuckets,
93 'minimumBucketDistance' => 0,
94 'width' => 3000,
95 'requestedWidth' => 3500,
96 'expectedBucket' => false,
97 'message' => 'Picking no bucket because requested size is bigger than original'
98 ] ],
99 [ [
100 'buckets' => [ 1024 ],
101 'minimumBucketDistance' => 0,
102 'width' => 3000,
103 'requestedWidth' => 1024,
104 'expectedBucket' => false,
105 'message' => 'Picking no bucket because requested size equals biggest bucket'
106 ] ],
107 [ [
108 'buckets' => null,
109 'minimumBucketDistance' => 0,
110 'width' => 3000,
111 'requestedWidth' => 1024,
112 'expectedBucket' => false,
113 'message' => 'Picking no bucket because no buckets have been specified'
114 ] ],
115 [ [
116 'buckets' => [ 256, 512 ],
117 'minimumBucketDistance' => 10,
118 'width' => 3000,
119 'requestedWidth' => 245,
120 'expectedBucket' => 256,
121 'message' => 'Requested width is distant enough from next bucket for it to be picked'
122 ] ],
123 [ [
124 'buckets' => [ 256, 512 ],
125 'minimumBucketDistance' => 10,
126 'width' => 3000,
127 'requestedWidth' => 246,
128 'expectedBucket' => 512,
129 'message' => 'Requested width is too close to next bucket, picking next one'
130 ] ],
131 ];
132 }
133
134 /**
135 * @dataProvider getThumbnailSourceProvider
136 * @covers File::getThumbnailSource
137 */
138 public function testGetThumbnailSource( $data ) {
139 $backendMock = $this->getMockBuilder( 'FSFileBackend' )
140 ->setConstructorArgs( [ [ 'name' => 'backendMock', 'wikiId' => wfWikiID() ] ] )
141 ->getMock();
142
143 $repoMock = $this->getMockBuilder( 'FileRepo' )
144 ->setConstructorArgs( [ [ 'name' => 'repoMock', 'backend' => $backendMock ] ] )
145 ->setMethods( [ 'fileExists', 'getLocalReference' ] )
146 ->getMock();
147
148 $fsFile = new FSFile( 'fsFilePath' );
149
150 $repoMock->expects( $this->any() )
151 ->method( 'fileExists' )
152 ->will( $this->returnValue( true ) );
153
154 $repoMock->expects( $this->any() )
155 ->method( 'getLocalReference' )
156 ->will( $this->returnValue( $fsFile ) );
157
158 $handlerMock = $this->getMockBuilder( 'BitmapHandler' )
159 ->setMethods( [ 'supportsBucketing' ] )->getMock();
160 $handlerMock->expects( $this->any() )
161 ->method( 'supportsBucketing' )
162 ->will( $this->returnValue( $data['supportsBucketing'] ) );
163
164 $fileMock = $this->getMockBuilder( 'File' )
165 ->setConstructorArgs( [ 'fileMock', $repoMock ] )
166 ->setMethods( [ 'getThumbnailBucket', 'getLocalRefPath', 'getHandler' ] )
167 ->getMockForAbstractClass();
168
169 $fileMock->expects( $this->any() )
170 ->method( 'getThumbnailBucket' )
171 ->will( $this->returnValue( $data['thumbnailBucket'] ) );
172
173 $fileMock->expects( $this->any() )
174 ->method( 'getLocalRefPath' )
175 ->will( $this->returnValue( 'localRefPath' ) );
176
177 $fileMock->expects( $this->any() )
178 ->method( 'getHandler' )
179 ->will( $this->returnValue( $handlerMock ) );
180
181 $reflection = new ReflectionClass( $fileMock );
182 $reflection_property = $reflection->getProperty( 'handler' );
183 $reflection_property->setAccessible( true );
184 $reflection_property->setValue( $fileMock, $handlerMock );
185
186 if ( !is_null( $data['tmpBucketedThumbCache'] ) ) {
187 $reflection_property = $reflection->getProperty( 'tmpBucketedThumbCache' );
188 $reflection_property->setAccessible( true );
189 $reflection_property->setValue( $fileMock, $data['tmpBucketedThumbCache'] );
190 }
191
192 $result = $fileMock->getThumbnailSource(
193 [ 'physicalWidth' => $data['physicalWidth'] ] );
194
195 $this->assertEquals( $data['expectedPath'], $result['path'], $data['message'] );
196 }
197
198 public function getThumbnailSourceProvider() {
199 return [
200 [ [
201 'supportsBucketing' => true,
202 'tmpBucketedThumbCache' => null,
203 'thumbnailBucket' => 1024,
204 'physicalWidth' => 2048,
205 'expectedPath' => 'fsFilePath',
206 'message' => 'Path downloaded from storage'
207 ] ],
208 [ [
209 'supportsBucketing' => true,
210 'tmpBucketedThumbCache' => [ 1024 => '/tmp/shouldnotexist' . rand() ],
211 'thumbnailBucket' => 1024,
212 'physicalWidth' => 2048,
213 'expectedPath' => 'fsFilePath',
214 'message' => 'Path downloaded from storage because temp file is missing'
215 ] ],
216 [ [
217 'supportsBucketing' => true,
218 'tmpBucketedThumbCache' => [ 1024 => '/tmp' ],
219 'thumbnailBucket' => 1024,
220 'physicalWidth' => 2048,
221 'expectedPath' => '/tmp',
222 'message' => 'Temporary path because temp file was found'
223 ] ],
224 [ [
225 'supportsBucketing' => false,
226 'tmpBucketedThumbCache' => null,
227 'thumbnailBucket' => 1024,
228 'physicalWidth' => 2048,
229 'expectedPath' => 'localRefPath',
230 'message' => 'Original file path because bucketing is unsupported by handler'
231 ] ],
232 [ [
233 'supportsBucketing' => true,
234 'tmpBucketedThumbCache' => null,
235 'thumbnailBucket' => false,
236 'physicalWidth' => 2048,
237 'expectedPath' => 'localRefPath',
238 'message' => 'Original file path because no width provided'
239 ] ],
240 ];
241 }
242
243 /**
244 * @dataProvider generateBucketsIfNeededProvider
245 * @covers File::generateBucketsIfNeeded
246 */
247 public function testGenerateBucketsIfNeeded( $data ) {
248 $this->setMwGlobals( 'wgThumbnailBuckets', $data['buckets'] );
249
250 $backendMock = $this->getMockBuilder( 'FSFileBackend' )
251 ->setConstructorArgs( [ [ 'name' => 'backendMock', 'wikiId' => wfWikiID() ] ] )
252 ->getMock();
253
254 $repoMock = $this->getMockBuilder( 'FileRepo' )
255 ->setConstructorArgs( [ [ 'name' => 'repoMock', 'backend' => $backendMock ] ] )
256 ->setMethods( [ 'fileExists', 'getLocalReference' ] )
257 ->getMock();
258
259 $fileMock = $this->getMockBuilder( 'File' )
260 ->setConstructorArgs( [ 'fileMock', $repoMock ] )
261 ->setMethods( [ 'getWidth', 'getBucketThumbPath', 'makeTransformTmpFile',
262 'generateAndSaveThumb', 'getHandler' ] )
263 ->getMockForAbstractClass();
264
265 $handlerMock = $this->getMockBuilder( 'JpegHandler' )
266 ->setMethods( [ 'supportsBucketing' ] )->getMock();
267 $handlerMock->expects( $this->any() )
268 ->method( 'supportsBucketing' )
269 ->will( $this->returnValue( true ) );
270
271 $fileMock->expects( $this->any() )
272 ->method( 'getHandler' )
273 ->will( $this->returnValue( $handlerMock ) );
274
275 $reflectionMethod = new ReflectionMethod( 'File', 'generateBucketsIfNeeded' );
276 $reflectionMethod->setAccessible( true );
277
278 $fileMock->expects( $this->any() )
279 ->method( 'getWidth' )
280 ->will( $this->returnValue( $data['width'] ) );
281
282 $fileMock->expects( $data['expectedGetBucketThumbPathCalls'] )
283 ->method( 'getBucketThumbPath' );
284
285 $repoMock->expects( $data['expectedFileExistsCalls'] )
286 ->method( 'fileExists' )
287 ->will( $this->returnValue( $data['fileExistsReturn'] ) );
288
289 $fileMock->expects( $data['expectedMakeTransformTmpFile'] )
290 ->method( 'makeTransformTmpFile' )
291 ->will( $this->returnValue( $data['makeTransformTmpFileReturn'] ) );
292
293 $fileMock->expects( $data['expectedGenerateAndSaveThumb'] )
294 ->method( 'generateAndSaveThumb' )
295 ->will( $this->returnValue( $data['generateAndSaveThumbReturn'] ) );
296
297 $this->assertEquals( $data['expectedResult'],
298 $reflectionMethod->invoke(
299 $fileMock,
300 [
301 'physicalWidth' => $data['physicalWidth'],
302 'physicalHeight' => $data['physicalHeight'] ]
303 ),
304 $data['message'] );
305 }
306
307 public function generateBucketsIfNeededProvider() {
308 $defaultBuckets = [ 256, 512, 1024, 2048, 4096 ];
309
310 return [
311 [ [
312 'buckets' => $defaultBuckets,
313 'width' => 256,
314 'physicalWidth' => 256,
315 'physicalHeight' => 100,
316 'expectedGetBucketThumbPathCalls' => $this->never(),
317 'expectedFileExistsCalls' => $this->never(),
318 'fileExistsReturn' => null,
319 'expectedMakeTransformTmpFile' => $this->never(),
320 'makeTransformTmpFileReturn' => false,
321 'expectedGenerateAndSaveThumb' => $this->never(),
322 'generateAndSaveThumbReturn' => false,
323 'expectedResult' => false,
324 'message' => 'No bucket found, nothing to generate'
325 ] ],
326 [ [
327 'buckets' => $defaultBuckets,
328 'width' => 5000,
329 'physicalWidth' => 300,
330 'physicalHeight' => 200,
331 'expectedGetBucketThumbPathCalls' => $this->once(),
332 'expectedFileExistsCalls' => $this->once(),
333 'fileExistsReturn' => true,
334 'expectedMakeTransformTmpFile' => $this->never(),
335 'makeTransformTmpFileReturn' => false,
336 'expectedGenerateAndSaveThumb' => $this->never(),
337 'generateAndSaveThumbReturn' => false,
338 'expectedResult' => false,
339 'message' => 'File already exists, no reason to generate buckets'
340 ] ],
341 [ [
342 'buckets' => $defaultBuckets,
343 'width' => 5000,
344 'physicalWidth' => 300,
345 'physicalHeight' => 200,
346 'expectedGetBucketThumbPathCalls' => $this->once(),
347 'expectedFileExistsCalls' => $this->once(),
348 'fileExistsReturn' => false,
349 'expectedMakeTransformTmpFile' => $this->once(),
350 'makeTransformTmpFileReturn' => false,
351 'expectedGenerateAndSaveThumb' => $this->never(),
352 'generateAndSaveThumbReturn' => false,
353 'expectedResult' => false,
354 'message' => 'Cannot generate temp file for bucket'
355 ] ],
356 [ [
357 'buckets' => $defaultBuckets,
358 'width' => 5000,
359 'physicalWidth' => 300,
360 'physicalHeight' => 200,
361 'expectedGetBucketThumbPathCalls' => $this->once(),
362 'expectedFileExistsCalls' => $this->once(),
363 'fileExistsReturn' => false,
364 'expectedMakeTransformTmpFile' => $this->once(),
365 'makeTransformTmpFileReturn' => new TempFSFile( '/tmp/foo' ),
366 'expectedGenerateAndSaveThumb' => $this->once(),
367 'generateAndSaveThumbReturn' => false,
368 'expectedResult' => false,
369 'message' => 'Bucket image could not be generated'
370 ] ],
371 [ [
372 'buckets' => $defaultBuckets,
373 'width' => 5000,
374 'physicalWidth' => 300,
375 'physicalHeight' => 200,
376 'expectedGetBucketThumbPathCalls' => $this->once(),
377 'expectedFileExistsCalls' => $this->once(),
378 'fileExistsReturn' => false,
379 'expectedMakeTransformTmpFile' => $this->once(),
380 'makeTransformTmpFileReturn' => new TempFSFile( '/tmp/foo' ),
381 'expectedGenerateAndSaveThumb' => $this->once(),
382 'generateAndSaveThumbReturn' => new ThumbnailImage( false, 'bar', false, false ),
383 'expectedResult' => true,
384 'message' => 'Bucket image could not be generated'
385 ] ],
386 ];
387 }
388 }