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