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
@@ -45,7 +45,7 @@ public class FlowDebuggerPageTests : BunitContext
};
/// <summary>
/// #37: the MesMoveOut shape — a REQUIRED array of objects — which the old flat text-box pane
/// The MesMoveOut shape — a REQUIRED array of objects — which the old flat text-box pane
/// could not take at all (the array reached the site empty).
/// </summary>
private static readonly ApiMethod MesMoveOut = new("MesMoveOut", "return 1;")
@@ -69,6 +69,7 @@ public class FlowDebuggerPageTests : BunitContext
],
[new("n1", "n2", false), new("n2", "n3", false)]);
/// <summary>Verifies that a refresh merge keeps the replay row order and then appends rows that exist only in the live run.</summary>
[Fact]
public void RefreshMerge_UsesReplayOrderThenLiveOnlyRows()
{
@@ -140,10 +141,14 @@ public class FlowDebuggerPageTests : BunitContext
private sealed class StubAuthStateProvider : AuthenticationStateProvider
{
private readonly AuthenticationState _state;
/// <summary>Initializes the provider with the authentication state to return.</summary>
/// <param name="state">The authentication state to return.</param>
public StubAuthStateProvider(AuthenticationState state) => _state = state;
/// <inheritdoc />
public override Task<AuthenticationState> GetAuthenticationStateAsync() => Task.FromResult(_state);
}
/// <summary>Verifies that the page renders the toolbar and an empty flow for a deployer.</summary>
[Fact]
public void Renders_ForDeployer_WithToolbarAndEmptyFlow()
{
@@ -164,6 +169,7 @@ public class FlowDebuggerPageTests : BunitContext
// ---- F3: Replay opens to the OperationalAudit roles; Live stays Deployer-only ----------------
/// <summary>Verifies that the page renders replay-only for a viewer, with no live run controls.</summary>
[Fact]
public void Renders_ForViewer_ReplayOnly_WithNoLiveControls()
{
@@ -186,6 +192,7 @@ public class FlowDebuggerPageTests : BunitContext
Assert.Empty(cut.FindAll("select[data-test='flow-method-select']"));
}
/// <summary>Verifies that a viewer can load a replay but gets no retry or discard actions on a parked node.</summary>
[Fact]
public void Viewer_LoadsAReplay_ButGetsNoRetryOrDiscardOnAParkedNode()
{
@@ -209,6 +216,7 @@ public class FlowDebuggerPageTests : BunitContext
_flow.Received(1).ReplayAsync(root, Arg.Any<CancellationToken>());
}
/// <summary>Verifies that a viewer drilling in with a method id does not open the live run surface.</summary>
[Fact]
public void Viewer_DrillInWithAMethodId_DoesNotOpenTheLiveRunSurface()
{
@@ -225,6 +233,7 @@ public class FlowDebuggerPageTests : BunitContext
Assert.NotNull(cut.Find("input[data-test='flow-execution-id']"));
}
/// <summary>Verifies that choosing a method shows the predicted graph and the inputs form.</summary>
[Fact]
public void ChoosingAMethod_ShowsThePredictedGraph_AndTheInputsForm()
{
@@ -236,7 +245,7 @@ public class FlowDebuggerPageTests : BunitContext
cut.WaitForAssertion(() => Assert.Equal(3, cut.FindAll("g[data-test='flow-node']").Count));
Assert.Equal("Predicted", cut.Find("[data-test='flow-state']").TextContent.Trim());
Assert.NotNull(cut.Find("[data-test='flow-predicted-note']"));
// #37: the method pane is the shared ParameterValueForm (typed inputs by field id), and
// The method pane is the shared ParameterValueForm (typed inputs by field id), and
// Run is gated on its validity — MachineCode is required, so Run stays off until it is set.
Assert.NotEmpty(cut.FindAll("[data-test='flow-method-params']"));
Assert.NotNull(cut.Find("#param-MachineCode"));
@@ -246,6 +255,7 @@ public class FlowDebuggerPageTests : BunitContext
cut.WaitForAssertion(() => Assert.False(cut.Find("button[data-test='flow-run']").HasAttribute("disabled")));
}
/// <summary>Verifies that a run sends the typed inputs and renders the returned graph.</summary>
[Fact]
public void Run_SendsTypedInputs_AndRendersTheReturnedGraph()
{
@@ -274,6 +284,7 @@ public class FlowDebuggerPageTests : BunitContext
Assert.Contains("POST /api/DelmiaRecipeDownload", cut.Find("[data-test='flow-step-title']").TextContent);
}
/// <summary>Verifies that a standby node refusal is shown verbatim in an inline alert.</summary>
[Fact]
public void Run_StandbyNodeRefusal_ShowsInlineAlertVerbatim()
{
@@ -293,6 +304,7 @@ public class FlowDebuggerPageTests : BunitContext
Assert.Equal("Failed", cut.Find("[data-test='flow-state']").TextContent.Trim());
}
/// <summary>Verifies that an execution id query parameter triggers a replay on the first render.</summary>
[Fact]
public void ExecutionIdQueryParameter_TriggersReplayOnFirstRender()
{
@@ -310,6 +322,7 @@ public class FlowDebuggerPageTests : BunitContext
Assert.Contains("btn-primary", cut.Find("button[data-test='flow-mode-replay']").ClassName);
}
/// <summary>Verifies that a run with no site steps and no child execution id shows the site-not-traced label.</summary>
[Fact]
public void Run_WithNoSiteStepsAndNoChildId_ShowsSiteNotTracedLabel()
{
@@ -325,7 +338,7 @@ public class FlowDebuggerPageTests : BunitContext
cut.WaitForElement("[data-test='flow-site-not-traced']");
}
// ---- Node actions (follow-ups plan 2026-09-06, Task 8): Retry / Discard on a Parked node -------
// ---- Node actions (follow-ups plan 2026-09-06): Retry / Discard on a Parked node -------
/// <summary>Same events as <see cref="OutboundOutcome"/> but the cached call ends Parked; the second
/// outcome shares the event objects (stable ids, as real audit rows are) and adds a Delivered resolve.</summary>
@@ -379,6 +392,7 @@ public class FlowDebuggerPageTests : BunitContext
return cut;
}
/// <summary>Verifies that retrying a parked node confirms, relays the retry and re-polls until the node is no longer parked.</summary>
[Fact]
public void ParkedNode_Retry_ConfirmsRelaysAndRepollsUntilNotParked()
{
@@ -401,6 +415,7 @@ public class FlowDebuggerPageTests : BunitContext
Assert.Empty(cut.FindAll("button[data-test='flow-step-retry']")); // the selected node is no longer parked
}
/// <summary>Verifies that discarding a parked node uses a danger confirmation and does not poll when the confirmation is refused.</summary>
[Fact]
public void ParkedNode_Discard_UsesDangerConfirm_AndDoesNotPollWhenRefused()
{
@@ -420,6 +435,7 @@ public class FlowDebuggerPageTests : BunitContext
Assert.NotNull(cut.Find("button[data-test='flow-step-retry']"));
}
/// <summary>Verifies that declining the confirmation for a parked node never relays the action.</summary>
[Fact]
public void ParkedNode_ConfirmDeclined_NeverRelays()
{
@@ -436,6 +452,7 @@ public class FlowDebuggerPageTests : BunitContext
_flow.DidNotReceive().ReplayAsync(Arg.Any<Guid>(), Arg.Any<CancellationToken>());
}
/// <summary>Verifies that an action on a parked node at an out-of-scope site is refused before any confirmation.</summary>
[Fact]
public void ParkedNode_OutOfScopeSite_RefusedBeforeConfirm()
{
@@ -452,7 +469,7 @@ public class FlowDebuggerPageTests : BunitContext
_flow.DidNotReceive().RetryOutboundAsync(Arg.Any<FlowStep>(), Arg.Any<CancellationToken>());
}
// ---- Outbound calls (2026-09-06 plan, Task 9): pending refresh after a Live run ----------
// ---- Outbound calls (2026-09-06 plan): pending refresh after a Live run ----------
/// <summary>
/// Inbound → route → site run → cached API call; the call is Pending unless <paramref name="resolved"/>.
@@ -498,6 +515,7 @@ public class FlowDebuggerPageTests : BunitContext
};
}
/// <summary>Verifies that a live run with a pending outbound call polls the replay until the call reaches a terminal state.</summary>
[Fact]
public void LiveRun_WithPendingOutbound_PollsReplayUntilTerminal()
{
@@ -560,6 +578,7 @@ public class FlowDebuggerPageTests : BunitContext
return new FlowDebugOutcome(FlowGraphBuilder.Build(events), raw, null, null);
}
/// <summary>Verifies that a pending refresh keeps the steps the live run already had when the replay lags behind telemetry.</summary>
[Fact]
public void PendingRefresh_KeepsStepsTheLiveRunAlreadyHad_WhenReplayLagsBehindTelemetry()
{
@@ -593,6 +612,7 @@ public class FlowDebuggerPageTests : BunitContext
Assert.Contains(cut.FindAll("[data-test='flow-node-pill']"), p => p.TextContent.Trim() == "Ok");
}
/// <summary>Verifies that a live run with no pending step never polls.</summary>
[Fact]
public void LiveRun_WithNoPendingStep_NeverPolls()
{
@@ -611,6 +631,7 @@ public class FlowDebuggerPageTests : BunitContext
Assert.Empty(cut.FindAll("[data-test='flow-pending-count']"));
}
/// <summary>Verifies that replay mode never polls but the refresh button replays once.</summary>
[Fact]
public void ReplayMode_NeverPolls_ButRefreshButtonReplaysOnce()
{
@@ -665,6 +686,7 @@ public class FlowDebuggerPageTests : BunitContext
_flow.PredictScriptAsync(7, Arg.Any<string>(), Arg.Any<CancellationToken>()).Returns(ThreeNodePrediction());
}
/// <summary>Verifies that the script entry lists scripts with their trigger labels once a site and instance are chosen.</summary>
[Fact]
public void ScriptEntry_ListsScriptsWithTriggerLabels_AfterSiteAndInstance()
{
@@ -679,6 +701,7 @@ public class FlowDebuggerPageTests : BunitContext
Assert.Empty(cut.FindAll("select[data-test='flow-attribute-select']"));
}
/// <summary>Verifies that a write-kind script shows a value field for the trigger attribute and gates Run on it.</summary>
[Fact]
public void ScriptEntry_WriteKind_ShowsTheValueField_ForTheTriggerAttribute_AndGatesRunOnIt()
{
@@ -697,6 +720,7 @@ public class FlowDebuggerPageTests : BunitContext
Assert.False(cut.Find("button[data-test='flow-run']").HasAttribute("disabled"));
}
/// <summary>Verifies that a call-kind script shows the parameter form and runs with the entered parameters.</summary>
[Fact]
public void ScriptEntry_CallKind_ShowsTheParameterForm_AndRunsWithParameters()
{
@@ -717,6 +741,7 @@ public class FlowDebuggerPageTests : BunitContext
_ = _flow.Received(1).RunScriptAsync(7, "Manual", Arg.Is<JsonElement?>(p => p != null && p.Value.GetProperty("n").GetInt64() == 3), null, Arg.Any<CancellationToken>());
}
/// <summary>Verifies that a call-kind script without parameters says so and can be run.</summary>
[Fact]
public void ScriptEntry_CallKindWithoutParameters_SaysSo_AndCanRun()
{
@@ -731,6 +756,7 @@ public class FlowDebuggerPageTests : BunitContext
Assert.False(cut.Find("button[data-test='flow-run']").HasAttribute("disabled"));
}
/// <summary>Verifies that a deep link with an instance and a script preselects both and shows the prediction.</summary>
[Fact]
public void DeepLink_InstanceAndScript_PreselectsAndPredicts()
{
@@ -774,6 +800,7 @@ public class FlowDebuggerPageTests : BunitContext
return cut;
}
/// <summary>Verifies that switching between call-kind scripts resets the parameter form and its validity.</summary>
[Fact]
public void ScriptEntry_SwitchingBetweenCallKindScripts_ResetsTheFormAndValidity()
{
@@ -792,6 +819,7 @@ public class FlowDebuggerPageTests : BunitContext
Assert.False(cut.Find("button[data-test='flow-run']").HasAttribute("disabled"));
}
/// <summary>Verifies that switching from an invalid form to a script without parameters enables Run.</summary>
[Fact]
public void ScriptEntry_SwitchingFromAnInvalidFormToANoParameterScript_EnablesRun()
{
@@ -805,6 +833,7 @@ public class FlowDebuggerPageTests : BunitContext
Assert.False(cut.Find("button[data-test='flow-run']").HasAttribute("disabled"));
}
/// <summary>Verifies that the instance picker shows areas collapsed until they are expanded.</summary>
[Fact]
public void ScriptEntry_InstancePicker_ShowsAreasCollapsed_UntilExpanded()
{
@@ -838,6 +867,7 @@ public class FlowDebuggerPageTests : BunitContext
Assert.Equal(["— choose —", "Manual (Call)", "OnFlag (ValueChange: Flag)", "Tick (Interval)"], options);
}
/// <summary>Verifies that a deep link with an instance id shows the instance name in the picker.</summary>
[Fact]
public void ScriptEntry_DeepLink_InstanceId_ShowsItsNameInThePicker()
{
@@ -913,6 +943,7 @@ public class FlowDebuggerPageTests : BunitContext
Assert.False(cut.Find("[data-test='flow-instance-input']").HasAttribute("disabled")));
}
/// <summary>Verifies that changing the site clears the picked instance.</summary>
[Fact]
public void ScriptEntry_SiteChange_ClearsThePickedInstance()
{
@@ -940,7 +971,7 @@ public class FlowDebuggerPageTests : BunitContext
Assert.Equal(["— choose —"], cut.FindAll("select[data-test='flow-script-select'] option").Select(o => o.TextContent.Trim()).ToList());
}
// ---- Step logs (plan 2026-09-09 D5/D7, Task 13): status-strip counts, truncation notes, cross-step hint ----
// ---- Step logs (plan 2026-09-09 D5/D7): status-strip counts, truncation notes, cross-step hint ----
/// <summary>One <c>ScriptTrace.ScriptLog</c> row — a line the builder folds onto a step, never a node of its own.</summary>
private static AuditEvent LogLine(Guid execution, string level, int ms, Guid? stepEventId = null, string message = "hello") =>
@@ -995,6 +1026,7 @@ public class FlowDebuggerPageTests : BunitContext
return cut;
}
/// <summary>Verifies that the status strip shows log counts by level.</summary>
[Fact]
public void StatusStrip_ShowsLogCountsByLevel()
{
@@ -1005,6 +1037,7 @@ public class FlowDebuggerPageTests : BunitContext
Assert.Equal("1 errors · 2 warnings · 3 info", cut.Find("[data-test='flow-log-counts']").TextContent.Trim());
}
/// <summary>Verifies that the status strip omits log counts when the run logged nothing.</summary>
[Fact]
public void StatusStrip_OmitsLogCounts_WhenTheRunLoggedNothing()
{
@@ -1017,6 +1050,7 @@ public class FlowDebuggerPageTests : BunitContext
Assert.Empty(cut.FindAll("[data-test='flow-unattached-logs']"));
}
/// <summary>Verifies that the status strip shows the inline log truncation badge.</summary>
[Fact]
public void StatusStrip_ShowsTheInlineLogTruncationBadge()
{
@@ -1028,6 +1062,7 @@ public class FlowDebuggerPageTests : BunitContext
Assert.Contains("inline log lines capped", cut.Find("[data-test='flow-logs-truncated']").TextContent);
}
/// <summary>Verifies that the status strip notes log lines that could not be placed on a step.</summary>
[Fact]
public void StatusStrip_NotesLinesThatCouldNotBePlacedOnAStep()
{
@@ -1040,6 +1075,7 @@ public class FlowDebuggerPageTests : BunitContext
Assert.Equal("0 errors · 0 warnings · 1 info", cut.Find("[data-test='flow-log-counts']").TextContent.Trim());
}
/// <summary>Verifies that the state chip stays completed when the only errors are log lines.</summary>
[Fact]
public void StateChip_StaysCompleted_WhenTheOnlyErrorsAreLogLines()
{
@@ -1052,6 +1088,7 @@ public class FlowDebuggerPageTests : BunitContext
Assert.Equal("2 errors · 0 warnings · 0 info", cut.Find("[data-test='flow-log-counts']").TextContent.Trim());
}
/// <summary>Verifies that the step detail log hint selects the sibling step that carries the other log lines.</summary>
[Fact]
public void StepDetail_LogHint_SelectsTheSiblingStepCarryingTheOtherLines()
{
@@ -1134,6 +1171,7 @@ public class FlowDebuggerPageTests : BunitContext
return (run, refreshed, root);
}
/// <summary>Verifies that refreshing outcomes clears the inline cap badge once it merges in more log rows.</summary>
[Fact]
public void RefreshOutcomes_ClearsTheInlineCapBadge_OnceItMergesInMoreLogRows()
{
@@ -1150,6 +1188,7 @@ public class FlowDebuggerPageTests : BunitContext
Assert.Equal("0 errors · 1 warnings · 1 info", cut.Find("[data-test='flow-log-counts']").TextContent.Trim());
}
/// <summary>Verifies that refreshing outcomes keeps the inline cap badge when the re-read brings back no new lines.</summary>
[Fact]
public void RefreshOutcomes_KeepsTheInlineCapBadge_WhenTheReReadBringsBackNoNewLines()
{
@@ -1170,6 +1209,7 @@ public class FlowDebuggerPageTests : BunitContext
// ---- CountLogs: the level buckets, straight ---------------------------------------------------
/// <summary>Verifies that log counting buckets lines by level case-insensitively and counts everything else as info.</summary>
[Fact]
public void CountLogs_BucketsByLevel_CaseInsensitively_WithEverythingElseAsInfo()
{
@@ -1189,6 +1229,7 @@ public class FlowDebuggerPageTests : BunitContext
Assert.Equal((1, 1, 3, 5), FlowDebuggerPage.CountLogs(graph));
}
/// <summary>Verifies that counting logs for a null graph yields all zeroes.</summary>
[Fact]
public void CountLogs_NullGraph_IsAllZeroes()
{
@@ -1197,7 +1238,7 @@ public class FlowDebuggerPageTests : BunitContext
/// <summary>
/// Waits for the method pane's <c>ParameterValueForm</c> and fills the fixture method's one
/// required field, so Run is enabled (#37 gates Run on the form's validity).
/// required field, so Run is enabled (Run is gated on the form's validity).
/// </summary>
private static void FillRequiredMethodInput(IRenderedComponent<FlowDebuggerPage> cut)
{
@@ -1205,8 +1246,9 @@ public class FlowDebuggerPageTests : BunitContext
cut.WaitForAssertion(() => Assert.False(cut.Find("button[data-test='flow-run']").HasAttribute("disabled")));
}
// ── #37: structured method parameters ───────────────────────────────────────────────────
// ── Structured method parameters ───────────────────────────────────────────────────
/// <summary>Verifies that an array of objects entered in the item editors round-trips into the run payload.</summary>
[Fact]
public void MethodEntry_ArrayOfObjects_RoundTripsFromItemEditorsToTheRunPayload()
{
@@ -1241,6 +1283,7 @@ public class FlowDebuggerPageTests : BunitContext
Assert.Equal("WO-2", orders[1].GetProperty("WorkOrderNumber").GetString());
}
/// <summary>Verifies that leaving a required list item field empty keeps Run disabled.</summary>
[Fact]
public void MethodEntry_RequiredListItemField_LeftEmpty_KeepsRunDisabled()
{
@@ -1258,6 +1301,8 @@ public class FlowDebuggerPageTests : BunitContext
cut.WaitForAssertion(() => Assert.False(cut.Find("button[data-test='flow-run']").HasAttribute("disabled")));
}
/// <summary>Verifies that an invalid raw JSON document blocks Run and shows the error.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task MethodEntry_RawJson_InvalidDocument_BlocksRun_AndShowsTheError()
{
@@ -1289,6 +1334,8 @@ public class FlowDebuggerPageTests : BunitContext
_ = _flow.DidNotReceive().RunMethodAsync(Arg.Any<int>(), Arg.Any<JsonElement?>(), Arg.Any<CancellationToken>());
}
/// <summary>Verifies that a valid raw JSON document is sent verbatim and survives switching back to the form.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task MethodEntry_RawJson_ValidDocument_IsSentVerbatim_AndSurvivesTheSwitchBackToForm()
{
@@ -1322,6 +1369,7 @@ public class FlowDebuggerPageTests : BunitContext
Assert.Equal("P-1", sent.Value.GetProperty("WorkOrders")[0].GetProperty("PartNumber").GetString());
}
/// <summary>Verifies that switching methods resets the form and its validity.</summary>
[Fact]
public void MethodEntry_SwitchingMethods_ResetsTheFormAndItsValidity()
{
@@ -1339,6 +1387,7 @@ public class FlowDebuggerPageTests : BunitContext
Assert.True(cut.Find("button[data-test='flow-run']").HasAttribute("disabled"));
}
/// <summary>Verifies that a persisted value tree is restored into the form.</summary>
[Fact]
public void MethodEntry_PersistedValueTree_IsRestoredIntoTheForm()
{
@@ -1353,11 +1402,12 @@ public class FlowDebuggerPageTests : BunitContext
cut.WaitForAssertion(() => Assert.False(cut.Find("button[data-test='flow-run']").HasAttribute("disabled")));
}
/// <summary>Verifies that a legacy flat string entry that no longer validates is dropped.</summary>
[Fact]
public void MethodEntry_LegacyFlatStringEntry_ThatNoLongerValidates_IsDropped()
{
RegisterServices();
// Pre-#37 entries stored every field as a string; "7" is not an Integer, so the whole
// Earlier entries stored every field as a string; "7" is not an Integer, so the whole
// entry is discarded rather than painted into the form as an error.
JSInterop.Setup<string?>("localStorage.getItem", "flowDebugger.inputs.4")
.SetResult("{\"MachineCode\":\"Z9\",\"Qty\":\"7\"}");