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
@@ -16,8 +16,8 @@ namespace ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests.Audit;
/// rows in <c>finally</c>.
///
/// <para>
/// This part (Wave 3, Task 10) covers render / search-narrows / pagination. The
/// class is intentionally structured so Task 11 can APPEND modal/copy/chip facts
/// This part covers render / search-narrows / pagination. The
/// class is intentionally structured so modal/copy/chip facts can be APPENDED
/// to it without restructuring: shared constants (the DB-unavailable skip reason,
/// the page route) and the seeded-test gate idiom live here once.
/// </para>
@@ -45,6 +45,8 @@ public class AuditConfigurationTests
private readonly PlaywrightFixture _fixture;
/// <summary>Initializes the tests with the shared Playwright fixture.</summary>
/// <param name="fixture">The Playwright fixture that supplies authenticated browser pages.</param>
public AuditConfigurationTests(PlaywrightFixture fixture)
{
_fixture = fixture;
@@ -58,6 +60,8 @@ public class AuditConfigurationTests
/// </summary>
private static string NewMarker() => "zzCfgAudit-" + Guid.NewGuid().ToString("N")[..8];
/// <summary>Verifies that the grid renders and that searching narrows the displayed rows.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[SkippableFact]
public async Task Grid_RendersAndSearchNarrows()
{
@@ -102,6 +106,8 @@ public class AuditConfigurationTests
}
}
/// <summary>Verifies that Previous is disabled on page 1 and that Next advances to the following page.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[SkippableFact]
public async Task Pagination_PrevDisabledOnPage1_NextPaginates()
{
@@ -122,7 +128,7 @@ public class AuditConfigurationTests
await page.Locator("button.btn.btn-primary:has-text('Search')").ClickAsync();
await page.WaitForLoadStateAsync(LoadState.NetworkIdle);
// Page 1 of 2: Previous disabled, Next enabled. (M10 OffsetPager summary:
// Page 1 of 2: Previous disabled, Next enabled. (OffsetPager summary:
// "Page {N} of {Y} · {Total} total".)
await Assertions.Expect(page.Locator("[data-test='pager-summary']")).ToContainTextAsync("Page 1 of 2");
await Assertions.Expect(page.Locator("[data-test='pager-summary']")).ToContainTextAsync("55 total");
@@ -143,6 +149,8 @@ public class AuditConfigurationTests
}
}
/// <summary>Verifies that a large state value opens a modal that can then be closed.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[SkippableFact]
public async Task LargeState_OpensAndClosesModal()
{
@@ -185,6 +193,8 @@ public class AuditConfigurationTests
}
}
/// <summary>Verifies that copying an entity ID shows a toast.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[SkippableFact]
public async Task CopyEntityId_ShowsToast()
{
@@ -221,6 +231,8 @@ public class AuditConfigurationTests
}
}
/// <summary>Verifies that the bundle import ID drill-in applies a filter chip that narrows the grid and can be cleared.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[SkippableFact]
public async Task BundleImportId_DrillIn_ChipFiltersAndClears()
{
@@ -231,7 +243,7 @@ public class AuditConfigurationTests
try
{
// 1 bulk row (EntityName "{marker}-0", BundleImportId NULL) + 2 bundle
// rows (EntityName "{marker}-bundle-0/1", BundleImportId = bundleId), all
// rows (EntityName "{marker}-bundle-" plus an index, BundleImportId = bundleId), all
// EntityType = marker so the finally cleanup removes every row.
await ConfigAuditDataSeeder.SeedAsync(marker, bundleId, bulkCount: 1, bundleRows: 2);
@@ -245,9 +257,9 @@ public class AuditConfigurationTests
// The filter chip is shown for the active bundle import.
await Assertions.Expect(page.Locator("span.badge.bg-primary:has-text('Filtered by Bundle Import:')")).ToBeVisibleAsync();
// Exactly the 2 bundle rows show (EntityName "{marker}-bundle-0/1"). The
// Exactly the 2 bundle rows show (EntityName "{marker}-bundle-" plus an index). The
// bulk row (EntityName "{marker}-0", BundleImportId NULL) is filtered out.
// The "{marker}-0" token is NOT a substring of "{marker}-bundle-0", so the
// The "{marker}-0" token is NOT a substring of the "{marker}-bundle-" names, so the
// two locators distinguish the bundle rows from the bulk row unambiguously.
await Assertions.Expect(page.Locator("tr").Filter(new() { HasText = $"{marker}-bundle-" }))
.ToHaveCountAsync(2, new() { Timeout = 10_000 });
@@ -6,7 +6,7 @@ using ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests.Cluster;
namespace ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests.Audit;
/// <summary>
/// Direct-SQL seeding helper for the Audit Log Playwright E2E tests (#23 M7-T16).
/// Direct-SQL seeding helper for the Audit Log Playwright E2E tests.
///
/// <para>
/// The Playwright suite runs against the live Docker cluster (the same one that
@@ -50,6 +50,25 @@ internal static class AuditDataSeeder
/// derive automatically. All optional fields are nullable so individual tests can shape
/// the row to whatever payload they need for their drawer/grid assertions.
/// </summary>
/// <param name="eventId">The unique event identifier.</param>
/// <param name="occurredAtUtc">When the event occurred, in UTC.</param>
/// <param name="channel">The audit channel.</param>
/// <param name="kind">The audit kind.</param>
/// <param name="status">The audit status.</param>
/// <param name="sourceSiteId">The originating site identifier, if any.</param>
/// <param name="target">The call target, if any.</param>
/// <param name="actor">The acting principal, if any.</param>
/// <param name="correlationId">The per-operation correlation identifier, if any.</param>
/// <param name="executionId">The per-run execution identifier, if any.</param>
/// <param name="parentExecutionId">The spawning execution identifier, if any.</param>
/// <param name="httpStatus">The HTTP status code, if any.</param>
/// <param name="durationMs">The duration in milliseconds, if any.</param>
/// <param name="errorMessage">The error message, if any.</param>
/// <param name="requestSummary">The request summary, if any.</param>
/// <param name="responseSummary">The response summary, if any.</param>
/// <param name="extra">Additional JSON details, if any.</param>
/// <param name="ct">A token to cancel the operation.</param>
/// <returns>A task that represents the asynchronous operation.</returns>
public static async Task InsertAuditEventAsync(
Guid eventId,
DateTime occurredAtUtc,
@@ -135,6 +154,9 @@ VALUES
/// stuck row carrying a random GUID suffix does not collide with future
/// runs and tests should not fail teardown.
/// </summary>
/// <param name="targetPrefix">The target prefix identifying the rows to delete.</param>
/// <param name="ct">A token to cancel the operation.</param>
/// <returns>A task that represents the asynchronous operation.</returns>
public static async Task DeleteByTargetPrefixAsync(string targetPrefix, CancellationToken ct = default)
{
try
@@ -158,6 +180,8 @@ VALUES
/// per-test setup on this; when the cluster is down the test fails with a
/// clear "MSSQL unavailable" message instead of an opaque SqlException.
/// </summary>
/// <param name="ct">A token to cancel the operation.</param>
/// <returns><c>true</c> if the database accepted a connection; otherwise <c>false</c>.</returns>
public static async Task<bool> IsAvailableAsync(CancellationToken ct = default)
{
try
@@ -4,8 +4,8 @@ using Xunit;
namespace ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests.Audit;
/// <summary>
/// End-to-end coverage for the Audit Log results-grid column UX (#23
/// follow-ups Task 10): drag-to-resize and drag-to-reorder columns, with the
/// End-to-end coverage for the Audit Log results-grid column UX (Audit Log
/// follow-ups): drag-to-resize and drag-to-reorder columns, with the
/// chosen widths + order persisted in the browser's <c>sessionStorage</c>.
///
/// <para>
@@ -34,6 +34,8 @@ public class AuditGridColumnTests
private readonly PlaywrightFixture _fixture;
/// <summary>Initializes the tests with the shared Playwright fixture.</summary>
/// <param name="fixture">The shared Playwright fixture.</param>
public AuditGridColumnTests(PlaywrightFixture fixture)
{
_fixture = fixture;
@@ -113,6 +115,8 @@ public class AuditGridColumnTests
expectedFirstKey);
}
/// <summary>Verifies that dragging a resize handle widens the column and the width survives a reload.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[SkippableFact]
public async Task ResizeHandle_DraggingWidensColumn_AndSurvivesReload()
{
@@ -171,6 +175,8 @@ public class AuditGridColumnTests
}
}
/// <summary>Verifies that dragging a column header reorders the columns and the order survives a reload.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[SkippableFact]
public async Task ReorderDrag_MovesColumn_AndSurvivesReload()
{
@@ -220,6 +226,8 @@ public class AuditGridColumnTests
}
}
/// <summary>Verifies that column order and widths persist across a reload via session storage.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[SkippableFact]
public async Task ColumnOrderAndWidths_PersistAcrossReload_ViaSessionStorage()
{
@@ -4,7 +4,7 @@ using ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests.Cluster;
namespace ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests.Audit;
/// <summary>
/// End-to-end coverage for the central Audit Log surface (#23 M7-T16 / Bundle H).
/// End-to-end coverage for the central Audit Log surface (Bundle H).
///
/// <para>
/// Each test seeds its own <c>AuditLog</c> rows directly into the running cluster's
@@ -15,7 +15,7 @@ namespace ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests.Audit;
/// </para>
///
/// <para>
/// Scenarios covered (per the M7-T16 brief):
/// Scenarios covered (per the brief):
/// <list type="bullet">
/// <item><c>FilterNarrowing</c> — the channel filter narrows the results grid.</item>
/// <item><c>DrilldownDrawer_JsonPrettyPrint</c> — JSON request bodies pretty-print.</item>
@@ -50,11 +50,15 @@ public class AuditLogPageTests
{
private readonly PlaywrightFixture _fixture;
/// <summary>Initializes the test class with the shared Playwright fixture.</summary>
/// <param name="fixture">The shared Playwright fixture.</param>
public AuditLogPageTests(PlaywrightFixture fixture)
{
_fixture = fixture;
}
/// <summary>Verifies that applying a channel filter shrinks the results grid.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[SkippableFact]
public async Task FilterNarrowing_ChannelFilterShrinksGrid()
{
@@ -112,6 +116,8 @@ public class AuditLogPageTests
}
}
/// <summary>Verifies that combining a channel filter with a target filter narrows the grid to the matching row.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[SkippableFact]
public async Task FilterCombination_ChannelPlusTarget_NarrowsToMatch()
{
@@ -172,6 +178,8 @@ public class AuditLogPageTests
}
}
/// <summary>Verifies that applying a filter with no matches shows the empty state.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[SkippableFact]
public async Task EmptyResults_AfterApply_ShowsEmptyState()
{
@@ -195,6 +203,8 @@ public class AuditLogPageTests
.ToContainTextAsync("No audit events match the current filter.");
}
/// <summary>Verifies that the drilldown drawer pretty-prints a JSON request body.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[SkippableFact]
public async Task DrilldownDrawer_JsonPrettyPrintsRequestBody()
{
@@ -257,6 +267,8 @@ public class AuditLogPageTests
}
}
/// <summary>Verifies that the copy-as-curl button is visible and clickable for an inbound API row.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[SkippableFact]
public async Task CopyAsCurlButton_IsVisibleAndClickableForApiInbound()
{
@@ -309,6 +321,8 @@ public class AuditLogPageTests
}
}
/// <summary>Verifies that drilling in from a correlation id lands on the Audit Log with the filter applied.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[SkippableFact]
public async Task DrillInFromCorrelationId_LandsOnAuditLogWithFilterContext()
{
@@ -366,6 +380,8 @@ public class AuditLogPageTests
}
}
/// <summary>Verifies that drilling in from an execution id lands on the Audit Log with the filter applied.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[SkippableFact]
public async Task DrillInFromExecutionId_LandsOnAuditLogWithFilterContext()
{
@@ -421,6 +437,8 @@ public class AuditLogPageTests
}
}
/// <summary>Verifies that drilling in from a parent execution filters the grid to the spawner execution.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[SkippableFact]
public async Task DrillInFromParentExecution_FiltersGridToSpawnerExecution()
{
@@ -498,12 +516,14 @@ public class AuditLogPageTests
}
}
/// <summary>Verifies that drilling into the execution chain renders the tree and that clicking a node filters the grid.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[SkippableFact]
public async Task DrillInToExecutionChain_RendersTree_AndNodeClickFiltersGrid()
{
Skip.IfNot(await ClusterAvailability.IsAvailableAsync(), ClusterAvailability.SkipReason);
// Audit Log ParentExecutionId feature, Task 10: the drawer's "View
// Audit Log ParentExecutionId feature: the drawer's "View
// execution chain" action opens /audit/execution-tree?executionId={id}.
// We seed a spawner row + a child row, open the child's drawer, click
// "View execution chain", assert the tree renders BOTH executions, then
@@ -577,12 +597,14 @@ public class AuditLogPageTests
}
}
/// <summary>Verifies that double-clicking a tree node opens the execution row modal.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[SkippableFact]
public async Task DoubleClickTreeNode_OpensExecutionRowModal()
{
Skip.IfNot(await ClusterAvailability.IsAvailableAsync(), ClusterAvailability.SkipReason);
// Execution-Tree Node Detail Modal feature, Task 5: double-clicking a
// Execution-Tree Node Detail Modal feature: double-clicking a
// node on the /audit/execution-tree page opens ExecutionDetailModal —
// a modal listing that execution's audit rows, with click-through to
// each row's full <AuditEventDetail> view. We seed ONE execution with
@@ -678,6 +700,8 @@ public class AuditLogPageTests
}
}
/// <summary>Verifies that the Notifications page renders the audit drill-in link pattern.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task NotificationsPage_RendersAuditDrillInLinkPattern()
{
@@ -712,6 +736,8 @@ public class AuditLogPageTests
// all we can assert without exercising the Akka query path to seed one.
}
/// <summary>Verifies that the CSV export link is visible to a user with audit export permission and triggers a download.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task ExportCsv_LinkVisibleForAuditExportUserAndTriggersDownload()
{
@@ -742,6 +768,8 @@ public class AuditLogPageTests
Assert.EndsWith(".csv", download.SuggestedFilename);
}
/// <summary>Verifies that a Designer without the operational audit permission is denied access.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task PermissionGating_DesignerWithoutOperationalAudit_IsDeniedAccess()
{
@@ -766,6 +794,8 @@ public class AuditLogPageTests
Assert.Equal(0, await page.Locator("[data-test='audit-results-grid']").CountAsync());
}
/// <summary>Verifies that the drawer for a non-API row omits the copy-as-curl button.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[SkippableFact]
public async Task NonApiRow_Drawer_OmitsCopyAsCurl()
{
@@ -821,6 +851,8 @@ public class AuditLogPageTests
}
}
/// <summary>Verifies that the drawer's close controls dismiss the drawer.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[SkippableFact]
public async Task Drawer_CloseControls_DismissTheDrawer()
{
@@ -50,6 +50,7 @@ VALUES (@user, @action, @entityType, @entityId, @entityName, @afterState, @ts, @
/// "MSSQL unavailable" message instead of an opaque SqlException. Mirrors
/// <see cref="AuditDataSeeder.IsAvailableAsync"/>.
/// </summary>
/// <returns>A task whose result is <c>true</c> when the configuration database accepts a connection; otherwise <c>false</c>.</returns>
public static async Task<bool> IsAvailableAsync()
{
try
@@ -77,6 +78,7 @@ VALUES (@user, @action, @entityType, @entityId, @entityName, @afterState, @ts, @
/// <param name="bundleId">Bundle import id stamped on the extra bundle rows.</param>
/// <param name="bulkCount">Number of bulk rows (default 55 — spans two pages at 50/page).</param>
/// <param name="bundleRows">Number of extra rows carrying the bundle import id (default 2).</param>
/// <returns>A task that represents the asynchronous operation.</returns>
public static async Task SeedAsync(string marker, Guid bundleId, int bulkCount = 55, int bundleRows = 2)
{
await using var connection = new SqlConnection(ConnectionString);
@@ -126,6 +128,8 @@ VALUES (@user, @action, @entityType, @entityId, @entityName, @afterState, @ts, @
/// should not fail teardown. Mirrors
/// <see cref="AuditDataSeeder.DeleteByTargetPrefixAsync"/>.
/// </summary>
/// <param name="marker">The unique per-test marker whose rows are deleted.</param>
/// <returns>A task that represents the asynchronous operation.</returns>
public static async Task DeleteByMarkerAsync(string marker)
{
try