using ClaudeDo.Data; using ClaudeDo.Ui.Services; using ClaudeDo.Ui.ViewModels.Islands; using Microsoft.EntityFrameworkCore; using TaskStatus = ClaudeDo.Data.Models.TaskStatus; namespace ClaudeDo.Ui.Tests.ViewModels; // Usability-Audit 2026-09-10: the detail pane showed nothing when a task was blocked on a // predecessor -- the header bar now renders a "Waiting on #N" line bound straight to the same // Task.IsWaiting/DependencyWaitLabel TasksIslandViewModel already computes (no new VM logic here). public class DetailsIslandDependencyWaitTests : IDisposable { private readonly string _dbPath; public DetailsIslandDependencyWaitTests() { _dbPath = Path.Combine(Path.GetTempPath(), $"claudedo_dep_wait_test_{Guid.NewGuid():N}.db"); using var ctx = NewContext(); ctx.Database.EnsureCreated(); } public void Dispose() { try { File.Delete(_dbPath); } catch { } try { File.Delete(_dbPath + "-wal"); } catch { } try { File.Delete(_dbPath + "-shm"); } catch { } } private ClaudeDoDbContext NewContext() { var opts = new DbContextOptionsBuilder() .UseSqlite($"Data Source={_dbPath}") .Options; return new ClaudeDoDbContext(opts); } private DetailsIslandViewModel NewVm() { var factory = new TestDbFactory(NewContext); return new DetailsIslandViewModel(factory, new DefaultStub(), new NullServiceProvider(), new ClaudeDo.Ui.Services.MergeCoordinator()); } [Fact] public void UnblockedTask_HasNoWaitingLine() { var vm = NewVm(); vm.Bind(new TaskRowViewModel { Id = Guid.NewGuid().ToString("N"), Number = 1, Status = TaskStatus.Queued }); Assert.False(vm.Task!.IsWaiting); Assert.Null(vm.Task.DependencyWaitLabel); } [Fact] public void BlockedTask_ExposesWaitingLineViaBoundRow() { var vm = NewVm(); var row = new TaskRowViewModel { Id = Guid.NewGuid().ToString("N"), Number = 2, Status = TaskStatus.Queued, IsBlockedByDependency = true, DependencyWaitLabel = "#42", }; vm.Bind(row); Assert.True(vm.Task!.IsWaiting); Assert.Equal("#42", vm.Task.DependencyWaitLabel); } }