fix(ui): refine amount entry, date warnings and booking actions
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
using Bunit;
|
||||
using Duempelkas.App.Components;
|
||||
using Xunit;
|
||||
|
||||
namespace Duempelkas.Tests;
|
||||
|
||||
public class BookingDateInputTests
|
||||
{
|
||||
[Fact]
|
||||
public void DateIsValidatedOnLeavingField_WithoutInterruptingNativeCalendar()
|
||||
{
|
||||
using var context = new BunitContext();
|
||||
var value = "2025-12-31";
|
||||
var field = context.Render<BookingDateInput>(p => p
|
||||
.Add(x => x.Value, value).Add(x => x.ValueChanged, next => value = next));
|
||||
field.Find("input").Input("2026-01-01");
|
||||
Assert.Equal("2025-12-31", value);
|
||||
field.Find("input").Blur();
|
||||
Assert.Equal("2026-01-01", value);
|
||||
field.Render(p => p.Add(x => x.Value, value));
|
||||
// The browser owns the edited value; avoid resetting its calendar by writing it back.
|
||||
Assert.Equal("2025-12-31", field.Find("input").GetAttribute("value"));
|
||||
field.Render(p => p.Add(x => x.Value, "2027-02-03"));
|
||||
Assert.Equal("2027-02-03", field.Find("input").GetAttribute("value"));
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,26 @@ namespace Duempelkas.Tests;
|
||||
|
||||
public class BookingFormTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task PendingDate_IsProtectedOnCancel_AndValidatedBeforeSubmit()
|
||||
{
|
||||
using var f = new LedgerUiFixture();
|
||||
var dialog = f.Context.Render<AddEntryDialog>(p => p.Add(x => x.AccountId, 1).Add(x => x.ContextYear, DateTime.Today.Year));
|
||||
dialog.Find("#entry-date").Input($"{DateTime.Today.Year + 1}-01-02");
|
||||
Assert.Empty(dialog.FindAll(".booking-year-warning"));
|
||||
var modal = dialog.FindComponent<ModalDialog>();
|
||||
await modal.InvokeAsync(() => modal.Instance.RequestCloseAsync());
|
||||
Assert.NotEmpty(dialog.FindAll("[role=alertdialog]"));
|
||||
dialog.Find("[data-discard-continue]").Click();
|
||||
dialog.Find("#entry-title").Input("Pending date");
|
||||
dialog.Find("#entry-amount").Input("12,50");
|
||||
// A keyboard submit can happen without the date field losing focus first.
|
||||
dialog.Find("form").Submit();
|
||||
Assert.NotEmpty(dialog.FindAll(".booking-year-warning"));
|
||||
Assert.True(dialog.Find("button.btn-success").HasAttribute("disabled"));
|
||||
Assert.Empty(await f.Service<IEntryService>().GetEntriesAsync(1, (int?)null));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Form_ExplainsMissingFields_AndDoesNotRoundInvalidInput()
|
||||
{
|
||||
@@ -31,9 +51,11 @@ public class BookingFormTests
|
||||
dialog.Find("#entry-amount").Input("12,50");
|
||||
Assert.False(dialog.Find("button.btn-success").HasAttribute("disabled"));
|
||||
dialog.Find("#entry-date").Input("");
|
||||
dialog.Find("#entry-date").Blur();
|
||||
Assert.True(dialog.Find("button.btn-success").HasAttribute("disabled"));
|
||||
Assert.Contains("Bitte ein gültiges Datum", dialog.Markup);
|
||||
dialog.Find("#entry-date").Input("2026-01-02");
|
||||
dialog.Find("#entry-date").Blur();
|
||||
Assert.False(dialog.Find("button.btn-success").HasAttribute("disabled"));
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ public class EntryLifecycleUiTests
|
||||
await entries.CreateTransferAsync(1, 2, DateTime.Today, "Testtransfer", 20m);
|
||||
var page = f.Context.Render<Routes>();
|
||||
page.WaitForElement(".account-card").Click();
|
||||
page.WaitForElement(".entry-action-menu");
|
||||
page.WaitForElement(".entry-action-buttons");
|
||||
page.Find("button.btn-outline-danger").Click();
|
||||
page.WaitForAssertion(() => Assert.Contains("beiden Konten", page.Markup));
|
||||
Assert.Contains("Barkasse", page.Find("dialog").TextContent);
|
||||
|
||||
@@ -18,14 +18,17 @@ public class EntryPresentationTests
|
||||
Assert.DoesNotContain("emptyEntriesMessage", page.Markup);
|
||||
}
|
||||
[Fact]
|
||||
public void Actions_HaveVisibleTextAndBookingSpecificNames()
|
||||
public void Actions_AreDirectIconButtonsWithTitlesAndBookingSpecificNames()
|
||||
{
|
||||
using var context = new BunitContext();
|
||||
var entry = new EntryDto(1, 1, "2026-001", EntryType.Expense, DateTime.Today, "Porto", 4.20m, false, false, null, null, null);
|
||||
var edited = 0;
|
||||
var table = context.Render<EntryTable>(p => p.Add(x => x.Entries, [entry]).Add(x => x.OnEditEntry, id => edited = id));
|
||||
Assert.Contains("2026-001 Porto", table.Find("summary").GetAttribute("aria-label"));
|
||||
var edit = table.FindAll("button").Single(b => b.TextContent.Contains("Bearbeiten"));
|
||||
Assert.Empty(table.FindAll("summary"));
|
||||
var edit = table.Find("button[title='Buchung bearbeiten']");
|
||||
Assert.Contains("2026-001 Porto", edit.GetAttribute("aria-label"));
|
||||
Assert.NotNull(edit.QuerySelector(".bi-pencil[aria-hidden=true]"));
|
||||
Assert.NotNull(table.Find("button.btn-outline-danger .bi-trash"));
|
||||
Assert.Contains("Porto", edit.GetAttribute("aria-label"));
|
||||
edit.Click();
|
||||
Assert.Equal(1, edited);
|
||||
|
||||
@@ -36,7 +36,7 @@ public class ToastTests
|
||||
var control = context.Render<AmountInput>(p => p.Add(x => x.Value, amount).Add(x => x.ValueChanged, value => amount = value));
|
||||
control.Find("input").Input("12,501");
|
||||
Assert.Equal("12,50", amount);
|
||||
Assert.Contains("nicht übernommen", control.Markup);
|
||||
Assert.Empty(control.FindAll("[role=status]"));
|
||||
control.Find("input").Input("12.25");
|
||||
Assert.Equal("12.25", amount);
|
||||
}
|
||||
|
||||
@@ -43,9 +43,11 @@ public class YearNavigationTests
|
||||
page.FindAll("button").Single(b => b.TextContent.Contains("Einnahme oder Ausgabe erfassen")).Click();
|
||||
var dialog = page.FindComponent<AddEntryDialog>();
|
||||
dialog.Find("input[type=date]").Input("2026-01-02");
|
||||
dialog.Find("input[type=date]").Blur();
|
||||
dialog.Find("#entry-title").Input("Außerhalb");
|
||||
dialog.Find("#entry-amount").Input("12.50");
|
||||
Assert.Contains("außerhalb", dialog.Markup);
|
||||
Assert.NotNull(dialog.Find(".booking-year-warning[role=status] .bi-exclamation-triangle-fill"));
|
||||
Assert.True(dialog.Find("button.btn-success").HasAttribute("disabled"));
|
||||
dialog.Find("input[type=checkbox]").Change(true);
|
||||
dialog.Find("form").Submit();
|
||||
|
||||
Reference in New Issue
Block a user