34d60c4125
The page ran members, the driver-instances heading, and every cluster group together inside one panel; driver name and id slammed inline; one long driver exception blew the table out sideways (Controls scrolled out of reach); and the inline #546 expander row dumped a full-width panel into the table. - One panel per cluster group, node chips in the panel head. - Driver id renders on its own muted mono line under the name. - Last error abbreviated to 60 chars (DisplayText.Abbreviate — #504 rule), full text on the tooltip and in the Controls dialog. - DriverStatusPanel moved from an inline expander row to a modal (one at a time); the dialog re-resolves its row from the current groups each render so the 5 s rebuild can't strand it, and the Enabled-in-key recycle discipline carries over unchanged. HostsPanelWiringTests re-pinned to the dialog markup. Live-verified on docker-dev: separated cards, in-viewport table, dialog opens with live breaker/status data and grouped Reconnect|Restart, closes cleanly.
63 lines
2.9 KiB
C#
63 lines
2.9 KiB
C#
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 dialog driver's real identity and enabled-state, not literals.
|
|
/// Hard-coding any of the three would make every dialog drive the same driver, or claim a
|
|
/// disabled instance is live — both of which a source scan for the tag alone would pass.
|
|
/// Since the Controls dialog rework the panel renders once, inside the modal, bound to the
|
|
/// row that <c>FindControlsDriver()</c> re-resolves from the current groups (<c>cd</c>/<c>cg</c>)
|
|
/// — never to a cached row record, which the 5 s rebuild replaces.
|
|
/// </summary>
|
|
[Fact]
|
|
public void The_panel_is_bound_to_the_dialogs_own_driver_cluster_and_enabled_state()
|
|
{
|
|
var source = ReadHostsPageSource();
|
|
|
|
source.ShouldContain("DriverInstanceId=\"@cd.DriverInstanceId\"");
|
|
source.ShouldContain("ClusterId=\"@cg.ClusterId\"");
|
|
source.ShouldContain("Enabled=\"@cd.Enabled\"");
|
|
}
|
|
}
|