refactor(central-ui): split Notification Report out of the Outbox page
This commit is contained in:
@@ -22,8 +22,8 @@ namespace ScadaLink.CentralUI.Tests.Pages;
|
||||
/// <see cref="ICentralHealthAggregator"/> is an interface (mockable), but
|
||||
/// <see cref="CommunicationService"/> is a concrete class whose outbox calls
|
||||
/// route through an injected notification-outbox <see cref="IActorRef"/>; the
|
||||
/// tests reuse the scripted-actor seam established by the Notification Outbox
|
||||
/// page tests (see <c>NotificationOutboxPageTests</c>).
|
||||
/// tests reuse the scripted-actor seam established by the Notification Report
|
||||
/// page tests (see <c>NotificationReportPageTests</c>).
|
||||
/// </summary>
|
||||
public class HealthPageTests : BunitContext
|
||||
{
|
||||
|
||||
@@ -13,30 +13,26 @@ using ScadaLink.Commons.Interfaces.Repositories;
|
||||
using ScadaLink.Commons.Messages.Notification;
|
||||
using ScadaLink.Communication;
|
||||
using ScadaLink.Security;
|
||||
using NotificationOutboxPage = ScadaLink.CentralUI.Components.Pages.Monitoring.NotificationOutbox;
|
||||
using NotificationReportPage = ScadaLink.CentralUI.Components.Pages.Notifications.NotificationReport;
|
||||
|
||||
namespace ScadaLink.CentralUI.Tests.Pages;
|
||||
|
||||
/// <summary>
|
||||
/// bUnit rendering tests for the Notification Outbox monitoring page (Task 23).
|
||||
/// bUnit rendering tests for the Notification Report page.
|
||||
///
|
||||
/// Testability note: <see cref="CommunicationService"/> is a concrete class with
|
||||
/// non-virtual methods, so NSubstitute cannot intercept it. The outbox calls all
|
||||
/// non-virtual methods, so NSubstitute cannot intercept it. The report calls all
|
||||
/// route through an injected <see cref="IActorRef"/> (the notification-outbox
|
||||
/// proxy), so the tests wire a real, lightweight <see cref="ActorSystem"/> with a
|
||||
/// scripted <see cref="ReceiveActor"/> that replies with fixed responses — the
|
||||
/// same seam <c>SetNotificationOutbox</c> exists for.
|
||||
/// </summary>
|
||||
public class NotificationOutboxPageTests : BunitContext
|
||||
public class NotificationReportPageTests : BunitContext
|
||||
{
|
||||
private readonly ActorSystem _system = ActorSystem.Create("notif-outbox-tests");
|
||||
private readonly ActorSystem _system = ActorSystem.Create("notif-report-tests");
|
||||
private readonly CommunicationService _comms;
|
||||
|
||||
// Mutable scripted replies — individual tests can override before rendering.
|
||||
private NotificationKpiResponse _kpiReply =
|
||||
new("k", true, null, QueueDepth: 7, StuckCount: 2, ParkedCount: 1,
|
||||
DeliveredLastInterval: 42, OldestPendingAge: TimeSpan.FromMinutes(9));
|
||||
|
||||
// Mutable scripted reply — individual tests can override before rendering.
|
||||
private NotificationOutboxQueryResponse _queryReply =
|
||||
new("q", true, null, new List<NotificationSummary>
|
||||
{
|
||||
@@ -54,7 +50,7 @@ public class NotificationOutboxPageTests : BunitContext
|
||||
private readonly List<RetryNotificationRequest> _retryRequests = new();
|
||||
private readonly List<DiscardNotificationRequest> _discardRequests = new();
|
||||
|
||||
public NotificationOutboxPageTests()
|
||||
public NotificationReportPageTests()
|
||||
{
|
||||
_comms = new CommunicationService(
|
||||
Options.Create(new CommunicationOptions()),
|
||||
@@ -88,7 +84,7 @@ public class NotificationOutboxPageTests : BunitContext
|
||||
[Fact]
|
||||
public void Page_RequiresDeploymentPolicy()
|
||||
{
|
||||
var attr = typeof(NotificationOutboxPage)
|
||||
var attr = typeof(NotificationReportPage)
|
||||
.GetCustomAttributes(typeof(AuthorizeAttribute), true)
|
||||
.Cast<AuthorizeAttribute>()
|
||||
.FirstOrDefault();
|
||||
@@ -97,28 +93,10 @@ public class NotificationOutboxPageTests : BunitContext
|
||||
Assert.Equal(AuthorizationPolicies.RequireDeployment, attr!.Policy);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Renders_KpiTiles_WithValues()
|
||||
{
|
||||
var cut = Render<NotificationOutboxPage>();
|
||||
|
||||
// KPI data arrives via an async actor Ask after first render.
|
||||
cut.WaitForAssertion(() =>
|
||||
{
|
||||
Assert.Contains("Queue Depth", cut.Markup);
|
||||
Assert.Contains("Stuck", cut.Markup);
|
||||
Assert.Contains("Parked", cut.Markup);
|
||||
Assert.Contains("Delivered", cut.Markup);
|
||||
// KPI numeric values surface in the tiles.
|
||||
Assert.Contains(">7<", cut.Markup); // QueueDepth
|
||||
Assert.Contains(">42<", cut.Markup); // DeliveredLastInterval
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Renders_NotificationRows()
|
||||
{
|
||||
var cut = Render<NotificationOutboxPage>();
|
||||
var cut = Render<NotificationReportPage>();
|
||||
|
||||
cut.WaitForAssertion(() =>
|
||||
{
|
||||
@@ -131,7 +109,7 @@ public class NotificationOutboxPageTests : BunitContext
|
||||
[Fact]
|
||||
public void StuckRow_IsBadged()
|
||||
{
|
||||
var cut = Render<NotificationOutboxPage>();
|
||||
var cut = Render<NotificationReportPage>();
|
||||
|
||||
cut.WaitForAssertion(() =>
|
||||
{
|
||||
@@ -147,7 +125,7 @@ public class NotificationOutboxPageTests : BunitContext
|
||||
[Fact]
|
||||
public void ClickRetry_OnParkedRow_CallsRetryNotification()
|
||||
{
|
||||
var cut = Render<NotificationOutboxPage>();
|
||||
var cut = Render<NotificationReportPage>();
|
||||
|
||||
cut.WaitForState(() => cut.Markup.Contains("Pump fault at Plant-A"));
|
||||
|
||||
@@ -168,7 +146,7 @@ public class NotificationOutboxPageTests : BunitContext
|
||||
[Fact]
|
||||
public void ClickDiscard_OnParkedRow_CallsDiscardNotification()
|
||||
{
|
||||
var cut = Render<NotificationOutboxPage>();
|
||||
var cut = Render<NotificationReportPage>();
|
||||
|
||||
cut.WaitForState(() => cut.Markup.Contains("Pump fault at Plant-A"));
|
||||
|
||||
@@ -186,18 +164,6 @@ public class NotificationOutboxPageTests : BunitContext
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void KpiFailure_ShowsErrorMessage()
|
||||
{
|
||||
_kpiReply = new NotificationKpiResponse(
|
||||
"k", false, "outbox repository unavailable", 0, 0, 0, 0, null);
|
||||
|
||||
var cut = Render<NotificationOutboxPage>();
|
||||
|
||||
cut.WaitForAssertion(() =>
|
||||
Assert.Contains("outbox repository unavailable", cut.Markup));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void QueryFailure_ShowsErrorMessage()
|
||||
{
|
||||
@@ -205,7 +171,7 @@ public class NotificationOutboxPageTests : BunitContext
|
||||
"q", false, "outbox query backend unavailable",
|
||||
new List<NotificationSummary>(), TotalCount: 0);
|
||||
|
||||
var cut = Render<NotificationOutboxPage>();
|
||||
var cut = Render<NotificationReportPage>();
|
||||
|
||||
cut.WaitForAssertion(() =>
|
||||
Assert.Contains("outbox query backend unavailable", cut.Markup));
|
||||
@@ -226,9 +192,8 @@ public class NotificationOutboxPageTests : BunitContext
|
||||
/// </summary>
|
||||
private sealed class ScriptedOutboxActor : ReceiveActor
|
||||
{
|
||||
public ScriptedOutboxActor(NotificationOutboxPageTests test)
|
||||
public ScriptedOutboxActor(NotificationReportPageTests test)
|
||||
{
|
||||
Receive<NotificationKpiRequest>(_ => Sender.Tell(test._kpiReply));
|
||||
Receive<NotificationOutboxQueryRequest>(_ => Sender.Tell(test._queryReply));
|
||||
Receive<RetryNotificationRequest>(r =>
|
||||
{
|
||||
Reference in New Issue
Block a user