setRawAttributes([ 'tenant_code' => 'acme', 'validity_time_id' => '12', 'date' => '2026-10-09', 'time_start' => '09:00:00', 'time_end' => '18:30:00', ]); $this->assertFalse($eventDate->usesTimestamps()); $this->assertSame('acme', $eventDate->tenant_code); $this->assertSame(12, $eventDate->validity_time_id); $this->assertSame('2026-10-09 09:00:00', $eventDate->startsAt()->format('Y-m-d H:i:s')); $this->assertSame('2026-10-09 18:30:00', $eventDate->endsAt()->format('Y-m-d H:i:s')); $this->assertInstanceOf(Tenant::class, $eventDate->tenant()->getRelated()); $this->assertInstanceOf(ValidityTime::class, $eventDate->validityTime()->getRelated()); $this->assertInstanceOf(EventDate::class, (new ValidityTime)->eventDate()->getRelated()); $this->assertInstanceOf(Variant::class, $eventDate->variants()->getRelated()); $this->assertInstanceOf(EventDate::class, $eventDate->rescheduledTo()->getRelated()); $this->assertInstanceOf(EventDate::class, $eventDate->rescheduledFrom()->getRelated()); } public function test_event_date_status_is_computed_in_business_priority_order(): void { Carbon::setTestNow('2026-10-09 10:00:00'); try { $eventDate = new EventDate([ 'date' => '2026-10-09', 'time_start' => '09:00:00', 'time_end' => '18:30:00', ]); $this->assertSame(EventDateStatus::InProgress, $eventDate->status); $eventDate->date = '2026-10-10'; $this->assertSame(EventDateStatus::Scheduled, $eventDate->status); $eventDate->date = '2026-10-08'; $this->assertSame(EventDateStatus::Completed, $eventDate->status); $eventDate->suspended_at = now(); $this->assertSame(EventDateStatus::Suspended, $eventDate->status); $eventDate->rescheduled_to_event_date_id = 123; $this->assertSame(EventDateStatus::Rescheduled, $eventDate->status); } finally { Carbon::setTestNow(); } } public function test_an_overnight_event_finishes_on_the_following_day(): void { Carbon::setTestNow('2026-10-10 01:00:00'); try { $eventDate = new EventDate([ 'date' => '2026-10-09', 'time_start' => '20:00:00', 'time_end' => '02:00:00', ]); $this->assertSame('2026-10-10 02:00:00', $eventDate->endsAt()->format('Y-m-d H:i:s')); $this->assertSame(EventDateStatus::InProgress, $eventDate->status); } finally { Carbon::setTestNow(); } } public function test_tenant_has_many_event_dates(): void { $tenant = new Tenant; $this->assertInstanceOf(EventDate::class, $tenant->eventDates()->getRelated()); } public function test_effective_date_follows_all_replacements_and_returns_null_when_suspended(): void { $original = new EventDate; $original->setRawAttributes(['id' => 1, 'rescheduled_to_event_date_id' => 2]); $middle = new EventDate; $middle->setRawAttributes(['id' => 2, 'rescheduled_to_event_date_id' => 3]); $latest = new EventDate; $latest->setRawAttributes(['id' => 3, 'date' => '2026-11-02']); $original->setRelation('rescheduledTo', $middle); $middle->setRelation('rescheduledTo', $latest); $this->assertSame($latest, $original->effectiveDate()); $latest->suspended_at = '2026-11-01 12:00:00'; $this->assertNull($original->effectiveDate()); } }