From 31b541d12f043690e4f76cbae19f7c1358556278 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 12 Jun 2024 11:47:13 +0200 Subject: [PATCH] Update AccompanyingPeriodWorkNormalizer and related classes Updated the AccompanyingPeriodWorkNormalizer, its test, and the related entity class. Now, the normalizer includes additional checks for different formats and conditions, and cleans the context accordingly before processing. AccompanyingPeriodWorkDocGenNormalizerTest now extends from a new abstract base class. Changes are made in AccompanyingPeriodWork entity for datetime handling and serialization. --- .../AccompanyingPeriodWork.php | 13 ++-- .../AccompanyingPeriodWorkNormalizer.php | 64 +++++++++++++++---- ...mpanyingPeriodWorkDocGenNormalizerTest.php | 59 ++++++++--------- 3 files changed, 83 insertions(+), 53 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodWork.php b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodWork.php index 53a1434a4..755f499d5 100644 --- a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodWork.php +++ b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod/AccompanyingPeriodWork.php @@ -60,13 +60,14 @@ class AccompanyingPeriodWork implements AccompanyingPeriodLinkedWithSocialIssues * orphanRemoval=true * ) * - * @Serializer\Groups({"read", "docgen:read"}) + * @Serializer\Groups({"read"}) * * @ORM\OrderBy({"startDate": "DESC", "id": "DESC"}) * * @var Collection * - * @internal /!\ the serialization for write evaluations is handled in `AccompanyingPeriodWorkDenormalizer` + * @internal the serialization for write evaluations is handled in `accompanyingperiodworkdenormalizer` + * @internal the serialization for context docgen:read is handled in `accompanyingperiodworknormalizer` */ private Collection $accompanyingPeriodWorkEvaluations; @@ -577,9 +578,9 @@ class AccompanyingPeriodWork implements AccompanyingPeriodLinkedWithSocialIssues return $this; } - public function setCreatedBy(?User $createdBy): self + public function setCreatedBy(?User $user): self { - $this->createdBy = $createdBy; + $this->createdBy = $user; return $this; } @@ -621,14 +622,14 @@ class AccompanyingPeriodWork implements AccompanyingPeriodLinkedWithSocialIssues public function setStartDate(\DateTimeInterface $startDate): self { - $this->startDate = $startDate; + $this->startDate = $startDate instanceof \DateTime ? \DateTimeImmutable::createFromMutable($startDate) : $startDate; return $this; } public function setUpdatedAt(\DateTimeInterface $datetime): TrackUpdateInterface { - $this->updatedAt = $datetime; + $this->updatedAt = $datetime instanceof \DateTime ? \DateTimeImmutable::createFromMutable($datetime) : $datetime; return $this; } diff --git a/src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodWorkNormalizer.php b/src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodWorkNormalizer.php index 13d25deb8..dbaa00728 100644 --- a/src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodWorkNormalizer.php +++ b/src/Bundle/ChillPersonBundle/Serializer/Normalizer/AccompanyingPeriodWorkNormalizer.php @@ -11,13 +11,16 @@ declare(strict_types=1); namespace Chill\PersonBundle\Serializer\Normalizer; +use Chill\MainBundle\Entity\User; use Chill\MainBundle\Repository\Workflow\EntityWorkflowRepository; use Chill\MainBundle\Serializer\Normalizer\UserNormalizer; use Chill\MainBundle\Workflow\Helper\MetadataExtractor; use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork; use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation; use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument; -use Symfony\Component\Serializer\Exception\ExceptionInterface; +use Chill\PersonBundle\Entity\SocialWork\SocialAction; +use Chill\ThirdPartyBundle\Entity\ThirdParty; +use Symfony\Component\Serializer\Exception\UnexpectedValueException; use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface; use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface; use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait; @@ -33,16 +36,48 @@ class AccompanyingPeriodWorkNormalizer implements ContextAwareNormalizerInterfac { } - /** - * @param AccompanyingPeriodWork $object - * - * @throws ExceptionInterface - */ public function normalize($object, ?string $format = null, array $context = []): array|\ArrayObject|bool|float|int|string|null { + if (!$object instanceof AccompanyingPeriodWork && 'json' === $format) { + throw new UnexpectedValueException('Object cannot be null or empty when format is json'); + } + if ('docgen' === $format && !($object instanceof AccompanyingPeriodWork || null === $object)) { + throw new UnexpectedValueException(sprintf('Object must be an instanceof AccompanyingPeriodWork or null when format is docgen, %s given', is_object($object) ? get_class($object) : gettype($object))); + } + + $cleanContext = array_filter($context, fn (string|int $key) => !in_array($key, ['docgen:expects', self::IGNORE_WORK], true), ARRAY_FILTER_USE_KEY); + + if (null === $object && 'docgen' === $format) { + $dateNull = $this->normalizer->normalize(null, $format, [...$context, 'docgen:expects' => \DateTimeImmutable::class]); + $userNull = $this->normalizer->normalize(null, $format, [...$context, 'docgen:expects' => User::class]); + + return [ + 'isNull' => true, + 'type' => 'accompanying_period_work', + 'accompanyingPeriodWorkEvaluations' => [], + 'referrers' => [], + 'createdAt' => $dateNull, + 'createdAutomatically' => 'false', + 'createdAutomaticallyReason' => '', + 'createdBy' => $userNull, + 'endDate' => $dateNull, + 'goals' => [], + 'handlingThierParty' => $this->normalizer->normalize(null, $format, [...$cleanContext, 'docgen:expects' => ThirdParty::class]), + 'id' => '', + 'note' => '', + 'persons' => [], + 'results' => [], + 'socialAction' => $this->normalizer->normalize(null, $format, [...$cleanContext, 'docgen:expects' => SocialAction::class]), + 'startDate' => $dateNull, + 'thirdParties' => [], + 'updatedAt' => $dateNull, + 'updatedBy' => $userNull, + ]; + } + $initial = $this->normalizer->normalize($object, $format, array_merge( - $context, - [self::IGNORE_WORK => spl_object_hash($object)] + $cleanContext, + [self::IGNORE_WORK => null === $object ? null : spl_object_hash($object)] )); // due to bug: https://api-platform.com/docs/core/serialization/#collection-relation @@ -51,7 +86,7 @@ class AccompanyingPeriodWorkNormalizer implements ContextAwareNormalizerInterfac $initial['accompanyingPeriodWorkEvaluations'] = $this->normalizer->normalize( $object->getAccompanyingPeriodWorkEvaluations()->getValues(), $format, - $context + [...$cleanContext] ); // add the referrers @@ -65,7 +100,7 @@ class AccompanyingPeriodWorkNormalizer implements ContextAwareNormalizerInterfac $initial['referrers'][] = $this->normalizer->normalize( $referrerHistory->getUser(), $format, - [...$context, UserNormalizer::AT_DATE => $referrerHistory->getStartDate()] + [...$cleanContext, UserNormalizer::AT_DATE => $referrerHistory->getStartDate()] ); } @@ -97,8 +132,11 @@ class AccompanyingPeriodWorkNormalizer implements ContextAwareNormalizerInterfac public function supportsNormalization($data, ?string $format = null, array $context = []): bool { - return ('json' === $format || 'docgen' === $format) - && ($data instanceof AccompanyingPeriodWork || ('docgen' === $format && null === $data && ($context['docgen:expects'] ?? null) === AccompanyingPeriodWork::class)) - && !\array_key_exists(self::IGNORE_WORK, $context); + return match ($format) { + 'json' => $data instanceof AccompanyingPeriodWork && ($context[self::IGNORE_WORK] ?? null) !== spl_object_hash($data), + 'docgen' => ($data instanceof AccompanyingPeriodWork || ($context['docgen:expects'] ?? null) === AccompanyingPeriodWork::class) + && !array_key_exists(self::IGNORE_WORK, $context), + default => false, + }; } } diff --git a/src/Bundle/ChillPersonBundle/Tests/Serializer/Normalizer/AccompanyingPeriodWorkDocGenNormalizerTest.php b/src/Bundle/ChillPersonBundle/Tests/Serializer/Normalizer/AccompanyingPeriodWorkDocGenNormalizerTest.php index c438be5f0..0c2219d17 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Serializer/Normalizer/AccompanyingPeriodWorkDocGenNormalizerTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Serializer/Normalizer/AccompanyingPeriodWorkDocGenNormalizerTest.php @@ -11,13 +11,13 @@ declare(strict_types=1); namespace Serializer\Normalizer; +use Chill\DocGeneratorBundle\Test\DocGenNormalizerTestAbstract; use Chill\MainBundle\Entity\User; use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork; use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkGoal; use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Entity\SocialWork\Goal; use Chill\PersonBundle\Entity\SocialWork\Result; -use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; use Symfony\Component\Serializer\Normalizer\AbstractNormalizer; use Symfony\Component\Serializer\Normalizer\NormalizerInterface; @@ -25,8 +25,10 @@ use Symfony\Component\Serializer\Normalizer\NormalizerInterface; * @internal * * @coversNothing + * + * @template-extends DocGenNormalizerTestAbstract */ -final class AccompanyingPeriodWorkDocGenNormalizerTest extends KernelTestCase +final class AccompanyingPeriodWorkDocGenNormalizerTest extends DocGenNormalizerTestAbstract { private NormalizerInterface $normalizer; @@ -36,28 +38,31 @@ final class AccompanyingPeriodWorkDocGenNormalizerTest extends KernelTestCase $this->normalizer = self::$container->get(NormalizerInterface::class); } - public function testNormalizationNull() + public function provideNotNullObject(): object { - $actual = $this->normalizer->normalize(null, 'docgen', [ - 'docgen:expects' => AccompanyingPeriodWork::class, - AbstractNormalizer::GROUPS => ['docgen:read'], - ]); + $work = new AccompanyingPeriodWork(); + $work + ->addPerson((new Person())->setFirstName('hello')->setLastName('name')) + ->addGoal($g = new AccompanyingPeriodWorkGoal()) + ->addResult($r = new Result()) + ->setCreatedAt(new \DateTimeImmutable()) + ->setUpdatedAt(new \DateTimeImmutable()) + ->setCreatedBy($user = new User()) + ->setUpdatedBy($user); + $g->addResult($r)->setGoal($goal = new Goal()); + $goal->addResult($r); - $expected = [ - 'id' => '', - ]; + return $work; + } - $this->assertIsArray($actual); - $this->markTestSkipped('specification still not finalized'); - $this->assertEqualsCanonicalizing(array_keys($expected), array_keys($actual)); + public function provideDocGenExpectClass(): string + { + return AccompanyingPeriodWork::class; + } - foreach ($expected as $key => $item) { - if ('@ignored' === $item) { - continue; - } - - $this->assertEquals($item, $actual[$key]); - } + public function getNormalizer(): NormalizerInterface + { + return $this->normalizer; } public function testNormalize() @@ -79,20 +84,6 @@ final class AccompanyingPeriodWorkDocGenNormalizerTest extends KernelTestCase AbstractNormalizer::GROUPS => ['docgen:read'], ]); - $expected = [ - 'id' => 0, - ]; - $this->assertIsArray($actual); - $this->markTestSkipped('specification still not finalized'); - $this->assertEqualsCanonicalizing(array_keys($expected), array_keys($actual)); - - foreach ($expected as $key => $item) { - if (0 === $item) { - continue; - } - - $this->assertEquals($item, $actual[$key]); - } } }