fix(worker,ui): route details-pane task delete through worker to advance blocked parents
Deleting a child from the details pane hard-deleted straight from the UI process via TaskRepository, bypassing TaskStateService.TryAdvanceParentAsync entirely. Deleting the last child of a WaitingForChildren parent that way left it wedged forever. WorkerHub.DeleteTask now mirrors the MCP delete_task tool (running-task guard, FK-friendly error, advance-parent call), and the UI goes through it. TryAdvanceParentAsync also short-circuited when zero children remained, treating "no children left" as "nothing to evaluate" instead of "all done" - removed the early return so an empty child list (vacuously) counts as all terminal.
This commit is contained in:
@@ -479,4 +479,42 @@ public sealed class TaskStateServiceTests : IDisposable
|
||||
Assert.Equal(TaskStatus.Queued, t2.Status);
|
||||
Assert.Equal(c1, t2.BlockedByTaskId);
|
||||
}
|
||||
|
||||
// ─── TryAdvanceParentAsync ────────────────────────────────────────────
|
||||
|
||||
[Fact]
|
||||
public async Task TryAdvanceParentAsync_ZeroChildren_AdvancesToWaitingForReview()
|
||||
{
|
||||
// Mirrors deleting the last remaining child: no terminal transition fires for it,
|
||||
// so the caller invokes TryAdvanceParentAsync directly with zero children left.
|
||||
var parent = await SeedTaskAsync(TaskStatus.WaitingForChildren, phase: PlanningPhase.Finalized);
|
||||
|
||||
await _sut.TryAdvanceParentAsync(parent);
|
||||
|
||||
Assert.Equal(TaskStatus.WaitingForReview, await GetStatusAsync(parent));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TryAdvanceParentAsync_AllChildrenTerminal_AdvancesToWaitingForReview()
|
||||
{
|
||||
var parent = await SeedTaskAsync(TaskStatus.WaitingForChildren, phase: PlanningPhase.Finalized);
|
||||
await SeedTaskAsync(TaskStatus.Done, parentId: parent);
|
||||
await SeedTaskAsync(TaskStatus.Done, parentId: parent);
|
||||
|
||||
await _sut.TryAdvanceParentAsync(parent);
|
||||
|
||||
Assert.Equal(TaskStatus.WaitingForReview, await GetStatusAsync(parent));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TryAdvanceParentAsync_SomeChildrenStillRunning_DoesNotAdvance()
|
||||
{
|
||||
var parent = await SeedTaskAsync(TaskStatus.WaitingForChildren, phase: PlanningPhase.Finalized);
|
||||
await SeedTaskAsync(TaskStatus.Done, parentId: parent);
|
||||
await SeedTaskAsync(TaskStatus.Running, parentId: parent);
|
||||
|
||||
await _sut.TryAdvanceParentAsync(parent);
|
||||
|
||||
Assert.Equal(TaskStatus.WaitingForChildren, await GetStatusAsync(parent));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user