using ClaudeDo.Worker; using ClaudeDo.Worker.Config; using ClaudeDo.Worker.Hub; using ClaudeDo.Worker.Tests.Infrastructure; using ClaudeDo.Worker.Tickets; using Xunit; namespace ClaudeDo.Worker.Tests.Hub; public sealed class TicketFallbackHubTests : IDisposable { private readonly DbFixture _db = new(); private readonly string _patDir = Path.Combine(Path.GetTempPath(), "cdo-hubpat-" + Guid.NewGuid().ToString("N")); public void Dispose() { _db.Dispose(); try { Directory.Delete(_patDir, recursive: true); } catch { /* best effort */ } } private WorkerHub CreateHub() { var ticketConfig = new TicketSystemConfig( new WorkerConfig(), new TicketPatStore(new DpapiTokenStore(Path.Combine(_patDir, "ticket.pat")))); var hub = new WorkerHub( null!, null!, null!, null!, new HubBroadcaster(new CapturingHubContext()), _db.CreateFactory(), null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, new ClaudeDo.Worker.Online.OnlineInboxConfig(), new ClaudeDo.Worker.OnlineRefreshTokenStore(new DpapiTokenStore("unused.token")), new ClaudeDo.Worker.Runner.PendingQuestionRegistry(), null!, ticketConfig: ticketConfig); hub.Clients = new FakeHubCallerClients(new RecordingClientProxy()); hub.Context = new FakeHubCallerContext(); return hub; } [Fact] public async Task Fallback_list_set_through_the_hub_comes_back_in_the_ticket_settings() { var hub = CreateHub(); await hub.SetTicketFallbackList("l-fallback"); var dto = await hub.GetTicketSettings(); Assert.Equal("l-fallback", dto.FallbackListId); Assert.False(dto.TokenSet); await hub.SetTicketFallbackList(null); Assert.Null((await hub.GetTicketSettings()).FallbackListId); } }