using Bunit; using Bunit.TestDoubles; using Microsoft.AspNetCore.Components; using Microsoft.Extensions.DependencyInjection; using ZB.MOM.WW.ScadaBridge.CentralUI.Components.Health; using ZB.MOM.WW.ScadaBridge.Commons.Messages.Audit; namespace ZB.MOM.WW.ScadaBridge.CentralUI.Tests.Components.Health; /// /// bUnit tests for . /// The component renders three Bootstrap-card tiles — Buffered, Stuck, Parked — /// from a single snapshot. The tests pin: /// /// /// Three-tile render contract (data-test attributes for stable selectors). /// Tile values render the snapshot's counters. /// Threshold borders fire correctly — danger on Parked > 0, warning /// on Stuck > 0, none when those counts are zero, none on Buffered. /// Unavailable snapshot renders em dashes plus the error message. /// Tile clicks navigate to the correct pre-filtered Site Calls report URL. /// /// public class SiteCallKpiTilesTests : BunitContext { private static SiteCallKpiResponse MakeSnapshot(int buffered, int parked, int stuck) => new( CorrelationId: "k", Success: true, ErrorMessage: null, BufferedCount: buffered, ParkedCount: parked, FailedLastInterval: 0, DeliveredLastInterval: 0, OldestPendingAge: null, StuckCount: stuck); /// Verifies that the component renders three tiles from a snapshot. [Fact] public void Renders_ThreeTiles_FromSnapshot() { var cut = Render(p => p .Add(c => c.Snapshot, MakeSnapshot(buffered: 120, parked: 3, stuck: 7)) .Add(c => c.IsAvailable, true)); // Three stable data-test selectors — the contract for both these tests // and any future Playwright sweep. Assert.Contains("data-test=\"site-call-kpi-buffered\"", cut.Markup); Assert.Contains("data-test=\"site-call-kpi-stuck\"", cut.Markup); Assert.Contains("data-test=\"site-call-kpi-parked\"", cut.Markup); // Tile values render the snapshot's counters. Assert.Contains(">120<", cut.Markup); // buffered Assert.Contains(">7<", cut.Markup); // stuck Assert.Contains(">3<", cut.Markup); // parked } /// Verifies that an unavailable snapshot renders em dashes and the error message. [Fact] public void UnavailableSnapshot_RendersEmDashes_AndErrorMessage() { var cut = Render(p => p .Add(c => c.Snapshot, (SiteCallKpiResponse?)null) .Add(c => c.IsAvailable, false) .Add(c => c.ErrorMessage, "site call repository unavailable")); // All three tiles show em dashes — em dash (U+2014) "—" must appear. Assert.Contains("—", cut.Markup); // Inline error message renders below. Assert.Contains("Site Call KPIs unavailable", cut.Markup); Assert.Contains("site call repository unavailable", cut.Markup); } /// Verifies that the parked tile gets a danger border when the parked count is above zero. [Fact] public void ParkedTile_GetsDangerBorder_WhenParkedAboveZero() { var cut = Render(p => p .Add(c => c.Snapshot, MakeSnapshot(buffered: 0, parked: 4, stuck: 0)) .Add(c => c.IsAvailable, true)); var tile = cut.Find("[data-test=\"site-call-kpi-parked\"]"); Assert.Contains("border-danger", tile.GetAttribute("class") ?? string.Empty); } /// Verifies that the parked tile has no danger border when the parked count is zero. [Fact] public void ParkedTile_NoDangerBorder_WhenParkedZero() { var cut = Render(p => p .Add(c => c.Snapshot, MakeSnapshot(buffered: 9, parked: 0, stuck: 0)) .Add(c => c.IsAvailable, true)); var tile = cut.Find("[data-test=\"site-call-kpi-parked\"]"); Assert.DoesNotContain("border-danger", tile.GetAttribute("class") ?? string.Empty); } /// Verifies that the stuck tile gets a warning border when the stuck count is above zero. [Fact] public void StuckTile_GetsWarningBorder_WhenStuckAboveZero() { var cut = Render(p => p .Add(c => c.Snapshot, MakeSnapshot(buffered: 0, parked: 0, stuck: 6)) .Add(c => c.IsAvailable, true)); var tile = cut.Find("[data-test=\"site-call-kpi-stuck\"]"); Assert.Contains("border-warning", tile.GetAttribute("class") ?? string.Empty); // Warning, not danger — Stuck is the softer signal. Assert.DoesNotContain("border-danger", tile.GetAttribute("class") ?? string.Empty); } /// Verifies that the stuck tile has no warning border when the stuck count is zero. [Fact] public void StuckTile_NoWarningBorder_WhenStuckZero() { var cut = Render(p => p .Add(c => c.Snapshot, MakeSnapshot(buffered: 9, parked: 0, stuck: 0)) .Add(c => c.IsAvailable, true)); var tile = cut.Find("[data-test=\"site-call-kpi-stuck\"]"); Assert.DoesNotContain("border-warning", tile.GetAttribute("class") ?? string.Empty); } /// Verifies that the buffered tile never gets a threshold border, even with a high count. [Fact] public void BufferedTile_HasNoThresholdBorder_EvenWithHighCount() { // A non-zero buffer is normal operation — the Buffered tile is a plain // count tile and never gets a danger/warning border. var cut = Render(p => p .Add(c => c.Snapshot, MakeSnapshot(buffered: 5000, parked: 0, stuck: 0)) .Add(c => c.IsAvailable, true)); var tile = cut.Find("[data-test=\"site-call-kpi-buffered\"]"); var cls = tile.GetAttribute("class") ?? string.Empty; Assert.DoesNotContain("border-danger", cls); Assert.DoesNotContain("border-warning", cls); } /// Verifies that clicking the buffered tile navigates to the unfiltered site calls report. [Fact] public void BufferedTile_Click_NavigatesToUnfilteredSiteCallsReport() { var cut = Render(p => p .Add(c => c.Snapshot, MakeSnapshot(buffered: 50, parked: 0, stuck: 0)) .Add(c => c.IsAvailable, true)); var nav = (BunitNavigationManager)Services.GetRequiredService(); var tile = cut.Find("[data-test=\"site-call-kpi-buffered\"]"); tile.Click(); // Unfiltered /site-calls/report — no query string. Assert.EndsWith("/site-calls/report", nav.Uri); } /// Verifies that clicking the stuck tile navigates to the site calls report with the stuck filter. [Fact] public void StuckTile_Click_NavigatesToSiteCallsReport_WithStuckFilter() { var cut = Render(p => p .Add(c => c.Snapshot, MakeSnapshot(buffered: 0, parked: 0, stuck: 6)) .Add(c => c.IsAvailable, true)); var nav = (BunitNavigationManager)Services.GetRequiredService(); var tile = cut.Find("[data-test=\"site-call-kpi-stuck\"]"); tile.Click(); // Spec: Stuck tile drills into the report's "stuck only" filter. Assert.Contains("/site-calls/report?stuck=true", nav.Uri); } /// Verifies that clicking the parked tile navigates to the site calls report with the parked status filter. [Fact] public void ParkedTile_Click_NavigatesToSiteCallsReport_WithParkedStatusFilter() { var cut = Render(p => p .Add(c => c.Snapshot, MakeSnapshot(buffered: 0, parked: 4, stuck: 0)) .Add(c => c.IsAvailable, true)); var nav = (BunitNavigationManager)Services.GetRequiredService(); var tile = cut.Find("[data-test=\"site-call-kpi-parked\"]"); tile.Click(); // Spec: Parked tile drills into ?status=Parked. Assert.Contains("/site-calls/report?status=Parked", nav.Uri); } }