using Bunit; using Microsoft.AspNetCore.Components; using ZB.MOM.WW.ScadaBridge.CentralUI.Components.Shared; namespace ZB.MOM.WW.ScadaBridge.CentralUI.Tests.Shared; /// /// bUnit tests for the reusable pagination bar (T35a). /// The component is purely presentational — it emits PageChanged callbacks /// and renders disabled states; the host page owns page-number and query state. /// public class OffsetPagerTests : BunitContext { // ── PrevDisabled_OnFirstPage ────────────────────────────────────────────── /// Verifies that the previous button is disabled on the first page. [Fact] public void PrevDisabled_OnFirstPage() { var cut = Render(ps => ps .Add(p => p.Page, 1) .Add(p => p.HasNextPage, true)); var prev = cut.Find("[data-test='pager-prev']"); Assert.NotNull(prev.GetAttribute("disabled")); } // ── NextDisabled_WhenNoNextPage ─────────────────────────────────────────── /// Verifies that the next button is disabled when there is no next page. [Fact] public void NextDisabled_WhenNoNextPage() { var cut = Render(ps => ps .Add(p => p.Page, 3) .Add(p => p.HasNextPage, false)); var next = cut.Find("[data-test='pager-next']"); Assert.NotNull(next.GetAttribute("disabled")); } // ── Next_Click_EmitsPagePlusOne ─────────────────────────────────────────── /// Verifies that clicking next emits the current page plus one. [Fact] public void Next_Click_EmitsPagePlusOne() { int? emitted = null; var cut = Render(ps => ps .Add(p => p.Page, 2) .Add(p => p.HasNextPage, true) .Add(p => p.PageChanged, EventCallback.Factory.Create(this, v => emitted = v))); cut.Find("[data-test='pager-next']").Click(); Assert.Equal(3, emitted); } // ── Prev_Click_EmitsPageMinusOne ───────────────────────────────────────── /// Verifies that clicking previous emits the current page minus one. [Fact] public void Prev_Click_EmitsPageMinusOne() { int? emitted = null; var cut = Render(ps => ps .Add(p => p.Page, 2) .Add(p => p.HasNextPage, false) .Add(p => p.PageChanged, EventCallback.Factory.Create(this, v => emitted = v))); cut.Find("[data-test='pager-prev']").Click(); Assert.Equal(1, emitted); } // ── Summary_RendersPageOfTotal ──────────────────────────────────────────── /// Verifies that the summary renders the current page out of the total. [Fact] public void Summary_RendersPageOfTotal() { var cut = Render(ps => ps .Add(p => p.Page, 2) .Add(p => p.PageSize, 50) .Add(p => p.TotalCount, 230) .Add(p => p.HasNextPage, true)); var summary = cut.Find("[data-test='pager-summary']"); Assert.Contains("Page 2 of 5", summary.TextContent); Assert.Contains("230 total", summary.TextContent); } // ── HideWhenSinglePage_HidesBar_OnSinglePage ────────────────────────────── /// Verifies that hide-when-single-page hides the bar when there is only one page. [Fact] public void HideWhenSinglePage_HidesBar_OnSinglePage() { var cut = Render(ps => ps .Add(p => p.Page, 1) .Add(p => p.PageSize, 50) .Add(p => p.TotalCount, 12) .Add(p => p.HasNextPage, false) .Add(p => p.HideWhenSinglePage, true)); Assert.Empty(cut.FindAll("[data-test='pager-prev']")); Assert.Empty(cut.FindAll("[data-test='pager-next']")); Assert.Empty(cut.FindAll("[data-test='pager-summary']")); } // ── HideWhenSinglePage_HidesBar_OnEmptyResult ───────────────────────────── /// Verifies that hide-when-single-page hides the bar when the result is empty. [Fact] public void HideWhenSinglePage_HidesBar_OnEmptyResult() { var cut = Render(ps => ps .Add(p => p.Page, 1) .Add(p => p.PageSize, 50) .Add(p => p.TotalCount, 0) .Add(p => p.HasNextPage, false) .Add(p => p.HideWhenSinglePage, true)); Assert.Empty(cut.FindAll("[data-test='pager-summary']")); } // ── HideWhenSinglePage_ShowsBar_WhenMultiplePages ───────────────────────── /// Verifies that hide-when-single-page shows the bar when there are multiple pages. [Fact] public void HideWhenSinglePage_ShowsBar_WhenMultiplePages() { var cut = Render(ps => ps .Add(p => p.Page, 1) .Add(p => p.PageSize, 50) .Add(p => p.TotalCount, 120) .Add(p => p.HasNextPage, true) .Add(p => p.HideWhenSinglePage, true)); Assert.Contains("Page 1 of 3", cut.Find("[data-test='pager-summary']").TextContent); } // ── HideWhenSinglePage_ShowsBar_WhenTotalCountUnknown ───────────────────── // TotalCount is null (the host cannot count), so single-page-ness is not // provable — the bar must stay so the user can still reach a further page. /// Verifies that hide-when-single-page shows the bar when the total count is unknown. [Fact] public void HideWhenSinglePage_ShowsBar_WhenTotalCountUnknown() { var cut = Render(ps => ps .Add(p => p.Page, 1) .Add(p => p.PageSize, 50) .Add(p => p.HasNextPage, false) .Add(p => p.HideWhenSinglePage, true)); Assert.NotNull(cut.Find("[data-test='pager-summary']")); } // ── HideWhenSinglePage_Off_KeepsBarVisible_OnSinglePage ─────────────────── // Default (opt-out) behaviour: consumers that use the summary as their only // "N total" readout keep the bar on a single page. /// Verifies that with hide-when-single-page off the bar stays visible on a single page. [Fact] public void HideWhenSinglePage_Off_KeepsBarVisible_OnSinglePage() { var cut = Render(ps => ps .Add(p => p.Page, 1) .Add(p => p.PageSize, 50) .Add(p => p.TotalCount, 3) .Add(p => p.HasNextPage, false)); Assert.Contains("3 total", cut.Find("[data-test='pager-summary']").TextContent); } // ── BothDisabled_WhenDisabled ───────────────────────────────────────────── /// Verifies that both navigation buttons are disabled when the pager is disabled. [Fact] public void BothDisabled_WhenDisabled() { var cut = Render(ps => ps .Add(p => p.Page, 3) .Add(p => p.HasNextPage, true) .Add(p => p.Disabled, true)); var prev = cut.Find("[data-test='pager-prev']"); var next = cut.Find("[data-test='pager-next']"); Assert.NotNull(prev.GetAttribute("disabled")); Assert.NotNull(next.GetAttribute("disabled")); } }