Add point-in-time normalization to stored object versions

Introduced a new normalizer for StoredObjectPointInTime and updated the StoredObjectVersionNormalizer to include point-in-time data when specified in the context. Added corresponding test cases to ensure the new normalization logic works correctly.
This commit is contained in:
Julien Fastré 2024-09-17 13:23:30 +02:00
parent 943a42cd38
commit 6a0e26ec31
Signed by: julienfastre
GPG Key ID: BDE2190974723FCB
4 changed files with 118 additions and 2 deletions

View File

@ -13,6 +13,7 @@ namespace Chill\DocStoreBundle\Controller;
use Chill\DocStoreBundle\Entity\StoredObject;
use Chill\DocStoreBundle\Security\Authorization\StoredObjectRoleEnum;
use Chill\DocStoreBundle\Serializer\Normalizer\StoredObjectVersionNormalizer;
use Chill\MainBundle\Pagination\PaginatorFactoryInterface;
use Chill\MainBundle\Serializer\Model\Collection;
use Doctrine\Common\Collections\Criteria;
@ -57,7 +58,11 @@ final readonly class StoredObjectVersionApiController
$items = $storedObject->getVersions()->matching($criteria);
return new JsonResponse(
$this->serializer->serialize(new Collection($items, $paginator), 'json', [AbstractNormalizer::GROUPS => ['read']]),
$this->serializer->serialize(
new Collection($items, $paginator),
'json',
[AbstractNormalizer::GROUPS => ['read', StoredObjectVersionNormalizer::WITH_POINT_IN_TIMES_CONTEXT]]
),
json: true
);
}

View File

@ -0,0 +1,38 @@
<?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\DocStoreBundle\Serializer\Normalizer;
use Chill\DocStoreBundle\Entity\StoredObjectPointInTime;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
class StoredObjectPointInTimeNormalizer implements NormalizerInterface, NormalizerAwareInterface
{
use NormalizerAwareTrait;
public function normalize($object, ?string $format = null, array $context = [])
{
/* @var StoredObjectPointInTime $object */
return [
'id' => $object->getId(),
'reason' => $object->getReason()->value,
'byUser' => $this->normalizer->normalize($object->getByUser(), $format, [AbstractNormalizer::GROUPS => 'read']),
];
}
public function supportsNormalization($data, ?string $format = null)
{
return $data instanceof StoredObjectPointInTime;
}
}

View File

@ -12,6 +12,7 @@ declare(strict_types=1);
namespace Chill\DocStoreBundle\Serializer\Normalizer;
use Chill\DocStoreBundle\Entity\StoredObjectVersion;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
@ -20,13 +21,15 @@ class StoredObjectVersionNormalizer implements NormalizerInterface, NormalizerAw
{
use NormalizerAwareTrait;
final public const WITH_POINT_IN_TIMES_CONTEXT = 'with-point-in-times';
public function normalize($object, ?string $format = null, array $context = [])
{
if (!$object instanceof StoredObjectVersion) {
throw new \InvalidArgumentException('The object must be an instance of '.StoredObjectVersion::class);
}
return [
$data = [
'id' => $object->getId(),
'filename' => $object->getFilename(),
'version' => $object->getVersion(),
@ -36,6 +39,12 @@ class StoredObjectVersionNormalizer implements NormalizerInterface, NormalizerAw
'createdAt' => $this->normalizer->normalize($object->getCreatedAt(), $format, $context),
'createdBy' => $this->normalizer->normalize($object->getCreatedBy(), $format, $context),
];
if (in_array(self::WITH_POINT_IN_TIMES_CONTEXT, $context[AbstractNormalizer::GROUPS])) {
$data['point-in-times'] = $this->normalizer->normalize($object->getPointInTimes(), $format, $context);
}
return $data;
}
public function supportsNormalization($data, ?string $format = null, array $context = [])

View File

@ -0,0 +1,64 @@
<?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\DocStoreBundle\Tests\Serializer\Normalizer;
use Chill\DocStoreBundle\Entity\StoredObject;
use Chill\DocStoreBundle\Entity\StoredObjectPointInTime;
use Chill\DocStoreBundle\Entity\StoredObjectPointInTimeReasonEnum;
use Chill\DocStoreBundle\Serializer\Normalizer\StoredObjectPointInTimeNormalizer;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Serializer\Normalizer\UserNormalizer;
use Chill\MainBundle\Templating\Entity\UserRender;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Prophecy\PhpUnit\ProphecyTrait;
use Symfony\Component\Clock\MockClock;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
use Symfony\Component\Serializer\Serializer;
/**
* @internal
*
* @coversNothing
*/
class StoredObjectPointInTimeNormalizerTest extends TestCase
{
use ProphecyTrait;
public function testNormalize(): void
{
$storedObject = new StoredObject();
$version = $storedObject->registerVersion();
$storedObjectPointInTime = new StoredObjectPointInTime($version, StoredObjectPointInTimeReasonEnum::KEEP_BEFORE_CONVERSION, new User());
$normalizer = new StoredObjectPointInTimeNormalizer();
$normalizer->setNormalizer($this->buildNormalizer());
$actual = $normalizer->normalize($storedObjectPointInTime, 'json', ['read']);
self::assertIsArray($actual);
self::assertArrayHasKey('id', $actual);
self::assertArrayHasKey('byUser', $actual);
self::assertArrayHasKey('reason', $actual);
self::assertEquals(StoredObjectPointInTimeReasonEnum::KEEP_BEFORE_CONVERSION->value, $actual['reason']);
}
public function buildNormalizer(): NormalizerInterface
{
$userRender = $this->prophesize(UserRender::class);
$userRender->renderString(Argument::type(User::class), Argument::type('array'))->willReturn('username');
return new Serializer(
[new UserNormalizer($userRender->reveal(), new MockClock())]
);
}
}