|
1 <?php |
|
2 |
|
3 /** |
|
4 * @file |
|
5 * Tests for core image handling API. |
|
6 */ |
|
7 |
|
8 /** |
|
9 * Base class for image manipulation testing. |
|
10 */ |
|
11 class ImageToolkitTestCase extends DrupalWebTestCase { |
|
12 protected $toolkit; |
|
13 protected $file; |
|
14 protected $image; |
|
15 |
|
16 function setUp() { |
|
17 $modules = func_get_args(); |
|
18 if (isset($modules[0]) && is_array($modules[0])) { |
|
19 $modules = $modules[0]; |
|
20 } |
|
21 $modules[] = 'image_test'; |
|
22 |
|
23 parent::setUp($modules); |
|
24 |
|
25 // Use the image_test.module's test toolkit. |
|
26 $this->toolkit = 'test'; |
|
27 |
|
28 // Pick a file for testing. |
|
29 $file = current($this->drupalGetTestFiles('image')); |
|
30 $this->file = $file->uri; |
|
31 |
|
32 // Setup a dummy image to work with, this replicate image_load() so we |
|
33 // can avoid calling it. |
|
34 $this->image = new stdClass(); |
|
35 $this->image->source = $this->file; |
|
36 $this->image->info = image_get_info($this->file); |
|
37 $this->image->toolkit = $this->toolkit; |
|
38 |
|
39 // Clear out any hook calls. |
|
40 image_test_reset(); |
|
41 } |
|
42 |
|
43 /** |
|
44 * Assert that all of the specified image toolkit operations were called |
|
45 * exactly once once, other values result in failure. |
|
46 * |
|
47 * @param $expected |
|
48 * Array with string containing with the operation name, e.g. 'load', |
|
49 * 'save', 'crop', etc. |
|
50 */ |
|
51 function assertToolkitOperationsCalled(array $expected) { |
|
52 // Determine which operations were called. |
|
53 $actual = array_keys(array_filter(image_test_get_all_calls())); |
|
54 |
|
55 // Determine if there were any expected that were not called. |
|
56 $uncalled = array_diff($expected, $actual); |
|
57 if (count($uncalled)) { |
|
58 $this->assertTrue(FALSE, format_string('Expected operations %expected to be called but %uncalled was not called.', array('%expected' => implode(', ', $expected), '%uncalled' => implode(', ', $uncalled)))); |
|
59 } |
|
60 else { |
|
61 $this->assertTrue(TRUE, format_string('All the expected operations were called: %expected', array('%expected' => implode(', ', $expected)))); |
|
62 } |
|
63 |
|
64 // Determine if there were any unexpected calls. |
|
65 $unexpected = array_diff($actual, $expected); |
|
66 if (count($unexpected)) { |
|
67 $this->assertTrue(FALSE, format_string('Unexpected operations were called: %unexpected.', array('%unexpected' => implode(', ', $unexpected)))); |
|
68 } |
|
69 else { |
|
70 $this->assertTrue(TRUE, 'No unexpected operations were called.'); |
|
71 } |
|
72 } |
|
73 } |
|
74 |
|
75 /** |
|
76 * Test that the functions in image.inc correctly pass data to the toolkit. |
|
77 */ |
|
78 class ImageToolkitUnitTest extends ImageToolkitTestCase { |
|
79 public static function getInfo() { |
|
80 return array( |
|
81 'name' => 'Image toolkit tests', |
|
82 'description' => 'Check image toolkit functions.', |
|
83 'group' => 'Image', |
|
84 ); |
|
85 } |
|
86 |
|
87 /** |
|
88 * Check that hook_image_toolkits() is called and only available toolkits are |
|
89 * returned. |
|
90 */ |
|
91 function testGetAvailableToolkits() { |
|
92 $toolkits = image_get_available_toolkits(); |
|
93 $this->assertTrue(isset($toolkits['test']), 'The working toolkit was returned.'); |
|
94 $this->assertFalse(isset($toolkits['broken']), 'The toolkit marked unavailable was not returned'); |
|
95 $this->assertToolkitOperationsCalled(array()); |
|
96 } |
|
97 |
|
98 /** |
|
99 * Test the image_load() function. |
|
100 */ |
|
101 function testLoad() { |
|
102 $image = image_load($this->file, $this->toolkit); |
|
103 $this->assertTrue(is_object($image), 'Returned an object.'); |
|
104 $this->assertEqual($this->toolkit, $image->toolkit, 'Image had toolkit set.'); |
|
105 $this->assertToolkitOperationsCalled(array('load', 'get_info')); |
|
106 } |
|
107 |
|
108 /** |
|
109 * Test the image_save() function. |
|
110 */ |
|
111 function testSave() { |
|
112 $this->assertFalse(image_save($this->image), 'Function returned the expected value.'); |
|
113 $this->assertToolkitOperationsCalled(array('save')); |
|
114 } |
|
115 |
|
116 /** |
|
117 * Test the image_resize() function. |
|
118 */ |
|
119 function testResize() { |
|
120 $this->assertTrue(image_resize($this->image, 1, 2), 'Function returned the expected value.'); |
|
121 $this->assertToolkitOperationsCalled(array('resize')); |
|
122 |
|
123 // Check the parameters. |
|
124 $calls = image_test_get_all_calls(); |
|
125 $this->assertEqual($calls['resize'][0][1], 1, 'Width was passed correctly'); |
|
126 $this->assertEqual($calls['resize'][0][2], 2, 'Height was passed correctly'); |
|
127 } |
|
128 |
|
129 /** |
|
130 * Test the image_scale() function. |
|
131 */ |
|
132 function testScale() { |
|
133 // TODO: need to test upscaling |
|
134 $this->assertTrue(image_scale($this->image, 10, 10), 'Function returned the expected value.'); |
|
135 $this->assertToolkitOperationsCalled(array('resize')); |
|
136 |
|
137 // Check the parameters. |
|
138 $calls = image_test_get_all_calls(); |
|
139 $this->assertEqual($calls['resize'][0][1], 10, 'Width was passed correctly'); |
|
140 $this->assertEqual($calls['resize'][0][2], 5, 'Height was based off aspect ratio and passed correctly'); |
|
141 } |
|
142 |
|
143 /** |
|
144 * Test the image_scale_and_crop() function. |
|
145 */ |
|
146 function testScaleAndCrop() { |
|
147 $this->assertTrue(image_scale_and_crop($this->image, 5, 10), 'Function returned the expected value.'); |
|
148 $this->assertToolkitOperationsCalled(array('resize', 'crop')); |
|
149 |
|
150 // Check the parameters. |
|
151 $calls = image_test_get_all_calls(); |
|
152 |
|
153 $this->assertEqual($calls['crop'][0][1], 7.5, 'X was computed and passed correctly'); |
|
154 $this->assertEqual($calls['crop'][0][2], 0, 'Y was computed and passed correctly'); |
|
155 $this->assertEqual($calls['crop'][0][3], 5, 'Width was computed and passed correctly'); |
|
156 $this->assertEqual($calls['crop'][0][4], 10, 'Height was computed and passed correctly'); |
|
157 } |
|
158 |
|
159 /** |
|
160 * Test the image_rotate() function. |
|
161 */ |
|
162 function testRotate() { |
|
163 $this->assertTrue(image_rotate($this->image, 90, 1), 'Function returned the expected value.'); |
|
164 $this->assertToolkitOperationsCalled(array('rotate')); |
|
165 |
|
166 // Check the parameters. |
|
167 $calls = image_test_get_all_calls(); |
|
168 $this->assertEqual($calls['rotate'][0][1], 90, 'Degrees were passed correctly'); |
|
169 $this->assertEqual($calls['rotate'][0][2], 1, 'Background color was passed correctly'); |
|
170 } |
|
171 |
|
172 /** |
|
173 * Test the image_crop() function. |
|
174 */ |
|
175 function testCrop() { |
|
176 $this->assertTrue(image_crop($this->image, 1, 2, 3, 4), 'Function returned the expected value.'); |
|
177 $this->assertToolkitOperationsCalled(array('crop')); |
|
178 |
|
179 // Check the parameters. |
|
180 $calls = image_test_get_all_calls(); |
|
181 $this->assertEqual($calls['crop'][0][1], 1, 'X was passed correctly'); |
|
182 $this->assertEqual($calls['crop'][0][2], 2, 'Y was passed correctly'); |
|
183 $this->assertEqual($calls['crop'][0][3], 3, 'Width was passed correctly'); |
|
184 $this->assertEqual($calls['crop'][0][4], 4, 'Height was passed correctly'); |
|
185 } |
|
186 |
|
187 /** |
|
188 * Test the image_desaturate() function. |
|
189 */ |
|
190 function testDesaturate() { |
|
191 $this->assertTrue(image_desaturate($this->image), 'Function returned the expected value.'); |
|
192 $this->assertToolkitOperationsCalled(array('desaturate')); |
|
193 |
|
194 // Check the parameters. |
|
195 $calls = image_test_get_all_calls(); |
|
196 $this->assertEqual(count($calls['desaturate'][0]), 1, 'Only the image was passed.'); |
|
197 } |
|
198 } |
|
199 |
|
200 /** |
|
201 * Test the core GD image manipulation functions. |
|
202 */ |
|
203 class ImageToolkitGdTestCase extends DrupalWebTestCase { |
|
204 // Colors that are used in testing. |
|
205 protected $black = array(0, 0, 0, 0); |
|
206 protected $red = array(255, 0, 0, 0); |
|
207 protected $green = array(0, 255, 0, 0); |
|
208 protected $blue = array(0, 0, 255, 0); |
|
209 protected $yellow = array(255, 255, 0, 0); |
|
210 protected $white = array(255, 255, 255, 0); |
|
211 protected $transparent = array(0, 0, 0, 127); |
|
212 // Used as rotate background colors. |
|
213 protected $fuchsia = array(255, 0, 255, 0); |
|
214 protected $rotate_transparent = array(255, 255, 255, 127); |
|
215 |
|
216 protected $width = 40; |
|
217 protected $height = 20; |
|
218 |
|
219 public static function getInfo() { |
|
220 return array( |
|
221 'name' => 'Image GD manipulation tests', |
|
222 'description' => 'Check that core image manipulations work properly: scale, resize, rotate, crop, scale and crop, and desaturate.', |
|
223 'group' => 'Image', |
|
224 ); |
|
225 } |
|
226 |
|
227 /** |
|
228 * Function to compare two colors by RGBa. |
|
229 */ |
|
230 function colorsAreEqual($color_a, $color_b) { |
|
231 // Fully transparent pixels are equal, regardless of RGB. |
|
232 if ($color_a[3] == 127 && $color_b[3] == 127) { |
|
233 return TRUE; |
|
234 } |
|
235 |
|
236 foreach ($color_a as $key => $value) { |
|
237 if ($color_b[$key] != $value) { |
|
238 return FALSE; |
|
239 } |
|
240 } |
|
241 |
|
242 return TRUE; |
|
243 } |
|
244 |
|
245 /** |
|
246 * Function for finding a pixel's RGBa values. |
|
247 */ |
|
248 function getPixelColor($image, $x, $y) { |
|
249 $color_index = imagecolorat($image->resource, $x, $y); |
|
250 |
|
251 $transparent_index = imagecolortransparent($image->resource); |
|
252 if ($color_index == $transparent_index) { |
|
253 return array(0, 0, 0, 127); |
|
254 } |
|
255 |
|
256 return array_values(imagecolorsforindex($image->resource, $color_index)); |
|
257 } |
|
258 |
|
259 /** |
|
260 * Since PHP can't visually check that our images have been manipulated |
|
261 * properly, build a list of expected color values for each of the corners and |
|
262 * the expected height and widths for the final images. |
|
263 */ |
|
264 function testManipulations() { |
|
265 // If GD isn't available don't bother testing this. |
|
266 module_load_include('inc', 'system', 'image.gd'); |
|
267 if (!function_exists('image_gd_check_settings') || !image_gd_check_settings()) { |
|
268 $this->pass(t('Image manipulations for the GD toolkit were skipped because the GD toolkit is not available.')); |
|
269 return; |
|
270 } |
|
271 |
|
272 // Typically the corner colors will be unchanged. These colors are in the |
|
273 // order of top-left, top-right, bottom-right, bottom-left. |
|
274 $default_corners = array($this->red, $this->green, $this->blue, $this->transparent); |
|
275 |
|
276 // A list of files that will be tested. |
|
277 $files = array( |
|
278 'image-test.png', |
|
279 'image-test.gif', |
|
280 'image-test-no-transparency.gif', |
|
281 'image-test.jpg', |
|
282 ); |
|
283 |
|
284 // Setup a list of tests to perform on each type. |
|
285 $operations = array( |
|
286 'resize' => array( |
|
287 'function' => 'resize', |
|
288 'arguments' => array(20, 10), |
|
289 'width' => 20, |
|
290 'height' => 10, |
|
291 'corners' => $default_corners, |
|
292 ), |
|
293 'scale_x' => array( |
|
294 'function' => 'scale', |
|
295 'arguments' => array(20, NULL), |
|
296 'width' => 20, |
|
297 'height' => 10, |
|
298 'corners' => $default_corners, |
|
299 ), |
|
300 'scale_y' => array( |
|
301 'function' => 'scale', |
|
302 'arguments' => array(NULL, 10), |
|
303 'width' => 20, |
|
304 'height' => 10, |
|
305 'corners' => $default_corners, |
|
306 ), |
|
307 'upscale_x' => array( |
|
308 'function' => 'scale', |
|
309 'arguments' => array(80, NULL, TRUE), |
|
310 'width' => 80, |
|
311 'height' => 40, |
|
312 'corners' => $default_corners, |
|
313 ), |
|
314 'upscale_y' => array( |
|
315 'function' => 'scale', |
|
316 'arguments' => array(NULL, 40, TRUE), |
|
317 'width' => 80, |
|
318 'height' => 40, |
|
319 'corners' => $default_corners, |
|
320 ), |
|
321 'crop' => array( |
|
322 'function' => 'crop', |
|
323 'arguments' => array(12, 4, 16, 12), |
|
324 'width' => 16, |
|
325 'height' => 12, |
|
326 'corners' => array_fill(0, 4, $this->white), |
|
327 ), |
|
328 'scale_and_crop' => array( |
|
329 'function' => 'scale_and_crop', |
|
330 'arguments' => array(10, 8), |
|
331 'width' => 10, |
|
332 'height' => 8, |
|
333 'corners' => array_fill(0, 4, $this->black), |
|
334 ), |
|
335 ); |
|
336 |
|
337 // Systems using non-bundled GD2 don't have imagerotate. Test if available. |
|
338 if (function_exists('imagerotate')) { |
|
339 $operations += array( |
|
340 'rotate_90' => array( |
|
341 'function' => 'rotate', |
|
342 'arguments' => array(90, 0xFF00FF), // Fuchsia background. |
|
343 'width' => 20, |
|
344 'height' => 40, |
|
345 'corners' => array($this->fuchsia, $this->red, $this->green, $this->blue), |
|
346 ), |
|
347 'rotate_transparent_90' => array( |
|
348 'function' => 'rotate', |
|
349 'arguments' => array(90), |
|
350 'width' => 20, |
|
351 'height' => 40, |
|
352 'corners' => array($this->transparent, $this->red, $this->green, $this->blue), |
|
353 ), |
|
354 ); |
|
355 // As of PHP version 5.5, GD uses a different algorithm to rotate images |
|
356 // than version 5.4 and below, resulting in different dimensions. |
|
357 // See https://bugs.php.net/bug.php?id=65148. |
|
358 // For the 40x20 test images, the dimensions resulting from rotation will |
|
359 // be 1 pixel smaller in both width and height in PHP 5.5 and above. |
|
360 // @todo: If and when the PHP bug gets solved, add an upper limit |
|
361 // version check. |
|
362 if (version_compare(PHP_VERSION, '5.5', '>=')) { |
|
363 $operations += array( |
|
364 'rotate_5' => array( |
|
365 'function' => 'rotate', |
|
366 'arguments' => array(5, 0xFF00FF), // Fuchsia background. |
|
367 'width' => 41, |
|
368 'height' => 23, |
|
369 'corners' => array_fill(0, 4, $this->fuchsia), |
|
370 ), |
|
371 'rotate_transparent_5' => array( |
|
372 'function' => 'rotate', |
|
373 'arguments' => array(5), |
|
374 'width' => 41, |
|
375 'height' => 23, |
|
376 'corners' => array_fill(0, 4, $this->rotate_transparent), |
|
377 ), |
|
378 ); |
|
379 } |
|
380 else { |
|
381 $operations += array( |
|
382 'rotate_5' => array( |
|
383 'function' => 'rotate', |
|
384 'arguments' => array(5, 0xFF00FF), // Fuchsia background. |
|
385 'width' => 42, |
|
386 'height' => 24, |
|
387 'corners' => array_fill(0, 4, $this->fuchsia), |
|
388 ), |
|
389 'rotate_transparent_5' => array( |
|
390 'function' => 'rotate', |
|
391 'arguments' => array(5), |
|
392 'width' => 42, |
|
393 'height' => 24, |
|
394 'corners' => array_fill(0, 4, $this->rotate_transparent), |
|
395 ), |
|
396 ); |
|
397 } |
|
398 } |
|
399 |
|
400 // Systems using non-bundled GD2 don't have imagefilter. Test if available. |
|
401 if (function_exists('imagefilter')) { |
|
402 $operations += array( |
|
403 'desaturate' => array( |
|
404 'function' => 'desaturate', |
|
405 'arguments' => array(), |
|
406 'height' => 20, |
|
407 'width' => 40, |
|
408 // Grayscale corners are a bit funky. Each of the corners are a shade of |
|
409 // gray. The values of these were determined simply by looking at the |
|
410 // final image to see what desaturated colors end up being. |
|
411 'corners' => array( |
|
412 array_fill(0, 3, 76) + array(3 => 0), |
|
413 array_fill(0, 3, 149) + array(3 => 0), |
|
414 array_fill(0, 3, 29) + array(3 => 0), |
|
415 array_fill(0, 3, 225) + array(3 => 127) |
|
416 ), |
|
417 ), |
|
418 ); |
|
419 } |
|
420 |
|
421 foreach ($files as $file) { |
|
422 foreach ($operations as $op => $values) { |
|
423 // Load up a fresh image. |
|
424 $image = image_load(drupal_get_path('module', 'simpletest') . '/files/' . $file, 'gd'); |
|
425 if (!$image) { |
|
426 $this->fail(t('Could not load image %file.', array('%file' => $file))); |
|
427 continue 2; |
|
428 } |
|
429 |
|
430 // All images should be converted to truecolor when loaded. |
|
431 $image_truecolor = imageistruecolor($image->resource); |
|
432 $this->assertTrue($image_truecolor, format_string('Image %file after load is a truecolor image.', array('%file' => $file))); |
|
433 |
|
434 if ($image->info['extension'] == 'gif') { |
|
435 if ($op == 'desaturate') { |
|
436 // Transparent GIFs and the imagefilter function don't work together. |
|
437 $values['corners'][3][3] = 0; |
|
438 } |
|
439 } |
|
440 |
|
441 // Perform our operation. |
|
442 $function = 'image_' . $values['function']; |
|
443 $arguments = array(); |
|
444 $arguments[] = &$image; |
|
445 $arguments = array_merge($arguments, $values['arguments']); |
|
446 call_user_func_array($function, $arguments); |
|
447 |
|
448 // To keep from flooding the test with assert values, make a general |
|
449 // value for whether each group of values fail. |
|
450 $correct_dimensions_real = TRUE; |
|
451 $correct_dimensions_object = TRUE; |
|
452 $correct_colors = TRUE; |
|
453 |
|
454 // Check the real dimensions of the image first. |
|
455 if (imagesy($image->resource) != $values['height'] || imagesx($image->resource) != $values['width']) { |
|
456 $correct_dimensions_real = FALSE; |
|
457 } |
|
458 |
|
459 // Check that the image object has an accurate record of the dimensions. |
|
460 if ($image->info['width'] != $values['width'] || $image->info['height'] != $values['height']) { |
|
461 $correct_dimensions_object = FALSE; |
|
462 } |
|
463 // Now check each of the corners to ensure color correctness. |
|
464 foreach ($values['corners'] as $key => $corner) { |
|
465 // The test gif that does not have transparency has yellow where the |
|
466 // others have transparent. |
|
467 if ($file === 'image-test-no-transparency.gif' && $corner === $this->transparent) { |
|
468 $corner = $this->yellow; |
|
469 } |
|
470 // Get the location of the corner. |
|
471 switch ($key) { |
|
472 case 0: |
|
473 $x = 0; |
|
474 $y = 0; |
|
475 break; |
|
476 case 1: |
|
477 $x = $values['width'] - 1; |
|
478 $y = 0; |
|
479 break; |
|
480 case 2: |
|
481 $x = $values['width'] - 1; |
|
482 $y = $values['height'] - 1; |
|
483 break; |
|
484 case 3: |
|
485 $x = 0; |
|
486 $y = $values['height'] - 1; |
|
487 break; |
|
488 } |
|
489 $color = $this->getPixelColor($image, $x, $y); |
|
490 $correct_colors = $this->colorsAreEqual($color, $corner); |
|
491 } |
|
492 |
|
493 $directory = file_default_scheme() . '://imagetests'; |
|
494 file_prepare_directory($directory, FILE_CREATE_DIRECTORY); |
|
495 $file_path = $directory . '/' . $op . '.' . $image->info['extension']; |
|
496 image_save($image, $file_path); |
|
497 |
|
498 $this->assertTrue($correct_dimensions_real, format_string('Image %file after %action action has proper dimensions.', array('%file' => $file, '%action' => $op))); |
|
499 $this->assertTrue($correct_dimensions_object, format_string('Image %file object after %action action is reporting the proper height and width values.', array('%file' => $file, '%action' => $op))); |
|
500 // JPEG colors will always be messed up due to compression. |
|
501 if ($image->info['extension'] != 'jpg') { |
|
502 $this->assertTrue($correct_colors, format_string('Image %file object after %action action has the correct color placement.', array('%file' => $file, '%action' => $op))); |
|
503 } |
|
504 } |
|
505 |
|
506 // Check that saved image reloads without raising PHP errors. |
|
507 $image_reloaded = image_load($file_path); |
|
508 } |
|
509 } |
|
510 |
|
511 /** |
|
512 * Tests loading an image whose transparent color index is out of range. |
|
513 */ |
|
514 function testTransparentColorOutOfRange() { |
|
515 // This image was generated by taking an initial image with a palette size |
|
516 // of 6 colors, and setting the transparent color index to 6 (one higher |
|
517 // than the largest allowed index), as follows: |
|
518 // @code |
|
519 // $image = imagecreatefromgif('modules/simpletest/files/image-test.gif'); |
|
520 // imagecolortransparent($image, 6); |
|
521 // imagegif($image, 'modules/simpletest/files/image-test-transparent-out-of-range.gif'); |
|
522 // @endcode |
|
523 // This allows us to test that an image with an out-of-range color index |
|
524 // can be loaded correctly. |
|
525 $file = 'image-test-transparent-out-of-range.gif'; |
|
526 $image = image_load(drupal_get_path('module', 'simpletest') . '/files/' . $file); |
|
527 |
|
528 if (!$image) { |
|
529 $this->fail(format_string('Could not load image %file.', array('%file' => $file))); |
|
530 } |
|
531 else { |
|
532 // All images should be converted to truecolor when loaded. |
|
533 $image_truecolor = imageistruecolor($image->resource); |
|
534 $this->assertTrue($image_truecolor, format_string('Image %file after load is a truecolor image.', array('%file' => $file))); |
|
535 } |
|
536 } |
|
537 } |
|
538 |
|
539 /** |
|
540 * Tests the file move function for managed files. |
|
541 */ |
|
542 class ImageFileMoveTest extends ImageToolkitTestCase { |
|
543 public static function getInfo() { |
|
544 return array( |
|
545 'name' => 'Image moving', |
|
546 'description' => 'Tests the file move function for managed files.', |
|
547 'group' => 'Image', |
|
548 ); |
|
549 } |
|
550 |
|
551 /** |
|
552 * Tests moving a randomly generated image. |
|
553 */ |
|
554 function testNormal() { |
|
555 // Pick a file for testing. |
|
556 $file = current($this->drupalGetTestFiles('image')); |
|
557 |
|
558 // Create derivative image. |
|
559 $style = image_style_load(key(image_styles())); |
|
560 $derivative_uri = image_style_path($style['name'], $file->uri); |
|
561 image_style_create_derivative($style, $file->uri, $derivative_uri); |
|
562 |
|
563 // Check if derivative image exists. |
|
564 $this->assertTrue(file_exists($derivative_uri), 'Make sure derivative image is generated successfully.'); |
|
565 |
|
566 // Clone the object so we don't have to worry about the function changing |
|
567 // our reference copy. |
|
568 $desired_filepath = 'public://' . $this->randomName(); |
|
569 $result = file_move(clone $file, $desired_filepath, FILE_EXISTS_ERROR); |
|
570 |
|
571 // Check if image has been moved. |
|
572 $this->assertTrue(file_exists($result->uri), 'Make sure image is moved successfully.'); |
|
573 |
|
574 // Check if derivative image has been flushed. |
|
575 $this->assertFalse(file_exists($derivative_uri), 'Make sure derivative image has been flushed.'); |
|
576 } |
|
577 } |
|
578 |