create(); $this->assertNull($ticket->board_column_id); $this->assertStringContainsString('-', $ticket->ticket_key); $this->assertSame(1, $ticket->sequence_number); } /** * Ensure the ticket seeder creates duplicate titles with project-local keys. */ public function test_ticket_seeder_creates_backlog_tickets_with_project_local_keys(): void { $this->seed([ ProjectSeeder::class, BoardColumnSeeder::class, ProjectTicketMetadataSeeder::class, TicketSeeder::class, ]); $coreProject = Project::query()->where('key', 'CORE')->firstOrFail(); $this->assertDatabaseHas('tickets', [ 'project_id' => $coreProject->id, 'ticket_key' => 'CORE-1', 'title' => 'Seed backlog item', 'board_column_id' => null, ]); $this->assertDatabaseHas('tickets', [ 'project_id' => $coreProject->id, 'ticket_key' => 'CORE-2', 'title' => 'Seed backlog item', 'board_column_id' => null, ]); } /** * Ensure ticket worklog entries are exposed newest first for timeline rendering. */ public function test_ticket_worklog_entries_are_returned_newest_first(): void { $ticket = Ticket::factory()->create(); $olderEntry = TicketWorklogEntry::factory()->for($ticket)->create([ 'created_at' => now()->subMinute(), 'updated_at' => now()->subMinute(), ]); $newerEntry = TicketWorklogEntry::factory()->for($ticket)->create([ 'created_at' => now(), 'updated_at' => now(), ]); $this->assertSame( [$newerEntry->id, $olderEntry->id], $ticket->fresh()->worklogEntries->modelKeys(), ); } }