Pending UI work: - My Day add/remove context actions on task rows (parent removal cascades to children) - orphan-aware grouping: a child whose parent isn't in view renders as a top-level row, not an indented draft - shell menu restructure (Worker / Repositories submenus); 'Finalize plan' action, drop 'Queue subtasks sequentially' - notes editor refinements - subtask-row hover tweak (Surface3, no transition) - bump Avalonia 12.0.0 -> 12.0.4
96 lines
3.2 KiB
C#
96 lines
3.2 KiB
C#
using ClaudeDo.Ui.Services;
|
|
using ClaudeDo.Ui.Services.Interfaces;
|
|
using ClaudeDo.Ui.ViewModels.Islands;
|
|
|
|
namespace ClaudeDo.Ui.Tests.ViewModels;
|
|
|
|
public class NotesEditorViewModelTests
|
|
{
|
|
private sealed class FakeNotes : INotesApi
|
|
{
|
|
public readonly List<DailyNoteDto> Store = new();
|
|
private int _seq;
|
|
public Task<List<DailyNoteDto>> ListAsync(DateOnly day) =>
|
|
Task.FromResult(Store.Where(n => n.Date == day.ToString("yyyy-MM-dd")).ToList());
|
|
public Task<DailyNoteDto?> AddAsync(DateOnly day, string text)
|
|
{
|
|
var dto = new DailyNoteDto($"id{_seq++}", day.ToString("yyyy-MM-dd"), text, Store.Count);
|
|
Store.Add(dto);
|
|
return Task.FromResult<DailyNoteDto?>(dto);
|
|
}
|
|
public Task UpdateAsync(string id, string text)
|
|
{
|
|
var i = Store.FindIndex(n => n.Id == id);
|
|
if (i >= 0) Store[i] = Store[i] with { Text = text };
|
|
return Task.CompletedTask;
|
|
}
|
|
public Task DeleteAsync(string id) { Store.RemoveAll(n => n.Id == id); return Task.CompletedTask; }
|
|
}
|
|
|
|
[Fact]
|
|
public async Task AddBullet_PersistsAndAppears_ForCurrentDay()
|
|
{
|
|
var api = new FakeNotes();
|
|
var vm = new NotesEditorViewModel(api);
|
|
await vm.LoadDayAsync(new DateOnly(2026, 6, 1));
|
|
|
|
vm.NewBulletText = "Standup vorbereitet";
|
|
await vm.AddBulletCommand.ExecuteAsync(null);
|
|
|
|
Assert.Single(vm.Bullets);
|
|
Assert.Equal("Standup vorbereitet", vm.Bullets[0].Text);
|
|
Assert.Equal("", vm.NewBulletText);
|
|
Assert.Single(api.Store);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task PrevAndNextDay_NavigateAndReload()
|
|
{
|
|
var api = new FakeNotes();
|
|
await api.AddAsync(new DateOnly(2026, 5, 31), "gestern");
|
|
var vm = new NotesEditorViewModel(api);
|
|
await vm.LoadDayAsync(new DateOnly(2026, 6, 1));
|
|
Assert.Empty(vm.Bullets);
|
|
|
|
await vm.PrevDayCommand.ExecuteAsync(null);
|
|
Assert.Equal(new DateOnly(2026, 5, 31), vm.CurrentDay);
|
|
Assert.Single(vm.Bullets);
|
|
|
|
await vm.NextDayCommand.ExecuteAsync(null);
|
|
Assert.Equal(new DateOnly(2026, 6, 1), vm.CurrentDay);
|
|
Assert.Empty(vm.Bullets);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CommitBullet_EmptyText_RemovesFromStoreAndList()
|
|
{
|
|
var api = new FakeNotes();
|
|
var vm = new NotesEditorViewModel(api);
|
|
await vm.LoadDayAsync(new DateOnly(2026, 6, 1));
|
|
vm.NewBulletText = "weg damit";
|
|
await vm.AddBulletCommand.ExecuteAsync(null);
|
|
|
|
vm.Bullets[0].Text = " ";
|
|
await vm.CommitBulletCommand.ExecuteAsync(vm.Bullets[0]);
|
|
|
|
Assert.Empty(vm.Bullets);
|
|
Assert.Empty(api.Store);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CommitBullet_NonEmptyText_PersistsEdit()
|
|
{
|
|
var api = new FakeNotes();
|
|
var vm = new NotesEditorViewModel(api);
|
|
await vm.LoadDayAsync(new DateOnly(2026, 6, 1));
|
|
vm.NewBulletText = "original";
|
|
await vm.AddBulletCommand.ExecuteAsync(null);
|
|
|
|
vm.Bullets[0].Text = "geändert";
|
|
await vm.CommitBulletCommand.ExecuteAsync(vm.Bullets[0]);
|
|
|
|
Assert.Single(vm.Bullets);
|
|
Assert.Equal("geändert", api.Store[0].Text);
|
|
}
|
|
}
|