create(); $crawl = PageCrawl::factory()->page($page)->successful()->create(); $this->assertSame(CrawlOutcomeEnum::Success, $crawl->outcome); $this->assertInstanceOf(Carbon::class, $crawl->completed_at); $this->assertNull($crawl->error_message); } public function test_factory_failed_state_produces_failed_outcome_with_message(): void { $page = Page::factory()->create(); $crawl = PageCrawl::factory()->page($page)->failed('Connection timed out')->create(); $this->assertSame(CrawlOutcomeEnum::Failed, $crawl->outcome); $this->assertInstanceOf(Carbon::class, $crawl->completed_at); $this->assertSame('Connection timed out', $crawl->error_message); } public function test_factory_locked_state_produces_in_flight_crawl(): void { $page = Page::factory()->create(); $crawl = PageCrawl::factory()->page($page)->locked()->create(); $this->assertInstanceOf(Carbon::class, $crawl->locked_at); $this->assertNull($crawl->completed_at); $this->assertNull($crawl->outcome); } public function test_factory_scheduled_at_state_overrides_default_scheduled_for(): void { $page = Page::factory()->create(); $timestamp = Carbon::parse('2026-05-01 10:00:00'); $crawl = PageCrawl::factory()->page($page)->scheduledAt($timestamp)->create(); $this->assertTrue($timestamp->equalTo($crawl->scheduled_for)); } }