From 70a90223aef02e6947376a44094304baf7acade7 Mon Sep 17 00:00:00 2001 From: BacLuc Date: Tue, 6 Sep 2022 13:10:00 +0200 Subject: [PATCH] TranslationConstraintViolationListNormalizer: add support for hydra problem format Issue: #2902 --- api/config/services.yaml | 4 ++- ...ationConstraintViolationListNormalizer.php | 23 +++++++++++----- ...ViolationListNormalizerIntegrationTest.php | 27 ++++++++++++++----- 3 files changed, 41 insertions(+), 13 deletions(-) diff --git a/api/config/services.yaml b/api/config/services.yaml index 18b5c6249b..204f42c4a7 100644 --- a/api/config/services.yaml +++ b/api/config/services.yaml @@ -70,7 +70,9 @@ services: decorates: 'api_platform.hal.normalizer.collection' App\Serializer\Normalizer\TranslationConstraintViolationListNormalizer: - decorates: 'api_platform.problem.normalizer.constraint_violation_list' + arguments: + - '@api_platform.hydra.normalizer.constraint_violation_list' + - '@api_platform.problem.normalizer.constraint_violation_list' App\Serializer\SerializerContextBuilder: decorates: 'api_platform.serializer.context_builder' diff --git a/api/src/Serializer/Normalizer/TranslationConstraintViolationListNormalizer.php b/api/src/Serializer/Normalizer/TranslationConstraintViolationListNormalizer.php index 9c00e03b3c..6fbd0d25c5 100644 --- a/api/src/Serializer/Normalizer/TranslationConstraintViolationListNormalizer.php +++ b/api/src/Serializer/Normalizer/TranslationConstraintViolationListNormalizer.php @@ -7,6 +7,8 @@ use ApiPlatform\Core\Serializer\AbstractConstraintViolationListNormalizer; use App\Serializer\Normalizer\Error\TranslationInfoOfConstraintViolation; use App\Service\TranslateToAllLocalesService; +use Doctrine\Common\Collections\ArrayCollection; +use RuntimeException; use Symfony\Component\Serializer\Normalizer\CacheableSupportsMethodInterface; use Symfony\Component\Serializer\Normalizer\NormalizerInterface; use Symfony\Component\Validator\ConstraintViolation; @@ -14,25 +16,30 @@ class TranslationConstraintViolationListNormalizer implements NormalizerInterface, CacheableSupportsMethodInterface { public function __construct( - private readonly AbstractConstraintViolationListNormalizer $decorated, + private readonly AbstractConstraintViolationListNormalizer $hydraNormalizer, + private readonly AbstractConstraintViolationListNormalizer $problemNormalizer, private readonly TranslationInfoOfConstraintViolation $translationInfoOfConstraintViolation, private readonly TranslateToAllLocalesService $translateToAllLocalesService ) { } public function supportsNormalization(mixed $data, string $format = null, array $context = []): bool { - return $this->decorated->supportsNormalization($data, $format); + return $this->getNormalizerCollection()->exists(fn ($_, $elem) => $elem->supportsNormalization($data, $format)); } public function normalize(mixed $object, string $format = null, array $context = []): float|int|bool|\ArrayObject|array|string|null { - $result = $this->decorated->normalize($object, $format, $context); + $normalizer = $this->getNormalizerCollection()->filter(fn ($elem) => $elem->supportsNormalization($object, $format))->first(); + if (false === $normalizer) { + throw new RuntimeException("Did not find a normalizer to normalize response to format {$format}"); + } + $result = $normalizer->normalize($object, $format, $context); /** @var ConstraintViolationList $object */ foreach ($object as $violation) { foreach ($result['violations'] as &$resultItem) { - $code = $resultItem['code']; + $code = $resultItem['code'] ?? null; $propertyPath = $resultItem['propertyPath']; - $message = $resultItem['message']; + $message = $resultItem['message'] ?? null; if ($violation->getPropertyPath() === $propertyPath && $violation->getCode() === $code @@ -64,6 +71,10 @@ public function normalize(mixed $object, string $format = null, array $context = } public function hasCacheableSupportsMethod(): bool { - return $this->decorated->hasCacheableSupportsMethod(); + return $this->getNormalizerCollection()->forAll(fn ($_, $elem) => $elem->hasCacheableSupportsMethod()); + } + + private function getNormalizerCollection(): ArrayCollection { + return new ArrayCollection([$this->hydraNormalizer, $this->problemNormalizer]); } } diff --git a/api/tests/Integration/Serializer/Normalizer/TranslationConstraintViolationListNormalizerIntegrationTest.php b/api/tests/Integration/Serializer/Normalizer/TranslationConstraintViolationListNormalizerIntegrationTest.php index ab41b3897e..311bccf6c1 100644 --- a/api/tests/Integration/Serializer/Normalizer/TranslationConstraintViolationListNormalizerIntegrationTest.php +++ b/api/tests/Integration/Serializer/Normalizer/TranslationConstraintViolationListNormalizerIntegrationTest.php @@ -3,7 +3,8 @@ namespace App\Tests\Integration\Serializer\Normalizer; use ApiPlatform\Core\Bridge\Symfony\Bundle\Test\ApiTestAssertionsTrait; -use ApiPlatform\Core\Problem\Serializer\ConstraintViolationListNormalizer; +use ApiPlatform\Core\Hydra\Serializer\ConstraintViolationListNormalizer as HydraConstraintViolationListNormalizer; +use ApiPlatform\Core\Problem\Serializer\ConstraintViolationListNormalizer as JsonProblemConstraintViolationListNormalizer; use App\Entity\CampCollaboration; use App\Serializer\Normalizer\TranslationConstraintViolationListNormalizer; use App\Validator\AllowTransition\AssertAllowTransitions; @@ -31,20 +32,22 @@ protected function setUp(): void { parent::setUp(); /** @var TranslationConstraintViolationListNormalizer $obj */ - $obj = self::getContainer()->get('api_platform.problem.normalizer.constraint_violation_list'); + $obj = self::getContainer()->get('App\Serializer\Normalizer\TranslationConstraintViolationListNormalizer'); $this->translationConstraintViolationListNormalizer = $obj; } /** * @throws ExceptionInterface * @throws \Exception + * + * @dataProvider getFormats() */ - public function testAddsTranslationKeyAndParameters() { + public function testAddsTranslationKeyAndParameters(string $format) { $constraintViolationList = new ConstraintViolationList(self::getConstraintViolations()); $result = $this->translationConstraintViolationListNormalizer->normalize( $constraintViolationList, - ConstraintViolationListNormalizer::FORMAT, + $format, [] ); @@ -84,13 +87,15 @@ public function testAddsTranslationKeyAndParameters() { /** * @throws ExceptionInterface * @throws \Exception + * + * @dataProvider getFormats() */ - public function testAddsTranslations() { + public function testAddsTranslations(string $format) { $constraintViolationList = new ConstraintViolationList(self::getConstraintViolations()); $result = $this->translationConstraintViolationListNormalizer->normalize( $constraintViolationList, - ConstraintViolationListNormalizer::FORMAT, + $format, [] ); @@ -142,6 +147,16 @@ public function testAddsTranslations() { ]], $result); } + public static function getFormats() { + $hydra = HydraConstraintViolationListNormalizer::FORMAT; + $problem = JsonProblemConstraintViolationListNormalizer::FORMAT; + + return [ + $hydra => [$hydra], + $problem => [$problem], + ]; + } + public static function getConstraintViolations(): array { return [ new ConstraintViolation(