using ScadaLink.Commons.Entities.Audit; using ScadaLink.Commons.Types.Enums; namespace ScadaLink.Commons.Tests.Entities.Audit; /// /// Verifies behaves as an init-only record: /// every property reads back as constructed, and with expressions /// produce a new instance with a single property changed. /// public class AuditEventTests { [Fact] public void Construction_AllPropertiesReadBack() { var eventId = Guid.NewGuid(); var occurredAt = new DateTime(2026, 5, 20, 12, 0, 0, DateTimeKind.Utc); var ingestedAt = new DateTime(2026, 5, 20, 12, 0, 1, DateTimeKind.Utc); var corrId = Guid.NewGuid(); var execId = Guid.NewGuid(); var evt = new AuditEvent { EventId = eventId, OccurredAtUtc = occurredAt, IngestedAtUtc = ingestedAt, Channel = AuditChannel.ApiOutbound, Kind = AuditKind.ApiCall, CorrelationId = corrId, ExecutionId = execId, SourceSiteId = "site-01", SourceInstanceId = "inst-7", SourceScript = "OnAlarm", Actor = "system", Target = "WeatherAPI", Status = AuditStatus.Delivered, HttpStatus = 200, DurationMs = 42, ErrorMessage = null, ErrorDetail = null, RequestSummary = "GET /forecast", ResponseSummary = "{\"temp\":21}", PayloadTruncated = false, Extra = "{}", ForwardState = AuditForwardState.Forwarded }; Assert.Equal(eventId, evt.EventId); Assert.Equal(occurredAt, evt.OccurredAtUtc); Assert.Equal(ingestedAt, evt.IngestedAtUtc); Assert.Equal(AuditChannel.ApiOutbound, evt.Channel); Assert.Equal(AuditKind.ApiCall, evt.Kind); Assert.Equal(corrId, evt.CorrelationId); Assert.Equal(execId, evt.ExecutionId); Assert.Equal("site-01", evt.SourceSiteId); Assert.Equal("inst-7", evt.SourceInstanceId); Assert.Equal("OnAlarm", evt.SourceScript); Assert.Equal("system", evt.Actor); Assert.Equal("WeatherAPI", evt.Target); Assert.Equal(AuditStatus.Delivered, evt.Status); Assert.Equal(200, evt.HttpStatus); Assert.Equal(42, evt.DurationMs); Assert.Null(evt.ErrorMessage); Assert.Null(evt.ErrorDetail); Assert.Equal("GET /forecast", evt.RequestSummary); Assert.Equal("{\"temp\":21}", evt.ResponseSummary); Assert.False(evt.PayloadTruncated); Assert.Equal("{}", evt.Extra); Assert.Equal(AuditForwardState.Forwarded, evt.ForwardState); } [Fact] public void NullableProperties_AcceptNull() { var evt = new AuditEvent { EventId = Guid.NewGuid(), OccurredAtUtc = DateTime.UtcNow, IngestedAtUtc = null, Channel = AuditChannel.Notification, Kind = AuditKind.NotifySend, CorrelationId = null, ExecutionId = null, SourceSiteId = null, SourceInstanceId = null, SourceScript = null, Actor = null, Target = null, Status = AuditStatus.Submitted, HttpStatus = null, DurationMs = null, ErrorMessage = null, ErrorDetail = null, RequestSummary = null, ResponseSummary = null, PayloadTruncated = false, Extra = null, ForwardState = null }; Assert.Null(evt.IngestedAtUtc); Assert.Null(evt.CorrelationId); Assert.Null(evt.ExecutionId); Assert.Null(evt.SourceSiteId); Assert.Null(evt.SourceInstanceId); Assert.Null(evt.SourceScript); Assert.Null(evt.Actor); Assert.Null(evt.Target); Assert.Null(evt.HttpStatus); Assert.Null(evt.DurationMs); Assert.Null(evt.ErrorMessage); Assert.Null(evt.ErrorDetail); Assert.Null(evt.RequestSummary); Assert.Null(evt.ResponseSummary); Assert.Null(evt.Extra); Assert.Null(evt.ForwardState); } [Fact] public void With_ProducesNewInstance_WithSingleFieldChanged() { var original = new AuditEvent { EventId = Guid.NewGuid(), OccurredAtUtc = DateTime.UtcNow, Channel = AuditChannel.ApiOutbound, Kind = AuditKind.ApiCall, Status = AuditStatus.Submitted, PayloadTruncated = false }; var updated = original with { Status = AuditStatus.Delivered }; Assert.NotSame(original, updated); Assert.Equal(AuditStatus.Submitted, original.Status); Assert.Equal(AuditStatus.Delivered, updated.Status); Assert.Equal(original.EventId, updated.EventId); Assert.NotEqual(original, updated); } }