docs(tests): fix CommentChecker findings across tests/ — 13,392 → 0 (repo-wide scan clean)

Comment/XML-doc changes only:
- add summaries to ~10k test methods, fixtures, fakes and helpers
  (+ <param> on theories, <returns> on async Task methods,
  <inheritdoc/> on interface implementations the checker can resolve)
- strip ~2.6k project-tracking references (WP*, P*-*, row-NN, Task N,
  #NN, Component-0NN) from comments, keeping the explanatory text;
  reword false positives in comments only
- real docs on fakes implementing BCL/library interfaces
  (IDisposable, ILogger, IOptionsMonitor, IAsyncLifetime)
- reword the last 5 src/ false positives (CWE-1236, failures-1,
  year-0001, M365)

Only non-comment edits: four one-line nested classes split across lines
so members can carry docs. Build 0 errors / 0 warnings.
This commit is contained in:
Joseph Doherty
2026-10-07 15:05:49 -04:00
parent 0ffd4bdbea
commit 513fa1aa16
998 changed files with 17896 additions and 2395 deletions
@@ -6,6 +6,7 @@ namespace ZB.MOM.WW.ScadaBridge.Commons.Tests.Messages;
public class AlarmStateChangedEnrichmentTests
{
/// <summary>Verifies that a default alarm state change is of the computed kind with auto-acknowledge.</summary>
[Fact]
public void Defaults_AreComputedKind_WithAutoAck()
{
@@ -17,6 +18,7 @@ public class AlarmStateChangedEnrichmentTests
Assert.Equal("", m.SourceReference);
}
/// <summary>Verifies that the computed factory maps priority and state onto the message.</summary>
[Fact]
public void Factory_ForComputed_MapsPriorityAndState()
{
@@ -28,6 +30,7 @@ public class AlarmStateChangedEnrichmentTests
// ── MES alarm-status API §6.4: additive AckTime ──
/// <summary>Verifies that the acknowledge time defaults to null when using the positional constructor.</summary>
[Fact]
public void AckTime_DefaultsToNull_OnThePositionalConstructor()
{
@@ -40,6 +43,7 @@ public class AlarmStateChangedEnrichmentTests
Assert.Null(m.AckTime); // …yet still no ack instant
}
/// <summary>Verifies that the acknowledge time round-trips through its init property.</summary>
[Fact]
public void AckTime_RoundTripsThroughTheInitProperty()
{
@@ -10,6 +10,7 @@ namespace ZB.MOM.WW.ScadaBridge.Commons.Tests.Messages;
/// </summary>
public class BrowseCommandsRegistryTests
{
/// <summary>Verifies that the command registry discovers the browse-node command.</summary>
[Fact]
public void Registry_discovers_BrowseNodeCommand()
{
@@ -4,7 +4,7 @@ using ZB.MOM.WW.ScadaBridge.Commons.Messages.Management;
namespace ZB.MOM.WW.ScadaBridge.Commons.Tests.Messages;
/// <summary>
/// Task 21 (PLAN-07): the additive optional <c>SiteIdentifier</c> trailing param on the
/// The additive optional <c>SiteIdentifier</c> trailing param on the
/// Browse/Verify/Cert-trust management commands. Verifies backward compatibility (legacy
/// JSON without the field deserializes to null) and round-trip survival when set.
/// </summary>
@@ -17,6 +17,7 @@ public class BrowseVerifyCertSiteIdentifierTests
// ── Backward compatibility: legacy JSON (no SiteIdentifier) → null ──
/// <summary>Verifies that browse node command legacy json site identifier null.</summary>
[Fact]
public void BrowseNodeCommand_LegacyJson_SiteIdentifierNull()
{
@@ -26,6 +27,7 @@ public class BrowseVerifyCertSiteIdentifierTests
Assert.Equal("conn", cmd.ConnectionName);
}
/// <summary>Verifies that search address space command legacy json site identifier null.</summary>
[Fact]
public void SearchAddressSpaceCommand_LegacyJson_SiteIdentifierNull()
{
@@ -35,6 +37,7 @@ public class BrowseVerifyCertSiteIdentifierTests
Assert.Equal("pump", cmd.Query);
}
/// <summary>Verifies that verify endpoint command legacy json site identifier null.</summary>
[Fact]
public void VerifyEndpointCommand_LegacyJson_SiteIdentifierNull()
{
@@ -44,6 +47,7 @@ public class BrowseVerifyCertSiteIdentifierTests
Assert.Equal("OpcUa", cmd.Protocol);
}
/// <summary>Verifies that trust server cert command legacy json site identifier null.</summary>
[Fact]
public void TrustServerCertCommand_LegacyJson_SiteIdentifierNull()
{
@@ -53,6 +57,7 @@ public class BrowseVerifyCertSiteIdentifierTests
Assert.Equal("ABCD", cmd.Thumbprint);
}
/// <summary>Verifies that remove server cert command legacy json site identifier null.</summary>
[Fact]
public void RemoveServerCertCommand_LegacyJson_SiteIdentifierNull()
{
@@ -62,6 +67,7 @@ public class BrowseVerifyCertSiteIdentifierTests
Assert.Equal("ABCD", cmd.Thumbprint);
}
/// <summary>Verifies that list server certs command legacy json site identifier null.</summary>
[Fact]
public void ListServerCertsCommand_LegacyJson_SiteIdentifierNull()
{
@@ -72,6 +78,7 @@ public class BrowseVerifyCertSiteIdentifierTests
// ── Round-trip: SiteIdentifier set survives serialize → deserialize ──
/// <summary>Verifies that browse node command round trip site identifier survives.</summary>
[Fact]
public void BrowseNodeCommand_RoundTrip_SiteIdentifierSurvives()
{
@@ -82,6 +89,7 @@ public class BrowseVerifyCertSiteIdentifierTests
Assert.Equal(original, round);
}
/// <summary>Verifies that search address space command round trip site identifier survives.</summary>
[Fact]
public void SearchAddressSpaceCommand_RoundTrip_SiteIdentifierSurvives()
{
@@ -92,6 +100,7 @@ public class BrowseVerifyCertSiteIdentifierTests
Assert.Equal(original, round);
}
/// <summary>Verifies that verify endpoint command round trip site identifier survives.</summary>
[Fact]
public void VerifyEndpointCommand_RoundTrip_SiteIdentifierSurvives()
{
@@ -102,6 +111,7 @@ public class BrowseVerifyCertSiteIdentifierTests
Assert.Equal(original, round);
}
/// <summary>Verifies that trust server cert command round trip site identifier survives.</summary>
[Fact]
public void TrustServerCertCommand_RoundTrip_SiteIdentifierSurvives()
{
@@ -112,6 +122,7 @@ public class BrowseVerifyCertSiteIdentifierTests
Assert.Equal(original, round);
}
/// <summary>Verifies that remove server cert command round trip site identifier survives.</summary>
[Fact]
public void RemoveServerCertCommand_RoundTrip_SiteIdentifierSurvives()
{
@@ -122,6 +133,7 @@ public class BrowseVerifyCertSiteIdentifierTests
Assert.Equal(original, round);
}
/// <summary>Verifies that list server certs command round trip site identifier survives.</summary>
[Fact]
public void ListServerCertsCommand_RoundTrip_SiteIdentifierSurvives()
{
@@ -39,6 +39,7 @@ public class ClusterClientContractLockTests
// (a) Old-shape payloads: newer trailing optional fields absent → defaults.
// ---------------------------------------------------------------------
/// <summary>Verifies that an old-shape <c>CreateDataConnectionCommand</c> without the newer trailing fields still deserializes.</summary>
[Fact]
public void CreateDataConnectionCommand_OldShape_WithoutNewerTrailingFields_Deserializes()
{
@@ -62,6 +63,7 @@ public class ClusterClientContractLockTests
Assert.Equal(0, cmd.FailoverRetryCount); // value-type missing field → default(int), not 3
}
/// <summary>Verifies that an old-shape <c>DeployInstanceCommand</c> without the fetch fields still deserializes.</summary>
[Fact]
public void DeployInstanceCommand_OldShape_WithoutFetchFields_Deserializes()
{
@@ -78,6 +80,7 @@ public class ClusterClientContractLockTests
Assert.Null(cmd.FetchToken); // default applied
}
/// <summary>Verifies that an old-shape <c>NotificationSubmit</c> without the execution correlation fields still deserializes.</summary>
[Fact]
public void NotificationSubmit_OldShape_WithoutExecutionCorrelationFields_Deserializes()
{
@@ -99,6 +102,7 @@ public class ClusterClientContractLockTests
// (b) Unknown fields from a newer peer are ignored (never throw).
// ---------------------------------------------------------------------
/// <summary>Verifies that an unknown field from a newer peer is ignored when deserializing <c>AttributeValueChanged</c>.</summary>
[Fact]
public void AttributeValueChanged_UnknownFieldFromNewerPeer_IsIgnored()
{
@@ -112,6 +116,7 @@ public class ClusterClientContractLockTests
Assert.Equal("Good", evt.Quality);
}
/// <summary>Verifies that an unknown field from a newer peer is ignored when deserializing <c>GetAttributeRequest</c>.</summary>
[Fact]
public void GetAttributeRequest_UnknownFieldFromNewerPeer_IsIgnored()
{
@@ -125,6 +130,7 @@ public class ClusterClientContractLockTests
Assert.Equal("a", req.AttributeName);
}
/// <summary>Verifies that an unknown field from a newer peer is ignored when deserializing <c>SetStaticAttributeCommand</c>.</summary>
[Fact]
public void SetStaticAttributeCommand_UnknownFieldFromNewerPeer_IsIgnored()
{
@@ -142,6 +148,7 @@ public class ClusterClientContractLockTests
// (c) Round-trip preserves values.
// ---------------------------------------------------------------------
/// <summary>Verifies that a <c>ManagementEnvelope</c> round trip preserves the correlation id and user.</summary>
[Fact]
public void ManagementEnvelope_RoundTrip_PreservesCorrelationIdAndUser()
{
@@ -159,6 +166,7 @@ public class ClusterClientContractLockTests
Assert.Equal(new[] { "site-1", "site-2" }, round.User.PermittedSiteIds);
}
/// <summary>Verifies that an <c>AttributeValueChanged</c> round trip preserves its values.</summary>
[Fact]
public void AttributeValueChanged_RoundTrip_PreservesValues()
{
@@ -175,6 +183,7 @@ public class ClusterClientContractLockTests
Assert.Equal(evt.Timestamp, round.Timestamp);
}
/// <summary>Verifies that a <c>CreateDataConnectionCommand</c> round trip preserves its values.</summary>
[Fact]
public void CreateDataConnectionCommand_RoundTrip_PreservesValues()
{
@@ -11,7 +11,7 @@ using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
namespace ZB.MOM.WW.ScadaBridge.Commons.Tests.Messages;
/// <summary>
/// WP-9 (Phase 8): Message contract compatibility tests.
/// Message contract compatibility tests.
/// Verifies forward compatibility (unknown fields), backward compatibility (missing optional fields),
/// and version skew scenarios for all critical message types.
/// </summary>
@@ -24,6 +24,7 @@ public class CompatibilityTests
// ── Forward Compatibility: unknown fields are ignored ──
/// <summary>Verifies that a deploy-instance command ignores an unknown field when deserialized.</summary>
[Fact]
public void ForwardCompat_DeployInstanceCommand_UnknownFieldIgnored()
{
@@ -46,6 +47,7 @@ public class CompatibilityTests
Assert.Equal("abc123", msg.RevisionHash);
}
/// <summary>Verifies that a site health report ignores an unknown field when deserialized.</summary>
[Fact]
public void ForwardCompat_SiteHealthReport_UnknownFieldIgnored()
{
@@ -70,6 +72,7 @@ public class CompatibilityTests
Assert.Equal(5, msg.SequenceNumber);
}
/// <summary>Verifies that a script call request ignores an unknown field when deserialized.</summary>
[Fact]
public void ForwardCompat_ScriptCallRequest_UnknownFieldIgnored()
{
@@ -90,6 +93,7 @@ public class CompatibilityTests
Assert.Equal("OnTrigger", msg.ScriptName);
}
/// <summary>Verifies that an attribute-value-changed message ignores an unknown field when deserialized.</summary>
[Fact]
public void ForwardCompat_AttributeValueChanged_UnknownFieldIgnored()
{
@@ -112,6 +116,7 @@ public class CompatibilityTests
// ── Backward Compatibility: missing optional fields ──
/// <summary>Verifies that a deployment status response deserializes when the error message is missing.</summary>
[Fact]
public void BackwardCompat_DeploymentStatusResponse_MissingErrorMessage()
{
@@ -130,6 +135,7 @@ public class CompatibilityTests
Assert.Null(msg.ErrorMessage);
}
/// <summary>Verifies that a script call result deserializes when the return value is missing.</summary>
[Fact]
public void BackwardCompat_ScriptCallResult_MissingReturnValue()
{
@@ -147,6 +153,7 @@ public class CompatibilityTests
Assert.Null(msg.ReturnValue);
}
/// <summary>Verifies that a deploy-artifacts command deserializes when the optional lists are missing.</summary>
[Fact]
public void BackwardCompat_DeployArtifactsCommand_MissingOptionalLists()
{
@@ -164,6 +171,7 @@ public class CompatibilityTests
Assert.Null(msg.ExternalSystems);
}
/// <summary>Verifies that an instance lifecycle response deserializes when the error message is missing.</summary>
[Fact]
public void BackwardCompat_InstanceLifecycleResponse_MissingErrorMessage()
{
@@ -184,6 +192,7 @@ public class CompatibilityTests
// ── Version Skew: old message format still deserializable ──
/// <summary>Verifies that an old-shape deploy command deserializes with default values for newer fields.</summary>
[Fact]
public void VersionSkew_OldDeployCommand_DeserializesWithDefaults()
{
@@ -205,6 +214,7 @@ public class CompatibilityTests
Assert.Equal("old-hash", msg.RevisionHash);
}
/// <summary>Verifies that an old-shape health report deserializes correctly.</summary>
[Fact]
public void VersionSkew_OldHealthReport_DeserializesCorrectly()
{
@@ -230,11 +240,12 @@ public class CompatibilityTests
// ── Round-trip serialization for all key message types ──
// Communication-016: RoundTrip_ConnectionStateChanged_Succeeds removed
// RoundTrip_ConnectionStateChanged_Succeeds removed
// alongside the dead ConnectionStateChanged message record. No production
// code emits or receives this message — disconnect detection is owned by
// the gRPC keepalive and the Ask-timeout path.
/// <summary>Verifies that an alarm-state-changed message survives a serialization round trip.</summary>
[Fact]
public void RoundTrip_AlarmStateChanged_Succeeds()
{
@@ -247,6 +258,7 @@ public class CompatibilityTests
Assert.Equal("HighTemp", deserialized.AlarmName);
}
/// <summary>Verifies that an alarm-state-changed message preserves its acknowledgement time across a round trip.</summary>
[Fact]
public void RoundTrip_AlarmStateChanged_PreservesAckTime()
{
@@ -264,6 +276,7 @@ public class CompatibilityTests
Assert.Equal(ackedAt, deserialized!.AckTime);
}
/// <summary>Verifies that a missing acknowledgement time deserializes as null.</summary>
[Fact]
public void BackwardCompat_AlarmStateChanged_MissingAckTime_DefaultsToNull()
{
@@ -285,6 +298,7 @@ public class CompatibilityTests
Assert.Null(deserialized!.AckTime);
}
/// <summary>Verifies that a missing MES-reportable flag deserializes as false.</summary>
[Fact]
public void BackwardCompat_AlarmStateChanged_MissingIsMesReportable_DefaultsToFalse()
{
@@ -308,6 +322,7 @@ public class CompatibilityTests
Assert.False(deserialized!.IsMesReportable);
}
/// <summary>Verifies that a heartbeat message survives a serialization round trip.</summary>
[Fact]
public void RoundTrip_HeartbeatMessage_Succeeds()
{
@@ -320,6 +335,7 @@ public class CompatibilityTests
Assert.Equal("node-a", deserialized.NodeHostname);
}
/// <summary>Verifies that a disable-instance command survives a serialization round trip.</summary>
[Fact]
public void RoundTrip_DisableInstanceCommand_Succeeds()
{
@@ -331,6 +347,7 @@ public class CompatibilityTests
Assert.Equal("cmd-1", deserialized!.CommandId);
}
/// <summary>Verifies that an enable-instance command survives a serialization round trip.</summary>
[Fact]
public void RoundTrip_EnableInstanceCommand_Succeeds()
{
@@ -342,6 +359,7 @@ public class CompatibilityTests
Assert.Equal("cmd-2", deserialized!.CommandId);
}
/// <summary>Verifies that a delete-instance command survives a serialization round trip.</summary>
[Fact]
public void RoundTrip_DeleteInstanceCommand_Succeeds()
{
@@ -355,6 +373,7 @@ public class CompatibilityTests
// ── Additive-only evolution: new fields added as nullable ──
/// <summary>Verifies that newly added nullable fields do not break deserialization of older payloads.</summary>
[Fact]
public void AdditiveEvolution_NewNullableFields_DoNotBreakDeserialization()
{
@@ -369,6 +388,7 @@ public class CompatibilityTests
Assert.Null(msg!.ErrorMessage); // Optional field defaults to null
}
/// <summary>Verifies that an unknown enum value is handled gracefully during deserialization.</summary>
[Fact]
public void EnumDeserialization_UnknownValue_HandledGracefully()
{
@@ -381,8 +401,9 @@ public class CompatibilityTests
Assert.Equal((DeploymentStatus)99, msg!.Status);
}
// ── DeploymentManager-006: query-the-site-before-redeploy contracts ──
// ── query-the-site-before-redeploy contracts ──
/// <summary>Verifies that a deployment-state query request survives a serialization round trip.</summary>
[Fact]
public void RoundTrip_DeploymentStateQueryRequest_Succeeds()
{
@@ -395,6 +416,7 @@ public class CompatibilityTests
Assert.Equal("inst-1", deserialized.InstanceUniqueName);
}
/// <summary>Verifies that a deployed deployment-state query response survives a serialization round trip.</summary>
[Fact]
public void RoundTrip_DeploymentStateQueryResponse_Deployed_Succeeds()
{
@@ -409,6 +431,7 @@ public class CompatibilityTests
Assert.Equal("sha256:abc", deserialized.AppliedRevisionHash);
}
/// <summary>Verifies that a not-deployed deployment-state query response keeps its null applied state across a round trip.</summary>
[Fact]
public void RoundTrip_DeploymentStateQueryResponse_NotDeployed_NullApplied()
{
@@ -4,13 +4,14 @@ using ZB.MOM.WW.ScadaBridge.Commons.Messages.Management;
namespace ZB.MOM.WW.ScadaBridge.Commons.Tests.Messages;
/// <summary>
/// Regression tests for Commons-008 — <see cref="SetConnectionBindingsCommand"/>
/// Regression tests: <see cref="SetConnectionBindingsCommand"/>
/// previously declared its bindings as <c>IReadOnlyList&lt;(string, int)&gt;</c>.
/// A <c>ValueTuple</c> serializes as <c>Item1</c>/<c>Item2</c> and cannot evolve
/// additively (REQ-COM-5a). It is now a named <see cref="ConnectionBinding"/> record.
/// </summary>
public class ConnectionBindingSerializationTests
{
/// <summary>Verifies that connection binding serializes with named properties.</summary>
[Fact]
public void ConnectionBinding_SerializesWithNamedProperties()
{
@@ -26,6 +27,7 @@ public class ConnectionBindingSerializationTests
Assert.False(doc.RootElement.TryGetProperty("Item2", out _));
}
/// <summary>Verifies that set connection bindings command round trips through json.</summary>
[Fact]
public void SetConnectionBindingsCommand_RoundTripsThroughJson()
{
@@ -52,6 +54,7 @@ public class ConnectionBindingSerializationTests
Assert.Equal(original.Bindings, deserialized.Bindings);
}
/// <summary>Verifies that roundtrip preserves override when set.</summary>
[Fact]
public void Roundtrip_preserves_override_when_set()
{
@@ -65,6 +68,7 @@ public class ConnectionBindingSerializationTests
Assert.Equal("ns=2;s=Pump1.Speed", roundtripped!.DataSourceReferenceOverride);
}
/// <summary>Verifies that roundtrip defaults override to null when absent.</summary>
[Fact]
public void Roundtrip_defaults_override_to_null_when_absent()
{
@@ -6,12 +6,12 @@ using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
namespace ZB.MOM.WW.ScadaBridge.Commons.Tests.Messages.Integration;
/// <summary>
/// Audit Log (#23) telemetry handoff: envelope + pull request/response DTOs.
/// Audit Log telemetry handoff: envelope + pull request/response DTOs.
/// At-least-once from sites; idempotent at central on <see cref="AuditEvent.EventId"/>.
/// </summary>
public class AuditTelemetryMessagesTests
{
// C3 (Task 2.5): canonical ZB.MOM.WW.Audit.AuditEvent built via the shared
// Canonical ZB.MOM.WW.Audit.AuditEvent built via the shared
// factory (domain fields ride in DetailsJson). These tests assert only the
// envelope/response DTO behaviour, so the audit row's contents are incidental.
private static AuditEvent MakeEvent(Guid? id = null) =>
@@ -21,6 +21,7 @@ public class AuditTelemetryMessagesTests
status: AuditStatus.Delivered,
eventId: id ?? Guid.NewGuid());
/// <summary>Verifies that a telemetry envelope constructed with three events can be enumerated.</summary>
[Fact]
public void AuditTelemetryEnvelope_ConstructsWithThreeEvents_AndIsEnumerable()
{
@@ -42,6 +43,7 @@ public class AuditTelemetryMessagesTests
Assert.Equal(3, collected.Count);
}
/// <summary>Verifies that the telemetry envelope is immutable and compares its event list by reference identity.</summary>
[Fact]
public void AuditTelemetryEnvelope_IsImmutable_RecordEqualityOnReferenceIdentityOfList()
{
@@ -62,6 +64,7 @@ public class AuditTelemetryMessagesTests
Assert.Equal("site-01", a.SourceSiteId);
}
/// <summary>Verifies that a pull request can be constructed and is immutable.</summary>
[Fact]
public void PullAuditEventsRequest_ConstructsAndIsImmutable()
{
@@ -77,6 +80,7 @@ public class AuditTelemetryMessagesTests
Assert.Equal(500, bigger.BatchSize);
}
/// <summary>Verifies that a pull response with more-available set can be constructed and enumerated.</summary>
[Fact]
public void PullAuditEventsResponse_ConstructsWithMoreAvailableTrue_AndIsEnumerable()
{
@@ -94,6 +98,7 @@ public class AuditTelemetryMessagesTests
Assert.Equal(2, collected.Count);
}
/// <summary>Verifies that a with-expression on a pull response changes only the targeted field.</summary>
[Fact]
public void PullAuditEventsResponse_WithExpression_ChangesSingleField()
{
@@ -7,7 +7,7 @@ using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
namespace ZB.MOM.WW.ScadaBridge.Commons.Tests.Messages.Integration;
/// <summary>
/// Audit Log #23 (M3 Bundle A — Task A4) — tests for the combined
/// Tests for the combined
/// audit + operational telemetry packet emitted per cached-call lifecycle event
/// (<c>Submit</c> → per-attempt <c>ApiCallCached</c> / <c>DbWriteCached</c> →
/// terminal <c>Resolve</c>). The site emits one packet per event; central writes
@@ -29,7 +29,7 @@ public class CachedCallTelemetryTests
string? errorMessage = null,
int? httpStatus = null)
{
// C3 (Task 2.5): build the canonical ZB.MOM.WW.Audit.AuditEvent via the
// Build the canonical ZB.MOM.WW.Audit.AuditEvent via the
// shared factory; the ScadaBridge domain fields ride in DetailsJson and
// are read back as typed properties via AsRow() in the assertions.
// ForwardState is no longer a packet field — it is a site-storage-only
@@ -61,7 +61,7 @@ public class CachedCallTelemetryTests
Channel: nameof(AuditChannel.ApiOutbound),
Target: "ERP.GetOrder",
SourceSite: SiteId,
// SourceNode: actual stamping arrives with Task 14; for now the
// SourceNode: actual stamping is not done here; the
// packet builder leaves the column null so existing assertions on
// the packet's other fields stay intact.
SourceNode: null,
@@ -74,6 +74,7 @@ public class CachedCallTelemetryTests
TerminalAtUtc: terminalAtUtc);
}
/// <summary>Verifies that a submit packet carries a CachedSubmit audit row and an operational retry count of zero.</summary>
[Fact]
public void SubmitPacket_AuditCarriesCachedSubmit_AndOperationalRetryCountZero()
{
@@ -91,6 +92,7 @@ public class CachedCallTelemetryTests
Assert.Equal(trackedId, packet.Operational.TrackedOperationId);
}
/// <summary>Verifies that an attempted packet carries an ApiCallCached audit row whose retry count matches the operational record.</summary>
[Fact]
public void AttemptedPacket_AuditCarriesApiCallCached_RetryCountAlignsBetweenAuditAndOperational()
{
@@ -121,6 +123,7 @@ public class CachedCallTelemetryTests
Assert.Null(packet.Operational.TerminalAtUtc);
}
/// <summary>Verifies that an attempted database-write packet carries the DbWriteCached kind.</summary>
[Fact]
public void AttemptedPacket_DbWriteCached_CarriesDbWriteCachedKind()
{
@@ -144,6 +147,8 @@ public class CachedCallTelemetryTests
Assert.Equal(1, packet.Operational.RetryCount);
}
/// <summary>Verifies that a resolve packet carries a CachedResolve audit row and sets the operational terminal timestamp.</summary>
/// <param name="terminalStatus">The terminal audit status being resolved.</param>
[Theory]
[InlineData(AuditStatus.Delivered)]
[InlineData(AuditStatus.Failed)]
@@ -169,6 +174,7 @@ public class CachedCallTelemetryTests
Assert.Equal(terminalAt, packet.Operational.TerminalAtUtc);
}
/// <summary>Verifies that a cached-call telemetry packet is equal to a copy built from the same values.</summary>
[Fact]
public void CachedCallTelemetry_RoundTripEquality()
{
@@ -190,6 +196,7 @@ public class CachedCallTelemetryTests
Assert.Equal(1, c.Operational.RetryCount);
}
/// <summary>Verifies that a site-call operational record supports value equality and non-destructive copying with a with-expression.</summary>
[Fact]
public void SiteCallOperational_RoundTripEquality_AndWithExpression()
{
@@ -4,8 +4,8 @@ using ZB.MOM.WW.ScadaBridge.Commons.Messages.Management;
namespace ZB.MOM.WW.ScadaBridge.Commons.Tests.Messages;
/// <summary>
/// Tests for <see cref="ManagementCommandRegistry"/>, including the Commons-004
/// regression: <c>GetCommandName</c> and <c>Resolve</c> must be symmetric — every
/// Tests for <see cref="ManagementCommandRegistry"/>, including the
/// regression where <c>GetCommandName</c> and <c>Resolve</c> must be symmetric — every
/// type for which <c>GetCommandName</c> yields a name must round-trip back to the
/// same type via <c>Resolve</c>.
/// </summary>
@@ -19,6 +19,7 @@ public class ManagementCommandRegistryTests
&& t != typeof(ReadTagValuesCommand)
&& t != typeof(ResolveRolesCommand));
/// <summary>Verifies that every registered command type round-trips through <c>GetCommandName</c> and <c>Resolve</c>.</summary>
[Fact]
public void GetCommandName_Resolve_RoundTrips_ForEveryRegisteredCommand()
{
@@ -30,6 +31,7 @@ public class ManagementCommandRegistryTests
}
}
/// <summary>Verifies that resolving a known command name returns its type.</summary>
[Fact]
public void Resolve_KnownCommand_ReturnsType()
{
@@ -37,12 +39,14 @@ public class ManagementCommandRegistryTests
Assert.Equal(typeof(CreateSiteCommand), type);
}
/// <summary>Verifies that resolving an unknown command name returns null.</summary>
[Fact]
public void Resolve_UnknownCommand_ReturnsNull()
{
Assert.Null(ManagementCommandRegistry.Resolve("NoSuchCommand"));
}
/// <summary>Verifies that resolving a command name is case-insensitive.</summary>
[Fact]
public void Resolve_IsCaseInsensitive()
{
@@ -50,7 +54,7 @@ public class ManagementCommandRegistryTests
}
/// <summary>
/// Commons-004: <c>GetCommandName</c> previously stripped a <c>Command</c> suffix
/// <c>GetCommandName</c> previously stripped a <c>Command</c> suffix
/// from <em>any</em> type, producing names the registry cannot resolve. It must
/// only return a name for a command type the registry actually contains.
/// </summary>
@@ -62,6 +66,7 @@ public class ManagementCommandRegistryTests
() => ManagementCommandRegistry.GetCommandName(typeof(UnregisteredFakeCommand)));
}
/// <summary>Verifies that <c>GetCommandName</c> throws for a type that is not a registered command.</summary>
[Fact]
public void GetCommandName_NonCommandType_Throws()
{
@@ -69,12 +74,14 @@ public class ManagementCommandRegistryTests
() => ManagementCommandRegistry.GetCommandName(typeof(string)));
}
/// <summary>Verifies that <c>GetCommandName</c> returns the command name with the <c>Command</c> suffix stripped.</summary>
[Fact]
public void GetCommandName_RegisteredCommand_ReturnsStrippedName()
{
Assert.Equal("CreateSite", ManagementCommandRegistry.GetCommandName(typeof(CreateSiteCommand)));
}
/// <summary>Verifies that all native alarm source commands are registered.</summary>
[Fact]
public void Resolve_NativeAlarmSourceCommands_AllRegistered()
{
@@ -95,7 +102,7 @@ public class ManagementCommandRegistryTests
}
/// <summary>
/// M9-T32c: the schema-library CRUD commands must auto-register by reflection
/// The schema-library CRUD commands must auto-register by reflection
/// (no manual registry entry) so the HTTP management boundary can route them.
/// </summary>
[Fact]
@@ -17,6 +17,7 @@ public class MessageConventionTests
&& !t.Name.StartsWith("<") // exclude compiler-generated types
&& (t.IsClass || (t.IsValueType && !t.IsPrimitive)));
/// <summary>Verifies that every message type is a record.</summary>
[Fact]
public void AllMessageTypes_ShouldBeRecords()
{
@@ -29,6 +30,7 @@ public class MessageConventionTests
}
}
/// <summary>Verifies that every message timestamp property is a <c>DateTimeOffset</c>.</summary>
[Fact]
public void AllMessageTimestampProperties_ShouldBeDateTimeOffset()
{
@@ -46,6 +48,7 @@ public class MessageConventionTests
}
}
/// <summary>Verifies that a deploy-instance command survives a JSON round trip.</summary>
[Fact]
public void JsonRoundTrip_DeployInstanceCommand_ShouldSucceed()
{
@@ -60,6 +63,7 @@ public class MessageConventionTests
Assert.Equal(msg.InstanceUniqueName, deserialized.InstanceUniqueName);
}
/// <summary>Verifies that JSON containing an unknown field still deserializes.</summary>
[Fact]
public void JsonForwardCompatibility_UnknownField_ShouldDeserialize()
{
@@ -72,6 +76,7 @@ public class MessageConventionTests
Assert.Equal("dep-1", deserialized!.DeploymentId);
}
/// <summary>Verifies that JSON missing an optional field still deserializes.</summary>
[Fact]
public void JsonBackwardCompatibility_MissingOptionalField_ShouldDeserialize()
{
@@ -85,6 +90,7 @@ public class MessageConventionTests
Assert.Null(deserialized.ErrorMessage);
}
/// <summary>Verifies that a site health report survives a JSON round trip.</summary>
[Fact]
public void JsonRoundTrip_SiteHealthReport_ShouldSucceed()
{
@@ -110,6 +116,7 @@ public class MessageConventionTests
Assert.Equal(1, deserialized.SequenceNumber);
}
/// <summary>Verifies that a deploy-artifacts command survives a JSON round trip.</summary>
[Fact]
public void JsonRoundTrip_DeployArtifactsCommand_ShouldSucceed()
{
@@ -6,6 +6,7 @@ namespace ZB.MOM.WW.ScadaBridge.Commons.Tests.Messages;
public class NativeAlarmMessagesTests
{
/// <summary>Verifies that subscribe alarms request: carries source and filter.</summary>
[Fact]
public void SubscribeAlarmsRequest_CarriesSourceAndFilter()
{
@@ -14,6 +15,7 @@ public class NativeAlarmMessagesTests
Assert.Null(r.ConditionFilter);
}
/// <summary>Verifies that native alarm transition update: wraps transition.</summary>
[Fact]
public void NativeAlarmTransitionUpdate_WrapsTransition()
{
@@ -25,6 +27,7 @@ public class NativeAlarmMessagesTests
Assert.Equal("Tank01", u.Transition.SourceObjectReference);
}
/// <summary>Verifies that native alarm transition, when ack time, is an additive trailing parameter.</summary>
[Fact]
public void NativeAlarmTransition_AckTime_IsAnAdditiveTrailingParameter()
{
@@ -9,8 +9,9 @@ namespace ZB.MOM.WW.ScadaBridge.Commons.Tests.Messages;
/// </summary>
public class NotificationMessagesTests
{
// ── Task 7: site/central notification message contracts ──
// ── Site/central notification message contracts ──
/// <summary>Verifies that positional construction of a notification submit sets all fields.</summary>
[Fact]
public void NotificationSubmit_PositionalConstruction_SetsAllFields()
{
@@ -29,6 +30,7 @@ public class NotificationMessagesTests
Assert.Equal(enqueuedAt, msg.SiteEnqueuedAt);
}
/// <summary>Verifies that a notification submit allows null optional source fields.</summary>
[Fact]
public void NotificationSubmit_AllowsNullOptionalSourceFields()
{
@@ -40,10 +42,11 @@ public class NotificationMessagesTests
Assert.Null(msg.SourceScript);
}
/// <summary>Verifies that the origin execution id of a notification submit defaults to null.</summary>
[Fact]
public void NotificationSubmit_OriginExecutionId_DefaultsToNull()
{
// Audit Log #23: OriginExecutionId is an additive trailing member — a
// OriginExecutionId is an additive trailing member — a
// submit built without it (old call sites / old serialized payloads)
// leaves the id null.
var msg = new NotificationSubmit(
@@ -53,6 +56,7 @@ public class NotificationMessagesTests
Assert.Null(msg.OriginExecutionId);
}
/// <summary>Verifies that the origin execution id round-trips when supplied.</summary>
[Fact]
public void NotificationSubmit_OriginExecutionId_RoundTripsWhenSupplied()
{
@@ -64,6 +68,7 @@ public class NotificationMessagesTests
Assert.Equal(executionId, msg.OriginExecutionId);
}
/// <summary>Verifies that the origin execution id survives a JSON round trip.</summary>
[Fact]
public void NotificationSubmit_OriginExecutionId_SurvivesJsonRoundTrip()
{
@@ -81,6 +86,7 @@ public class NotificationMessagesTests
Assert.Equal(executionId, roundTripped!.OriginExecutionId);
}
/// <summary>Verifies that the origin parent execution id defaults to null.</summary>
[Fact]
public void NotificationSubmit_OriginParentExecutionId_DefaultsToNull()
{
@@ -94,6 +100,7 @@ public class NotificationMessagesTests
Assert.Null(msg.OriginParentExecutionId);
}
/// <summary>Verifies that the origin parent execution id round-trips when supplied.</summary>
[Fact]
public void NotificationSubmit_OriginParentExecutionId_RoundTripsWhenSupplied()
{
@@ -107,6 +114,7 @@ public class NotificationMessagesTests
Assert.Equal(parentExecutionId, msg.OriginParentExecutionId);
}
/// <summary>Verifies that the origin parent execution id survives a JSON round trip.</summary>
[Fact]
public void NotificationSubmit_OriginParentExecutionId_SurvivesJsonRoundTrip()
{
@@ -126,6 +134,7 @@ public class NotificationMessagesTests
Assert.Equal(parentExecutionId, roundTripped!.OriginParentExecutionId);
}
/// <summary>Verifies that a notification submit carries the source node.</summary>
[Fact]
public void NotificationSubmit_carries_SourceNode()
{
@@ -152,6 +161,7 @@ public class NotificationMessagesTests
Assert.Equal("node-a", roundTripped!.SourceNode);
}
/// <summary>Verifies that two notification submits are equal when all fields match.</summary>
[Fact]
public void NotificationSubmit_ValueEquality_EqualWhenAllFieldsMatch()
{
@@ -163,6 +173,7 @@ public class NotificationMessagesTests
Assert.Equal(a.GetHashCode(), b.GetHashCode());
}
/// <summary>Verifies that a with-expression on a notification submit ack changes a single field.</summary>
[Fact]
public void NotificationSubmitAck_WithExpression_ChangesSingleField()
{
@@ -176,6 +187,7 @@ public class NotificationMessagesTests
Assert.NotEqual(ack, rejected);
}
/// <summary>Verifies that positional construction of a notification status query sets all fields.</summary>
[Fact]
public void NotificationStatusQuery_PositionalConstruction_SetsAllFields()
{
@@ -185,6 +197,7 @@ public class NotificationMessagesTests
Assert.Equal("notif-9", msg.NotificationId);
}
/// <summary>Verifies that positional construction of a notification status response sets all fields.</summary>
[Fact]
public void NotificationStatusResponse_PositionalConstruction_SetsAllFields()
{
@@ -200,8 +213,9 @@ public class NotificationMessagesTests
Assert.Equal(deliveredAt, msg.DeliveredAt);
}
// ── Task 8: outbox UI query/action contracts ──
// ── Outbox UI query/action contracts ──
/// <summary>Verifies that positional construction of a notification outbox query request sets all fields.</summary>
[Fact]
public void NotificationOutboxQueryRequest_PositionalConstruction_SetsAllFields()
{
@@ -224,6 +238,7 @@ public class NotificationMessagesTests
Assert.Equal(50, msg.PageSize);
}
/// <summary>Verifies that two notification summaries are equal when all fields match.</summary>
[Fact]
public void NotificationSummary_ValueEquality_EqualWhenAllFieldsMatch()
{
@@ -239,6 +254,7 @@ public class NotificationMessagesTests
Assert.Equal(a.GetHashCode(), b.GetHashCode());
}
/// <summary>Verifies that positional construction of a notification outbox query response sets all fields.</summary>
[Fact]
public void NotificationOutboxQueryResponse_PositionalConstruction_SetsAllFields()
{
@@ -255,6 +271,7 @@ public class NotificationMessagesTests
Assert.Equal(1, msg.TotalCount);
}
/// <summary>Verifies that the retry notification request and response round-trip their fields.</summary>
[Fact]
public void RetryNotificationRequestAndResponse_RoundTripFields()
{
@@ -267,6 +284,7 @@ public class NotificationMessagesTests
Assert.Null(response.ErrorMessage);
}
/// <summary>Verifies that the discard notification request and response round-trip their fields.</summary>
[Fact]
public void DiscardNotificationRequestAndResponse_RoundTripFields()
{
@@ -278,6 +296,7 @@ public class NotificationMessagesTests
Assert.Equal("not found", response.ErrorMessage);
}
/// <summary>Verifies that a with-expression on a notification KPI response changes a single field.</summary>
[Fact]
public void NotificationKpiResponse_WithExpression_ChangesSingleField()
{
@@ -294,6 +313,7 @@ public class NotificationMessagesTests
Assert.NotEqual(kpi, updated);
}
/// <summary>Verifies that positional construction of a notification KPI request sets the correlation id.</summary>
[Fact]
public void NotificationKpiRequest_PositionalConstruction_SetsCorrelationId()
{
@@ -301,6 +321,7 @@ public class NotificationMessagesTests
Assert.Equal("corr-1", msg.CorrelationId);
}
/// <summary>Verifies that the per-site notification KPI request carries the correlation id.</summary>
[Fact]
public void PerSiteNotificationKpiRequest_CarriesCorrelationId()
{
@@ -308,6 +329,7 @@ public class NotificationMessagesTests
Assert.Equal("corr-1", request.CorrelationId);
}
/// <summary>Verifies that the per-site notification KPI response carries the per-site snapshots.</summary>
[Fact]
public void PerSiteNotificationKpiResponse_CarriesPerSiteSnapshots()
{
@@ -4,6 +4,9 @@ namespace ZB.MOM.WW.ScadaBridge.Commons.Tests.Messages;
public class ReadTagValuesCommandRegistryTests
{
/// <summary>Verifies that site-only and retired commands are not registered as HTTP commands.</summary>
/// <param name="type">The command message type.</param>
/// <param name="wireName">The command wire name.</param>
[Theory]
[InlineData(typeof(ReadTagValuesCommand), "ReadTagValues")]
[InlineData(typeof(ResolveRolesCommand), "ResolveRoles")]
@@ -4,13 +4,14 @@ using ZB.MOM.WW.ScadaBridge.Commons.Types.Audit;
namespace ZB.MOM.WW.ScadaBridge.Commons.Tests.Messages;
/// <summary>
/// Site Call Audit (#22): construction, value-equality and optionality tests
/// Site Call Audit: construction, value-equality and optionality tests
/// for the Site Calls UI query / KPI / detail message contracts. Mirrors the
/// Notification Outbox <c>NotificationMessagesTests</c> coverage of the read
/// side, scoped to the contracts the Site Calls page consumes.
/// </summary>
public class SiteCallQueriesTests
{
/// <summary>Verifies that positional construction of a site call query request sets all fields.</summary>
[Fact]
public void SiteCallQueryRequest_PositionalConstruction_SetsAllFields()
{
@@ -33,6 +34,7 @@ public class SiteCallQueriesTests
Assert.Equal(50, request.PageSize);
}
/// <summary>Verifies that a site call query request allows its optional filters to be null.</summary>
[Fact]
public void SiteCallQueryRequest_AllowsNullOptionalFilters()
{
@@ -48,6 +50,7 @@ public class SiteCallQueriesTests
Assert.Null(request.AfterId);
}
/// <summary>Verifies that two site call query responses are equal when all their fields match.</summary>
[Fact]
public void SiteCallQueryResponse_ValueEquality_EqualWhenAllFieldsMatch()
{
@@ -58,6 +61,7 @@ public class SiteCallQueriesTests
Assert.Equal(a.GetHashCode(), b.GetHashCode());
}
/// <summary>Verifies that a site call summary carries the entity columns and the stuck flag.</summary>
[Fact]
public void SiteCallSummary_CarriesEntityColumnsAndStuckFlag()
{
@@ -77,6 +81,7 @@ public class SiteCallQueriesTests
Assert.True(summary.IsStuck);
}
/// <summary>Verifies that a detail response for a missing row has a null detail.</summary>
[Fact]
public void SiteCallDetailResponse_MissingRow_HasNullDetail()
{
@@ -87,6 +92,7 @@ public class SiteCallQueriesTests
Assert.Equal("site call not found", response.ErrorMessage);
}
/// <summary>Verifies that a failed KPI response zeroes its KPI fields.</summary>
[Fact]
public void SiteCallKpiResponse_FailureShape_ZeroesKpiFields()
{
@@ -101,6 +107,7 @@ public class SiteCallQueriesTests
Assert.Null(response.OldestPendingAge);
}
/// <summary>Verifies that the per-site KPI response carries a snapshot for each site.</summary>
[Fact]
public void PerSiteSiteCallKpiResponse_CarriesPerSiteSnapshots()
{
@@ -119,6 +126,7 @@ public class SiteCallQueriesTests
Assert.Equal(TimeSpan.FromMinutes(15), site.OldestPendingAge);
}
/// <summary>Verifies that the oldest pending age of a KPI snapshot can be null for an empty table.</summary>
[Fact]
public void SiteCallKpiSnapshot_OldestPendingAge_IsNullableForEmptyTable()
{
@@ -12,6 +12,7 @@ namespace ZB.MOM.WW.ScadaBridge.Commons.Tests.Messages;
/// </summary>
public class TraceFlagDefaultsTests
{
/// <summary>Verifies that existing positional constructions default to untraced.</summary>
[Fact]
public void ExistingPositionalConstructions_DefaultToUntraced()
{
@@ -31,6 +32,7 @@ public class TraceFlagDefaultsTests
Assert.Null(result.TraceEvents);
}
/// <summary>Verifies that trace events are audit events.</summary>
[Fact]
public void TraceEvents_AreAuditEvents()
{