Security update for Core, with self-updated composer
[yaffs-website] / vendor / symfony / serializer / Tests / Normalizer / PropertyNormalizerTest.php
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
12 namespace Symfony\Component\Serializer\Tests\Normalizer;
13
14 use Doctrine\Common\Annotations\AnnotationReader;
15 use PHPUnit\Framework\TestCase;
16 use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
17 use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
18 use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter;
19 use Symfony\Component\Serializer\Normalizer\PropertyNormalizer;
20 use Symfony\Component\Serializer\Serializer;
21 use Symfony\Component\Serializer\SerializerInterface;
22 use Symfony\Component\Serializer\Tests\Fixtures\GroupDummy;
23 use Symfony\Component\Serializer\Tests\Fixtures\MaxDepthDummy;
24 use Symfony\Component\Serializer\Tests\Fixtures\PropertyCircularReferenceDummy;
25 use Symfony\Component\Serializer\Tests\Fixtures\PropertySiblingHolder;
26
27 class PropertyNormalizerTest extends TestCase
28 {
29     /**
30      * @var PropertyNormalizer
31      */
32     private $normalizer;
33     /**
34      * @var SerializerInterface
35      */
36     private $serializer;
37
38     protected function setUp()
39     {
40         $this->serializer = $this->getMockBuilder('Symfony\Component\Serializer\SerializerInterface')->getMock();
41         $this->normalizer = new PropertyNormalizer();
42         $this->normalizer->setSerializer($this->serializer);
43     }
44
45     public function testNormalize()
46     {
47         $obj = new PropertyDummy();
48         $obj->foo = 'foo';
49         $obj->setBar('bar');
50         $obj->setCamelCase('camelcase');
51         $this->assertEquals(
52             array('foo' => 'foo', 'bar' => 'bar', 'camelCase' => 'camelcase'),
53             $this->normalizer->normalize($obj, 'any')
54         );
55     }
56
57     public function testDenormalize()
58     {
59         $obj = $this->normalizer->denormalize(
60             array('foo' => 'foo', 'bar' => 'bar'),
61             __NAMESPACE__.'\PropertyDummy',
62             'any'
63         );
64         $this->assertEquals('foo', $obj->foo);
65         $this->assertEquals('bar', $obj->getBar());
66     }
67
68     public function testConstructorDenormalize()
69     {
70         $obj = $this->normalizer->denormalize(
71             array('foo' => 'foo', 'bar' => 'bar'),
72             __NAMESPACE__.'\PropertyConstructorDummy',
73             'any'
74         );
75         $this->assertEquals('foo', $obj->getFoo());
76         $this->assertEquals('bar', $obj->getBar());
77     }
78
79     public function testConstructorDenormalizeWithNullArgument()
80     {
81         $obj = $this->normalizer->denormalize(
82             array('foo' => null, 'bar' => 'bar'),
83             __NAMESPACE__.'\PropertyConstructorDummy', '
84             any'
85         );
86         $this->assertNull($obj->getFoo());
87         $this->assertEquals('bar', $obj->getBar());
88     }
89
90     /**
91      * @dataProvider provideCallbacks
92      */
93     public function testCallbacks($callbacks, $value, $result, $message)
94     {
95         $this->normalizer->setCallbacks($callbacks);
96
97         $obj = new PropertyConstructorDummy('', $value);
98
99         $this->assertEquals(
100             $result,
101             $this->normalizer->normalize($obj, 'any'),
102             $message
103         );
104     }
105
106     /**
107      * @expectedException \InvalidArgumentException
108      */
109     public function testUncallableCallbacks()
110     {
111         $this->normalizer->setCallbacks(array('bar' => null));
112
113         $obj = new PropertyConstructorDummy('baz', 'quux');
114
115         $this->normalizer->normalize($obj, 'any');
116     }
117
118     public function testIgnoredAttributes()
119     {
120         $this->normalizer->setIgnoredAttributes(array('foo', 'bar', 'camelCase'));
121
122         $obj = new PropertyDummy();
123         $obj->foo = 'foo';
124         $obj->setBar('bar');
125
126         $this->assertEquals(
127             array(),
128             $this->normalizer->normalize($obj, 'any')
129         );
130     }
131
132     public function testGroupsNormalize()
133     {
134         $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
135         $this->normalizer = new PropertyNormalizer($classMetadataFactory);
136         $this->normalizer->setSerializer($this->serializer);
137
138         $obj = new GroupDummy();
139         $obj->setFoo('foo');
140         $obj->setBar('bar');
141         $obj->setFooBar('fooBar');
142         $obj->setSymfony('symfony');
143         $obj->setKevin('kevin');
144         $obj->setCoopTilleuls('coopTilleuls');
145
146         $this->assertEquals(array(
147             'bar' => 'bar',
148         ), $this->normalizer->normalize($obj, null, array(PropertyNormalizer::GROUPS => array('c'))));
149
150         // The PropertyNormalizer is not able to hydrate properties from parent classes
151         $this->assertEquals(array(
152             'symfony' => 'symfony',
153             'foo' => 'foo',
154             'fooBar' => 'fooBar',
155             'bar' => 'bar',
156         ), $this->normalizer->normalize($obj, null, array(PropertyNormalizer::GROUPS => array('a', 'c'))));
157     }
158
159     public function testGroupsDenormalize()
160     {
161         $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
162         $this->normalizer = new PropertyNormalizer($classMetadataFactory);
163         $this->normalizer->setSerializer($this->serializer);
164
165         $obj = new GroupDummy();
166         $obj->setFoo('foo');
167
168         $toNormalize = array('foo' => 'foo', 'bar' => 'bar');
169
170         $normalized = $this->normalizer->denormalize(
171             $toNormalize,
172             'Symfony\Component\Serializer\Tests\Fixtures\GroupDummy',
173             null,
174             array(PropertyNormalizer::GROUPS => array('a'))
175         );
176         $this->assertEquals($obj, $normalized);
177
178         $obj->setBar('bar');
179
180         $normalized = $this->normalizer->denormalize(
181             $toNormalize,
182             'Symfony\Component\Serializer\Tests\Fixtures\GroupDummy',
183             null,
184             array(PropertyNormalizer::GROUPS => array('a', 'b'))
185         );
186         $this->assertEquals($obj, $normalized);
187     }
188
189     public function testGroupsNormalizeWithNameConverter()
190     {
191         $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
192         $this->normalizer = new PropertyNormalizer($classMetadataFactory, new CamelCaseToSnakeCaseNameConverter());
193         $this->normalizer->setSerializer($this->serializer);
194
195         $obj = new GroupDummy();
196         $obj->setFooBar('@dunglas');
197         $obj->setSymfony('@coopTilleuls');
198         $obj->setCoopTilleuls('les-tilleuls.coop');
199
200         $this->assertEquals(
201             array(
202                 'bar' => null,
203                 'foo_bar' => '@dunglas',
204                 'symfony' => '@coopTilleuls',
205             ),
206             $this->normalizer->normalize($obj, null, array(PropertyNormalizer::GROUPS => array('name_converter')))
207         );
208     }
209
210     public function testGroupsDenormalizeWithNameConverter()
211     {
212         $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
213         $this->normalizer = new PropertyNormalizer($classMetadataFactory, new CamelCaseToSnakeCaseNameConverter());
214         $this->normalizer->setSerializer($this->serializer);
215
216         $obj = new GroupDummy();
217         $obj->setFooBar('@dunglas');
218         $obj->setSymfony('@coopTilleuls');
219
220         $this->assertEquals(
221             $obj,
222             $this->normalizer->denormalize(array(
223                 'bar' => null,
224                 'foo_bar' => '@dunglas',
225                 'symfony' => '@coopTilleuls',
226                 'coop_tilleuls' => 'les-tilleuls.coop',
227             ), 'Symfony\Component\Serializer\Tests\Fixtures\GroupDummy', null, array(PropertyNormalizer::GROUPS => array('name_converter')))
228         );
229     }
230
231     public function provideCallbacks()
232     {
233         return array(
234             array(
235                 array(
236                     'bar' => function ($bar) {
237                         return 'baz';
238                     },
239                 ),
240                 'baz',
241                 array('foo' => '', 'bar' => 'baz'),
242                 'Change a string',
243             ),
244             array(
245                 array(
246                     'bar' => function ($bar) {
247                         return;
248                     },
249                 ),
250                 'baz',
251                 array('foo' => '', 'bar' => null),
252                 'Null an item',
253             ),
254             array(
255                 array(
256                     'bar' => function ($bar) {
257                         return $bar->format('d-m-Y H:i:s');
258                     },
259                 ),
260                 new \DateTime('2011-09-10 06:30:00'),
261                 array('foo' => '', 'bar' => '10-09-2011 06:30:00'),
262                 'Format a date',
263             ),
264             array(
265                 array(
266                     'bar' => function ($bars) {
267                         $foos = '';
268                         foreach ($bars as $bar) {
269                             $foos .= $bar->getFoo();
270                         }
271
272                         return $foos;
273                     },
274                 ),
275                 array(new PropertyConstructorDummy('baz', ''), new PropertyConstructorDummy('quux', '')),
276                 array('foo' => '', 'bar' => 'bazquux'),
277                 'Collect a property',
278             ),
279             array(
280                 array(
281                     'bar' => function ($bars) {
282                         return count($bars);
283                     },
284                 ),
285                 array(new PropertyConstructorDummy('baz', ''), new PropertyConstructorDummy('quux', '')),
286                 array('foo' => '', 'bar' => 2),
287                 'Count a property',
288             ),
289         );
290     }
291
292     /**
293      * @expectedException \Symfony\Component\Serializer\Exception\CircularReferenceException
294      */
295     public function testUnableToNormalizeCircularReference()
296     {
297         $serializer = new Serializer(array($this->normalizer));
298         $this->normalizer->setSerializer($serializer);
299         $this->normalizer->setCircularReferenceLimit(2);
300
301         $obj = new PropertyCircularReferenceDummy();
302
303         $this->normalizer->normalize($obj);
304     }
305
306     public function testSiblingReference()
307     {
308         $serializer = new Serializer(array($this->normalizer));
309         $this->normalizer->setSerializer($serializer);
310
311         $siblingHolder = new PropertySiblingHolder();
312
313         $expected = array(
314             'sibling0' => array('coopTilleuls' => 'Les-Tilleuls.coop'),
315             'sibling1' => array('coopTilleuls' => 'Les-Tilleuls.coop'),
316             'sibling2' => array('coopTilleuls' => 'Les-Tilleuls.coop'),
317         );
318         $this->assertEquals($expected, $this->normalizer->normalize($siblingHolder));
319     }
320
321     public function testCircularReferenceHandler()
322     {
323         $serializer = new Serializer(array($this->normalizer));
324         $this->normalizer->setSerializer($serializer);
325         $this->normalizer->setCircularReferenceHandler(function ($obj) {
326             return get_class($obj);
327         });
328
329         $obj = new PropertyCircularReferenceDummy();
330
331         $expected = array('me' => 'Symfony\Component\Serializer\Tests\Fixtures\PropertyCircularReferenceDummy');
332         $this->assertEquals($expected, $this->normalizer->normalize($obj));
333     }
334
335     public function testDenormalizeNonExistingAttribute()
336     {
337         $this->assertEquals(
338             new PropertyDummy(),
339             $this->normalizer->denormalize(array('non_existing' => true), __NAMESPACE__.'\PropertyDummy')
340         );
341     }
342
343     public function testDenormalizeShouldIgnoreStaticProperty()
344     {
345         $obj = $this->normalizer->denormalize(array('outOfScope' => true), __NAMESPACE__.'\PropertyDummy');
346
347         $this->assertEquals(new PropertyDummy(), $obj);
348         $this->assertEquals('out_of_scope', PropertyDummy::$outOfScope);
349     }
350
351     /**
352      * @expectedException \Symfony\Component\Serializer\Exception\LogicException
353      * @expectedExceptionMessage Cannot normalize attribute "bar" because the injected serializer is not a normalizer
354      */
355     public function testUnableToNormalizeObjectAttribute()
356     {
357         $serializer = $this->getMockBuilder('Symfony\Component\Serializer\SerializerInterface')->getMock();
358         $this->normalizer->setSerializer($serializer);
359
360         $obj = new PropertyDummy();
361         $object = new \stdClass();
362         $obj->setBar($object);
363
364         $this->normalizer->normalize($obj, 'any');
365     }
366
367     public function testNoTraversableSupport()
368     {
369         $this->assertFalse($this->normalizer->supportsNormalization(new \ArrayObject()));
370     }
371
372     public function testNoStaticPropertySupport()
373     {
374         $this->assertFalse($this->normalizer->supportsNormalization(new StaticPropertyDummy()));
375     }
376
377     public function testMaxDepth()
378     {
379         $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
380         $this->normalizer = new PropertyNormalizer($classMetadataFactory);
381         $serializer = new Serializer(array($this->normalizer));
382         $this->normalizer->setSerializer($serializer);
383
384         $level1 = new MaxDepthDummy();
385         $level1->foo = 'level1';
386
387         $level2 = new MaxDepthDummy();
388         $level2->foo = 'level2';
389         $level1->child = $level2;
390
391         $level3 = new MaxDepthDummy();
392         $level3->foo = 'level3';
393         $level2->child = $level3;
394
395         $result = $serializer->normalize($level1, null, array(PropertyNormalizer::ENABLE_MAX_DEPTH => true));
396
397         $expected = array(
398             'foo' => 'level1',
399             'child' => array(
400                     'foo' => 'level2',
401                     'child' => array(
402                             'child' => null,
403                             'bar' => null,
404                         ),
405                     'bar' => null,
406                 ),
407             'bar' => null,
408         );
409
410         $this->assertEquals($expected, $result);
411     }
412 }
413
414 class PropertyDummy
415 {
416     public static $outOfScope = 'out_of_scope';
417     public $foo;
418     private $bar;
419     protected $camelCase;
420
421     public function getBar()
422     {
423         return $this->bar;
424     }
425
426     public function setBar($bar)
427     {
428         $this->bar = $bar;
429     }
430
431     public function getCamelCase()
432     {
433         return $this->camelCase;
434     }
435
436     public function setCamelCase($camelCase)
437     {
438         $this->camelCase = $camelCase;
439     }
440 }
441
442 class PropertyConstructorDummy
443 {
444     protected $foo;
445     private $bar;
446
447     public function __construct($foo, $bar)
448     {
449         $this->foo = $foo;
450         $this->bar = $bar;
451     }
452
453     public function getFoo()
454     {
455         return $this->foo;
456     }
457
458     public function getBar()
459     {
460         return $this->bar;
461     }
462 }
463
464 class PropertyCamelizedDummy
465 {
466     private $kevinDunglas;
467     public $fooBar;
468     public $bar_foo;
469
470     public function __construct($kevinDunglas = null)
471     {
472         $this->kevinDunglas = $kevinDunglas;
473     }
474 }
475
476 class StaticPropertyDummy
477 {
478     private static $property = 'value';
479 }