Files
lmxopcua/tests/Server/ZB.MOM.WW.OtOpcUa.AdminUI.Tests/AlertsAckPathTests.cs
T
Joseph Doherty b211911f98
v2-ci / unit-tests (push) Failing after 13m22s
test: migrate AdminUI/ControlPlane/Runtime/Host tests to xunit.v3 (#756)
Akka.TestKit.Xunit2 -> Akka.TestKit.Xunit 1.5.62 (xunit.v3 TestKit; needs xunit.v3 3.2.2, set via
VersionOverride on the four projects). Removes the xunit 2.9.3 pin. IAsyncLifetime returns ValueTask,
SqlServerFactAttribute gains the source-info ctor, and xUnit1051 call sites pass
TestContext.Current.CancellationToken. Test counts unchanged.

Claude-Session: https://claude.ai/code/session_01GT67AEHd2Acv1YPwGfXEoV
2026-11-10 08:57:33 -05:00

82 lines
3.8 KiB
C#

using Akka.Hosting;
using Akka.TestKit.Xunit;
using Shouldly;
using Xunit;
using ZB.MOM.WW.OtOpcUa.AdminUI.Clients;
using ZB.MOM.WW.OtOpcUa.AdminUI.Tests.Acls;
using ZB.MOM.WW.OtOpcUa.Commons.Messages.Admin;
using ZB.MOM.WW.OtOpcUa.Commons.Messages.Mesh;
using ZB.MOM.WW.OtOpcUa.Commons.OpcUa;
using ZB.MOM.WW.OtOpcUa.ControlPlane;
using ZB.MOM.WW.OtOpcUa.ControlPlane.AdminOperations;
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
namespace ZB.MOM.WW.OtOpcUa.AdminUI.Tests;
/// <summary>
/// Gitea #597 — the AdminUI <c>/alerts</c> acknowledge / shelve path, from the page's client call down to
/// the command the cluster receives: <see cref="AdminOperationsClient"/> (what <c>Alerts.razor</c>'s
/// per-row buttons call) Asks the real <see cref="AdminOperationsActor"/> registered under
/// <see cref="AdminOperationsActorKey"/>, which maps the request to an <see cref="AlarmCommand"/> and hands
/// it to the mesh transport. Until now only the actor half had a test; the client seam the page goes
/// through had none.
/// </summary>
/// <remarks>
/// The razor click handler itself is not driven here — this repo has no bUnit. What it adds on top of the
/// client call is the operator name and <c>comment: null</c>, both reproduced below exactly as the page
/// passes them.
/// </remarks>
public sealed class AlertsAckPathTests : TestKit
{
private (AdminOperationsClient Client, Akka.TestKit.TestProbe Mesh) Wire()
{
var mesh = CreateTestProbe("mesh-router");
var actor = Sys.ActorOf(AdminOperationsActor.Props(
AclScopeTestDb.Factory($"alerts-ack-{Guid.NewGuid():N}"),
coordinator: CreateTestProbe("coordinator").Ref,
probes: Enumerable.Empty<IDriverProbe>(),
meshRouter: mesh.Ref));
var registry = new ActorRegistry();
registry.Register<AdminOperationsActorKey>(actor);
return (new AdminOperationsClient(registry), mesh);
}
/// <summary>The page's Acknowledge reaches the cluster as an <c>Acknowledge</c> AlarmCommand on the
/// <c>alarm-commands</c> topic carrying the alarm id and the operator, and the page is told it was sent.</summary>
[Fact]
public async Task Acknowledge_from_the_alerts_page_dispatches_an_Acknowledge_command_and_reports_sent()
{
var (client, mesh) = Wire();
var result = await client.AcknowledgeAlarmAsync("alarm-42", "operator-jo", comment: null, CancellationToken.None);
result.Ok.ShouldBeTrue();
result.Message.ShouldBeNull();
var sent = mesh.ExpectMsg<MeshCommand>(TimeSpan.FromSeconds(5), cancellationToken: TestContext.Current.CancellationToken);
sent.Topic.ShouldBe(AlarmCommandsTopic.Name);
var command = sent.Message.ShouldBeOfType<AlarmCommand>();
command.AlarmId.ShouldBe("alarm-42");
command.Operation.ShouldBe("Acknowledge");
command.User.ShouldBe("operator-jo");
command.Comment.ShouldBeNull();
command.UnshelveAtUtc.ShouldBeNull();
}
/// <summary>The page's timed shelve carries its expiry through to the command — the instant the engine
/// projects as the node's <c>UnshelveTime</c>.</summary>
[Fact]
public async Task Timed_shelve_from_the_alerts_page_carries_its_expiry_to_the_command()
{
var (client, mesh) = Wire();
var until = new DateTime(2026, 10, 8, 12, 30, 0, DateTimeKind.Utc);
var result = await client.ShelveAlarmAsync(
"alarm-7", "operator-kim", ShelveKind.Timed, unshelveAtUtc: until, comment: null, CancellationToken.None);
result.Ok.ShouldBeTrue();
var command = mesh.ExpectMsg<MeshCommand>(TimeSpan.FromSeconds(5), cancellationToken: TestContext.Current.CancellationToken).Message.ShouldBeOfType<AlarmCommand>();
command.Operation.ShouldBe("TimedShelve");
command.UnshelveAtUtc.ShouldBe(until);
}
}