feat(m9/T25): connection live-status indicators on the design page
This commit is contained in:
@@ -5,8 +5,10 @@ using Microsoft.AspNetCore.Components.Authorization;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using NSubstitute;
|
||||
using ZB.MOM.WW.ScadaBridge.CentralUI.Components.Shared;
|
||||
using ZB.MOM.WW.ScadaBridge.CentralUI.Services;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Entities.Sites;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Repositories;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
|
||||
using DataConnectionsPage = ZB.MOM.WW.ScadaBridge.CentralUI.Components.Pages.Design.DataConnections;
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.CentralUI.Tests;
|
||||
@@ -19,15 +21,26 @@ namespace ZB.MOM.WW.ScadaBridge.CentralUI.Tests;
|
||||
public class DataConnectionsPageTests : BunitContext
|
||||
{
|
||||
private readonly ISiteRepository _siteRepo = Substitute.For<ISiteRepository>();
|
||||
// M9-T25: the design page now injects IConnectionHealthQueryService to render
|
||||
// per-connection live health badges. A substitute defaulting to an empty map
|
||||
// keeps every existing test green (no badge / unknown state when no report).
|
||||
private readonly IConnectionHealthQueryService _healthQuery =
|
||||
Substitute.For<IConnectionHealthQueryService>();
|
||||
|
||||
public DataConnectionsPageTests()
|
||||
{
|
||||
Services.AddSingleton(_siteRepo);
|
||||
Services.AddSingleton(_healthQuery);
|
||||
// Satisfy the page's [Inject] IDialogService — the host that actually
|
||||
// renders the dialog lives in MainLayout, not in bUnit's render scope.
|
||||
Services.AddScoped<IDialogService, DialogService>();
|
||||
AddTestAuth();
|
||||
|
||||
// Default: no health known. Tests that assert badge state override this.
|
||||
_healthQuery.GetConnectionHealthAsync(Arg.Any<CancellationToken>())
|
||||
.Returns(Task.FromResult<IReadOnlyDictionary<int, ConnectionHealth>>(
|
||||
new Dictionary<int, ConnectionHealth>()));
|
||||
|
||||
JSInterop.Setup<string?>("treeviewStorage.load", _ => true).SetResult(null);
|
||||
JSInterop.SetupVoid("treeviewStorage.save", _ => true);
|
||||
}
|
||||
@@ -162,4 +175,38 @@ public class DataConnectionsPageTests : BunitContext
|
||||
Assert.Contains("/design/connections", routes);
|
||||
Assert.Contains("/design/data-connections", routes);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ConnectionNode_RendersLiveHealthBadge_MatchingStatus()
|
||||
{
|
||||
// M9-T25: a connection whose live health is Connected gets the success
|
||||
// health badge next to its node; a Disconnected one gets the danger badge.
|
||||
SeedRepos(
|
||||
sites: new[] { new Site("Plant-A", "plant-a") { Id = 1 } },
|
||||
connections: new[]
|
||||
{
|
||||
new DataConnection("PLC-1", "OpcUa", 1) { Id = 100 },
|
||||
new DataConnection("RTU-9", "Custom", 1) { Id = 200 }
|
||||
});
|
||||
_healthQuery.GetConnectionHealthAsync(Arg.Any<CancellationToken>())
|
||||
.Returns(Task.FromResult<IReadOnlyDictionary<int, ConnectionHealth>>(
|
||||
new Dictionary<int, ConnectionHealth>
|
||||
{
|
||||
[100] = ConnectionHealth.Connected,
|
||||
[200] = ConnectionHealth.Disconnected,
|
||||
}));
|
||||
|
||||
var cut = Render<DataConnectionsPage>();
|
||||
FindToggleForLabel(cut, "Plant-A")!.Click();
|
||||
|
||||
// Each connection node carries a status badge keyed by connection id so the
|
||||
// assertion targets the right node regardless of tree ordering.
|
||||
var connectedBadge = cut.Find("[data-test='conn-health-100']");
|
||||
Assert.Contains("bg-success", connectedBadge.GetAttribute("class"));
|
||||
Assert.Contains("Connected", connectedBadge.TextContent);
|
||||
|
||||
var disconnectedBadge = cut.Find("[data-test='conn-health-200']");
|
||||
Assert.Contains("bg-danger", disconnectedBadge.GetAttribute("class"));
|
||||
Assert.Contains("Disconnected", disconnectedBadge.TextContent);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user