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);