feat(KAN-29): rework backlog ticket tree
This commit is contained in:
@@ -71,6 +71,110 @@ class ProjectBacklogTest extends TestCase
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the backlog payload supports nested tickets and their allowed status moves.
|
||||
*/
|
||||
public function test_backlog_includes_nested_tickets_and_allowed_status_moves(): void
|
||||
{
|
||||
$editor = User::factory()->create();
|
||||
$project = Project::factory()->create([
|
||||
'key' => 'TREE',
|
||||
]);
|
||||
|
||||
app(InitializeProjectTicketMetadata::class)->handle($project);
|
||||
|
||||
$backlogStatus = $project->ticketStatuses()
|
||||
->whereNull('board_column_id')
|
||||
->firstOrFail();
|
||||
$boardColumn = BoardColumn::factory()->for($project)->create([
|
||||
'name' => 'Todo',
|
||||
'position' => 1,
|
||||
]);
|
||||
$boardStatus = TicketStatus::factory()
|
||||
->for($project)
|
||||
->for($boardColumn)
|
||||
->create([
|
||||
'name' => 'Ready',
|
||||
'position' => 1,
|
||||
]);
|
||||
$backlogStatus->allowedTargetStatuses()->sync([$boardStatus->id]);
|
||||
|
||||
$parentType = $project->ticketTypes()
|
||||
->where('is_parent', true)
|
||||
->firstOrFail();
|
||||
$taskType = $project->ticketTypes()
|
||||
->where('is_parent', false)
|
||||
->firstOrFail();
|
||||
$priority = $project->ticketPriorities()->firstOrFail();
|
||||
|
||||
$parentTicket = Ticket::factory()->create([
|
||||
'project_id' => $project->id,
|
||||
'sequence_number' => 1,
|
||||
'ticket_key' => 'TREE-1',
|
||||
'ticket_priority_id' => $priority->id,
|
||||
'ticket_status_id' => $backlogStatus->id,
|
||||
'ticket_type_id' => $parentType->id,
|
||||
'title' => 'Parent ticket',
|
||||
]);
|
||||
$childTicket = Ticket::factory()->create([
|
||||
'parent_ticket_id' => $parentTicket->id,
|
||||
'project_id' => $project->id,
|
||||
'sequence_number' => 2,
|
||||
'ticket_key' => 'TREE-2',
|
||||
'ticket_priority_id' => $priority->id,
|
||||
'ticket_status_id' => $backlogStatus->id,
|
||||
'ticket_type_id' => $taskType->id,
|
||||
'title' => 'Child ticket',
|
||||
]);
|
||||
|
||||
$this->syncProjectPermissions($project, $editor, ['edit', 'view']);
|
||||
|
||||
$this->actingAs($editor)
|
||||
->get(route('projects.backlog.index', $project))
|
||||
->assertOk()
|
||||
->assertInertia(fn (Assert $page) => $page
|
||||
->component('projects/Backlog')
|
||||
->where('canEditTickets', true)
|
||||
->has('tickets', 2)
|
||||
->where('tickets.0.id', $childTicket->id)
|
||||
->where('tickets.0.parent_ticket_id', $parentTicket->id)
|
||||
->where('tickets.0.ticket_status.allowed_target_statuses.0.id', $boardStatus->id)
|
||||
->where('tickets.1.id', $parentTicket->id)
|
||||
->where('tickets.1.parent_ticket_id', null)
|
||||
->where('tickets.1.ticket_status.allowed_target_statuses.0.id', $boardStatus->id),
|
||||
);
|
||||
|
||||
$this->assertDatabaseHas('tickets', [
|
||||
'id' => $parentTicket->id,
|
||||
'ticket_status_id' => $backlogStatus->id,
|
||||
]);
|
||||
$this->assertDatabaseHas('tickets', [
|
||||
'id' => $childTicket->id,
|
||||
'parent_ticket_id' => $parentTicket->id,
|
||||
'ticket_status_id' => $backlogStatus->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure projects without backlog tickets receive an empty collection.
|
||||
*/
|
||||
public function test_projects_without_backlog_tickets_receive_an_empty_collection(): void
|
||||
{
|
||||
$viewer = User::factory()->create();
|
||||
$project = Project::factory()->create();
|
||||
|
||||
app(InitializeProjectTicketMetadata::class)->handle($project);
|
||||
$this->syncProjectPermissions($project, $viewer, ['view']);
|
||||
|
||||
$this->actingAs($viewer)
|
||||
->get(route('projects.backlog.index', $project))
|
||||
->assertOk()
|
||||
->assertInertia(fn (Assert $page) => $page
|
||||
->component('projects/Backlog')
|
||||
->where('tickets', []),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure creating tickets requires the project write permission.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user