feat(claude-do): merge Task context menu: "Mark as → Idle" for cancelled tasks

ClaudeDo-Task: ad39dbb38d314e96803decc4e194e180
This commit is contained in:
mika kuns
2026-10-02 10:33:36 +02:00
5 changed files with 42 additions and 3 deletions
@@ -76,6 +76,38 @@ public sealed class SetTaskStatusHubTests : IDisposable
Assert.Equal(TaskStatus.Cancelled, task!.Status);
}
[Fact]
public async Task SetTaskStatus_Idle_OnCancelledTask_ClearsTimestampsAndKeepsWorktree()
{
var taskId = await SeedTaskAsync(TaskStatus.Cancelled);
await using (var seed = _db.CreateContext())
{
var t = (await seed.Tasks.FindAsync(taskId))!;
t.StartedAt = DateTime.UtcNow.AddMinutes(-5);
t.FinishedAt = DateTime.UtcNow;
t.Result = "stale";
await seed.SaveChangesAsync();
await new WorktreeRepository(seed).AddAsync(new WorktreeEntity
{
TaskId = taskId, Path = "/tmp/x", BranchName = "claudedo/x",
BaseCommit = "deadbeef", State = WorktreeState.Active, CreatedAt = DateTime.UtcNow,
});
}
var hub = CreateHub();
await hub.SetTaskStatus(taskId, "Idle");
await using var ctx = _db.CreateContext();
var task = await ctx.Tasks.AsNoTracking().SingleAsync(t => t.Id == taskId);
Assert.Equal(TaskStatus.Idle, task.Status);
Assert.Null(task.StartedAt);
Assert.Null(task.FinishedAt);
Assert.Null(task.Result);
var wt = await ctx.Worktrees.AsNoTracking().SingleAsync(w => w.TaskId == taskId);
Assert.Equal(WorktreeState.Active, wt.State);
Assert.Equal("claudedo/x", wt.BranchName);
}
[Fact]
public async Task SetTaskStatus_Missing_Throws()
{