Files
ScadaBridge/tests/ZB.MOM.WW.ScadaBridge.ManagementService.Tests/ApiMethodTraceAllCallsTests.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

95 lines
4.3 KiB
C#

using Akka.Actor;
using Akka.TestKit.Xunit2;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging.Abstractions;
using NSubstitute;
using ZB.MOM.WW.ScadaBridge.Commons.Entities.InboundApi;
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Repositories;
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Services;
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Management;
namespace ZB.MOM.WW.ScadaBridge.ManagementService.Tests;
/// <summary>
/// Flow Debugger design 2026-09-05 §5.2: <c>ApiMethod.TraceAllCalls</c> round-trips through the
/// Create/Update management commands, defaults to off, and an Update that omits it (an older
/// CLI) leaves the stored value unchanged.
/// </summary>
public class ApiMethodTraceAllCallsTests : TestKit, IDisposable
{
private readonly ServiceCollection _services = new ServiceCollection().AddTestConfigurationTransaction();
private readonly IInboundApiRepository _apiRepo = Substitute.For<IInboundApiRepository>();
/// <summary>Initializes the test class with a stubbed inbound API repository and test services.</summary>
public ApiMethodTraceAllCallsTests()
{
_services.AddScoped(_ => _apiRepo);
_services.AddScoped(_ => Substitute.For<IAuditService>());
_apiRepo.SaveChangesAsync(Arg.Any<CancellationToken>()).Returns(1);
}
private IActorRef CreateActor() =>
Sys.ActorOf(Props.Create(() => new ManagementActor(
_services.BuildServiceProvider(), NullLogger<ManagementActor>.Instance)));
private static ManagementEnvelope Envelope(object command) =>
new(new AuthenticatedUser("designer", "Designer", new[] { "Designer" }, Array.Empty<string>()),
command, Guid.NewGuid().ToString("N"));
/// <inheritdoc />
void IDisposable.Dispose() => Shutdown();
/// <summary>Verifies that commands default to untraced when built with the five-argument constructor.</summary>
[Fact]
public void Commands_DefaultToUntraced_ForTheFiveArgConstructor()
{
Assert.False(new CreateApiMethodCommand("m", "return 1;", 30, null, null).TraceAllCalls);
Assert.Null(new UpdateApiMethodCommand(1, "return 1;", 30, null, null).TraceAllCalls);
Assert.False(new ApiMethod("m", "return 1;").TraceAllCalls);
}
/// <summary>Verifies that creating a method with the trace-all-calls flag persists it and echoes it in the result.</summary>
[Fact]
public void Create_WithTraceAllCalls_PersistsTheFlag_AndEchoesItInTheResult()
{
ApiMethod? added = null;
_apiRepo.AddApiMethodAsync(Arg.Do<ApiMethod>(m => added = m), Arg.Any<CancellationToken>())
.Returns(Task.CompletedTask);
CreateActor().Tell(Envelope(new CreateApiMethodCommand("Traced", "return 1;", 30, null, null, TraceAllCalls: true)));
var response = ExpectMsg<ManagementSuccess>(TimeSpan.FromSeconds(10));
Assert.NotNull(added);
Assert.True(added!.TraceAllCalls);
Assert.Contains("\"traceAllCalls\":true", response.JsonData.Replace(" ", ""));
}
/// <summary>Verifies that updating with an explicit false clears the trace-all-calls flag.</summary>
[Fact]
public void Update_WithExplicitFalse_ClearsTheFlag()
{
var existing = new ApiMethod("M", "return 1;") { Id = 7, TimeoutSeconds = 10, TraceAllCalls = true };
_apiRepo.GetApiMethodByIdAsync(7, Arg.Any<CancellationToken>()).Returns(existing);
CreateActor().Tell(Envelope(new UpdateApiMethodCommand(7, "return 2;", 10, null, null, TraceAllCalls: false)));
ExpectMsg<ManagementSuccess>(TimeSpan.FromSeconds(10));
Assert.False(existing.TraceAllCalls);
}
/// <summary>Verifies that an update that omits the flag leaves the stored value unchanged.</summary>
[Fact]
public void Update_OmittingTheFlag_LeavesTheStoredValueUnchanged()
{
var existing = new ApiMethod("M", "return 1;") { Id = 7, TimeoutSeconds = 10, TraceAllCalls = true };
_apiRepo.GetApiMethodByIdAsync(7, Arg.Any<CancellationToken>()).Returns(existing);
// The 5-arg shape an older CLI sends: TraceAllCalls == null.
CreateActor().Tell(Envelope(new UpdateApiMethodCommand(7, "return 2;", 10, null, null)));
ExpectMsg<ManagementSuccess>(TimeSpan.FromSeconds(10));
Assert.True(existing.TraceAllCalls);
Assert.Equal("return 2;", existing.Script);
}
}