using Bunit; using Duempelkas.App.Components.Dialogs; using Duempelkas.App.Services; using Duempelkas.Domain.Enums; using Xunit; namespace Duempelkas.Tests; public class CarryoverCorrectionTests { [Fact] public async Task Correction_ShiftsAllYearsByDelta_AndRejectsStaleState() { using var f = new LedgerUiFixture(); var accounts = f.Service(); var entries = f.Service(); var balances = f.Service(); await entries.CreateEntryAsync(1, EntryType.Income, new(2025, 1, 1), "Alt", 10m); await entries.CreateEntryAsync(1, EntryType.Expense, new(2026, 1, 1), "Neu", 5m); await accounts.CorrectCarryoverAsync(1, 120m, 2026, 110m, 100m); Assert.Equal(110m, (await accounts.GetAccountAsync(1)).CarryoverBalance); Assert.Equal(120m, (await balances.GetAccountBalanceAsync(1, 2025)).TotalBalance); Assert.Equal(115m, (await balances.GetAccountBalanceAsync(1, 2026)).TotalBalance); Assert.Equal(115m, (await balances.GetAccountBalanceAsync(1, 2027)).TotalBalance); Assert.Equal(2, (await entries.GetEntriesAsync(1, (int?)null)).Count); await Assert.ThrowsAsync(() => accounts.CorrectCarryoverAsync(1, 130m, 2026, 110m, 100m)); var newAccount = await accounts.CreateAccountAsync("Neues Konto", -20m); Assert.Equal(-20m, newAccount.TotalBalance); Assert.Empty(await entries.GetEntriesAsync(newAccount.Id, (int?)null)); } [Fact] public void CorrectionForm_ShowsBeforeAfter_AndRequiresAcknowledgement() { using var f = new LedgerUiFixture(); var saved = 0m; var dialog = f.Context.Render(p => p.Add(x => x.CurrentAmount, 110m) .Add(x => x.InitialBalance, 100m).Add(x => x.Year, 2026).Add(x => x.AccountName, "Barkasse") .Add(x => x.OnSave, value => saved = value)); Assert.Equal("110,00", dialog.Find("#carryover").GetAttribute("value")); dialog.Find("#carryover").Input("120,00"); Assert.Equal("120,00", dialog.Find("#carryover").GetAttribute("value")); Assert.Contains("frühere und spätere Jahre", dialog.Markup); Assert.Contains("110,00", dialog.Find(".correction-preview").TextContent); Assert.True(dialog.Find("button.btn-success").HasAttribute("disabled")); dialog.Find("input[type=checkbox]").Change(true); dialog.Find("button.btn-success").Click(); Assert.Equal(120m, saved); } }