From 4f030eb11a0a1cd531f9adba0d49133875aef468 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 12 Mar 2025 10:00:39 +0100 Subject: [PATCH] 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. --- .../Export/ExportDataNormalizerTrait.php | 26 +++++ .../Export/ExportDataNormalizerTraitTest.php | 101 ++++++++++++++++++ 2 files changed, 127 insertions(+) create mode 100644 src/Bundle/ChillMainBundle/Tests/Export/ExportDataNormalizerTraitTest.php diff --git a/src/Bundle/ChillMainBundle/Export/ExportDataNormalizerTrait.php b/src/Bundle/ChillMainBundle/Export/ExportDataNormalizerTrait.php index 0e24ce375..9dafd597b 100644 --- a/src/Bundle/ChillMainBundle/Export/ExportDataNormalizerTrait.php +++ b/src/Bundle/ChillMainBundle/Export/ExportDataNormalizerTrait.php @@ -39,4 +39,30 @@ trait ExportDataNormalizerTrait 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; + } } diff --git a/src/Bundle/ChillMainBundle/Tests/Export/ExportDataNormalizerTraitTest.php b/src/Bundle/ChillMainBundle/Tests/Export/ExportDataNormalizerTraitTest.php new file mode 100644 index 000000000..56d38d571 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Tests/Export/ExportDataNormalizerTraitTest.php @@ -0,0 +1,101 @@ +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'))]; + } +}