112 lines
3.5 KiB
PHP
112 lines
3.5 KiB
PHP
<?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');
|
|
});
|
|
});
|