using Microsoft.Extensions.Options; namespace ZB.MOM.WW.ScadaBridge.InboundAPI.Tests; /// /// Arch-review 08 ยง1.5: feeds a per-request timeout /// () and a body-size cap /// () into the inbound-API request /// pipeline; a zero/negative timeout or a non-positive body cap must be rejected fast at /// startup with a clear, key-naming message rather than silently degrading the endpoint. /// The is deliberately NOT required non-empty /// here (empty is a legitimate dev default; production pepper strength is enforced elsewhere). /// public class InboundApiOptionsValidatorTests { private static ValidateOptionsResult Validate(InboundApiOptions options) => new InboundApiOptionsValidator().Validate(Options.DefaultName, options); [Fact] public void DefaultOptions_AreValid() { var result = Validate(new InboundApiOptions()); Assert.True(result.Succeeded, result.FailureMessage); } [Fact] public void EmptyApiKeyPepper_IsValid() { var result = Validate(new InboundApiOptions { ApiKeyPepper = string.Empty }); Assert.True(result.Succeeded, result.FailureMessage); } [Fact] public void ZeroDefaultMethodTimeout_IsRejected() { var result = Validate(new InboundApiOptions { DefaultMethodTimeout = TimeSpan.Zero }); Assert.True(result.Failed); Assert.Contains("DefaultMethodTimeout", result.FailureMessage); } [Fact] public void NegativeDefaultMethodTimeout_IsRejected() { var result = Validate(new InboundApiOptions { DefaultMethodTimeout = TimeSpan.FromSeconds(-1) }); Assert.True(result.Failed); Assert.Contains("DefaultMethodTimeout", result.FailureMessage); } [Fact] public void ZeroMaxRequestBodyBytes_IsRejected() { var result = Validate(new InboundApiOptions { MaxRequestBodyBytes = 0 }); Assert.True(result.Failed); Assert.Contains("MaxRequestBodyBytes", result.FailureMessage); } [Fact] public void NegativeMaxRequestBodyBytes_IsRejected() { var result = Validate(new InboundApiOptions { MaxRequestBodyBytes = -1 }); Assert.True(result.Failed); Assert.Contains("MaxRequestBodyBytes", result.FailureMessage); } }