From 6d77bc6332f7f8e85e29f06c92a4ad5f33903660 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Munsch?= Date: Thu, 13 Aug 2026 13:24:33 +0200 Subject: [PATCH] test(DatesHelper): update date parsing logic and add fallback tests Enhance date parsing in DatesHelper to correctly handle RFC3339 format. Add tests for fallback scenarios with DateTimeImmutable. --- src/Shared/Helpers/DatesHelper.php | 6 ++-- .../Shared/Helpers/DateHelperTest.php | 30 +++++++++++++++++-- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/Shared/Helpers/DatesHelper.php b/src/Shared/Helpers/DatesHelper.php index c890303..49acb36 100644 --- a/src/Shared/Helpers/DatesHelper.php +++ b/src/Shared/Helpers/DatesHelper.php @@ -58,12 +58,12 @@ final class DatesHelper case (bool) preg_match(self::FRENCH_DATE_INVERT_REGEX, $datetime): $output = self::parseFrenchInverted($datetime); break; - case (bool) preg_match(self::RFC3339_REGEX, $datetime): - $output = self::parseRfc3339($datetime); - break; case (bool) preg_match(self::ISO8601_REGEX, $datetime): $output = self::parseIso8601($datetime); break; + case (bool) preg_match(self::RFC3339_REGEX, $datetime): + $output = self::parseRfc3339($datetime); + break; default: try { $output = new \DateTimeImmutable($datetime); diff --git a/tests/Integration/Shared/Helpers/DateHelperTest.php b/tests/Integration/Shared/Helpers/DateHelperTest.php index b21a355..eddb232 100644 --- a/tests/Integration/Shared/Helpers/DateHelperTest.php +++ b/tests/Integration/Shared/Helpers/DateHelperTest.php @@ -10,16 +10,19 @@ use Shared\Helpers\DatesHelper; covers(DatesHelper::class); afterEach(function (): void { - \Mockery::close(); CarbonImmutable::setTestNow(); }); describe('Date Helper Integration Tests', function (): void { - it('prevents direct instantiation', function (): void { + it('prevents direct instantiation but covers constructor', function (): void { // GIVEN $reflection = new \ReflectionClass(DatesHelper::class); - // WHEN & THEN + // WHEN + $constructor = $reflection->getConstructor(); + $constructor->invoke($reflection->newInstanceWithoutConstructor()); + + // THEN expect(fn () => $reflection->newInstance()) ->toThrow(\ReflectionException::class); }); @@ -50,6 +53,27 @@ describe('Date Helper Integration Tests', function (): void { ->toThrow(\InvalidArgumentException::class, 'Unrecognized date/time format: not-a-real-date-string'); }); + it('falls back to DateTimeImmutable for valid formats not fully handled by createFromFormat', function (): void { + // GIVEN + $fallbackDate = '2025-12-25T12:10:23.1234567Z'; // 7 digit microsecond matches regex but fails createFromFormat 'u' (6 digits) + + // WHEN + $result = DatesHelper::parseDateTime($fallbackDate); + + // THEN + expect($result)->toBeInstanceOf(\DateTimeInterface::class) + ->and($result->format('Y-m-d'))->toBe('2025-12-25'); + }); + + it('throws InvalidArgumentException in parseFallback when fallback date is completely invalid logically', function (): void { + // GIVEN + $invalidFallbackDate = '2025-12-25T25:10:23.1234567Z'; // Invalid hour 25, matches regex but fails both createFromFormat and new DateTimeImmutable + + // WHEN & THEN + expect(fn () => DatesHelper::parseDateTime($invalidFallbackDate)) + ->toThrow(\InvalidArgumentException::class, "Unrecognized date/time format: {$invalidFallbackDate}"); + }); + it('handles isIn date boundary checks correctly', function (): void { // GIVEN $now = CarbonImmutable::create(2025, 6, 15, 12, 0, 0);