using ClaudeDo.Ui.ViewModels; using Xunit; namespace ClaudeDo.Ui.Tests; // Covers C2: the six Lifecycle/*Recovery startup sweeps broadcast OperationProgress under the // stable "startup-recovery" opKey; the shell replaces the generic "connecting" text with it // while the worker is reconnecting. public class IslandsShellViewModelStartupRecoveryTests { private sealed class ReconnectingWorkerClient : StubWorkerClient { public override bool IsReconnecting => true; } [Fact] public void StartupRecoveryProgress_ReplacesConnectingText() { var vm = new IslandsShellViewModel(); var worker = new ReconnectingWorkerClient(); vm.Worker = worker; worker.OperationProgressEvent += vm.OnOperationProgress; worker.RaiseOperationProgress("startup-recovery", "attachments", 3, 6); Assert.Contains("3/6", vm.ConnectionText); } [Fact] public void StartupRecoveryProgress_WithoutTotal_ShowsLabelOnly() { var vm = new IslandsShellViewModel(); var worker = new ReconnectingWorkerClient(); vm.Worker = worker; worker.OperationProgressEvent += vm.OnOperationProgress; worker.RaiseOperationProgress("startup-recovery", "stale-tasks", 0, 0); Assert.DoesNotContain("/", vm.ConnectionText); Assert.NotEqual(string.Empty, vm.ConnectionText); } [Fact] public void ForeignOpKey_DoesNotChangeConnectionText() { var vm = new IslandsShellViewModel(); var worker = new ReconnectingWorkerClient(); vm.Worker = worker; worker.OperationProgressEvent += vm.OnOperationProgress; var before = vm.ConnectionText; worker.RaiseOperationProgress("merge:task-123", "merging", 0, 0); Assert.Equal(before, vm.ConnectionText); } }