91 lines
5.0 KiB
PHP
91 lines
5.0 KiB
PHP
<?php
|
|
|
|
namespace Tests\Unit\Ticket;
|
|
|
|
use App\Domains\Commerce\Catalog\Models\CatalogItem;
|
|
use App\Domains\Commerce\Catalog\Models\Variant;
|
|
use App\Domains\Core\Tenant\Models\Tenant;
|
|
use App\Domains\Ticketing\Event\Models\EventDate;
|
|
use App\Domains\Ticketing\Ticket\Enums\ValidityTimeType;
|
|
use App\Domains\Ticketing\Ticket\Models\ValidityTime;
|
|
use App\Domains\Ticketing\Ticket\Resources\ValidityTimeResource;
|
|
use App\Domains\Ticketing\Ticket\Services\ResolvedValidityGroup;
|
|
use App\Domains\Ticketing\Ticket\Services\TicketValidityResolver;
|
|
use Carbon\CarbonImmutable;
|
|
use Illuminate\Database\Eloquent\Collection;
|
|
use Tests\TestCase;
|
|
|
|
class TenantTimezoneValidityTest extends TestCase
|
|
{
|
|
public function test_recurring_windows_use_local_day_and_exclusive_end(): void
|
|
{
|
|
$window = new ValidityTime(['type' => ValidityTimeType::TimeWindow, 'start_time' => '22:00', 'end_time' => '02:00']);
|
|
$group = new ResolvedValidityGroup(collect([$window]), 'America/Argentina/Buenos_Aires');
|
|
foreach (['2026-09-22 01:00' => true, '2026-09-22 04:59' => true, '2026-09-22 05:00' => false, '2026-09-22 18:00' => false] as $time => $expected) {
|
|
$at = CarbonImmutable::parse($time, 'UTC');
|
|
$this->assertSame($expected, $group->isValid($at), $time);
|
|
$this->assertSame($expected, $window->isValid($at, 'America/Argentina/Buenos_Aires'), $time);
|
|
}
|
|
$this->assertFalse((new ResolvedValidityGroup(collect([$window]), 'Asia/Tokyo'))->isValid(CarbonImmutable::parse('2026-09-22 01:00', 'UTC')));
|
|
}
|
|
|
|
public function test_event_anchor_uses_local_date_when_utc_date_is_next_day(): void
|
|
{
|
|
$fixed = new ValidityTime(['type' => ValidityTimeType::FixedWindow,
|
|
'fixed_starts_at' => '2026-09-22 01:00', 'fixed_expires_at' => '2026-09-22 06:00']);
|
|
$window = new ValidityTime(['type' => ValidityTimeType::TimeWindow, 'start_time' => '22:00', 'end_time' => '02:00']);
|
|
$group = new ResolvedValidityGroup(collect([$fixed, $window]), 'America/Argentina/Buenos_Aires');
|
|
$this->assertTrue($group->isValid(CarbonImmutable::parse('2026-09-22 04:00', 'UTC')));
|
|
$this->assertFalse($group->isValid(CarbonImmutable::parse('2026-09-23 04:00', 'UTC')));
|
|
$this->assertSame('2026-09-22 01:00', $group->effectiveStartsAt()->utc()->format('Y-m-d H:i'));
|
|
$this->assertSame('2026-09-22 05:00', $group->effectiveExpiresAt()->utc()->format('Y-m-d H:i'));
|
|
}
|
|
|
|
public function test_local_window_compares_with_utc_now_in_resource(): void
|
|
{
|
|
$this->travelTo(CarbonImmutable::parse('2026-09-21 22:00', 'UTC'));
|
|
$window = new ValidityTime(['type' => ValidityTimeType::TimeWindow, 'start_time' => '18:00', 'end_time' => '20:00']);
|
|
$resource = ValidityTimeResource::make($window, 'America/Argentina/Buenos_Aires');
|
|
$this->assertTrue($resource->resolve()['is_valid']);
|
|
$this->assertFalse($window->isValid(now(), 'Asia/Tokyo'));
|
|
$this->travelBack();
|
|
}
|
|
|
|
public function test_daylight_saving_uses_date_specific_offset(): void
|
|
{
|
|
$window = new ValidityTime(['type' => ValidityTimeType::TimeWindow, 'start_time' => '18:00', 'end_time' => '20:00']);
|
|
$this->assertSame('2026-01-21 23:00', $window->startsAt(CarbonImmutable::parse('2026-01-21 12:00', 'UTC'), 'America/New_York')->utc()->format('Y-m-d H:i'));
|
|
$this->assertSame('2026-07-21 22:00', $window->startsAt(CarbonImmutable::parse('2026-07-21 12:00', 'UTC'), 'America/New_York')->utc()->format('Y-m-d H:i'));
|
|
}
|
|
|
|
public function test_resolver_passes_tenant_timezone_to_groups(): void
|
|
{
|
|
$tenant = new Tenant(['timezone' => 'Asia/Tokyo']);
|
|
$item = new CatalogItem;
|
|
$item->setRelation('tenant', $tenant);
|
|
$date = new EventDate;
|
|
$date->setRelation('validityTime', new ValidityTime([
|
|
'type' => ValidityTimeType::FixedWindow,
|
|
'fixed_starts_at' => '2026-09-21 13:00',
|
|
'fixed_expires_at' => '2026-09-21 17:00',
|
|
]));
|
|
$variant = new Variant;
|
|
$variant->setRelation('catalogItem', $item);
|
|
$variant->setRelation('eventDates', new Collection([$date]));
|
|
$variant->setRelation('eventDate', null);
|
|
$variant->setRelation('definitions', new Collection);
|
|
$resolved = (new TicketValidityResolver)->resolveVariant($variant);
|
|
$this->assertSame('Asia/Tokyo', $resolved->groups->first()->timezone);
|
|
}
|
|
|
|
public function test_event_hours_are_local_and_end_can_be_next_day(): void
|
|
{
|
|
$date = new EventDate(['date' => '2026-09-21', 'time_start' => '22:00', 'time_end' => '02:00']);
|
|
$date->setRelation('tenant', new Tenant(['timezone' => 'America/Argentina/Buenos_Aires']));
|
|
$this->assertSame('2026-09-22 01:00', $date->startsAt()->utc()->format('Y-m-d H:i'));
|
|
$this->assertSame('2026-09-22 05:00', $date->endsAt()->utc()->format('Y-m-d H:i'));
|
|
$date->setRelation('tenant', new Tenant(['timezone' => 'Asia/Tokyo']));
|
|
$this->assertSame('2026-09-21 13:00', $date->startsAt()->utc()->format('Y-m-d H:i'));
|
|
}
|
|
}
|