using CliFx.Exceptions; using Opc.Ua; using Shouldly; using Xunit; using ZB.MOM.WW.OtOpcUa.Client.CLI.Commands; using ZB.MOM.WW.OtOpcUa.Client.CLI.Tests.Fakes; namespace ZB.MOM.WW.OtOpcUa.Client.CLI.Tests; public class AcknowledgeCommandTests { private static string HexOf(byte[] bytes) => Convert.ToHexString(bytes); /// Verifies that a successful ack prints a success message. [Fact] public async Task Execute_Success_PrintsSuccessMessage() { var fakeService = new FakeOpcUaClientService { AcknowledgeAlarmResult = StatusCodes.Good }; var factory = new FakeOpcUaClientServiceFactory(fakeService); var eventId = new byte[] { 0x01, 0x02, 0x03 }; var command = new AcknowledgeCommand(factory) { Url = "opc.tcp://localhost:4840", NodeId = "ns=2;s=MyAlarm", EventId = HexOf(eventId), Comment = "test comment" }; using var console = TestConsoleHelper.CreateConsole(); await command.ExecuteAsync(console); var output = TestConsoleHelper.GetOutput(console); output.ShouldContain("Acknowledge successful"); fakeService.AcknowledgeAlarmCalls.Count.ShouldBe(1); fakeService.AcknowledgeAlarmCalls[0].ConditionNodeId.ShouldBe("ns=2;s=MyAlarm"); fakeService.AcknowledgeAlarmCalls[0].EventId.ShouldBe(eventId); fakeService.AcknowledgeAlarmCalls[0].Comment.ShouldBe("test comment"); } /// Verifies that a bad StatusCode from the service prints a failure message. [Fact] public async Task Execute_BadStatus_PrintsFailureMessage() { var fakeService = new FakeOpcUaClientService { AcknowledgeAlarmResult = StatusCodes.BadEventNotAcknowledgeable }; var factory = new FakeOpcUaClientServiceFactory(fakeService); var command = new AcknowledgeCommand(factory) { Url = "opc.tcp://localhost:4840", NodeId = "ns=2;s=MyAlarm", EventId = HexOf(new byte[] { 0xAB }), Comment = "" }; using var console = TestConsoleHelper.CreateConsole(); await command.ExecuteAsync(console); var output = TestConsoleHelper.GetOutput(console); output.ShouldContain("Acknowledge failed"); } /// Verifies that an invalid hex event-id throws CommandException. [Fact] public async Task Execute_InvalidEventId_ThrowsCommandException() { var fakeService = new FakeOpcUaClientService(); var factory = new FakeOpcUaClientServiceFactory(fakeService); var command = new AcknowledgeCommand(factory) { Url = "opc.tcp://localhost:4840", NodeId = "ns=2;s=MyAlarm", EventId = "not-hex!", Comment = "" }; using var console = TestConsoleHelper.CreateConsole(); var ex = await Should.ThrowAsync(async () => await command.ExecuteAsync(console)); ex.Message.ShouldContain("event-id", Case.Insensitive); } /// Verifies that the command disconnects in the finally block. [Fact] public async Task Execute_DisconnectsInFinally() { var fakeService = new FakeOpcUaClientService(); var factory = new FakeOpcUaClientServiceFactory(fakeService); var command = new AcknowledgeCommand(factory) { Url = "opc.tcp://localhost:4840", NodeId = "ns=2;s=MyAlarm", EventId = HexOf(new byte[] { 0x01 }), Comment = "" }; using var console = TestConsoleHelper.CreateConsole(); await command.ExecuteAsync(console); fakeService.DisconnectCalled.ShouldBeTrue(); fakeService.DisposeCalled.ShouldBeTrue(); } }