Files
ScadaBridge/tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests/Pages/AuditLogPageExportUrlTests.cs
T
Joseph Doherty 513fa1aa16 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.
2026-10-07 15:05:49 -04:00

130 lines
5.7 KiB
C#

using Microsoft.AspNetCore.WebUtilities;
using ZB.MOM.WW.ScadaBridge.Commons.Types.Audit;
using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
using AuditLogPage = ZB.MOM.WW.ScadaBridge.CentralUI.Components.Pages.Audit.AuditLogPage;
namespace ZB.MOM.WW.ScadaBridge.CentralUI.Tests.Pages;
/// <summary>
/// Unit tests for <see cref="AuditLogPage.BuildExportUrl"/> (audit log export). Builds the <c>?...</c> querystring the Export-CSV link points
/// at; the same conversion is round-tripped on the server side by
/// <see cref="ZB.MOM.WW.ScadaBridge.CentralUI.Audit.AuditExportEndpoints.ParseFilter"/>.
/// These tests pin the no-filter base path + the round-trip back through
/// <see cref="QueryHelpers.ParseQuery"/> so the link contract stays stable.
/// </summary>
public class AuditLogPageExportUrlTests
{
/// <summary>Verifies that a null filter yields the base export path.</summary>
[Fact]
public void BuildExportUrl_NullFilter_ReturnsBasePath()
{
var url = AuditLogPage.BuildExportUrl(null);
Assert.Equal("/api/centralui/audit/export", url);
}
/// <summary>Verifies that an empty filter yields the base export path.</summary>
[Fact]
public void BuildExportUrl_EmptyFilter_ReturnsBasePath()
{
// Defensive: a filter where every column is null should still render
// as the bare path — no trailing "?" so the URL stays clean.
var url = AuditLogPage.BuildExportUrl(new AuditLogQueryFilter());
Assert.Equal("/api/centralui/audit/export", url);
}
/// <summary>Verifies that a filter with every field set round-trips through the export URL.</summary>
[Fact]
public void BuildExportUrl_AllFiltersSet_RoundTrips()
{
var corr = Guid.Parse("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa");
var filter = new AuditLogQueryFilter(
Channels: new[] { AuditChannel.ApiOutbound },
Kinds: new[] { AuditKind.ApiCall },
Statuses: new[] { AuditStatus.Failed },
SourceSiteIds: new[] { "plant-a" },
Target: "PaymentApi",
Actor: "apikey-1",
CorrelationId: corr,
FromUtc: new DateTime(2026, 5, 20, 0, 0, 0, DateTimeKind.Utc),
ToUtc: new DateTime(2026, 5, 20, 23, 59, 59, DateTimeKind.Utc));
var url = AuditLogPage.BuildExportUrl(filter);
Assert.StartsWith("/api/centralui/audit/export?", url);
var query = QueryHelpers.ParseQuery(new Uri("http://x" + url).Query);
Assert.Equal("ApiOutbound", query["channel"]);
Assert.Equal("ApiCall", query["kind"]);
Assert.Equal("Failed", query["status"]);
Assert.Equal("plant-a", query["site"]);
Assert.Equal("PaymentApi", query["target"]);
Assert.Equal("apikey-1", query["actor"]);
Assert.Equal(corr.ToString(), query["correlationId"]);
Assert.Equal("2026-05-20T00:00:00.0000000Z", query["from"]);
Assert.Equal("2026-05-20T23:59:59.0000000Z", query["to"]);
}
/// <summary>Verifies that a filter with only a channel set omits all other query parameters.</summary>
[Fact]
public void BuildExportUrl_OnlyChannelSet_OmitsOtherParams()
{
var filter = new AuditLogQueryFilter(Channels: new[] { AuditChannel.Notification });
var url = AuditLogPage.BuildExportUrl(filter);
Assert.StartsWith("/api/centralui/audit/export?", url);
var query = QueryHelpers.ParseQuery(new Uri("http://x" + url).Query);
Assert.Single(query);
Assert.Equal("Notification", query["channel"]);
}
/// <summary>Verifies that setting an execution id emits the execution id query parameter.</summary>
[Fact]
public void BuildExportUrl_ExecutionIdSet_EmitsExecutionIdParam()
{
var exec = Guid.Parse("12121212-3434-5656-7878-909090909090");
var filter = new AuditLogQueryFilter(ExecutionId: exec);
var url = AuditLogPage.BuildExportUrl(filter);
Assert.StartsWith("/api/centralui/audit/export?", url);
var query = QueryHelpers.ParseQuery(new Uri("http://x" + url).Query);
Assert.Single(query);
Assert.Equal(exec.ToString(), query["executionId"]);
}
/// <summary>Verifies that setting a parent execution id emits the parent execution id query parameter.</summary>
[Fact]
public void BuildExportUrl_ParentExecutionIdSet_EmitsParentExecutionIdParam()
{
var parent = Guid.Parse("34343434-5656-7878-9090-121212121212");
var filter = new AuditLogQueryFilter(ParentExecutionId: parent);
var url = AuditLogPage.BuildExportUrl(filter);
Assert.StartsWith("/api/centralui/audit/export?", url);
var query = QueryHelpers.ParseQuery(new Uri("http://x" + url).Query);
Assert.Single(query);
Assert.Equal(parent.ToString(), query["parentExecutionId"]);
}
/// <summary>Verifies that multi-value dimensions emit repeated query parameters.</summary>
[Fact]
public void BuildExportUrl_MultiValueDimensions_EmitRepeatedParams()
{
// Each multi-value dimension emits one repeated query-string key
// per selected value so the export endpoint's ParseFilter sees them all.
var filter = new AuditLogQueryFilter(
Channels: new[] { AuditChannel.ApiOutbound, AuditChannel.DbOutbound },
Statuses: new[] { AuditStatus.Failed, AuditStatus.Parked },
SourceSiteIds: new[] { "plant-a", "plant-b" });
var url = AuditLogPage.BuildExportUrl(filter);
var query = QueryHelpers.ParseQuery(new Uri("http://x" + url).Query);
Assert.Equal(new[] { "ApiOutbound", "DbOutbound" }, query["channel"].ToArray());
Assert.Equal(new[] { "Failed", "Parked" }, query["status"].ToArray());
Assert.Equal(new[] { "plant-a", "plant-b" }, query["site"].ToArray());
}
}