addDays(1)->startOfDay(); $event = Event::factory()->create(['date' => $eventDate]); $token = $event->ensureLiveShowToken(); $this->assertIsString($token); $this->assertSame(64, strlen($token)); $this->assertSame($token, $event->refresh()->live_show_token); $this->assertNotNull($event->live_show_token_rotated_at); $this->assertSame($eventDate->copy()->addDay()->endOfDay()->toIso8601String(), $event->live_show_token_expires_at?->toIso8601String()); $rotated = $event->rotateLiveShowToken(); $this->assertIsString($rotated); $this->assertSame(64, strlen($rotated)); $this->assertNotSame($token, $rotated); $this->assertSame($rotated, $event->refresh()->live_show_token); $this->assertSame($eventDate->copy()->addDay()->endOfDay()->toIso8601String(), $event->live_show_token_expires_at?->toIso8601String()); } public function test_live_show_token_expiry_updates_when_event_date_changes(): void { $eventDate = now()->addDays(3)->startOfDay(); $event = Event::factory()->create(['date' => $eventDate]); $event->ensureLiveShowToken(); $event->refresh(); $this->assertSame($eventDate->copy()->addDay()->endOfDay()->toIso8601String(), $event->live_show_token_expires_at?->toIso8601String()); $newDate = now()->addDays(7)->startOfDay(); $event->update(['date' => $newDate]); $event->refresh(); $this->assertSame($newDate->copy()->addDay()->endOfDay()->toIso8601String(), $event->live_show_token_expires_at?->toIso8601String()); } public function test_photo_live_status_is_cast_and_defaults_to_none(): void { $photo = Photo::factory()->create(); $photo->refresh(); $this->assertInstanceOf(PhotoLiveStatus::class, $photo->live_status); $this->assertSame(PhotoLiveStatus::NONE, $photo->live_status); $photo->forceFill([ 'live_status' => PhotoLiveStatus::PENDING, 'live_submitted_at' => now(), ])->save(); $photo->refresh(); $this->assertSame(PhotoLiveStatus::PENDING, $photo->live_status); $this->assertNotNull($photo->live_submitted_at); } public function test_photo_live_workflow_sets_expected_timestamps_and_reviewer(): void { $reviewer = User::factory()->create(); $photo = Photo::factory()->create(); $photo->markLivePending(); $photo->refresh(); $this->assertSame(PhotoLiveStatus::PENDING, $photo->live_status); $this->assertNotNull($photo->live_submitted_at); $this->assertNull($photo->live_reviewed_at); $this->assertNull($photo->live_approved_at); $photo->approveForLiveShow($reviewer); $photo->refresh(); $this->assertSame(PhotoLiveStatus::APPROVED, $photo->live_status); $this->assertNotNull($photo->live_reviewed_at); $this->assertNotNull($photo->live_approved_at); $this->assertSame($reviewer->id, $photo->live_reviewed_by); $this->assertNull($photo->live_rejection_reason); $photo->rejectForLiveShow($reviewer, 'policy_violation'); $photo->refresh(); $this->assertSame(PhotoLiveStatus::REJECTED, $photo->live_status); $this->assertNotNull($photo->live_reviewed_at); $this->assertNull($photo->live_approved_at); $this->assertSame($reviewer->id, $photo->live_reviewed_by); $this->assertSame('policy_violation', $photo->live_rejection_reason); } }