From d51150f4ee4f7b964debd3d0c4c704b6bb3c0dc3 Mon Sep 17 00:00:00 2001 From: Jelle van Oosterbosch Date: Thu, 6 Feb 2020 00:44:05 +0100 Subject: [PATCH 1/9] Added first build for recursive json normalization Added the DateTimeNormalizator with unit test --- Resources/config/services.exporter.types.yml | 5 ++ .../Normalizer/AnnotationNormalizer.php | 45 +++++++++++++++- Tests/AnnotatedMock.php | 20 ++++++++ Tests/Annotation/AnnotationReaderTest.php | 10 ++-- .../json/annotation_normalize_result.json | 1 + .../xml/annotation_normalizer_result.xml | 2 +- .../Normalizer/AnnotationNormalizerTest.php | 51 ++++++++++++++++--- 7 files changed, 120 insertions(+), 14 deletions(-) create mode 100644 Tests/Resources/json/annotation_normalize_result.json diff --git a/Resources/config/services.exporter.types.yml b/Resources/config/services.exporter.types.yml index ed00698..af9f918 100644 --- a/Resources/config/services.exporter.types.yml +++ b/Resources/config/services.exporter.types.yml @@ -2,6 +2,11 @@ services: _defaults: public: false + superbrave_gdpr.exporter.serializer.normalizer.datetime_normalizer: + class: Symfony\Component\Serializer\Normalizer\DateTimeNormalizer + tags: + - { name: "superbrave_gdpr.serializer.normalizer" } + superbrave_gdpr.exporter.serializer.normalizer.export_annotation: class: Superbrave\GdprBundle\Serializer\Normalizer\AnnotationNormalizer arguments: diff --git a/Serializer/Normalizer/AnnotationNormalizer.php b/Serializer/Normalizer/AnnotationNormalizer.php index b3e89c5..f3f6fac 100644 --- a/Serializer/Normalizer/AnnotationNormalizer.php +++ b/Serializer/Normalizer/AnnotationNormalizer.php @@ -16,15 +16,20 @@ use Superbrave\GdprBundle\Annotation\AnnotationReader; use Superbrave\GdprBundle\Manipulator\PropertyManipulator; use Symfony\Component\PropertyAccess\PropertyAccessorInterface; +use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface; +use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait; use Symfony\Component\Serializer\Normalizer\NormalizerInterface; /** * Normalizes object data based on the specified property annotation. * * @author Niels Nijens + * @author Jelle van Oosterbosch */ -class AnnotationNormalizer implements NormalizerInterface +class AnnotationNormalizer implements NormalizerInterface, NormalizerAwareInterface { + use NormalizerAwareTrait; + /** * The AnnotationReader instance. * @@ -70,6 +75,8 @@ public function __construct( * @param string $format The format being (de-)serialized from or into * * @return bool + * + * @throws \ReflectionException */ public function supportsNormalization($data, $format = null) { @@ -93,10 +100,13 @@ public function supportsNormalization($data, $format = null) * @param array $context Context options for the normalizer * * @return array|string|int|float|bool + * + * @throws \ReflectionException */ public function normalize($object, $format = null, array $context = array()) { $normalizedData = array(); + $index = 0; $propertyAnnotations = $this->annotationReader->getPropertiesWithAnnotation( new ReflectionClass($object), $this->annotationName @@ -108,12 +118,43 @@ public function normalize($object, $format = null, array $context = array()) $propertyName = $propertyAnnotation->alias; } - $normalizedData[$propertyName] = $this->getMappedPropertyValue($propertyAnnotation, $propertyValue); + if (is_iterable($propertyValue) && count($propertyValue) > 0) { + $normalizedData[$propertyName] = $this->normalizeArray($propertyValue, $index, $format, $context); + } else { + $normalizedData[$propertyName] = $this->getMappedPropertyValue($propertyAnnotation, $propertyValue); + } } return $normalizedData; } + /** + * Normalizes an array recursively by calling the chain normalizer. + * + * @param iterable $propertyValue + * @param int $index + * @param string $format + * @param array $context + * + * @return array + */ + private function normalizeArray($propertyValue, &$index, $format = null, array $context = array()) + { + $data = []; + + foreach ($propertyValue as $value) { + $data[$index][] = $this->normalizer->normalize( + $value, + $format, + $context + ); + } + + $index++; + + return $data; + } + /** * Returns the mapped value of a property or the original value when no value map is configured on the annotation. * diff --git a/Tests/AnnotatedMock.php b/Tests/AnnotatedMock.php index 4f8300d..4efc676 100644 --- a/Tests/AnnotatedMock.php +++ b/Tests/AnnotatedMock.php @@ -19,6 +19,7 @@ * Class used to test the @see GDPR\AnnotationReader. * * @author Niels Nijens + * @author Jelle van Oosterbosch */ class AnnotatedMock { @@ -59,6 +60,15 @@ class AnnotatedMock */ private $quux; + /** + * The quuz property. + * + * @GDPR\Export() + * + * @var \DateTime + */ + private $quuz; + /** * The property that is annotated with the Export annotation, but without getter method. * @@ -90,8 +100,10 @@ public function __construct(AnnotatedMock $annotatedMock = null) $elements = array(); if ($annotatedMock instanceof AnnotatedMock) { $elements[] = $annotatedMock; + $elements[] = clone $annotatedMock; } + $this->quuz = new \DateTime('2016/01/01'); $this->quux = new ArrayCollection($elements); } @@ -135,6 +147,14 @@ public function getQuux() return $this->quux; } + /** + * @return \DateTime + */ + public function getQuuz() + { + return $this->quuz; + } + /** * Returns the value of the notAnnotatedProperty property. * diff --git a/Tests/Annotation/AnnotationReaderTest.php b/Tests/Annotation/AnnotationReaderTest.php index fa308a7..1c020d0 100644 --- a/Tests/Annotation/AnnotationReaderTest.php +++ b/Tests/Annotation/AnnotationReaderTest.php @@ -24,6 +24,7 @@ * AnnotationReaderTest. * * @author Niels Nijens + * @author Jelle van Oosterbosch */ class AnnotationReaderTest extends PHPUnit_Framework_TestCase { @@ -64,9 +65,9 @@ public function testGetPropertiesWithAnnotationExport() ); $this->assertInternalType('array', $result); - $this->assertCount(5, $result); + $this->assertCount(6, $result); $this->assertSame( - array('foo', 'baz', 'qux', 'quux', 'annotatedPropertyWithoutMethod'), + array('foo', 'baz', 'qux', 'quux', 'quuz', 'annotatedPropertyWithoutMethod'), array_keys($result) ); $this->assertInstanceOf(Export::class, current($result)); @@ -108,11 +109,12 @@ public function testGetPropertiesWithAnnotationForExtendedClass() ); $this->assertInternalType('array', $result); - $this->assertCount(6, $result); + $this->assertCount(7, $result); $this->assertSame( - array('extendedProperty', 'foo', 'baz', 'qux', 'quux', 'annotatedPropertyWithoutMethod'), + array('extendedProperty', 'foo', 'baz', 'qux', 'quux', 'quuz', 'annotatedPropertyWithoutMethod'), array_keys($result) ); + $this->assertInstanceOf(Export::class, current($result)); } } diff --git a/Tests/Resources/json/annotation_normalize_result.json b/Tests/Resources/json/annotation_normalize_result.json new file mode 100644 index 0000000..5f03af5 --- /dev/null +++ b/Tests/Resources/json/annotation_normalize_result.json @@ -0,0 +1 @@ +{"foo":"bar","baz":1,"qux":[],"quuxs":[[{"foo":"bar","baz":1,"qux":[],"quuxs":{},"quuz":{"date":"2016-01-01 00:00:00.000000","timezone_type":3,"timezone":"UTC"},"annotatedPropertyWithoutMethod":"Yes"},{"foo":"bar","baz":1,"qux":[],"quuxs":{},"quuz":{"date":"2016-01-01 00:00:00.000000","timezone_type":3,"timezone":"UTC"},"annotatedPropertyWithoutMethod":"Yes"}]],"quuz":{"date":"2016-01-01 00:00:00.000000","timezone_type":3,"timezone":"UTC"},"annotatedPropertyWithoutMethod":"Yes"} \ No newline at end of file diff --git a/Tests/Resources/xml/annotation_normalizer_result.xml b/Tests/Resources/xml/annotation_normalizer_result.xml index 1114392..9a2fb40 100644 --- a/Tests/Resources/xml/annotation_normalizer_result.xml +++ b/Tests/Resources/xml/annotation_normalizer_result.xml @@ -1,2 +1,2 @@ -bar1bar1YesYes +bar1bar12016-01-01T00:00:00+00:00Yesbar12016-01-01T00:00:00+00:00Yes2016-01-01T00:00:00+00:00Yes diff --git a/Tests/Serializer/Normalizer/AnnotationNormalizerTest.php b/Tests/Serializer/Normalizer/AnnotationNormalizerTest.php index 031ad19..099f9a8 100644 --- a/Tests/Serializer/Normalizer/AnnotationNormalizerTest.php +++ b/Tests/Serializer/Normalizer/AnnotationNormalizerTest.php @@ -21,13 +21,16 @@ use Superbrave\GdprBundle\Serializer\Normalizer\AnnotationNormalizer; use Superbrave\GdprBundle\Tests\AnnotatedMock; use Symfony\Component\PropertyAccess\PropertyAccess; +use Symfony\Component\Serializer\Encoder\JsonEncoder; use Symfony\Component\Serializer\Encoder\XmlEncoder; +use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer; use Symfony\Component\Serializer\Serializer; /** * AnnotationNormalizerTest. * * @author Niels Nijens + * @author Jelle van Oosterbosch */ class AnnotationNormalizerTest extends \PHPUnit_Framework_TestCase { @@ -162,6 +165,7 @@ public function testNormalize() 'baz' => 1, 'qux' => array(), 'quuxs' => new ArrayCollection(), + 'quuz' => new \DateTime('2016/01/01'), 'annotatedPropertyWithoutMethod' => 'Yes', ), $normalizer->normalize($annotatedMock) @@ -169,31 +173,64 @@ public function testNormalize() } /** - * Tests if AnnotationNormalizer::normalize returns the expected normalized data + * Tests if @see AnnotationNormalizer::normalize returns the expected xml normalized data * for serialization through the Serializer. * * @return void */ - public function testNormalizeThroughSerializer() + public function testNormalizeThroughXmlSerializer() { $annotationReader = new AnnotationReader(); $propertyManipulator = new PropertyManipulator( PropertyAccess::createPropertyAccessor() ); - $normalizer = new AnnotationNormalizer($annotationReader, Export::class, $propertyManipulator); - $encoder = new XmlEncoder('mock'); + $normalizers = [ + new DateTimeNormalizer(), + new AnnotationNormalizer($annotationReader, Export::class, $propertyManipulator), + ]; + $encoders = [new XmlEncoder('mock')]; $serializer = new Serializer( - array($normalizer), - array($encoder) + $normalizers, + $encoders ); $data = new AnnotatedMock(new AnnotatedMock()); $this->assertStringEqualsFile( - __DIR__.'/../../Resources/xml/annotation_normalizer_result.xml', + __DIR__ . '/../../Resources/xml/annotation_normalizer_result.xml', $serializer->serialize($data, 'xml') ); } + + /** + * Test if @see AnnotationNormalizer::normalize returns the expected json normalized data + * for serialization through the Serializer. + */ + public function testNormalizeThroughJsonSerializer() + { + $annotationReader = new AnnotationReader(); + $propertyManipulator = new PropertyManipulator( + PropertyAccess::createPropertyAccessor() + ); + + $normalizers = [ + new DateTimeNormalizer(), + new AnnotationNormalizer($annotationReader, Export::class, $propertyManipulator), + ]; + $encoders = [new JsonEncoder()]; + + $serializer = new Serializer( + $normalizers, + $encoders + ); + + $data = new AnnotatedMock(new AnnotatedMock()); + + $this->assertStringEqualsFile( + __DIR__ . '/../../Resources/json/annotation_normalize_result.json', + $serializer->serialize($data, 'json') + ); + } } From 778433cbced16c9a196c8cae5b28983caceedb60 Mon Sep 17 00:00:00 2001 From: Jelle van Oosterbosch Date: Thu, 6 Feb 2020 11:23:24 +0100 Subject: [PATCH 2/9] Refactored so the logic lies in the abstraction of the normalizers Added an extra IterableNormalizer so we can traverse back to the AnnotationNormalizer Updated the unit tests --- Resources/config/services.exporter.types.yml | 5 ++ .../Normalizer/AnnotationNormalizer.php | 36 +------------- Serializer/Normalizer/IterableNormalizer.php | 47 +++++++++++++++++++ .../json/annotation_normalize_result.json | 2 +- .../xml/annotation_normalizer_result.xml | 2 +- .../Normalizer/AnnotationNormalizerTest.php | 16 +++++-- 6 files changed, 68 insertions(+), 40 deletions(-) create mode 100644 Serializer/Normalizer/IterableNormalizer.php diff --git a/Resources/config/services.exporter.types.yml b/Resources/config/services.exporter.types.yml index af9f918..326b9cf 100644 --- a/Resources/config/services.exporter.types.yml +++ b/Resources/config/services.exporter.types.yml @@ -2,6 +2,11 @@ services: _defaults: public: false + superbrave_gdpr.exporter.serializer.normalizer.iterable_normalizer: + class: Superbrave\GdprBundle\Serializer\Normalizer\IterableNormalizer + tags: + - { name: "superbrave_gdpr.serializer.normalizer" } + superbrave_gdpr.exporter.serializer.normalizer.datetime_normalizer: class: Symfony\Component\Serializer\Normalizer\DateTimeNormalizer tags: diff --git a/Serializer/Normalizer/AnnotationNormalizer.php b/Serializer/Normalizer/AnnotationNormalizer.php index f3f6fac..31768ba 100644 --- a/Serializer/Normalizer/AnnotationNormalizer.php +++ b/Serializer/Normalizer/AnnotationNormalizer.php @@ -106,7 +106,6 @@ public function supportsNormalization($data, $format = null) public function normalize($object, $format = null, array $context = array()) { $normalizedData = array(); - $index = 0; $propertyAnnotations = $this->annotationReader->getPropertiesWithAnnotation( new ReflectionClass($object), $this->annotationName @@ -118,8 +117,8 @@ public function normalize($object, $format = null, array $context = array()) $propertyName = $propertyAnnotation->alias; } - if (is_iterable($propertyValue) && count($propertyValue) > 0) { - $normalizedData[$propertyName] = $this->normalizeArray($propertyValue, $index, $format, $context); + if (false === is_scalar($propertyValue)) { + $normalizedData[$propertyName] = $this->normalizer->normalize($propertyValue, $format, $context); } else { $normalizedData[$propertyName] = $this->getMappedPropertyValue($propertyAnnotation, $propertyValue); } @@ -128,33 +127,6 @@ public function normalize($object, $format = null, array $context = array()) return $normalizedData; } - /** - * Normalizes an array recursively by calling the chain normalizer. - * - * @param iterable $propertyValue - * @param int $index - * @param string $format - * @param array $context - * - * @return array - */ - private function normalizeArray($propertyValue, &$index, $format = null, array $context = array()) - { - $data = []; - - foreach ($propertyValue as $value) { - $data[$index][] = $this->normalizer->normalize( - $value, - $format, - $context - ); - } - - $index++; - - return $data; - } - /** * Returns the mapped value of a property or the original value when no value map is configured on the annotation. * @@ -165,10 +137,6 @@ private function normalizeArray($propertyValue, &$index, $format = null, array $ */ private function getMappedPropertyValue($annotation, $propertyValue) { - if (is_scalar($propertyValue) === false) { - return $propertyValue; - } - if (property_exists($annotation, 'valueMap') === false || isset($annotation->valueMap) === false) { return $propertyValue; } diff --git a/Serializer/Normalizer/IterableNormalizer.php b/Serializer/Normalizer/IterableNormalizer.php new file mode 100644 index 0000000..d3a6010 --- /dev/null +++ b/Serializer/Normalizer/IterableNormalizer.php @@ -0,0 +1,47 @@ + + */ +class IterableNormalizer implements NormalizerInterface, NormalizerAwareInterface +{ + use NormalizerAwareTrait; + + /** + * {@inheritDoc} + */ + public function supportsNormalization($data, $format = null) + { + if (true === is_object($data) && true === is_iterable($data)) { + return true; + } + + if (true === is_array($data)) { + return true; + } + + return false; + } + + /** + * {@inheritDoc} + */ + public function normalize($object, $format = null, array $context = array()) + { + $normalizedData = []; + + foreach ($object as $value) { + $normalizedData[] = $this->normalizer->normalize($value, $format, $context); + } + + return $normalizedData; + } +} diff --git a/Tests/Resources/json/annotation_normalize_result.json b/Tests/Resources/json/annotation_normalize_result.json index 5f03af5..7b3713d 100644 --- a/Tests/Resources/json/annotation_normalize_result.json +++ b/Tests/Resources/json/annotation_normalize_result.json @@ -1 +1 @@ -{"foo":"bar","baz":1,"qux":[],"quuxs":[[{"foo":"bar","baz":1,"qux":[],"quuxs":{},"quuz":{"date":"2016-01-01 00:00:00.000000","timezone_type":3,"timezone":"UTC"},"annotatedPropertyWithoutMethod":"Yes"},{"foo":"bar","baz":1,"qux":[],"quuxs":{},"quuz":{"date":"2016-01-01 00:00:00.000000","timezone_type":3,"timezone":"UTC"},"annotatedPropertyWithoutMethod":"Yes"}]],"quuz":{"date":"2016-01-01 00:00:00.000000","timezone_type":3,"timezone":"UTC"},"annotatedPropertyWithoutMethod":"Yes"} \ No newline at end of file +{"foo":"bar","baz":1,"qux":[],"quuxs":[{"foo":"bar","baz":1,"qux":[],"quuxs":[],"quuz":"2016-01-01T00:00:00+00:00","annotatedPropertyWithoutMethod":"Yes"},{"foo":"bar","baz":1,"qux":[],"quuxs":[],"quuz":"2016-01-01T00:00:00+00:00","annotatedPropertyWithoutMethod":"Yes"}],"quuz":"2016-01-01T00:00:00+00:00","annotatedPropertyWithoutMethod":"Yes"} \ No newline at end of file diff --git a/Tests/Resources/xml/annotation_normalizer_result.xml b/Tests/Resources/xml/annotation_normalizer_result.xml index 9a2fb40..2db23dc 100644 --- a/Tests/Resources/xml/annotation_normalizer_result.xml +++ b/Tests/Resources/xml/annotation_normalizer_result.xml @@ -1,2 +1,2 @@ -bar1bar12016-01-01T00:00:00+00:00Yesbar12016-01-01T00:00:00+00:00Yes2016-01-01T00:00:00+00:00Yes +bar1bar12016-01-01T00:00:00+00:00Yesbar12016-01-01T00:00:00+00:00Yes2016-01-01T00:00:00+00:00Yes diff --git a/Tests/Serializer/Normalizer/AnnotationNormalizerTest.php b/Tests/Serializer/Normalizer/AnnotationNormalizerTest.php index 099f9a8..9f85687 100644 --- a/Tests/Serializer/Normalizer/AnnotationNormalizerTest.php +++ b/Tests/Serializer/Normalizer/AnnotationNormalizerTest.php @@ -12,13 +12,13 @@ namespace Superbrave\GdprBundle\Tests\Serializer\Normalizer; -use Doctrine\Common\Collections\ArrayCollection; use PHPUnit_Framework_MockObject_MockObject; use ReflectionClass; use Superbrave\GdprBundle\Annotation\AnnotationReader; use Superbrave\GdprBundle\Annotation\Export; use Superbrave\GdprBundle\Manipulator\PropertyManipulator; use Superbrave\GdprBundle\Serializer\Normalizer\AnnotationNormalizer; +use Superbrave\GdprBundle\Serializer\Normalizer\IterableNormalizer; use Superbrave\GdprBundle\Tests\AnnotatedMock; use Symfony\Component\PropertyAccess\PropertyAccess; use Symfony\Component\Serializer\Encoder\JsonEncoder; @@ -156,6 +156,12 @@ public function testNormalize() ); $normalizer = new AnnotationNormalizer($annotationReader, Export::class, $propertyManipulator); + $serializer = new Serializer([ + new DateTimeNormalizer(), + new IterableNormalizer(), + $normalizer, + ]); + $normalizer->setNormalizer($serializer); $annotatedMock = new AnnotatedMock(); @@ -163,9 +169,9 @@ public function testNormalize() array( 'foo' => 'bar', 'baz' => 1, - 'qux' => array(), - 'quuxs' => new ArrayCollection(), - 'quuz' => new \DateTime('2016/01/01'), + 'qux' => [], + 'quuxs' => [], + 'quuz' => '2016-01-01T00:00:00+00:00', 'annotatedPropertyWithoutMethod' => 'Yes', ), $normalizer->normalize($annotatedMock) @@ -187,6 +193,7 @@ public function testNormalizeThroughXmlSerializer() $normalizers = [ new DateTimeNormalizer(), + new IterableNormalizer(), new AnnotationNormalizer($annotationReader, Export::class, $propertyManipulator), ]; $encoders = [new XmlEncoder('mock')]; @@ -217,6 +224,7 @@ public function testNormalizeThroughJsonSerializer() $normalizers = [ new DateTimeNormalizer(), + new IterableNormalizer(), new AnnotationNormalizer($annotationReader, Export::class, $propertyManipulator), ]; $encoders = [new JsonEncoder()]; From 026dabb98a87d8479b5a2177ca6dcb656131c58b Mon Sep 17 00:00:00 2001 From: Jelle van Oosterbosch Date: Thu, 6 Feb 2020 11:39:07 +0100 Subject: [PATCH 3/9] Make it work for php56 --- Serializer/Normalizer/IterableNormalizer.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Serializer/Normalizer/IterableNormalizer.php b/Serializer/Normalizer/IterableNormalizer.php index d3a6010..6ba16a1 100644 --- a/Serializer/Normalizer/IterableNormalizer.php +++ b/Serializer/Normalizer/IterableNormalizer.php @@ -20,7 +20,9 @@ class IterableNormalizer implements NormalizerInterface, NormalizerAwareInterfac */ public function supportsNormalization($data, $format = null) { - if (true === is_object($data) && true === is_iterable($data)) { + if (true === is_object($data) && + (is_array($data) || (is_object($data)) && ($data instanceof \Traversable)) + ) { return true; } From 84865a7cf08f7526525413a2aa059248d1f45253 Mon Sep 17 00:00:00 2001 From: Jelle van Oosterbosch Date: Thu, 6 Feb 2020 11:40:27 +0100 Subject: [PATCH 4/9] Added missing required phpdoc --- Serializer/Normalizer/IterableNormalizer.php | 10 ++++++++++ .../Serializer/Normalizer/AnnotationNormalizerTest.php | 2 ++ 2 files changed, 12 insertions(+) diff --git a/Serializer/Normalizer/IterableNormalizer.php b/Serializer/Normalizer/IterableNormalizer.php index 6ba16a1..24957fa 100644 --- a/Serializer/Normalizer/IterableNormalizer.php +++ b/Serializer/Normalizer/IterableNormalizer.php @@ -1,4 +1,14 @@ + * @copyright 2018 SuperBrave + * @license https://github.com/superbrave/gdpr-bundle/blob/master/LICENSE MIT + * @link https://www.superbrave.nl/ + */ namespace Superbrave\GdprBundle\Serializer\Normalizer; diff --git a/Tests/Serializer/Normalizer/AnnotationNormalizerTest.php b/Tests/Serializer/Normalizer/AnnotationNormalizerTest.php index 9f85687..58d2ee2 100644 --- a/Tests/Serializer/Normalizer/AnnotationNormalizerTest.php +++ b/Tests/Serializer/Normalizer/AnnotationNormalizerTest.php @@ -214,6 +214,8 @@ public function testNormalizeThroughXmlSerializer() /** * Test if @see AnnotationNormalizer::normalize returns the expected json normalized data * for serialization through the Serializer. + * + * @return void */ public function testNormalizeThroughJsonSerializer() { From 31f1837735b3aef5a51fb914e6c25d18f143260b Mon Sep 17 00:00:00 2001 From: Jelle van Oosterbosch Date: Thu, 6 Feb 2020 11:41:45 +0100 Subject: [PATCH 5/9] Fixed typo in IterableNormalizer --- Serializer/Normalizer/IterableNormalizer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Serializer/Normalizer/IterableNormalizer.php b/Serializer/Normalizer/IterableNormalizer.php index 24957fa..90756da 100644 --- a/Serializer/Normalizer/IterableNormalizer.php +++ b/Serializer/Normalizer/IterableNormalizer.php @@ -17,7 +17,7 @@ use Symfony\Component\Serializer\Normalizer\NormalizerInterface; /** - * Normalizes data if its iterable by calling the normalizer chain. + * Normalizes data if it's iterable by calling the normalizer chain. * * @author Jelle van Oosterbosch */ From 18468582d81133aa8f9ed1242acc955982d927e9 Mon Sep 17 00:00:00 2001 From: Jelle van Oosterbosch Date: Thu, 6 Feb 2020 12:14:10 +0100 Subject: [PATCH 6/9] Added unit test for the IterableNormalizer class --- .../json/iterable_normalize_result.json | 1 + .../Normalizer/IterableNormalizerTest.php | 124 ++++++++++++++++++ 2 files changed, 125 insertions(+) create mode 100644 Tests/Resources/json/iterable_normalize_result.json create mode 100644 Tests/Serializer/Normalizer/IterableNormalizerTest.php diff --git a/Tests/Resources/json/iterable_normalize_result.json b/Tests/Resources/json/iterable_normalize_result.json new file mode 100644 index 0000000..4e73407 --- /dev/null +++ b/Tests/Resources/json/iterable_normalize_result.json @@ -0,0 +1 @@ +["bar",1,[["2020-01-01T00:00:00+00:00","2020-01-01T00:00:00+00:00"]]] \ No newline at end of file diff --git a/Tests/Serializer/Normalizer/IterableNormalizerTest.php b/Tests/Serializer/Normalizer/IterableNormalizerTest.php new file mode 100644 index 0000000..0e229b3 --- /dev/null +++ b/Tests/Serializer/Normalizer/IterableNormalizerTest.php @@ -0,0 +1,124 @@ + + * @copyright 2018 SuperBrave + * @license https://github.com/superbrave/gdpr-bundle/blob/master/LICENSE MIT + * @link https://www.superbrave.nl/ + */ + +namespace Superbrave\GdprBundle\Tests\Serializer\Normalizer; + +use Doctrine\Common\Collections\ArrayCollection; +use Superbrave\GdprBundle\Serializer\Normalizer\IterableNormalizer; +use Symfony\Component\Serializer\Encoder\JsonEncoder; +use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer; +use Symfony\Component\Serializer\Serializer; + +/** + * AnnotationNormalizerTest. + * + * @author Jelle van Oosterbosch + */ +class IterableNormalizerTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var IterableNormalizer + */ + private $normalizer; + + /** + * @var Serializer + */ + private $serializer; + + /** + * {@inheritDoc} + */ + public function setUp() + { + $this->normalizer = new IterableNormalizer(); + $this->serializer = new Serializer([ + new DateTimeNormalizer(), + $this->normalizer, + ], [ + new JsonEncoder() + ]); + + $this->normalizer->setNormalizer($this->serializer); + } + + /** + * Tests if @see IterableNormalizer::supportsNormalization() returns false + * when the data is not iterable. + * + * @return void + */ + public function testSupportsNormalizationReturnsFalseWhenDataIsNotIterable() + { + $this->assertFalse($this->normalizer->supportsNormalization('no object')); + $this->assertFalse($this->normalizer->supportsNormalization(new \stdClass())); + } + + /** + * Tests if @see IterableNormalizer::supportsNormalization() returns true + * when the data is iterable. + * + * @return void + */ + public function testSupportsNormalizationReturnsTrueWhenDataIsIterable() + { + $this->assertTrue($this->normalizer->supportsNormalization(array())); + $this->assertTrue($this->normalizer->supportsNormalization(new ArrayCollection())); + } + + /** + * Tests if @see IterableNormalizer::$normalizer returns the expected array of a iterable object. + * + * @return void + * + * @throws \Exception + */ + public function testNormalize() + { + $collection = new ArrayCollection(); + $collection->add(new \DateTime('2020/01/01')); + $collection->add(new \DateTime('2020/01/01')); + + $this->assertEquals( + [ + '2020-01-01T00:00:00+00:00', + '2020-01-01T00:00:00+00:00', + ], + $this->normalizer->normalize($collection) + ); + } + + /** + * Test is @see IterableNormalizer::$normalizer returns the expected json normalized data + * for serialization through the Serializer. + * + * @throws \Exception + */ + public function testNormalizeThroughJsonSerializer() + { + $data = [ + 'foo' => 'bar', + 'baz' => 1, + 'qux' => [ + new ArrayCollection([ + new \DateTime('2020/01/01'), + new \DateTime('2020/01/01'), + ]) + ] + ]; + + $this->assertStringEqualsFile( + __DIR__ . '/../../Resources/json/iterable_normalize_result.json', + $this->serializer->serialize($data, 'json') + ); + } +} From feff8083a19d71e92fedfe2fe5e892c79e96aa9e Mon Sep 17 00:00:00 2001 From: Jelle van Oosterbosch Date: Thu, 6 Feb 2020 12:15:43 +0100 Subject: [PATCH 7/9] Added required return phpdoc for IterableNormalizerTest --- Tests/Serializer/Normalizer/IterableNormalizerTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Tests/Serializer/Normalizer/IterableNormalizerTest.php b/Tests/Serializer/Normalizer/IterableNormalizerTest.php index 0e229b3..862f32f 100644 --- a/Tests/Serializer/Normalizer/IterableNormalizerTest.php +++ b/Tests/Serializer/Normalizer/IterableNormalizerTest.php @@ -101,6 +101,8 @@ public function testNormalize() * Test is @see IterableNormalizer::$normalizer returns the expected json normalized data * for serialization through the Serializer. * + * @return void + * * @throws \Exception */ public function testNormalizeThroughJsonSerializer() From fc6422cf317971ce95db49991cfc4789d1a0d32a Mon Sep 17 00:00:00 2001 From: Jelle van Oosterbosch Date: Thu, 6 Feb 2020 12:17:10 +0100 Subject: [PATCH 8/9] Lowercased the inheritdoc phpdoc to match the whole project --- Serializer/Normalizer/IterableNormalizer.php | 4 ++-- Tests/Serializer/Normalizer/IterableNormalizerTest.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Serializer/Normalizer/IterableNormalizer.php b/Serializer/Normalizer/IterableNormalizer.php index 90756da..fe77fd1 100644 --- a/Serializer/Normalizer/IterableNormalizer.php +++ b/Serializer/Normalizer/IterableNormalizer.php @@ -26,7 +26,7 @@ class IterableNormalizer implements NormalizerInterface, NormalizerAwareInterfac use NormalizerAwareTrait; /** - * {@inheritDoc} + * {@inheritdoc} */ public function supportsNormalization($data, $format = null) { @@ -44,7 +44,7 @@ public function supportsNormalization($data, $format = null) } /** - * {@inheritDoc} + * {@inheritdoc} */ public function normalize($object, $format = null, array $context = array()) { diff --git a/Tests/Serializer/Normalizer/IterableNormalizerTest.php b/Tests/Serializer/Normalizer/IterableNormalizerTest.php index 862f32f..4e7a26c 100644 --- a/Tests/Serializer/Normalizer/IterableNormalizerTest.php +++ b/Tests/Serializer/Normalizer/IterableNormalizerTest.php @@ -36,7 +36,7 @@ class IterableNormalizerTest extends \PHPUnit_Framework_TestCase private $serializer; /** - * {@inheritDoc} + * {@inheritdoc} */ public function setUp() { From 39dcf8bb39e879a120ddf71f061c1528281928d8 Mon Sep 17 00:00:00 2001 From: Jelle van Oosterbosch Date: Thu, 6 Feb 2020 13:46:45 +0100 Subject: [PATCH 9/9] Updated support check according to feedback for the IterableNormalizer --- Serializer/Normalizer/IterableNormalizer.php | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/Serializer/Normalizer/IterableNormalizer.php b/Serializer/Normalizer/IterableNormalizer.php index fe77fd1..ccdbd9b 100644 --- a/Serializer/Normalizer/IterableNormalizer.php +++ b/Serializer/Normalizer/IterableNormalizer.php @@ -30,13 +30,7 @@ class IterableNormalizer implements NormalizerInterface, NormalizerAwareInterfac */ public function supportsNormalization($data, $format = null) { - if (true === is_object($data) && - (is_array($data) || (is_object($data)) && ($data instanceof \Traversable)) - ) { - return true; - } - - if (true === is_array($data)) { + if (is_array($data) || $data instanceof \Traversable) { return true; }