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());
}
}