Files
scadalink-design/tests/ScadaLink.Commons.Tests/Entities/Audit/AuditEventTests.cs
2026-05-20 09:56:11 -04:00

136 lines
4.7 KiB
C#

using ScadaLink.Commons.Entities.Audit;
using ScadaLink.Commons.Types.Enums;
namespace ScadaLink.Commons.Tests.Entities.Audit;
/// <summary>
/// Verifies <see cref="AuditEvent"/> behaves as an init-only record:
/// every property reads back as constructed, and <c>with</c> expressions
/// produce a new instance with a single property changed.
/// </summary>
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 evt = new AuditEvent
{
EventId = eventId,
OccurredAtUtc = occurredAt,
IngestedAtUtc = ingestedAt,
Channel = AuditChannel.ApiOutbound,
Kind = AuditKind.ApiCall,
CorrelationId = corrId,
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("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,
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.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);
}
}