review(Client.CLI): wrap NodeId parse errors in CommandException for alarm-op commands
Re-review at 7286d320. -011: ack/confirm/enable/disable/shelve now pre-validate --node and
surface a clean CommandException (was a raw FormatException) + tests. -012: refresh stale
test count in docs/Client.CLI.md.
This commit is contained in:
+108
@@ -0,0 +1,108 @@
|
||||
using CliFx.Exceptions;
|
||||
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;
|
||||
|
||||
/// <summary>
|
||||
/// Regression tests for Client.CLI-011: alarm-op commands (ack, confirm, enable, disable, shelve)
|
||||
/// must validate the --node option with a clean CommandException rather than letting a raw
|
||||
/// exception propagate from NodeId.Parse inside the service.
|
||||
/// </summary>
|
||||
public class AlarmOpCommandNodeIdValidationTests
|
||||
{
|
||||
private static string HexOf(byte[] bytes) => Convert.ToHexString(bytes);
|
||||
|
||||
/// <summary>AcknowledgeCommand with an invalid node ID must throw CommandException, not a raw exception.</summary>
|
||||
[Fact]
|
||||
public async Task AcknowledgeCommand_InvalidNodeId_ThrowsCommandException()
|
||||
{
|
||||
var fakeService = new FakeOpcUaClientService();
|
||||
var factory = new FakeOpcUaClientServiceFactory(fakeService);
|
||||
var command = new AcknowledgeCommand(factory)
|
||||
{
|
||||
Url = "opc.tcp://localhost:4840",
|
||||
NodeId = "not-a-node-id",
|
||||
EventId = HexOf(new byte[] { 0x01 }),
|
||||
Comment = ""
|
||||
};
|
||||
|
||||
using var console = TestConsoleHelper.CreateConsole();
|
||||
var ex = await Should.ThrowAsync<CommandException>(async () => await command.ExecuteAsync(console));
|
||||
ex.Message.ShouldContain("node", Case.Insensitive);
|
||||
}
|
||||
|
||||
/// <summary>ConfirmCommand with an invalid node ID must throw CommandException, not a raw exception.</summary>
|
||||
[Fact]
|
||||
public async Task ConfirmCommand_InvalidNodeId_ThrowsCommandException()
|
||||
{
|
||||
var fakeService = new FakeOpcUaClientService();
|
||||
var factory = new FakeOpcUaClientServiceFactory(fakeService);
|
||||
var command = new ConfirmCommand(factory)
|
||||
{
|
||||
Url = "opc.tcp://localhost:4840",
|
||||
NodeId = "not-a-node-id",
|
||||
EventId = HexOf(new byte[] { 0x01 }),
|
||||
Comment = ""
|
||||
};
|
||||
|
||||
using var console = TestConsoleHelper.CreateConsole();
|
||||
var ex = await Should.ThrowAsync<CommandException>(async () => await command.ExecuteAsync(console));
|
||||
ex.Message.ShouldContain("node", Case.Insensitive);
|
||||
}
|
||||
|
||||
/// <summary>EnableCommand with an invalid node ID must throw CommandException, not a raw exception.</summary>
|
||||
[Fact]
|
||||
public async Task EnableCommand_InvalidNodeId_ThrowsCommandException()
|
||||
{
|
||||
var fakeService = new FakeOpcUaClientService();
|
||||
var factory = new FakeOpcUaClientServiceFactory(fakeService);
|
||||
var command = new EnableCommand(factory)
|
||||
{
|
||||
Url = "opc.tcp://localhost:4840",
|
||||
NodeId = "not-a-node-id"
|
||||
};
|
||||
|
||||
using var console = TestConsoleHelper.CreateConsole();
|
||||
var ex = await Should.ThrowAsync<CommandException>(async () => await command.ExecuteAsync(console));
|
||||
ex.Message.ShouldContain("node", Case.Insensitive);
|
||||
}
|
||||
|
||||
/// <summary>DisableCommand with an invalid node ID must throw CommandException, not a raw exception.</summary>
|
||||
[Fact]
|
||||
public async Task DisableCommand_InvalidNodeId_ThrowsCommandException()
|
||||
{
|
||||
var fakeService = new FakeOpcUaClientService();
|
||||
var factory = new FakeOpcUaClientServiceFactory(fakeService);
|
||||
var command = new DisableCommand(factory)
|
||||
{
|
||||
Url = "opc.tcp://localhost:4840",
|
||||
NodeId = "not-a-node-id"
|
||||
};
|
||||
|
||||
using var console = TestConsoleHelper.CreateConsole();
|
||||
var ex = await Should.ThrowAsync<CommandException>(async () => await command.ExecuteAsync(console));
|
||||
ex.Message.ShouldContain("node", Case.Insensitive);
|
||||
}
|
||||
|
||||
/// <summary>ShelveCommand with an invalid node ID must throw CommandException, not a raw exception.</summary>
|
||||
[Fact]
|
||||
public async Task ShelveCommand_InvalidNodeId_ThrowsCommandException()
|
||||
{
|
||||
var fakeService = new FakeOpcUaClientService();
|
||||
var factory = new FakeOpcUaClientServiceFactory(fakeService);
|
||||
var command = new ShelveCommand(factory)
|
||||
{
|
||||
Url = "opc.tcp://localhost:4840",
|
||||
NodeId = "not-a-node-id",
|
||||
Kind = "OneShot",
|
||||
DurationSeconds = 0
|
||||
};
|
||||
|
||||
using var console = TestConsoleHelper.CreateConsole();
|
||||
var ex = await Should.ThrowAsync<CommandException>(async () => await command.ExecuteAsync(console));
|
||||
ex.Message.ShouldContain("node", Case.Insensitive);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user