Add date normalization and denormalization functionality

Introduce methods to normalize and denormalize DateTime objects using specific formats. Also, implement corresponding unit tests to ensure correct handling of single and multiple Doctrine entities, as well as date normalization.
This commit is contained in:
Julien Fastré 2025-03-12 10:00:39 +01:00
parent 0d2a487ae7
commit 4f030eb11a
Signed by: julienfastre
GPG Key ID: BDE2190974723FCB
2 changed files with 127 additions and 0 deletions

View File

@ -39,4 +39,30 @@ trait ExportDataNormalizerTrait
return $object; return $object;
} }
public function normalizeDate(\DateTimeImmutable|\DateTime $date): string
{
return sprintf(
'%s,%s',
$date instanceof \DateTimeImmutable ? 'imm1' : 'mut1',
$date->format('d-m-Y-H:i:s.u e'),
);
}
public function denormalizeDate(string $date): \DateTimeImmutable|\DateTime
{
$format = 'd-m-Y-H:i:s.u e';
$denormalized = match (substr($date, 0, 4)) {
'imm1' => \DateTimeImmutable::createFromFormat($format, substr($date, 5)),
'mut1' => \DateTime::createFromFormat($format, substr($date, 5)),
default => throw new \UnexpectedValueException(sprintf('Unexpected format for the kind selector: %s', substr($date, 0, 4))),
};
if (false === $denormalized) {
throw new \UnexpectedValueException(sprintf('Unexpected date format: %s', substr($date, 5)));
}
return $denormalized;
}
} }

View File

@ -0,0 +1,101 @@
<?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\MainBundle\Tests\Export;
use Chill\MainBundle\Export\ExportDataNormalizerTrait;
use Doctrine\Persistence\ObjectRepository;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Prophecy\PhpUnit\ProphecyTrait;
/**
* @internal
*
* @coversNothing
*/
class ExportDataNormalizerTraitTest extends TestCase
{
use ProphecyTrait;
private function buildTrait(): object
{
return new class () {
use ExportDataNormalizerTrait;
};
}
public function testNormalizationDoctrineEntitySingle(): void
{
$entity = new class () {
public function getId(): int
{
return 1;
}
};
$repository = $this->prophesize(ObjectRepository::class);
$repository->find(1)->willReturn($entity);
$normalized = $this->buildTrait()->normalizeDoctrineEntity($entity);
$actual = $this->buildTrait()->denormalizeDoctrineEntity($normalized, $repository->reveal());
self::assertSame($entity, $actual);
}
public function testNormalizationDoctrineEntityMulti(): void
{
$entityA = new class () {
public function getId(): int
{
return 1;
}
};
$entityB = new class () {
public function getId(): int
{
return 2;
}
};
$repository = $this->prophesize(ObjectRepository::class);
$repository->findBy(
Argument::that(static fn ($arg): bool => in_array(1, $arg['id'] ?? []) && in_array(2, $arg['id'] ?? []))
)->willReturn([$entityA, $entityB]);
$normalized = $this->buildTrait()->normalizeDoctrineEntity([$entityA, $entityB]);
$actual = $this->buildTrait()->denormalizeDoctrineEntity($normalized, $repository->reveal());
self::assertContains(1, array_map(static fn (object $item) => $item->getId(), $actual));
self::assertContains(2, array_map(static fn (object $item) => $item->getId(), $actual));
self::assertCount(2, $actual);
}
/**
* @dataProvider provideDate
*/
public function testNormalizationDate(\DateTimeImmutable|\DateTime $date): void
{
$normalized = $this->buildTrait()->normalizeDate($date);
$actual = $this->buildTrait()->denormalizeDate($normalized);
self::assertEquals($date, $actual);
}
public static function provideDate(): iterable
{
yield [new \DateTimeImmutable('2024-01-15T18:57:20', new \DateTimeZone('Europe/Athens'))];
yield [new \DateTimeImmutable('2024-01-15T18:57:30', new \DateTimeZone('America/Havana'))];
yield [new \DateTime('2024-01-15T18:57:40', new \DateTimeZone('Europe/Madrid'))];
yield [new \DateTime('2024-01-15T18:57:50', new \DateTimeZone('Africa/Kinshasa'))];
}
}