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]); - } } }