Merge branch 'claudedo/9f963a215bb34ca4a28050d4f39178d3'

This commit is contained in:
mika kuns
2026-08-10 15:19:57 +02:00
23 changed files with 481 additions and 32 deletions
+35 -3
View File
@@ -4,6 +4,7 @@ using ClaudeDo.Data.Models;
using ClaudeDo.Data.Repositories;
using ClaudeDo.Worker.Config;
using ClaudeDo.Worker.External;
using ClaudeDo.Worker.Git;
using ClaudeDo.Worker.Hub;
using ClaudeDo.Worker.Lifecycle;
using ClaudeDo.Worker.Planning;
@@ -24,6 +25,9 @@ public sealed class BatchMcpToolsTests : IDisposable
private readonly TaskRepository _tasks;
private readonly ListRepository _lists;
private readonly HubBroadcaster _broadcaster;
private readonly List<GitRepoFixture> _repos = new();
private static bool GitAvailable => GitRepoFixture.IsGitAvailable();
public BatchMcpToolsTests()
{
@@ -35,14 +39,15 @@ public sealed class BatchMcpToolsTests : IDisposable
public void Dispose()
{
foreach (var r in _repos) r.Dispose();
_ctx.Dispose();
_db.Dispose();
}
private async Task<string> SeedListAsync()
private async Task<string> SeedListAsync(string? workingDir = null)
{
var id = Guid.NewGuid().ToString();
await _lists.AddAsync(new ListEntity { Id = id, Name = "L", CreatedAt = DateTime.UtcNow });
await _lists.AddAsync(new ListEntity { Id = id, Name = "L", CreatedAt = DateTime.UtcNow, WorkingDir = workingDir });
return id;
}
@@ -74,7 +79,8 @@ public sealed class BatchMcpToolsTests : IDisposable
var svc = new ExternalMcpService(
_tasks, _lists, CreateQueue(), _broadcaster,
state,
git, factory, maintenance, merge, planningMerge);
git, factory, maintenance, merge, planningMerge,
new BaseDirtyChecker(git, NullLogger<BaseDirtyChecker>.Instance));
return new BatchMcpTools(svc);
}
@@ -414,6 +420,32 @@ public sealed class BatchMcpToolsTests : IDisposable
Assert.Equal(TaskStatus.Queued, (await _tasks.GetByIdAsync(t2.Id))!.Status);
}
[Fact]
public async Task BatchUpdateTaskStatus_DirtyBaseRepo_ReportsWarningPerItem_OneListOneRepo()
{
if (!GitAvailable) { Assert.True(true, "git not available -- skipping"); return; }
var repo = new GitRepoFixture();
_repos.Add(repo);
File.WriteAllText(Path.Combine(repo.RepoDir, "scratch.txt"), "new");
var listId = await SeedListAsync(repo.RepoDir);
var t1 = await SeedTaskAsync(listId, "a", TaskStatus.Idle);
var t2 = await SeedTaskAsync(listId, "b", TaskStatus.Idle);
var sut = BuildSut();
// Two tasks queued from the same list -- BaseDirtyChecker's TTL cache means only one
// `git status` actually runs underneath, but both items still see the warning.
var results = await sut.BatchUpdateTaskStatus(new[] { t1.Id, t2.Id }, "Queued", CancellationToken.None);
Assert.All(results, r => Assert.True(r.Ok));
Assert.All(results, r =>
{
Assert.NotNull(r.BaseDirty);
Assert.Equal(1, r.BaseDirty!.UntrackedCount);
});
}
[Fact]
public async Task BatchUpdateTaskStatus_Done_MixedWorktreeState_ReportsPerItemAndDoesNotAbort()
{