Merge fix/issue-546-panel: wire DriverStatusPanel into /hosts driver rows (#546)
Claude-Session: https://claude.ai/code/session_014WNM4vjoVksyyBraTXSZE1
This commit is contained in:
@@ -22,8 +22,9 @@ public sealed class HostsDriverViewTests
|
||||
private static HostsNodeInfo Node(string cluster, string node, string host = "h", int port = 4840) =>
|
||||
new(cluster, node, host, port);
|
||||
|
||||
private static HostsDriverInstanceInfo Instance(string instance, string cluster, string name, string type) =>
|
||||
new(instance, cluster, name, type);
|
||||
private static HostsDriverInstanceInfo Instance(
|
||||
string instance, string cluster, string name, string type, bool enabled = true) =>
|
||||
new(instance, cluster, name, type, enabled);
|
||||
|
||||
[Fact]
|
||||
public void Build_groups_two_clusters_with_their_nodes_and_snapshots()
|
||||
@@ -214,6 +215,38 @@ public sealed class HostsDriverViewTests
|
||||
row.DegradedHosts.ShouldBeEmpty();
|
||||
}
|
||||
|
||||
// ---- authored enabled-state (Gitea #546) ----
|
||||
|
||||
/// <summary>
|
||||
/// The authored enabled flag reaches the row, which forwards it to the row's
|
||||
/// <c>DriverStatusPanel</c>. Defaulting it to true would have the panel open a live
|
||||
/// subscription for an instance that was deliberately taken out of the deployment.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void Build_carries_the_authored_enabled_flag_onto_the_row()
|
||||
{
|
||||
var groups = HostsDriverView.Build(
|
||||
[Snap("MAIN", "drv-a")],
|
||||
nodes: null,
|
||||
[Instance("drv-a", "MAIN", "Pump House Modbus", "Modbus", enabled: false)]);
|
||||
|
||||
groups.Single().Drivers.Single().Enabled.ShouldBeFalse();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A snapshot with no matching configured instance is treated as enabled. The row only exists
|
||||
/// because live health arrived for it, so rendering the panel's "Disabled — not deployed"
|
||||
/// notice would contradict the evidence on the same row.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void An_unmatched_driver_row_is_treated_as_enabled()
|
||||
{
|
||||
var row = HostsDriverView.Build([Snap("MAIN", "orphan")], nodes: null, instances: null)
|
||||
.Single().Drivers.Single();
|
||||
|
||||
row.Enabled.ShouldBeTrue();
|
||||
}
|
||||
|
||||
// ---- skipped tags (Gitea #541) ----
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
|
||||
namespace ZB.MOM.WW.OtOpcUa.AdminUI.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// Pins <c>DriverStatusPanel</c> to the <c>/hosts</c> page (Gitea #546). The panel is the only
|
||||
/// component carrying the Restart/Reconnect driver controls, and it had ZERO references
|
||||
/// repo-wide — the commands worked end to end over the mesh transport while no user could reach
|
||||
/// them, and nothing failed to build, test or deploy. Deleting the last <c><DriverStatusPanel</c>
|
||||
/// tag would silently restore exactly that state, so it is pinned here.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is a source scan rather than a rendering assertion because the repo has no bUnit (same
|
||||
/// technique as <c>MeshRegistrationRoleScopingTests</c>; panel markup is otherwise live-verified).
|
||||
/// A scan proves reachability of the component, not that it renders correctly.
|
||||
/// </remarks>
|
||||
[Trait("Category", "Unit")]
|
||||
public sealed class HostsPanelWiringTests
|
||||
{
|
||||
private static string ReadHostsPageSource()
|
||||
{
|
||||
var dir = new DirectoryInfo(AppContext.BaseDirectory);
|
||||
while (dir is not null && !File.Exists(Path.Combine(dir.FullName, "ZB.MOM.WW.OtOpcUa.slnx")))
|
||||
dir = dir.Parent;
|
||||
dir.ShouldNotBeNull("could not locate the repository root (no ZB.MOM.WW.OtOpcUa.slnx above the test binary)");
|
||||
|
||||
return File.ReadAllText(Path.Combine(
|
||||
dir!.FullName, "src", "Server", "ZB.MOM.WW.OtOpcUa.AdminUI",
|
||||
"Components", "Pages", "Hosts.razor"));
|
||||
}
|
||||
|
||||
/// <summary>THE #546 regression pin: the panel must remain reachable from a routable page.</summary>
|
||||
[Fact]
|
||||
public void Hosts_page_renders_the_driver_status_panel()
|
||||
{
|
||||
ReadHostsPageSource().ShouldContain(
|
||||
"<DriverStatusPanel",
|
||||
Case.Sensitive,
|
||||
customMessage:
|
||||
"/hosts no longer renders DriverStatusPanel — the Restart/Reconnect driver controls " +
|
||||
"are orphaned again with no reachable UI, which is Gitea #546");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The panel must be fed the row's real identity and enabled-state, not literals. Hard-coding
|
||||
/// any of the three would make every expanded row drive the same driver, or claim a disabled
|
||||
/// instance is live — both of which a source scan for the tag alone would pass.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void The_panel_is_bound_to_the_rows_own_driver_cluster_and_enabled_state()
|
||||
{
|
||||
var source = ReadHostsPageSource();
|
||||
|
||||
source.ShouldContain("DriverInstanceId=\"@d.DriverInstanceId\"");
|
||||
source.ShouldContain("ClusterId=\"@g.ClusterId\"");
|
||||
source.ShouldContain("Enabled=\"@d.Enabled\"");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user