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