87 lines
3.1 KiB
C#
87 lines
3.1 KiB
C#
using ClaudeDo.Worker.Hub;
|
|
using ClaudeDo.Worker.Lifecycle;
|
|
using ClaudeDo.Worker.Tests.Infrastructure;
|
|
using Microsoft.Extensions.Logging.Abstractions;
|
|
|
|
namespace ClaudeDo.Worker.Tests.Lifecycle;
|
|
|
|
public sealed class UntrackedWorktreeRecoveryTests : IDisposable
|
|
{
|
|
private readonly DbFixture _db = new();
|
|
|
|
public void Dispose() => _db.Dispose();
|
|
|
|
[Fact]
|
|
public void FindUntrackedPaths_PathNotInDb_IsReturned()
|
|
{
|
|
var registered = new[] { @"C:\repo\.worktrees\abc123" };
|
|
var db = new[] { @"C:\repo\.worktrees\def456" };
|
|
|
|
var untracked = UntrackedWorktreeRecovery.FindUntrackedPaths(registered, db);
|
|
|
|
Assert.Equal(registered, untracked);
|
|
}
|
|
|
|
[Fact]
|
|
public void FindUntrackedPaths_PathInDb_IsExcluded()
|
|
{
|
|
var registered = new[] { @"C:\repo\.worktrees\abc123" };
|
|
var db = new[] { @"C:\repo\.worktrees\abc123" };
|
|
|
|
var untracked = UntrackedWorktreeRecovery.FindUntrackedPaths(registered, db);
|
|
|
|
Assert.Empty(untracked);
|
|
}
|
|
|
|
[Fact]
|
|
public void FindUntrackedPaths_DifferentCasingAndSeparators_StillMatches()
|
|
{
|
|
var registered = new[] { @"C:\repo\.worktrees\abc123\" };
|
|
var db = new[] { "c:/repo/.worktrees/ABC123" };
|
|
|
|
var untracked = UntrackedWorktreeRecovery.FindUntrackedPaths(registered, db);
|
|
|
|
Assert.Empty(untracked);
|
|
}
|
|
|
|
[Fact]
|
|
public void FindUntrackedPaths_EmptyDb_ReturnsAllRegistered()
|
|
{
|
|
var registered = new[] { @"C:\repo\.worktrees\abc123", @"C:\repo\.worktrees\def456" };
|
|
|
|
var untracked = UntrackedWorktreeRecovery.FindUntrackedPaths(registered, Array.Empty<string>());
|
|
|
|
Assert.Equal(registered, untracked);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(@"C:\src\.claudedo-worktrees\lager-app\412-fix", @"C:\Users\x\.claudeDo\worktrees", true)]
|
|
[InlineData(@"C:\src\.claudedo-worktrees\planning\abc123", @"C:\Users\x\.claudeDo\worktrees", false)]
|
|
[InlineData(@"C:\Users\x\.claudeDo\worktrees\lager-app\412-fix", @"C:\Users\x\.claudeDo\worktrees", true)]
|
|
[InlineData(@"C:\Users\x\.claudeDo\worktrees\planning\abc123", @"C:\Users\x\.claudeDo\worktrees", false)]
|
|
[InlineData(@"C:\src\my-own-worktree", @"C:\Users\x\.claudeDo\worktrees", false)]
|
|
public void IsTaskWorktreePath(string path, string centralRoot, bool expected)
|
|
{
|
|
if (!OperatingSystem.IsWindows()) return;
|
|
Assert.Equal(expected, UntrackedWorktreeRecovery.IsTaskWorktreePath(path, centralRoot));
|
|
}
|
|
|
|
[Fact]
|
|
public async Task StartAsync_NoLists_DoesNotThrow()
|
|
{
|
|
var hubContext = new CapturingHubContext();
|
|
var sut = new UntrackedWorktreeRecovery(
|
|
_db.CreateFactory(),
|
|
new ClaudeDo.Data.Git.GitService(),
|
|
new HubBroadcaster(hubContext),
|
|
new ClaudeDo.Worker.Config.WorkerConfig(),
|
|
NullLogger<UntrackedWorktreeRecovery>.Instance);
|
|
|
|
await sut.StartAsync(CancellationToken.None);
|
|
await sut.StopAsync(CancellationToken.None);
|
|
|
|
Assert.Contains(hubContext.Proxy.Calls, c =>
|
|
c.Method == "OperationProgress" && (string)c.Args[0]! == "startup-recovery");
|
|
}
|
|
}
|