using CliFx.Attributes; using CliFx.Exceptions; using CliFx.Infrastructure; using Shouldly; using Xunit; using ZB.MOM.WW.OtOpcUa.Driver.S7; using ZB.MOM.WW.OtOpcUa.Driver.S7.Cli; namespace ZB.MOM.WW.OtOpcUa.Driver.S7.Cli.Tests; /// /// Driver.S7.Cli-008: S7CommandBase must reject out-of-range port and non-positive /// timeout values before the command body opens a driver — matching the validation pattern /// established by ModbusCommandBase.ValidateEndpoint. /// [Trait("Category", "Unit")] public sealed class S7EndpointValidationTests { // Test-only subclass that exposes ValidateEndpoint and delegates the abstract ExecuteAsync. [Command("noop-validate", Description = "Test-only stub for S7CommandBase.ValidateEndpoint.")] private sealed class ValidateStub : S7CommandBase { /// public override ValueTask ExecuteAsync(IConsole console) => default; /// Exposes the protected ValidateEndpoint method for tests. public void InvokeValidate() => ValidateEndpoint(); } /// Verifies that a valid port and timeout passes validation without throwing. [Fact] public void ValidateEndpoint_valid_inputs_pass() { // Driver.S7.Cli-008: verify the happy path does not throw. var sut = new ValidateStub { Host = "plc.local", Port = 102, TimeoutMs = 5000 }; Should.NotThrow(() => sut.InvokeValidate()); } /// Verifies that port 0 is rejected as out of range. [Theory] [InlineData(0)] [InlineData(-1)] [InlineData(65536)] public void ValidateEndpoint_invalid_port_throws_CommandException(int port) { // Driver.S7.Cli-008: port must be 1..65535. var sut = new ValidateStub { Host = "h", Port = port, TimeoutMs = 5000 }; Should.Throw(() => sut.InvokeValidate()) .Message.ShouldContain("--port"); } /// Verifies that a non-positive timeout is rejected. [Theory] [InlineData(0)] [InlineData(-1)] public void ValidateEndpoint_non_positive_timeout_throws_CommandException(int timeoutMs) { // Driver.S7.Cli-008: timeout must be strictly positive. var sut = new ValidateStub { Host = "h", Port = 102, TimeoutMs = timeoutMs }; Should.Throw(() => sut.InvokeValidate()) .Message.ShouldContain("--timeout-ms"); } /// Verifies that the boundary port values 1 and 65535 pass validation. [Theory] [InlineData(1)] [InlineData(65535)] public void ValidateEndpoint_boundary_ports_pass(int port) { var sut = new ValidateStub { Host = "h", Port = port, TimeoutMs = 1000 }; Should.NotThrow(() => sut.InvokeValidate()); } }