using FluentAssertions; using Microsoft.AspNetCore.Http; using NSubstitute; using SIGCM2.Application.Audit; using SIGCM2.Infrastructure.Audit; using Xunit; namespace SIGCM2.Application.Tests.Infrastructure.Audit; /// UDT-010 Batch 4 — AuditContext (scoped IAuditContext impl) unit tests. /// Reads audit fields from HttpContext.Items populated by CorrelationIdMiddleware + AuditActorMiddleware. public sealed class AuditContextTests { private static (AuditContext ctx, DefaultHttpContext http) Build() { var http = new DefaultHttpContext(); var accessor = Substitute.For(); accessor.HttpContext.Returns(http); return (new AuditContext(accessor), http); } [Fact] public void ReadsActorUserIdFromItems() { var (ctx, http) = Build(); http.Items["audit:actorUserId"] = 42; ctx.ActorUserId.Should().Be(42); } [Fact] public void ActorUserId_IsNull_WhenNotPresent() { var (ctx, _) = Build(); ctx.ActorUserId.Should().BeNull(); } [Fact] public void ReadsIpAndUserAgentFromItems() { var (ctx, http) = Build(); http.Items["audit:ip"] = "10.20.30.40"; http.Items["audit:userAgent"] = "ua/1.0"; ctx.Ip.Should().Be("10.20.30.40"); ctx.UserAgent.Should().Be("ua/1.0"); } [Fact] public void ReadsCorrelationIdFromItems() { var (ctx, http) = Build(); var id = Guid.NewGuid(); http.Items["audit:correlationId"] = id; ctx.CorrelationId.Should().Be(id); } [Fact] public void CorrelationId_IsEmpty_WhenNotPresent() { var (ctx, _) = Build(); ctx.CorrelationId.Should().Be(Guid.Empty); } [Fact] public void AllFields_AreNull_WhenHttpContextIsNull() { var accessor = Substitute.For(); accessor.HttpContext.Returns((HttpContext?)null); var ctx = new AuditContext(accessor); ctx.ActorUserId.Should().BeNull(); ctx.ActorRoleId.Should().BeNull(); ctx.Ip.Should().BeNull(); ctx.UserAgent.Should().BeNull(); ctx.CorrelationId.Should().Be(Guid.Empty); } [Fact] public void ActorRoleId_IsNull_Always_InB4() { // B4 middleware does not resolve rol code -> id; future batches may. var (ctx, http) = Build(); http.Items["audit:actorUserId"] = 42; ctx.ActorRoleId.Should().BeNull(); } }