using ClaudeDo.Data.Models; using ClaudeDo.Data.Repositories; using ClaudeDo.Worker.Hub; using ClaudeDo.Worker.Tests.Infrastructure; using Xunit; namespace ClaudeDo.Worker.Tests.Hub; public sealed class RepoImportFoldersHubTests : IDisposable { private readonly DbFixture _db = new(); public void Dispose() => _db.Dispose(); private WorkerHub CreateHub() { var broadcaster = new HubBroadcaster(new CapturingHubContext()); var hub = new WorkerHub( null!, null!, null!, null!, broadcaster, _db.CreateFactory(), null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, new ClaudeDo.Worker.Online.OnlineInboxConfig(), new ClaudeDo.Worker.Online.OnlineTokenStore(), new ClaudeDo.Worker.Runner.PendingQuestionRegistry(), null!); hub.Clients = new FakeHubCallerClients(new RecordingClientProxy()); hub.Context = new FakeHubCallerContext(); return hub; } [Fact] public async Task GetRepoImportFolders_NoRow_ReturnsEmptyList() { var hub = CreateHub(); var folders = await hub.GetRepoImportFolders(); Assert.Empty(folders); } [Fact] public async Task SetRepoImportFolders_then_GetRepoImportFolders_RoundTrips() { var hub = CreateHub(); await hub.SetRepoImportFolders(new List { @"C:\src\repo-a", @"C:\src\repo-b" }); var folders = await hub.GetRepoImportFolders(); Assert.Equal(new List { @"C:\src\repo-a", @"C:\src\repo-b" }, folders); } [Fact] public async Task SetRepoImportFolders_PersistsSameJsonShapeAsRepository() { var hub = CreateHub(); await hub.SetRepoImportFolders(new List { @"C:\src\repo-a" }); using var ctx = _db.CreateContext(); var viaRepository = await new AppSettingsRepository(ctx).GetRepoImportFoldersAsync(); Assert.Equal(new List { @"C:\src\repo-a" }, viaRepository); } [Fact] public async Task SetRepoImportFolders_DoesNotClearOtherAppSettings() { var hub = CreateHub(); var before = await hub.GetAppSettings(); await hub.SetRepoImportFolders(new List { @"C:\src\repo-a" }); var after = await hub.GetAppSettings(); Assert.Equal(before.DefaultModel, after.DefaultModel); Assert.Equal(before.DefaultMaxTurns, after.DefaultMaxTurns); } }