test(sitecall-audit): symmetric SourceNode coverage on DbOutbound emitter + clarify DI comments

Two follow-ups from the T13/T14 code review:

- M1: Add CachedWrite_StampsSourceNode_OnSubmitTelemetryRow and
  CachedWrite_NoSourceNodeWired_LeavesSourceNodeNull to DatabaseCachedWriteEmissionTests,
  mirroring the existing ApiOutbound SourceNode tests in
  ExternalSystemCachedCallEmissionTests. Site-emitter coverage now symmetric
  across both cached-call channels.
- M2: Clarify the GetService(INodeIdentityProvider) DI comments on the
  CachedCallTelemetryForwarder and CachedCallLifecycleBridge factories:
  it's test composition roots that may not register the provider, not
  central production. Both site and central hosts always register it via
  SiteServiceRegistration.BindSharedOptions.
This commit is contained in:
Joseph Doherty
2026-05-23 17:50:14 -04:00
parent 06ed0acead
commit 466e1454fe
2 changed files with 76 additions and 7 deletions

View File

@@ -328,4 +328,68 @@ public class DatabaseCachedWriteEmissionTests
It.IsAny<Guid?>(), It.IsAny<string?>(), It.IsAny<Guid?>()),
Times.Once);
}
// ── SourceNode-stamping (Task 14) ──
[Fact]
public async Task CachedWrite_StampsSourceNode_OnSubmitTelemetryRow()
{
// Symmetric to ExternalSystemCachedCallEmissionTests's
// CachedCall_StampsSourceNode_OnEverySiteCallOperationalRow — locks
// the DbOutbound emitter against a future refactor that drops
// _sourceNode from the Database.CachedWrite CachedSubmit row.
var gateway = new Mock<IDatabaseGateway>();
gateway
.Setup(g => g.CachedWriteAsync(
"myDb", "INSERT INTO t VALUES (1)",
It.IsAny<IReadOnlyDictionary<string, object?>?>(),
InstanceName,
It.IsAny<CancellationToken>(),
It.IsAny<TrackedOperationId?>(),
It.IsAny<Guid?>(), It.IsAny<string?>(), It.IsAny<Guid?>()))
.Returns(Task.CompletedTask);
var forwarder = new CapturingForwarder();
var helper = new ScriptRuntimeContext.DatabaseHelper(
gateway.Object,
InstanceName,
NullLogger.Instance,
TestExecutionId,
auditWriter: null,
siteId: SiteId,
sourceScript: SourceScript,
cachedForwarder: forwarder,
parentExecutionId: null,
sourceNode: "node-a");
await helper.CachedWrite("myDb", "INSERT INTO t VALUES (1)");
var packet = Assert.Single(forwarder.Telemetry);
Assert.Equal("node-a", packet.Operational.SourceNode);
}
[Fact]
public async Task CachedWrite_NoSourceNodeWired_LeavesSourceNodeNull()
{
// Default CreateHelper does NOT pass sourceNode — the legacy / test
// host path. The operational row carries null SourceNode, leaving
// central's SiteCalls.SourceNode NULL.
var gateway = new Mock<IDatabaseGateway>();
gateway
.Setup(g => g.CachedWriteAsync(
"myDb", "INSERT INTO t VALUES (1)",
It.IsAny<IReadOnlyDictionary<string, object?>?>(),
InstanceName,
It.IsAny<CancellationToken>(),
It.IsAny<TrackedOperationId?>(),
It.IsAny<Guid?>(), It.IsAny<string?>(), It.IsAny<Guid?>()))
.Returns(Task.CompletedTask);
var forwarder = new CapturingForwarder();
var helper = CreateHelper(gateway.Object, forwarder);
await helper.CachedWrite("myDb", "INSERT INTO t VALUES (1)");
var packet = Assert.Single(forwarder.Telemetry);
Assert.Null(packet.Operational.SourceNode);
}
}