513fa1aa16
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.
113 lines
5.5 KiB
C#
113 lines
5.5 KiB
C#
using Google.Protobuf.WellKnownTypes;
|
|
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Artifacts;
|
|
using ZB.MOM.WW.ScadaBridge.Communication.Grpc;
|
|
|
|
namespace ZB.MOM.WW.ScadaBridge.Communication.Tests.Grpc;
|
|
|
|
/// <summary>
|
|
/// Round-trip tests for the additive <c>Secrets</c> / <c>SecretsApplied</c> wire contract
|
|
/// on <see cref="DeployArtifactsCommand"/> / <see cref="ArtifactDeploymentResponse"/>
|
|
/// (proto field 9 / field 6). Site secrets design §3.3,
|
|
/// docs/plans/2026-09-28-site-secrets-artifact-deploy-design.md.
|
|
/// </summary>
|
|
public class SiteCommandDtoMapperSecretsTests
|
|
{
|
|
private static SecretArtifact Sample(string name) => new(name, "text/plain",
|
|
[1, 2, 3], [4], [5], [6, 7], [8], [9], "kek-A", 7,
|
|
DateTimeOffset.Parse("2026-09-01T00:00:00Z"), DateTimeOffset.Parse("2026-09-02T00:00:00Z"), "d");
|
|
|
|
/// <summary>Verifies that deploy-artifacts secrets round-trip verbatim through the DTO mapper.</summary>
|
|
[Fact]
|
|
public void DeployArtifacts_Secrets_RoundTrip_Verbatim()
|
|
{
|
|
var cmd = new DeployArtifactsCommand("dep", null, null, null, null, null, null,
|
|
DateTimeOffset.UtcNow, [Sample("A"), Sample("B")]);
|
|
var back = (DeployArtifactsCommand)SiteCommandDtoMapper.FromProto(SiteCommandDtoMapper.ToProto(cmd));
|
|
Assert.Equal(2, back.Secrets!.Count);
|
|
Assert.Equal(cmd.Secrets![0].Ciphertext, back.Secrets[0].Ciphertext);
|
|
Assert.Equal(cmd.Secrets[0].Nonce, back.Secrets[0].Nonce);
|
|
Assert.Equal(cmd.Secrets[0].Tag, back.Secrets[0].Tag);
|
|
Assert.Equal(cmd.Secrets[0].WrappedDek, back.Secrets[0].WrappedDek);
|
|
Assert.Equal(cmd.Secrets[0].WrapNonce, back.Secrets[0].WrapNonce);
|
|
Assert.Equal(cmd.Secrets[0].WrapTag, back.Secrets[0].WrapTag);
|
|
Assert.Equal(cmd.Secrets[0].ContentType, back.Secrets[0].ContentType);
|
|
Assert.Equal(cmd.Secrets[0].CreatedUtc, back.Secrets[0].CreatedUtc);
|
|
Assert.Equal(cmd.Secrets[0].UpdatedUtc, back.Secrets[0].UpdatedUtc);
|
|
Assert.Equal(cmd.Secrets[0].Description, back.Secrets[0].Description);
|
|
Assert.Equal("kek-A", back.Secrets[1].KekId);
|
|
Assert.Equal(7, back.Secrets[1].Revision);
|
|
}
|
|
|
|
/// <summary>Verifies that null deploy-artifacts secrets stay null through the mapper.</summary>
|
|
[Fact]
|
|
public void DeployArtifacts_NullSecrets_StaysNull()
|
|
{
|
|
var cmd = new DeployArtifactsCommand("dep", null, null, null, null, null, null, DateTimeOffset.UtcNow);
|
|
var dto = SiteCommandDtoMapper.ToProto(cmd);
|
|
Assert.Null(dto.Secrets);
|
|
Assert.Null(((DeployArtifactsCommand)SiteCommandDtoMapper.FromProto(dto)).Secrets);
|
|
}
|
|
|
|
/// <summary>Verifies that empty deploy-artifacts secrets stay empty rather than becoming null.</summary>
|
|
[Fact]
|
|
public void DeployArtifacts_EmptySecrets_StaysEmpty_NotNull()
|
|
{
|
|
var cmd = new DeployArtifactsCommand("dep", null, null, null, null, null, null,
|
|
DateTimeOffset.UtcNow, []);
|
|
var back = (DeployArtifactsCommand)SiteCommandDtoMapper.FromProto(SiteCommandDtoMapper.ToProto(cmd));
|
|
Assert.NotNull(back.Secrets);
|
|
Assert.Empty(back.Secrets!);
|
|
}
|
|
|
|
/// <summary>Verifies that a command DTO that lacks the secrets field maps to null secrets.</summary>
|
|
[Fact]
|
|
public void DeployArtifacts_CommandDtoWithoutField9_MapsToNullSecrets()
|
|
{
|
|
// Simulates an OLD CENTRAL that never set field 9 — the DTO here carries no
|
|
// Secrets wrapper at all, exactly as a pre-upgrade sender's wire bytes would
|
|
// decode. FromProto must treat that absence as null, not an empty list.
|
|
var dto = new DeployArtifactsCommandDto
|
|
{
|
|
DeploymentId = "dep",
|
|
Timestamp = Timestamp.FromDateTimeOffset(DateTimeOffset.UtcNow)
|
|
};
|
|
|
|
Assert.Null(dto.Secrets);
|
|
|
|
var back = SiteCommandDtoMapper.FromProto(dto);
|
|
Assert.Null(back.Secrets);
|
|
}
|
|
|
|
/// <summary>Verifies that the applied-secrets count of an artifact response round-trips through the mapper.</summary>
|
|
/// <param name="applied">The applied-secrets count, or <see langword="null"/> when the site did not report one.</param>
|
|
[Theory]
|
|
[InlineData(null)]
|
|
[InlineData(3)]
|
|
public void ArtifactResponse_SecretsApplied_RoundTrips(int? applied)
|
|
{
|
|
var r = new ArtifactDeploymentResponse("dep", "site-a", true, null, DateTimeOffset.UtcNow, applied);
|
|
Assert.Equal(applied, SiteCommandDtoMapper.FromProto(SiteCommandDtoMapper.ToProto(r)).SecretsApplied);
|
|
}
|
|
|
|
/// <summary>Verifies that the removed-secrets list of an artifact response round-trips through the mapper.</summary>
|
|
[Fact]
|
|
public void ArtifactResponse_SecretsRemoved_RoundTrips()
|
|
{
|
|
var r = new ArtifactDeploymentResponse(
|
|
"dep", "site-a", true, null, DateTimeOffset.UtcNow, 0, ["old-1", "old-2"]);
|
|
Assert.Equal(["old-1", "old-2"], SiteCommandDtoMapper.FromProto(SiteCommandDtoMapper.ToProto(r)).SecretsRemoved!);
|
|
}
|
|
|
|
/// <summary>Verifies that an artifact response with no removed secrets is null on both sides of the mapper.</summary>
|
|
[Fact]
|
|
public void ArtifactResponse_NoSecretsRemoved_IsNullOnBothSides()
|
|
{
|
|
// Absent on the wire (an old site, or nothing removed) must read back as null.
|
|
var none = new ArtifactDeploymentResponse("dep", "site-a", true, null, DateTimeOffset.UtcNow, 1);
|
|
Assert.Null(SiteCommandDtoMapper.FromProto(SiteCommandDtoMapper.ToProto(none)).SecretsRemoved);
|
|
|
|
var empty = none with { SecretsRemoved = [] };
|
|
Assert.Null(SiteCommandDtoMapper.FromProto(SiteCommandDtoMapper.ToProto(empty)).SecretsRemoved);
|
|
}
|
|
}
|