Files
ScadaBridge/tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests/Shared/DataTablePagerTests.cs
T

105 lines
4.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Bunit;
using Microsoft.AspNetCore.Components;
using ZB.MOM.WW.ScadaBridge.CentralUI.Components.Shared;
namespace ZB.MOM.WW.ScadaBridge.CentralUI.Tests.Shared;
/// <summary>
/// Regression tests for the <c>DataTable</c> pager, which looped
/// <c>for i = 1..totalPages</c> and emitted one numbered <c>&lt;li&gt;</c>
/// button per page; a few thousand records at page size 25 rendered hundreds
/// of buttons into the diff on every state change. The fix windows the pager
/// so only first / last / a small range around the current page render.
/// </summary>
public class DataTablePagerTests : BunitContext
{
private IRenderedComponent<DataTable<int>> RenderTable(int itemCount, int pageSize = 25)
{
return Render<DataTable<int>>(parameters => parameters
.Add(p => p.Items, Enumerable.Range(1, itemCount).ToList())
.Add(p => p.PageSize, pageSize)
.Add(p => p.ShowSearch, false)
.Add(p => p.HeaderContent, (RenderFragment)(b => b.AddMarkupContent(0, "<th>N</th>")))
.Add(p => p.RowContent, (RenderFragment<int>)(item => b => b.AddMarkupContent(0, $"<tr><td>{item}</td></tr>"))));
}
/// <summary>True empty results show no contradictory one-to-zero range.</summary>
[Fact]
public void EmptyTable_ShowsZeroItems()
{
var cut = RenderTable(0);
Assert.Equal("0 items", cut.Find(".text-muted.small").TextContent.Trim());
}
/// <summary>Filtering to zero and clearing preserves the correct range and paging state.</summary>
[Fact]
public void FilterToEmpty_ThenClear_RestoresRealCount()
{
var cut = RenderTable(60);
cut.Render(p => p.Add(c => c.ShowSearch, true).Add(c => c.SearchFilter, (item, search) => item.ToString().Contains(search)));
cut.Find("input").Input("no-match");
Assert.Equal("0 items", cut.Find(".text-muted.small").TextContent.Trim());
cut.Find("button[aria-label='Clear search']").Click();
Assert.Contains("1–25 of 60 items", cut.Find(".text-muted.small").TextContent);
}
/// <summary>The reusable table has one named keyboard-accessible overflow region.</summary>
[Fact]
public void Table_HasNamedKeyboardScrollRegion()
{
var cut = RenderTable(4);
var region = cut.Find("[role=region]");
Assert.Equal("Data table", region.GetAttribute("aria-label"));
Assert.Equal("0", region.GetAttribute("tabindex"));
Assert.Single(region.QuerySelectorAll("table"));
cut.Render(p => p.Add(c => c.TableLabel, "Synthetic records"));
Assert.Equal("Synthetic records", cut.Find("[role=region]").GetAttribute("aria-label"));
}
private static int NumberedPageButtons(IRenderedComponent<DataTable<int>> cut)
=> cut.FindAll("ul.pagination li.page-item button")
.Count(b => int.TryParse(b.TextContent.Trim(), out _));
/// <summary>Verifies that a pager with thousands of pages renders a window of buttons rather than every page.</summary>
[Fact]
public void Pager_WithThousandsOfPages_RendersWindowedNotEveryPage()
{
// 5000 items / 25 = 200 pages. The pre-fix pager rendered 200 numbered
// buttons; the windowed pager renders at most a dozen.
var cut = RenderTable(itemCount: 5000);
var numbered = NumberedPageButtons(cut);
Assert.True(numbered <= 12,
$"Expected a windowed pager (<= 12 numbered buttons) but rendered {numbered}.");
}
/// <summary>Verifies that a pager over a small dataset still renders a button for every page.</summary>
[Fact]
public void Pager_SmallDataset_StillRendersEveryPage()
{
// 5 pages — small enough to render all numbered buttons (no windowing harm).
var cut = RenderTable(itemCount: 125);
var numbered = NumberedPageButtons(cut);
Assert.Equal(5, numbered);
}
/// <summary>Verifies that the windowed pager always includes the first and last pages around the current page.</summary>
[Fact]
public void Pager_WindowedAroundCurrentPage_AlwaysIncludesFirstAndLast()
{
var cut = RenderTable(itemCount: 5000); // 200 pages
var numbered = cut.FindAll("ul.pagination li.page-item button")
.Select(b => b.TextContent.Trim())
.Where(t => int.TryParse(t, out _))
.ToList();
// First and last page are always reachable from the windowed pager.
Assert.Contains("1", numbered);
Assert.Contains("200", numbered);
}
}