using Shouldly;
using Xunit;
using ZB.MOM.WW.OtOpcUa.Security.Audit;
namespace ZB.MOM.WW.OtOpcUa.Security.Tests.Audit;
///
/// Unit tests for — the static resolution helper that sources the
/// Actor field of a canonical ZB.MOM.WW.Audit.AuditEvent from the current
/// HTTP principal and falls back to a configurable value when no principal is available.
///
public sealed class AuditActorTests
{
///
/// returns the accessor's value
/// when the accessor returns a non-null string.
///
[Fact]
public void Resolve_returns_accessor_value_when_present()
{
var accessor = new StubAccessor("alice");
AuditActor.Resolve(accessor).ShouldBe("alice");
}
///
/// returns
/// when the accessor returns null
/// (unauthenticated / no HTTP context).
///
[Fact]
public void Resolve_returns_system_fallback_when_accessor_returns_null()
{
var accessor = new StubAccessor(null);
AuditActor.Resolve(accessor).ShouldBe(AuditActor.SystemFallback);
}
///
/// returns
/// when the accessor reference itself is null
/// (e.g. in a background/non-HTTP context where DI did not inject the accessor).
///
[Fact]
public void Resolve_returns_system_fallback_when_accessor_is_null()
{
AuditActor.Resolve(null).ShouldBe(AuditActor.SystemFallback);
}
///
/// uses the explicit
/// fallback string rather than when the accessor
/// returns null.
///
[Fact]
public void Resolve_uses_explicit_fallback_when_accessor_returns_null()
{
var accessor = new StubAccessor(null);
AuditActor.Resolve(accessor, "scheduler").ShouldBe("scheduler");
}
///
/// prefers the accessor's
/// value over the explicit fallback when the accessor returns a non-null string.
///
[Fact]
public void Resolve_prefers_accessor_value_over_explicit_fallback()
{
var accessor = new StubAccessor("bob");
AuditActor.Resolve(accessor, "scheduler").ShouldBe("bob");
}
// ── stub ──────────────────────────────────────────────────────────────────────
private sealed class StubAccessor(string? value) : IAuditActorAccessor
{
public string? CurrentActor { get; } = value;
}
}