Merge "Skip 64 bit MWMessagePack tests on 32 bit machines"
[lhc/web/wiklou.git] / tests / phpunit / includes / filerepo / file / FileTest.php
1 <?php
2
3 class FileRepoFileTest extends MediaWikiMediaTestCase {
4 /**
5 * @dataProvider getThumbnailBucketProvider
6 * @covers File::getThumbnailBucket
7 */
8 public function testGetThumbnailBucket( $data ) {
9 $this->setMwGlobals( 'wgThumbnailBuckets', $data['buckets'] );
10 $this->setMwGlobals( 'wgThumbnailMinimumBucketDistance', $data['minimumBucketDistance'] );
11
12 $fileMock = $this->getMockBuilder( 'File' )
13 ->setConstructorArgs( array( 'fileMock', false ) )
14 ->setMethods( array( 'getWidth' ) )
15 ->getMockForAbstractClass();
16
17 $fileMock->expects( $this->any() )->method( 'getWidth' )->will(
18 $this->returnValue( $data['width'] ) );
19
20 $this->assertEquals(
21 $data['expectedBucket'],
22 $fileMock->getThumbnailBucket( $data['requestedWidth'] ),
23 $data['message'] );
24 }
25
26 public function getThumbnailBucketProvider() {
27 $defaultBuckets = array( 256, 512, 1024, 2048, 4096 );
28
29 return array(
30 array( array(
31 'buckets' => $defaultBuckets,
32 'minimumBucketDistance' => 0,
33 'width' => 3000,
34 'requestedWidth' => 120,
35 'expectedBucket' => 256,
36 'message' => 'Picking bucket bigger than requested size'
37 ) ),
38 array( array(
39 'buckets' => $defaultBuckets,
40 'minimumBucketDistance' => 0,
41 'width' => 3000,
42 'requestedWidth' => 300,
43 'expectedBucket' => 512,
44 'message' => 'Picking bucket bigger than requested size'
45 ) ),
46 array( array(
47 'buckets' => $defaultBuckets,
48 'minimumBucketDistance' => 0,
49 'width' => 3000,
50 'requestedWidth' => 1024,
51 'expectedBucket' => 2048,
52 'message' => 'Picking bucket bigger than requested size'
53 ) ),
54 array( array(
55 'buckets' => $defaultBuckets,
56 'minimumBucketDistance' => 0,
57 'width' => 3000,
58 'requestedWidth' => 2048,
59 'expectedBucket' => false,
60 'message' => 'Picking no bucket because none is bigger than the requested size'
61 ) ),
62 array( array(
63 'buckets' => $defaultBuckets,
64 'minimumBucketDistance' => 0,
65 'width' => 3000,
66 'requestedWidth' => 3500,
67 'expectedBucket' => false,
68 'message' => 'Picking no bucket because requested size is bigger than original'
69 ) ),
70 array( array(
71 'buckets' => array( 1024 ),
72 'minimumBucketDistance' => 0,
73 'width' => 3000,
74 'requestedWidth' => 1024,
75 'expectedBucket' => false,
76 'message' => 'Picking no bucket because requested size equals biggest bucket'
77 ) ),
78 array( array(
79 'buckets' => null,
80 'minimumBucketDistance' => 0,
81 'width' => 3000,
82 'requestedWidth' => 1024,
83 'expectedBucket' => false,
84 'message' => 'Picking no bucket because no buckets have been specified'
85 ) ),
86 array( array(
87 'buckets' => array( 256, 512 ),
88 'minimumBucketDistance' => 10,
89 'width' => 3000,
90 'requestedWidth' => 245,
91 'expectedBucket' => 256,
92 'message' => 'Requested width is distant enough from next bucket for it to be picked'
93 ) ),
94 array( array(
95 'buckets' => array( 256, 512 ),
96 'minimumBucketDistance' => 10,
97 'width' => 3000,
98 'requestedWidth' => 246,
99 'expectedBucket' => 512,
100 'message' => 'Requested width is too close to next bucket, picking next one'
101 ) ),
102 );
103 }
104
105 /**
106 * @dataProvider getThumbnailSourceProvider
107 * @covers File::getThumbnailSource
108 */
109 public function testGetThumbnailSource( $data ) {
110 $backendMock = $this->getMockBuilder( 'FSFileBackend' )
111 ->setConstructorArgs( array( array( 'name' => 'backendMock', 'wikiId' => wfWikiId() ) ) )
112 ->getMock();
113
114 $repoMock = $this->getMockBuilder( 'FileRepo' )
115 ->setConstructorArgs( array( array( 'name' => 'repoMock', 'backend' => $backendMock ) ) )
116 ->setMethods( array( 'fileExists', 'getLocalReference' ) )
117 ->getMock();
118
119 $fsFile = new FSFile( 'fsFilePath' );
120
121 $repoMock->expects( $this->any() )->method( 'fileExists' )->will(
122 $this->returnValue( true ) );
123
124 $repoMock->expects( $this->any() )->method( 'getLocalReference' )->will(
125 $this->returnValue( $fsFile ) );
126
127 $handlerMock = $this->getMock( 'BitmapHandler', array( 'supportsBucketing' ) );
128 $handlerMock->expects( $this->any() )->method( 'supportsBucketing' )->will(
129 $this->returnValue( $data['supportsBucketing'] ) );
130
131 $fileMock = $this->getMockBuilder( 'File' )
132 ->setConstructorArgs( array( 'fileMock', $repoMock ) )
133 ->setMethods( array( 'getThumbnailBucket', 'getLocalRefPath', 'getHandler' ) )
134 ->getMockForAbstractClass();
135
136 $fileMock->expects( $this->any() )->method( 'getThumbnailBucket' )->will(
137 $this->returnValue( $data['thumbnailBucket'] ) );
138
139 $fileMock->expects( $this->any() )->method( 'getLocalRefPath' )->will(
140 $this->returnValue( 'localRefPath' ) );
141
142 $fileMock->expects( $this->any() )->method( 'getHandler' )->will(
143 $this->returnValue( $handlerMock ) );
144
145 $reflection = new ReflectionClass( $fileMock );
146 $reflection_property = $reflection->getProperty( 'handler' );
147 $reflection_property->setAccessible( true );
148 $reflection_property->setValue( $fileMock, $handlerMock );
149
150 if ( !is_null( $data['tmpBucketedThumbCache'] ) ) {
151 $reflection_property = $reflection->getProperty( 'tmpBucketedThumbCache' );
152 $reflection_property->setAccessible( true );
153 $reflection_property->setValue( $fileMock, $data['tmpBucketedThumbCache'] );
154 }
155
156 $result = $fileMock->getThumbnailSource(
157 array( 'physicalWidth' => $data['physicalWidth'] ) );
158
159 $this->assertEquals( $data['expectedPath'], $result['path'], $data['message'] );
160 }
161
162 public function getThumbnailSourceProvider() {
163 return array(
164 array( array(
165 'supportsBucketing' => true,
166 'tmpBucketedThumbCache' => null,
167 'thumbnailBucket' => 1024,
168 'physicalWidth' => 2048,
169 'expectedPath' => 'fsFilePath',
170 'message' => 'Path downloaded from storage'
171 ) ),
172 array( array(
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'
179 ) ),
180 array( array(
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'
187 ) ),
188 array( array(
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'
195 ) ),
196 array( array(
197 'supportsBucketing' => true,
198 'tmpBucketedThumbCache' => null,
199 'thumbnailBucket' => false,
200 'physicalWidth' => 2048,
201 'expectedPath' => 'localRefPath',
202 'message' => 'Original file path because no width provided'
203 ) ),
204 );
205 }
206
207 /**
208 * @dataProvider generateBucketsIfNeededProvider
209 * @covers File::generateBucketsIfNeeded
210 */
211 public function testGenerateBucketsIfNeeded( $data ) {
212 $this->setMwGlobals( 'wgThumbnailBuckets', $data['buckets'] );
213
214 $backendMock = $this->getMockBuilder( 'FSFileBackend' )
215 ->setConstructorArgs( array( array( 'name' => 'backendMock', 'wikiId' => wfWikiId() ) ) )
216 ->getMock();
217
218 $repoMock = $this->getMockBuilder( 'FileRepo' )
219 ->setConstructorArgs( array( array( 'name' => 'repoMock', 'backend' => $backendMock ) ) )
220 ->setMethods( array( 'fileExists', 'getLocalReference' ) )
221 ->getMock();
222
223 $fileMock = $this->getMockBuilder( 'File' )
224 ->setConstructorArgs( array( 'fileMock', $repoMock ) )
225 ->setMethods( array( 'getWidth', 'getBucketThumbPath', 'makeTransformTmpFile', 'generateAndSaveThumb', 'getHandler' ) )
226 ->getMockForAbstractClass();
227
228 $handlerMock = $this->getMock( 'JpegHandler', array( 'supportsBucketing' ) );
229 $handlerMock->expects( $this->any() )->method( 'supportsBucketing' )->will(
230 $this->returnValue( true ) );
231
232 $fileMock->expects( $this->any() )->method( 'getHandler' )->will(
233 $this->returnValue( $handlerMock ) );
234
235 $reflectionMethod = new ReflectionMethod( 'File', 'generateBucketsIfNeeded' );
236 $reflectionMethod->setAccessible( true );
237
238 $fileMock->expects( $this->any() )
239 ->method( 'getWidth' )
240 ->will( $this->returnValue( $data['width'] ) );
241
242 $fileMock->expects( $data['expectedGetBucketThumbPathCalls'] )
243 ->method( 'getBucketThumbPath' );
244
245 $repoMock->expects( $data['expectedFileExistsCalls'] )
246 ->method( 'fileExists' )
247 ->will( $this->returnValue( $data['fileExistsReturn'] ) );
248
249 $fileMock->expects( $data['expectedMakeTransformTmpFile'] )
250 ->method( 'makeTransformTmpFile' )
251 ->will( $this->returnValue( $data['makeTransformTmpFileReturn'] ) );
252
253 $fileMock->expects( $data['expectedGenerateAndSaveThumb'] )
254 ->method( 'generateAndSaveThumb' )
255 ->will( $this->returnValue( $data['generateAndSaveThumbReturn'] ) );
256
257 $this->assertEquals( $data['expectedResult'],
258 $reflectionMethod->invoke(
259 $fileMock,
260 array(
261 'physicalWidth' => $data['physicalWidth'],
262 'physicalHeight' => $data['physicalHeight'] )
263 ),
264 $data['message'] );
265 }
266
267 public function generateBucketsIfNeededProvider() {
268 $defaultBuckets = array( 256, 512, 1024, 2048, 4096 );
269
270 return array(
271 array( array(
272 'buckets' => $defaultBuckets,
273 'width' => 256,
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'
285 ) ),
286 array( array(
287 'buckets' => $defaultBuckets,
288 'width' => 5000,
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'
300 ) ),
301 array( array(
302 'buckets' => $defaultBuckets,
303 'width' => 5000,
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'
315 ) ),
316 array( array(
317 'buckets' => $defaultBuckets,
318 'width' => 5000,
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'
330 ) ),
331 array( array(
332 'buckets' => $defaultBuckets,
333 'width' => 5000,
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'
345 ) ),
346 );
347 }
348 }