Files
shopit-back/tests/Unit/Ticket/TenantTimezoneValidityTest.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'));
}
}