using System.Collections.Generic; using System.Text.RegularExpressions; using FluentAssertions; using Microsoft.Extensions.Logging; using StellaOps.TestKit.Observability; using Xunit; namespace StellaOps.TestKit.Tests; public sealed partial class ObservabilityContractTests { [Fact] public void HasRequiredFields_AllPresent_NoException() { var record = new CapturedLogRecord { LogLevel = LogLevel.Information, Message = "Test message", StateValues = new Dictionary { ["CorrelationId"] = "abc-123", ["TenantId"] = "acme" } }; var act = () => LogContractAssert.HasRequiredFields(record, "CorrelationId", "TenantId"); act.Should().NotThrow(); } [Fact] public void HasRequiredFields_Missing_ThrowsContractViolation() { var record = new CapturedLogRecord { LogLevel = LogLevel.Information, Message = "Test message", StateValues = new Dictionary { ["CorrelationId"] = "abc-123" } }; var act = () => LogContractAssert.HasRequiredFields(record, "CorrelationId", "MissingField"); act.Should().Throw() .WithMessage("*MissingField*"); } [Fact] public void NoSensitiveData_Clean_NoException() { var records = new[] { new CapturedLogRecord { LogLevel = LogLevel.Information, Message = "User logged in successfully", StateValues = new Dictionary { ["UserId"] = "user-123" } } }; var piiPatterns = new[] { new Regex(@"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b") }; var act = () => LogContractAssert.NoSensitiveData(records, piiPatterns); act.Should().NotThrow(); } }