ldc-arcadia-api/tests/Unit/Infra/Casts/UtcDateTimeCastTest.php

113 lines
3.5 KiB
PHP
Raw Permalink Normal View History

<?php
declare(strict_types=1);
namespace Tests\Unit\Infra\Casts;
use Illuminate\Database\Eloquent\Model;
use Infra\Casts\UtcDateTimeCast;
covers(UtcDateTimeCast::class);
describe('UtcDateTimeCast Unit Tests', function (): void {
it('casts database string to UTC DateTimeImmutable', function (): void {
// GIVEN
$cast = new UtcDateTimeCast();
$model = new class () extends Model
{
};
// WHEN
$result = $cast->get($model, 'created_at', '2026-08-21 14:30:00', []);
// THEN
expect($result)->toBeInstanceOf(\DateTimeImmutable::class)
->and($result?->getTimezone()->getName())->toBe('UTC')
->and($result?->format('Y-m-d H:i:s'))->toBe('2026-08-21 14:30:00');
});
it('casts non-UTC DateTimeInterface to UTC DateTimeImmutable upon get', function (): void {
// GIVEN
$cast = new UtcDateTimeCast();
$model = new class () extends Model
{
};
$parisDate = new \DateTimeImmutable('2026-08-21 16:30:00', new \DateTimeZone('Europe/Paris'));
// WHEN
$result = $cast->get($model, 'created_at', $parisDate, []);
// THEN
expect($result)->toBeInstanceOf(\DateTimeImmutable::class)
->and($result?->getTimezone()->getName())->toBe('UTC')
->and($result?->format('Y-m-d H:i:s'))->toBe('2026-08-21 14:30:00');
});
it('handles null and empty string upon get', function (): void {
// GIVEN
$cast = new UtcDateTimeCast();
$model = new class () extends Model
{
};
// WHEN & THEN
expect($cast->get($model, 'created_at', null, []))->toBeNull()
->and($cast->get($model, 'created_at', '', []))->toBeNull()
->and($cast->get($model, 'created_at', ' ', []))->toBeNull();
});
it('sets DateTimeInterface to UTC string format for database storage', function (): void {
// GIVEN
$cast = new UtcDateTimeCast();
$model = new class () extends Model
{
};
$parisDate = new \DateTimeImmutable('2026-08-21 16:30:00', new \DateTimeZone('Europe/Paris'));
// WHEN
$result = $cast->set($model, 'created_at', $parisDate, []);
// THEN
expect($result)->toBe('2026-08-21 14:30:00');
});
it('sets string date to UTC string format for database storage', function (): void {
// GIVEN
$cast = new UtcDateTimeCast();
$model = new class () extends Model
{
};
// WHEN
$result = $cast->set($model, 'created_at', '2026-08-21T16:30:00+02:00', []);
// THEN
expect($result)->toBe('2026-08-21 14:30:00');
});
it('handles null and empty string upon set', function (): void {
// GIVEN
$cast = new UtcDateTimeCast();
$model = new class () extends Model
{
};
// WHEN & THEN
expect($cast->set($model, 'created_at', null, []))->toBeNull()
->and($cast->set($model, 'created_at', '', []))->toBeNull()
->and($cast->set($model, 'created_at', ' ', []))->toBeNull();
});
it('throws InvalidArgumentException when setting unsupported type', function (): void {
// GIVEN
$cast = new UtcDateTimeCast();
$model = new class () extends Model
{
};
// WHEN & THEN
expect(fn () => $cast->set($model, 'created_at', 12345, []))
->toThrow(\InvalidArgumentException::class, 'Cannot cast value of type int to UTC datetime');
});
});