using ClaudeDo.Data; using ClaudeDo.Data.Models; using ClaudeDo.Ui.ViewModels.Islands; using Microsoft.EntityFrameworkCore; using TaskStatus = ClaudeDo.Data.Models.TaskStatus; namespace ClaudeDo.Ui.Tests.ViewModels; public class TasksIslandEmptyStateTests : IDisposable { private readonly string _dbPath; public TasksIslandEmptyStateTests() { _dbPath = Path.Combine(Path.GetTempPath(), $"claudedo_ui_emptystate_{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 sealed class TestDbFactory : IDbContextFactory { private readonly Func _create; public TestDbFactory(Func create) => _create = create; public ClaudeDoDbContext CreateDbContext() => _create(); } private async Task SeedListAsync(string listId, string title = "seed task") { await using var db = NewContext(); db.Lists.Add(new ListEntity { Id = listId, Name = "Work", CreatedAt = DateTime.UtcNow }); db.Tasks.Add(new TaskEntity { Id = Guid.NewGuid().ToString("N"), ListId = listId, Title = title, Status = TaskStatus.Idle, CreatedAt = DateTime.UtcNow, }); await db.SaveChangesAsync(); } private TasksIslandViewModel NewVm() => new(new TestDbFactory(NewContext), worker: null); [Fact] public async Task IsTasksEmptyHintVisible_true_for_empty_user_list_with_working_dir() { await using var db = NewContext(); db.Lists.Add(new ListEntity { Id = "L1", Name = "Work", CreatedAt = DateTime.UtcNow }); await db.SaveChangesAsync(); var vm = NewVm(); vm.LoadForList(new ListNavItemViewModel { Id = "user:L1", Name = "Work", Kind = ListKind.User, WorkingDir = "C:/repo" }); await vm.LoadTask!; Assert.True(vm.IsTasksEmptyHintVisible); Assert.False(vm.IsTasksEmptyRepoHintVisible); } [Fact] public async Task IsTasksEmptyRepoHintVisible_true_for_empty_user_list_without_working_dir() { await using var db = NewContext(); db.Lists.Add(new ListEntity { Id = "L2", Name = "Work", CreatedAt = DateTime.UtcNow }); await db.SaveChangesAsync(); var vm = NewVm(); vm.LoadForList(new ListNavItemViewModel { Id = "user:L2", Name = "Work", Kind = ListKind.User, WorkingDir = null }); await vm.LoadTask!; Assert.True(vm.IsTasksEmptyHintVisible); Assert.True(vm.IsTasksEmptyRepoHintVisible); } [Fact] public async Task IsTasksEmptyRepoHintVisible_false_for_empty_smart_list_without_working_dir() { var vm = NewVm(); vm.LoadForList(new ListNavItemViewModel { Id = "smart:important", Name = "Important", Kind = ListKind.Smart, WorkingDir = null }); await vm.LoadTask!; Assert.True(vm.IsTasksEmptyHintVisible); Assert.False(vm.IsTasksEmptyRepoHintVisible); } [Fact] public async Task IsTasksEmptyHintVisible_false_once_a_task_is_loaded() { await SeedListAsync("L3"); var vm = NewVm(); vm.LoadForList(new ListNavItemViewModel { Id = "user:L3", Name = "Work", Kind = ListKind.User, WorkingDir = null }); await vm.LoadTask!; Assert.False(vm.IsTasksEmptyHintVisible); Assert.False(vm.IsTasksEmptyRepoHintVisible); } }