using ClaudeDo.Ui.Services; using ClaudeDo.Ui.ViewModels.Modals.Settings; namespace ClaudeDo.Ui.Tests.ViewModels; public class PrimeClaudeTabViewModelTests { private sealed class FakeApi : IPrimeScheduleApi { public List Stored { get; } = new(); public List Upserts { get; } = new(); public List Deletes { get; } = new(); public Task> ListAsync() => Task.FromResult(Stored.ToList()); public Task UpsertAsync(PrimeScheduleDto dto) { Upserts.Add(dto); return Task.FromResult(dto); } public Task DeleteAsync(Guid id) { Deletes.Add(id); return Task.CompletedTask; } } private static PrimeScheduleDto Dto(Guid id, int days, TimeSpan time) => new(id, days, time, true, null, null); [Fact] public async Task Load_Populates_Rows() { var api = new FakeApi(); api.Stored.Add(Dto(Guid.NewGuid(), 31, new TimeSpan(7, 0, 0))); var vm = new PrimeClaudeTabViewModel(api); await vm.LoadAsync(); Assert.Single(vm.Rows); } [Fact] public void AddSchedule_Appends_Row_With_Defaults() { var vm = new PrimeClaudeTabViewModel(new FakeApi()); vm.AddScheduleCommand.Execute(null); Assert.Single(vm.Rows); Assert.True(vm.Rows[0].Enabled); Assert.True(vm.Rows[0].Monday); Assert.True(vm.Rows[0].Friday); Assert.False(vm.Rows[0].Saturday); Assert.Equal(new TimeSpan(7, 0, 0), vm.Rows[0].TimeOfDay); } [Fact] public void Row_Decomposes_And_Recomposes_Days() { var vm = new PrimeClaudeTabViewModel(new FakeApi()); vm.AddScheduleCommand.Execute(null); var row = vm.Rows[0]; Assert.Equal(31, row.DaysMask()); row.Saturday = true; Assert.Equal(63, row.DaysMask()); } [Fact] public async Task Save_Diffs_New_And_Removed_Rows() { var api = new FakeApi(); var keptId = Guid.NewGuid(); var deletedId = Guid.NewGuid(); api.Stored.Add(Dto(keptId, 31, new TimeSpan(7, 0, 0))); api.Stored.Add(Dto(deletedId, 31, new TimeSpan(8, 0, 0))); var vm = new PrimeClaudeTabViewModel(api); await vm.LoadAsync(); vm.RemoveScheduleCommand.Execute(vm.Rows.Single(r => r.Id == deletedId)); vm.AddScheduleCommand.Execute(null); await vm.SaveAsync(); Assert.Contains(deletedId, api.Deletes); Assert.Equal(2, api.Upserts.Count); } [Fact] public void Validate_Reports_No_Days_Selected() { var vm = new PrimeClaudeTabViewModel(new FakeApi()); vm.AddScheduleCommand.Execute(null); var row = vm.Rows[0]; row.Monday = row.Tuesday = row.Wednesday = row.Thursday = row.Friday = false; Assert.NotNull(vm.Validate()); } [Fact] public void Validate_Passes_With_One_Day() { var vm = new PrimeClaudeTabViewModel(new FakeApi()); vm.AddScheduleCommand.Execute(null); Assert.Null(vm.Validate()); } }