mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2026-01-15 13:51:24 +00:00
Add tests for AccompanyingPeriodWorkEvaluationNormalizer and refactor normalization logic
This commit is contained in:
@@ -17,28 +17,25 @@ use Chill\MainBundle\Entity\User;
|
||||
use Chill\PersonBundle\Entity\SocialWork\Evaluation;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\Common\Collections\ReadableCollection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Serializer\Attribute as Serializer;
|
||||
|
||||
#[Serializer\DiscriminatorMap(typeProperty: 'type', mapping: ['accompanying_period_work_evaluation' => AccompanyingPeriodWorkEvaluation::class])]
|
||||
#[ORM\Entity]
|
||||
#[ORM\Table('chill_person_accompanying_period_work_evaluation')]
|
||||
class AccompanyingPeriodWorkEvaluation implements TrackCreationInterface, TrackUpdateInterface
|
||||
{
|
||||
#[Serializer\Groups(['read:evaluation:include-work'])]
|
||||
#[ORM\ManyToOne(targetEntity: AccompanyingPeriodWork::class, inversedBy: 'accompanyingPeriodWorkEvaluations')]
|
||||
#[Serializer\Context(normalizationContext: ['groups' => ['read:accompanyingPeriodWork:light']], groups: ['read:evaluation:include-work'])]
|
||||
private ?AccompanyingPeriodWork $accompanyingPeriodWork = null;
|
||||
|
||||
#[Serializer\Groups(['read', 'docgen:read', 'write', 'accompanying_period_work_evaluation:create'])]
|
||||
#[Serializer\Groups(['write', 'accompanying_period_work_evaluation:create'])]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::TEXT, nullable: false, options: ['default' => ''])]
|
||||
private string $comment = '';
|
||||
|
||||
#[Serializer\Groups(['read', 'docgen:read'])]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::DATE_IMMUTABLE, nullable: true, options: ['default' => null])]
|
||||
private ?\DateTimeImmutable $createdAt = null;
|
||||
|
||||
#[Serializer\Groups(['read', 'docgen:read'])]
|
||||
#[ORM\ManyToOne(targetEntity: User::class)]
|
||||
private ?User $createdBy = null;
|
||||
|
||||
@@ -49,20 +46,18 @@ class AccompanyingPeriodWorkEvaluation implements TrackCreationInterface, TrackU
|
||||
*
|
||||
* @var Collection<int, AccompanyingPeriodWorkEvaluationDocument>
|
||||
*/
|
||||
#[Serializer\Groups(['read'])]
|
||||
#[ORM\OneToMany(mappedBy: 'accompanyingPeriodWorkEvaluation', targetEntity: AccompanyingPeriodWorkEvaluationDocument::class, cascade: ['remove', 'persist'], orphanRemoval: true)]
|
||||
#[ORM\OrderBy(['createdAt' => \Doctrine\Common\Collections\Criteria::DESC, 'id' => 'DESC'])]
|
||||
private Collection $documents;
|
||||
|
||||
#[Serializer\Groups(['read', 'docgen:read', 'write', 'accompanying_period_work_evaluation:create'])]
|
||||
#[Serializer\Groups(['write', 'accompanying_period_work_evaluation:create'])]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::DATE_IMMUTABLE, nullable: true, options: ['default' => null])]
|
||||
private ?\DateTimeImmutable $endDate = null;
|
||||
|
||||
#[Serializer\Groups(['read', 'docgen:read', 'accompanying_period_work_evaluation:create'])]
|
||||
#[Serializer\Groups(['accompanying_period_work_evaluation:create'])]
|
||||
#[ORM\ManyToOne(targetEntity: Evaluation::class)]
|
||||
private ?Evaluation $evaluation = null;
|
||||
|
||||
#[Serializer\Groups(['read', 'docgen:read'])]
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::INTEGER)]
|
||||
@@ -75,30 +70,28 @@ class AccompanyingPeriodWorkEvaluation implements TrackCreationInterface, TrackU
|
||||
* This data is not persisted into database, but will appears on the data
|
||||
* normalized during the same request (like PUT/PATCH request)
|
||||
*/
|
||||
#[Serializer\Groups(['read', 'write', 'accompanying_period_work_evaluation:create'])]
|
||||
#[Serializer\Groups(['write', 'accompanying_period_work_evaluation:create'])]
|
||||
private $key;
|
||||
|
||||
#[Serializer\Groups(['read', 'docgen:read', 'write', 'accompanying_period_work_evaluation:create'])]
|
||||
#[Serializer\Groups(['write', 'accompanying_period_work_evaluation:create'])]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::DATE_IMMUTABLE, nullable: true, options: ['default' => null])]
|
||||
private ?\DateTimeImmutable $maxDate = null;
|
||||
|
||||
#[Serializer\Groups(['read', 'docgen:read', 'write', 'accompanying_period_work_evaluation:create'])]
|
||||
#[Serializer\Groups(['write', 'accompanying_period_work_evaluation:create'])]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::DATE_IMMUTABLE, nullable: true, options: ['default' => null])]
|
||||
private ?\DateTimeImmutable $startDate = null;
|
||||
|
||||
#[Serializer\Groups(['read', 'docgen:read'])]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::DATE_IMMUTABLE, nullable: true, options: ['default' => null])]
|
||||
private ?\DateTimeImmutable $updatedAt = null;
|
||||
|
||||
#[Serializer\Groups(['read', 'docgen:read'])]
|
||||
#[ORM\ManyToOne(targetEntity: User::class)]
|
||||
private ?User $updatedBy = null;
|
||||
|
||||
#[Serializer\Groups(['read', 'write', 'accompanying_period_work_evaluation:create'])]
|
||||
#[Serializer\Groups(['write', 'accompanying_period_work_evaluation:create'])]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::DATEINTERVAL, nullable: true, options: ['default' => null])]
|
||||
private ?\DateInterval $warningInterval = null;
|
||||
|
||||
#[Serializer\Groups(['read', 'docgen:read', 'write', 'accompanying_period_work_evaluation:create'])]
|
||||
#[Serializer\Groups(['write', 'accompanying_period_work_evaluation:create'])]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::INTEGER, nullable: true)]
|
||||
private ?int $timeSpent = null;
|
||||
|
||||
@@ -138,9 +131,9 @@ class AccompanyingPeriodWorkEvaluation implements TrackCreationInterface, TrackU
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection<AccompanyingPeriodWorkEvaluationDocument>
|
||||
* @return ReadableCollection<AccompanyingPeriodWorkEvaluationDocument>
|
||||
*/
|
||||
public function getDocuments(): Collection
|
||||
public function getDocuments(): ReadableCollection
|
||||
{
|
||||
return $this->documents;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ namespace Chill\PersonBundle\Serializer\Normalizer;
|
||||
use Chill\MainBundle\Repository\Workflow\EntityWorkflowRepository;
|
||||
use Chill\MainBundle\Workflow\Helper\MetadataExtractor;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation;
|
||||
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||
@@ -23,22 +24,26 @@ class AccompanyingPeriodWorkEvaluationNormalizer implements NormalizerInterface,
|
||||
{
|
||||
use NormalizerAwareTrait;
|
||||
|
||||
private const string IGNORE_EVALUATION = 'evaluation:ignore';
|
||||
public function __construct(
|
||||
private readonly Registry $registry,
|
||||
private readonly EntityWorkflowRepository $entityWorkflowRepository,
|
||||
private readonly MetadataExtractor $metadataExtractor,
|
||||
) {}
|
||||
|
||||
public function __construct(private readonly Registry $registry, private readonly EntityWorkflowRepository $entityWorkflowRepository, private readonly MetadataExtractor $metadataExtractor) {}
|
||||
|
||||
/**
|
||||
* @param AccompanyingPeriodWorkEvaluation $object
|
||||
*/
|
||||
public function normalize($object, ?string $format = null, array $context = []): array
|
||||
{
|
||||
$initial = $this->normalizer->normalize($object, $format, array_merge(
|
||||
$context,
|
||||
));
|
||||
if (!$object instanceof AccompanyingPeriodWorkEvaluation) {
|
||||
throw new UnexpectedValueException('expected AccompanyingPeriodWorkEvaluation instance, got '.gettype($object));
|
||||
}
|
||||
|
||||
// due to bug: https://api-platform.com/docs/core/serialization/#collection-relation
|
||||
// and also: https://github.com/symfony/symfony/issues/36965
|
||||
// we have to rewrite the documents as a collection
|
||||
$groups = (array) ($context['groups'] ?? []);
|
||||
if ([] === $groups) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$initial = $this->normalizeProperties($object, $format, $context);
|
||||
|
||||
// we have to rewrite the documents as a collection to avoid non contiguous list
|
||||
$initial['documents'] = $this->normalizer->normalize(
|
||||
$object->getDocuments()->getValues(),
|
||||
$format,
|
||||
@@ -56,14 +61,62 @@ class AccompanyingPeriodWorkEvaluationNormalizer implements NormalizerInterface,
|
||||
]);
|
||||
$initial['workflows'] = $this->normalizer->normalize($workflows, 'json', $context);
|
||||
|
||||
$initial['type'] = 'accompanying_period_work_evaluation';
|
||||
|
||||
return $initial;
|
||||
}
|
||||
|
||||
private function normalizeProperties(AccompanyingPeriodWorkEvaluation $object, ?string $format, array $context): array
|
||||
{
|
||||
$data = [];
|
||||
$groups = (array) ($context['groups'] ?? []);
|
||||
|
||||
$isRead = in_array('read', $groups, true);
|
||||
$isDocgenRead = in_array('docgen:read', $groups, true);
|
||||
|
||||
if ($isRead || $isDocgenRead) {
|
||||
$data['id'] = $object->getId();
|
||||
$data['comment'] = $object->getComment();
|
||||
$data['createdAt'] = $this->normalizer->normalize($object->getCreatedAt(), $format, $context);
|
||||
$data['createdBy'] = $this->normalizer->normalize($object->getCreatedBy(), $format, $context);
|
||||
$data['endDate'] = $this->normalizer->normalize($object->getEndDate(), $format, $context);
|
||||
$data['evaluation'] = $this->normalizer->normalize($object->getEvaluation(), $format, $context);
|
||||
$data['maxDate'] = $this->normalizer->normalize($object->getMaxDate(), $format, $context);
|
||||
$data['startDate'] = $this->normalizer->normalize($object->getStartDate(), $format, $context);
|
||||
$data['updatedAt'] = $this->normalizer->normalize($object->getUpdatedAt(), $format, $context);
|
||||
$data['updatedBy'] = $this->normalizer->normalize($object->getUpdatedBy(), $format, $context);
|
||||
$data['timeSpent'] = $object->getTimeSpent();
|
||||
}
|
||||
|
||||
if ($isRead) {
|
||||
$data['key'] = $object->getKey();
|
||||
$data['warningInterval'] = $this->normalizer->normalize($object->getWarningInterval(), $format, $context);
|
||||
}
|
||||
|
||||
// Handle 'read:evaluation:include-work' group for accompanyingPeriodWork
|
||||
if (in_array('read:evaluation:include-work', $groups, true)) {
|
||||
$workContext = $context;
|
||||
$workContext['groups'] = ['read:accompanyingPeriodWork:light'];
|
||||
$data['accompanyingPeriodWork'] = $this->normalizer->normalize($object->getAccompanyingPeriodWork(), $format, $workContext);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function supportsNormalization($data, ?string $format = null, array $context = []): bool
|
||||
{
|
||||
return 'json' === $format
|
||||
&& $data instanceof AccompanyingPeriodWorkEvaluation
|
||||
&& !\array_key_exists(self::IGNORE_EVALUATION, $context);
|
||||
if ('json' !== $format || !$data instanceof AccompanyingPeriodWorkEvaluation) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$groups = (array) ($context['groups'] ?? []);
|
||||
foreach (['write', 'accompanying_period_work_evaluation:create'] as $forbiddenGroup) {
|
||||
if (in_array($forbiddenGroup, $groups, true)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getSupportedTypes(?string $format): array
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\PersonBundle\Tests\Serializer\Normalizer;
|
||||
|
||||
use Chill\MainBundle\Repository\Workflow\EntityWorkflowRepository;
|
||||
use Chill\MainBundle\Workflow\Helper\MetadataExtractor;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation;
|
||||
use Chill\PersonBundle\Serializer\Normalizer\AccompanyingPeriodWorkEvaluationNormalizer;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Prophecy\PhpUnit\ProphecyTrait;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||
use Symfony\Component\Workflow\Registry;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @coversNothing
|
||||
*/
|
||||
class AccompanyingPeriodWorkEvaluationNormalizerTest extends TestCase
|
||||
{
|
||||
use ProphecyTrait;
|
||||
|
||||
public function testNormalize(): void
|
||||
{
|
||||
$registry = $this->prophesize(Registry::class);
|
||||
$entityWorkflowRepository = $this->prophesize(EntityWorkflowRepository::class);
|
||||
$metadataExtractor = $this->prophesize(MetadataExtractor::class);
|
||||
$serializer = $this->prophesize(NormalizerInterface::class);
|
||||
|
||||
$normalizer = new AccompanyingPeriodWorkEvaluationNormalizer(
|
||||
$registry->reveal(),
|
||||
$entityWorkflowRepository->reveal(),
|
||||
$metadataExtractor->reveal()
|
||||
);
|
||||
$normalizer->setNormalizer($serializer->reveal());
|
||||
|
||||
$object = new AccompanyingPeriodWorkEvaluation();
|
||||
|
||||
// Mocking calls from manualNormalize and other parts of normalize()
|
||||
$serializer->normalize(null, 'json', ['groups' => ['read']])->willReturn(null);
|
||||
$serializer->normalize($object->getDocuments()->getValues(), 'json', ['groups' => ['read']])->willReturn([]);
|
||||
$metadataExtractor->availableWorkflowFor(AccompanyingPeriodWorkEvaluation::class)->willReturn([]);
|
||||
$entityWorkflowRepository->findBy(['relatedEntityClass' => AccompanyingPeriodWorkEvaluation::class])->willReturn([]);
|
||||
$serializer->normalize([], 'json', ['groups' => ['read']])->willReturn([]);
|
||||
|
||||
$result = $normalizer->normalize($object, 'json', ['groups' => ['read']]);
|
||||
|
||||
$this->assertArrayHasKey('type', $result);
|
||||
$this->assertEquals('accompanying_period_work_evaluation', $result['type']);
|
||||
$this->assertArrayHasKey('id', $result);
|
||||
$this->assertArrayHasKey('comment', $result);
|
||||
$this->assertArrayHasKey('key', $result);
|
||||
$this->assertArrayHasKey('warningInterval', $result);
|
||||
$this->assertArrayHasKey('documents', $result);
|
||||
$this->assertArrayHasKey('workflows_availables', $result);
|
||||
$this->assertArrayHasKey('workflows', $result);
|
||||
}
|
||||
|
||||
public function testNormalizeDocgenRead(): void
|
||||
{
|
||||
$registry = $this->prophesize(Registry::class);
|
||||
$entityWorkflowRepository = $this->prophesize(EntityWorkflowRepository::class);
|
||||
$metadataExtractor = $this->prophesize(MetadataExtractor::class);
|
||||
$serializer = $this->prophesize(NormalizerInterface::class);
|
||||
|
||||
$normalizer = new AccompanyingPeriodWorkEvaluationNormalizer(
|
||||
$registry->reveal(),
|
||||
$entityWorkflowRepository->reveal(),
|
||||
$metadataExtractor->reveal()
|
||||
);
|
||||
$normalizer->setNormalizer($serializer->reveal());
|
||||
|
||||
$object = new AccompanyingPeriodWorkEvaluation();
|
||||
|
||||
// Mocking calls
|
||||
$serializer->normalize(null, 'json', ['groups' => ['docgen:read']])->willReturn(null);
|
||||
$serializer->normalize($object->getDocuments()->getValues(), 'json', ['groups' => ['docgen:read']])->willReturn([]);
|
||||
$metadataExtractor->availableWorkflowFor(AccompanyingPeriodWorkEvaluation::class)->willReturn([]);
|
||||
$entityWorkflowRepository->findBy(['relatedEntityClass' => AccompanyingPeriodWorkEvaluation::class])->willReturn([]);
|
||||
$serializer->normalize([], 'json', ['groups' => ['docgen:read']])->willReturn([]);
|
||||
|
||||
$result = $normalizer->normalize($object, 'json', ['groups' => ['docgen:read']]);
|
||||
|
||||
$this->assertArrayHasKey('type', $result);
|
||||
$this->assertEquals('accompanying_period_work_evaluation', $result['type']);
|
||||
$this->assertArrayHasKey('id', $result);
|
||||
$this->assertArrayHasKey('comment', $result);
|
||||
$this->assertArrayNotHasKey('key', $result);
|
||||
$this->assertArrayNotHasKey('warningInterval', $result);
|
||||
$this->assertArrayHasKey('documents', $result);
|
||||
}
|
||||
|
||||
public function testNormalizeWithoutGroups(): void
|
||||
{
|
||||
$registry = $this->prophesize(Registry::class);
|
||||
$entityWorkflowRepository = $this->prophesize(EntityWorkflowRepository::class);
|
||||
$metadataExtractor = $this->prophesize(MetadataExtractor::class);
|
||||
$serializer = $this->prophesize(NormalizerInterface::class);
|
||||
|
||||
$normalizer = new AccompanyingPeriodWorkEvaluationNormalizer(
|
||||
$registry->reveal(),
|
||||
$entityWorkflowRepository->reveal(),
|
||||
$metadataExtractor->reveal()
|
||||
);
|
||||
$normalizer->setNormalizer($serializer->reveal());
|
||||
|
||||
$object = new AccompanyingPeriodWorkEvaluation();
|
||||
|
||||
// When no groups are provided, it should return an empty array
|
||||
$result = $normalizer->normalize($object, 'json', []);
|
||||
|
||||
$this->assertSame([], $result);
|
||||
}
|
||||
|
||||
public function testSupportsNormalization(): void
|
||||
{
|
||||
$registry = $this->prophesize(Registry::class);
|
||||
$entityWorkflowRepository = $this->prophesize(EntityWorkflowRepository::class);
|
||||
$metadataExtractor = $this->prophesize(MetadataExtractor::class);
|
||||
|
||||
$normalizer = new AccompanyingPeriodWorkEvaluationNormalizer(
|
||||
$registry->reveal(),
|
||||
$entityWorkflowRepository->reveal(),
|
||||
$metadataExtractor->reveal()
|
||||
);
|
||||
|
||||
$object = new AccompanyingPeriodWorkEvaluation();
|
||||
|
||||
$this->assertTrue($normalizer->supportsNormalization($object, 'json', ['groups' => ['read']]));
|
||||
$this->assertFalse($normalizer->supportsNormalization($object, 'json', ['groups' => ['write']]));
|
||||
$this->assertFalse($normalizer->supportsNormalization($object, 'json', ['groups' => ['accompanying_period_work_evaluation:create']]));
|
||||
$this->assertFalse($normalizer->supportsNormalization($object, 'json', ['groups' => ['read', 'write']]));
|
||||
$this->assertFalse($normalizer->supportsNormalization(new \stdClass(), 'json'));
|
||||
$this->assertFalse($normalizer->supportsNormalization($object, 'xml'));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user