feat(ui): show SourceNode under SourceSiteId in audit log detail popup
The audit log drilldown drawer (and the execution-tree node-detail modal, which shares this component) now renders the SourceNode field directly under SourceSiteId so provenance reads 'site → node → instance → script' in declared order. Two focused tests pin the field's presence in both populated and null cases plus the inter-field ordering.
This commit is contained in:
@@ -28,6 +28,9 @@
|
||||
<dt class="col-4 text-muted fw-normal">SourceSiteId</dt>
|
||||
<dd class="col-8" data-test="field-SourceSiteId">@(Event.SourceSiteId ?? "—")</dd>
|
||||
|
||||
<dt class="col-4 text-muted fw-normal">SourceNode</dt>
|
||||
<dd class="col-8" data-test="field-SourceNode">@(Event.SourceNode ?? "—")</dd>
|
||||
|
||||
<dt class="col-4 text-muted fw-normal">SourceInstanceId</dt>
|
||||
<dd class="col-8" data-test="field-SourceInstanceId">@(Event.SourceInstanceId ?? "—")</dd>
|
||||
|
||||
|
||||
@@ -81,6 +81,44 @@ public class AuditEventDetailTests : BunitContext
|
||||
Assert.Contains("2026-05-20T12:30:45", cut.Markup);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RendersSourceNodeField_BetweenSiteAndInstance()
|
||||
{
|
||||
// SourceNode is rendered as a sibling row directly under SourceSiteId
|
||||
// so the popup reads "site → node → instance → script" in provenance
|
||||
// order. Populated case.
|
||||
var ev = MakeEvent() with { SourceNode = "node-a" };
|
||||
|
||||
var cut = Render<AuditEventDetail>(p => p.Add(c => c.Event, ev));
|
||||
|
||||
Assert.Contains("data-test=\"field-SourceNode\"", cut.Markup);
|
||||
Assert.Contains("node-a", cut.Markup);
|
||||
|
||||
// Ordering: SourceSiteId appears before SourceNode, which appears
|
||||
// before SourceInstanceId.
|
||||
var siteIdx = cut.Markup.IndexOf("data-test=\"field-SourceSiteId\"", StringComparison.Ordinal);
|
||||
var nodeIdx = cut.Markup.IndexOf("data-test=\"field-SourceNode\"", StringComparison.Ordinal);
|
||||
var instanceIdx = cut.Markup.IndexOf("data-test=\"field-SourceInstanceId\"", StringComparison.Ordinal);
|
||||
Assert.True(siteIdx > 0 && nodeIdx > siteIdx && instanceIdx > nodeIdx,
|
||||
$"Expected SourceSiteId < SourceNode < SourceInstanceId; got {siteIdx}, {nodeIdx}, {instanceIdx}");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RendersSourceNodeField_AsDashWhenNull()
|
||||
{
|
||||
// Null SourceNode (e.g. central direct-write row pre-feature, or a
|
||||
// reconciled row from a retired node) renders as the em-dash, same
|
||||
// convention as the sibling provenance fields.
|
||||
var ev = MakeEvent(); // SourceNode left at default null
|
||||
Assert.Null(ev.SourceNode);
|
||||
|
||||
var cut = Render<AuditEventDetail>(p => p.Add(c => c.Event, ev));
|
||||
|
||||
Assert.Contains("data-test=\"field-SourceNode\"", cut.Markup);
|
||||
// The field is present and renders the em-dash placeholder.
|
||||
Assert.Contains(">—<", cut.Markup);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ErrorSection_RendersWhenErrorPresent()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user