1<?php
2
3/*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <fabien@symfony.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12namespace Symfony\Component\Validator\Tests\Constraints;
13
14use Symfony\Component\Validator\Constraints\Image;
15use Symfony\Component\Validator\Constraints\ImageValidator;
16use Symfony\Component\Validator\Test\ConstraintValidatorTestCase;
17
18/**
19 * @requires extension fileinfo
20 */
21class ImageValidatorTest extends ConstraintValidatorTestCase
22{
23    protected $context;
24
25    /**
26     * @var ImageValidator
27     */
28    protected $validator;
29
30    protected $path;
31    protected $image;
32    protected $imageLandscape;
33    protected $imagePortrait;
34    protected $image4By3;
35    protected $imageCorrupted;
36
37    protected function createValidator()
38    {
39        return new ImageValidator();
40    }
41
42    protected function setUp()
43    {
44        parent::setUp();
45
46        $this->image = __DIR__.'/Fixtures/test.gif';
47        $this->imageLandscape = __DIR__.'/Fixtures/test_landscape.gif';
48        $this->imagePortrait = __DIR__.'/Fixtures/test_portrait.gif';
49        $this->image4By3 = __DIR__.'/Fixtures/test_4by3.gif';
50        $this->imageCorrupted = __DIR__.'/Fixtures/test_corrupted.gif';
51    }
52
53    public function testNullIsValid()
54    {
55        $this->validator->validate(null, new Image());
56
57        $this->assertNoViolation();
58    }
59
60    public function testEmptyStringIsValid()
61    {
62        $this->validator->validate('', new Image());
63
64        $this->assertNoViolation();
65    }
66
67    public function testValidImage()
68    {
69        $this->validator->validate($this->image, new Image());
70
71        $this->assertNoViolation();
72    }
73
74    public function testFileNotFound()
75    {
76        // Check that the logic from FileValidator still works
77        $constraint = new Image([
78            'notFoundMessage' => 'myMessage',
79        ]);
80
81        $this->validator->validate('foobar', $constraint);
82
83        $this->buildViolation('myMessage')
84            ->setParameter('{{ file }}', '"foobar"')
85            ->setCode(Image::NOT_FOUND_ERROR)
86            ->assertRaised();
87    }
88
89    public function testValidSize()
90    {
91        $constraint = new Image([
92            'minWidth' => 1,
93            'maxWidth' => 2,
94            'minHeight' => 1,
95            'maxHeight' => 2,
96        ]);
97
98        $this->validator->validate($this->image, $constraint);
99
100        $this->assertNoViolation();
101    }
102
103    public function testWidthTooSmall()
104    {
105        $constraint = new Image([
106            'minWidth' => 3,
107            'minWidthMessage' => 'myMessage',
108        ]);
109
110        $this->validator->validate($this->image, $constraint);
111
112        $this->buildViolation('myMessage')
113            ->setParameter('{{ width }}', '2')
114            ->setParameter('{{ min_width }}', '3')
115            ->setCode(Image::TOO_NARROW_ERROR)
116            ->assertRaised();
117    }
118
119    public function testWidthTooBig()
120    {
121        $constraint = new Image([
122            'maxWidth' => 1,
123            'maxWidthMessage' => 'myMessage',
124        ]);
125
126        $this->validator->validate($this->image, $constraint);
127
128        $this->buildViolation('myMessage')
129            ->setParameter('{{ width }}', '2')
130            ->setParameter('{{ max_width }}', '1')
131            ->setCode(Image::TOO_WIDE_ERROR)
132            ->assertRaised();
133    }
134
135    public function testHeightTooSmall()
136    {
137        $constraint = new Image([
138            'minHeight' => 3,
139            'minHeightMessage' => 'myMessage',
140        ]);
141
142        $this->validator->validate($this->image, $constraint);
143
144        $this->buildViolation('myMessage')
145            ->setParameter('{{ height }}', '2')
146            ->setParameter('{{ min_height }}', '3')
147            ->setCode(Image::TOO_LOW_ERROR)
148            ->assertRaised();
149    }
150
151    public function testHeightTooBig()
152    {
153        $constraint = new Image([
154            'maxHeight' => 1,
155            'maxHeightMessage' => 'myMessage',
156        ]);
157
158        $this->validator->validate($this->image, $constraint);
159
160        $this->buildViolation('myMessage')
161            ->setParameter('{{ height }}', '2')
162            ->setParameter('{{ max_height }}', '1')
163            ->setCode(Image::TOO_HIGH_ERROR)
164            ->assertRaised();
165    }
166
167    public function testPixelsTooFew()
168    {
169        $constraint = new Image([
170            'minPixels' => 5,
171            'minPixelsMessage' => 'myMessage',
172        ]);
173
174        $this->validator->validate($this->image, $constraint);
175
176        $this->buildViolation('myMessage')
177            ->setParameter('{{ pixels }}', '4')
178            ->setParameter('{{ min_pixels }}', '5')
179            ->setParameter('{{ height }}', '2')
180            ->setParameter('{{ width }}', '2')
181            ->setCode(Image::TOO_FEW_PIXEL_ERROR)
182            ->assertRaised();
183    }
184
185    public function testPixelsTooMany()
186    {
187        $constraint = new Image([
188            'maxPixels' => 3,
189            'maxPixelsMessage' => 'myMessage',
190        ]);
191
192        $this->validator->validate($this->image, $constraint);
193
194        $this->buildViolation('myMessage')
195            ->setParameter('{{ pixels }}', '4')
196            ->setParameter('{{ max_pixels }}', '3')
197            ->setParameter('{{ height }}', '2')
198            ->setParameter('{{ width }}', '2')
199            ->setCode(Image::TOO_MANY_PIXEL_ERROR)
200            ->assertRaised();
201    }
202
203    public function testInvalidMinWidth()
204    {
205        $this->expectException('Symfony\Component\Validator\Exception\ConstraintDefinitionException');
206        $constraint = new Image([
207            'minWidth' => '1abc',
208        ]);
209
210        $this->validator->validate($this->image, $constraint);
211    }
212
213    public function testInvalidMaxWidth()
214    {
215        $this->expectException('Symfony\Component\Validator\Exception\ConstraintDefinitionException');
216        $constraint = new Image([
217            'maxWidth' => '1abc',
218        ]);
219
220        $this->validator->validate($this->image, $constraint);
221    }
222
223    public function testInvalidMinHeight()
224    {
225        $this->expectException('Symfony\Component\Validator\Exception\ConstraintDefinitionException');
226        $constraint = new Image([
227            'minHeight' => '1abc',
228        ]);
229
230        $this->validator->validate($this->image, $constraint);
231    }
232
233    public function testInvalidMaxHeight()
234    {
235        $this->expectException('Symfony\Component\Validator\Exception\ConstraintDefinitionException');
236        $constraint = new Image([
237            'maxHeight' => '1abc',
238        ]);
239
240        $this->validator->validate($this->image, $constraint);
241    }
242
243    public function testInvalidMinPixels()
244    {
245        $this->expectException('Symfony\Component\Validator\Exception\ConstraintDefinitionException');
246        $constraint = new Image([
247            'minPixels' => '1abc',
248        ]);
249
250        $this->validator->validate($this->image, $constraint);
251    }
252
253    public function testInvalidMaxPixels()
254    {
255        $this->expectException('Symfony\Component\Validator\Exception\ConstraintDefinitionException');
256        $constraint = new Image([
257            'maxPixels' => '1abc',
258        ]);
259
260        $this->validator->validate($this->image, $constraint);
261    }
262
263    public function testRatioTooSmall()
264    {
265        $constraint = new Image([
266            'minRatio' => 2,
267            'minRatioMessage' => 'myMessage',
268        ]);
269
270        $this->validator->validate($this->image, $constraint);
271
272        $this->buildViolation('myMessage')
273            ->setParameter('{{ ratio }}', 1)
274            ->setParameter('{{ min_ratio }}', 2)
275            ->setCode(Image::RATIO_TOO_SMALL_ERROR)
276            ->assertRaised();
277    }
278
279    public function testRatioTooBig()
280    {
281        $constraint = new Image([
282            'maxRatio' => 0.5,
283            'maxRatioMessage' => 'myMessage',
284        ]);
285
286        $this->validator->validate($this->image, $constraint);
287
288        $this->buildViolation('myMessage')
289            ->setParameter('{{ ratio }}', 1)
290            ->setParameter('{{ max_ratio }}', 0.5)
291            ->setCode(Image::RATIO_TOO_BIG_ERROR)
292            ->assertRaised();
293    }
294
295    public function testMaxRatioUsesTwoDecimalsOnly()
296    {
297        $constraint = new Image([
298            'maxRatio' => 1.33,
299        ]);
300
301        $this->validator->validate($this->image4By3, $constraint);
302
303        $this->assertNoViolation();
304    }
305
306    public function testInvalidMinRatio()
307    {
308        $this->expectException('Symfony\Component\Validator\Exception\ConstraintDefinitionException');
309        $constraint = new Image([
310            'minRatio' => '1abc',
311        ]);
312
313        $this->validator->validate($this->image, $constraint);
314    }
315
316    public function testInvalidMaxRatio()
317    {
318        $this->expectException('Symfony\Component\Validator\Exception\ConstraintDefinitionException');
319        $constraint = new Image([
320            'maxRatio' => '1abc',
321        ]);
322
323        $this->validator->validate($this->image, $constraint);
324    }
325
326    public function testSquareNotAllowed()
327    {
328        $constraint = new Image([
329            'allowSquare' => false,
330            'allowSquareMessage' => 'myMessage',
331        ]);
332
333        $this->validator->validate($this->image, $constraint);
334
335        $this->buildViolation('myMessage')
336            ->setParameter('{{ width }}', 2)
337            ->setParameter('{{ height }}', 2)
338            ->setCode(Image::SQUARE_NOT_ALLOWED_ERROR)
339            ->assertRaised();
340    }
341
342    public function testLandscapeNotAllowed()
343    {
344        $constraint = new Image([
345            'allowLandscape' => false,
346            'allowLandscapeMessage' => 'myMessage',
347        ]);
348
349        $this->validator->validate($this->imageLandscape, $constraint);
350
351        $this->buildViolation('myMessage')
352            ->setParameter('{{ width }}', 2)
353            ->setParameter('{{ height }}', 1)
354            ->setCode(Image::LANDSCAPE_NOT_ALLOWED_ERROR)
355            ->assertRaised();
356    }
357
358    public function testPortraitNotAllowed()
359    {
360        $constraint = new Image([
361            'allowPortrait' => false,
362            'allowPortraitMessage' => 'myMessage',
363        ]);
364
365        $this->validator->validate($this->imagePortrait, $constraint);
366
367        $this->buildViolation('myMessage')
368            ->setParameter('{{ width }}', 1)
369            ->setParameter('{{ height }}', 2)
370            ->setCode(Image::PORTRAIT_NOT_ALLOWED_ERROR)
371            ->assertRaised();
372    }
373
374    public function testCorrupted()
375    {
376        if (!\function_exists('imagecreatefromstring')) {
377            $this->markTestSkipped('This test require GD extension');
378        }
379
380        $constraint = new Image([
381            'detectCorrupted' => true,
382            'corruptedMessage' => 'myMessage',
383        ]);
384
385        $this->validator->validate($this->image, $constraint);
386
387        $this->assertNoViolation();
388
389        $this->validator->validate($this->imageCorrupted, $constraint);
390
391        $this->buildViolation('myMessage')
392            ->setCode(Image::CORRUPTED_IMAGE_ERROR)
393            ->assertRaised();
394    }
395}
396