fix(audit): ScadaBridge C3 review — safe enum-parse (fallback) in SqliteAuditWriter.MapRow + AuditEventDtoMapper.FromDto (Task 2.5)

This commit is contained in:
Joseph Doherty
2026-06-02 12:55:07 -04:00
parent db707bb0de
commit c27b2c3d5f
5 changed files with 82 additions and 7 deletions
@@ -268,4 +268,30 @@ public class AuditEventDtoMapperTests
// …and FromDto rehydrates empty → null.
Assert.Null(roundTripped.SourceNode);
}
/// <summary>
/// C3 hardening (Task 2.5): a DTO that carries an unknown/renamed enum string
/// for Channel, Kind, or Status must NOT throw on <see cref="AuditEventDtoMapper.FromDto"/>;
/// it degrades gracefully to the same fallbacks used by <c>AuditRowProjection.Decompose</c>
/// (ApiInbound / InboundRequest / Submitted).
/// </summary>
[Fact]
public void FromDto_UnknownEnumStrings_DoNotThrow_YieldFallbackValues()
{
var dto = new AuditEventDto
{
EventId = Guid.NewGuid().ToString(),
OccurredAtUtc = Timestamp.FromDateTime(DateTime.UtcNow),
Channel = "ObsoleteChannelV0", // unknown — not a declared AuditChannel member
Kind = "LegacyKindName", // unknown — not a declared AuditKind member
Status = "RenamedStatus99", // unknown — not a declared AuditStatus member
};
// Must not throw (previously would throw ArgumentException from Enum.Parse).
var row = AuditEventDtoMapper.FromDto(dto).AsRow();
Assert.Equal(AuditChannel.ApiInbound, row.Channel);
Assert.Equal(AuditKind.InboundRequest, row.Kind);
Assert.Equal(AuditStatus.Submitted, row.Status);
}
}