Guard directional ticket link writes
This commit is contained in:
@@ -146,6 +146,66 @@ class ProjectTicketLinkControllerTest extends TestCase
|
||||
->assertSessionHasErrors('linked_ticket_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure relinking an existing reverse-direction pair updates the existing row instead of creating a duplicate.
|
||||
*/
|
||||
public function test_linking_an_existing_reverse_direction_pair_reuses_the_same_row(): void
|
||||
{
|
||||
$user = User::factory()->create();
|
||||
$project = Project::factory()->create([
|
||||
'key' => 'CORE',
|
||||
]);
|
||||
|
||||
app(InitializeProjectTicketMetadata::class)->handle($project);
|
||||
|
||||
$priority = $project->ticketPriorities()->firstOrFail();
|
||||
$taskType = $project->ticketTypes()
|
||||
->where('is_parent', false)
|
||||
->orderBy('position')
|
||||
->firstOrFail();
|
||||
$ticketLinkType = TicketLinkType::factory()->for($project)->create([
|
||||
'label' => 'Blocks',
|
||||
'counterpart_label' => 'Blocked by',
|
||||
'position' => 1,
|
||||
]);
|
||||
$ticket = Ticket::factory()->create([
|
||||
'project_id' => $project->id,
|
||||
'sequence_number' => 1,
|
||||
'ticket_key' => 'CORE-1',
|
||||
'ticket_priority_id' => $priority->id,
|
||||
'ticket_type_id' => $taskType->id,
|
||||
]);
|
||||
$linkedTicket = Ticket::factory()->create([
|
||||
'project_id' => $project->id,
|
||||
'sequence_number' => 2,
|
||||
'ticket_key' => 'CORE-2',
|
||||
'ticket_priority_id' => $priority->id,
|
||||
'ticket_type_id' => $taskType->id,
|
||||
]);
|
||||
$existingLink = TicketLink::factory()->create([
|
||||
'source_ticket_id' => $linkedTicket->id,
|
||||
'target_ticket_id' => $ticket->id,
|
||||
'ticket_link_type_id' => $ticketLinkType->id,
|
||||
]);
|
||||
|
||||
$this->syncProjectPermissions($project, $user, ['edit', 'view']);
|
||||
|
||||
$this->actingAs($user)
|
||||
->post(route('projects.tickets.links.store', [$project, $ticket]), [
|
||||
'linked_ticket_id' => $linkedTicket->id,
|
||||
'ticket_link_type_id' => $ticketLinkType->id,
|
||||
])
|
||||
->assertRedirect(route('projects.tickets.show', [$project, $ticket]))
|
||||
->assertSessionHas('status', 'Blocks link was saved.');
|
||||
|
||||
$this->assertSame(1, TicketLink::query()->count());
|
||||
|
||||
$existingLink->refresh();
|
||||
|
||||
$this->assertSame($ticket->id, $existingLink->source_ticket_id);
|
||||
$this->assertSame($linkedTicket->id, $existingLink->target_ticket_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure users with edit permission can remove ticket links.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user