using Microsoft.Extensions.Options; using Shouldly; using Xunit; using ZB.MOM.WW.OtOpcUa.Core.Authorization; using ZB.MOM.WW.OtOpcUa.Host.Configuration; namespace ZB.MOM.WW.OtOpcUa.Host.Tests.Configuration; /// /// R03:2.3 — an unset or placeholder pepper must fail host start, not surface as "Invalid API key" /// on the first activation. /// public sealed class ApiKeyOptionsValidatorTests { private static ValidateOptionsResult Validate(ApiKeyOptions options) => new ApiKeyOptionsValidator().Validate(Options.DefaultName, options); [Theory] [InlineData("")] [InlineData(" ")] public void Blank_pepper_fails(string pepper) { var result = Validate(new ApiKeyOptions { Pepper = pepper }); result.Failed.ShouldBeTrue(); result.FailureMessage.ShouldNotBeNull(); result.FailureMessage.ShouldContain("Pepper is required"); } [Fact] public void Short_pepper_fails() { var result = Validate(new ApiKeyOptions { Pepper = "x" }); result.Failed.ShouldBeTrue(); result.FailureMessage.ShouldNotBeNull(); result.FailureMessage.ShouldContain($"at least {ApiKeyOptionsValidator.MinPepperLength}"); } [Fact] public void Blank_username_fails() { var result = Validate(new ApiKeyOptions { Pepper = new string('p', 32), Username = " " }); result.Failed.ShouldBeTrue(); result.FailureMessage.ShouldNotBeNull(); result.FailureMessage.ShouldContain("Username"); } /// Positive control: the docker-dev rig's pepper and the defaults pass unchanged. [Fact] public void Configured_pepper_passes() { Validate(new ApiKeyOptions { Pepper = "docker-dev-apikey-pepper-not-for-production" }) .Succeeded.ShouldBeTrue(); } }