fix(configuration-database): resolve ConfigurationDatabase-002..007 — remove hardcoded sa creds, fail-fast no-arg DI, encrypt secret columns, resilient audit serialization
This commit is contained in:
@@ -124,4 +124,35 @@ public class AuditServiceTests : IDisposable
|
||||
Assert.DoesNotContain(methods, m => m.Name.Contains("Update", StringComparison.OrdinalIgnoreCase));
|
||||
Assert.DoesNotContain(methods, m => m.Name.Contains("Delete", StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
// Self-referential POCO used to reproduce a reference cycle in afterState.
|
||||
private sealed class CyclicNode
|
||||
{
|
||||
public string Name { get; set; } = "node";
|
||||
public CyclicNode? Self { get; set; }
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task LogAsync_AfterStateWithReferenceCycle_DoesNotThrow_AndDoesNotRollBackOperation()
|
||||
{
|
||||
// Regression guard for ConfigurationDatabase-007: serializing an afterState
|
||||
// object that contains a reference cycle must not throw a JsonException —
|
||||
// that would roll back the entire business operation it is auditing.
|
||||
var node = new CyclicNode();
|
||||
node.Self = node; // reference cycle
|
||||
|
||||
var template = new Template("CyclicAuditTemplate");
|
||||
_context.Templates.Add(template);
|
||||
|
||||
// Must not throw.
|
||||
await _auditService.LogAsync("admin", "Create", "Template", "1", "CyclicAuditTemplate", node);
|
||||
|
||||
// The audited business operation must still commit successfully.
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
var audit = await _context.AuditLogEntries.SingleAsync();
|
||||
Assert.NotNull(audit.AfterStateJson);
|
||||
Assert.Contains("node", audit.AfterStateJson);
|
||||
Assert.Single(await _context.Templates.Where(t => t.Name == "CyclicAuditTemplate").ToListAsync());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user