bd6c0b4d3d
Add missing <returns>/<param>/<summary>/<typeparam> tags and clean up misused inheritdoc across 481 files so the documented API surface is complete. Documentation-only (zero code lines changed). The 131 remaining findings are inheritdoc-style warnings deliberately left to preserve hand-written implementation rationale (plan-decision notes, race-condition explanations).
117 lines
4.5 KiB
C#
117 lines
4.5 KiB
C#
using System.Text.Json;
|
|
using System.Text.Json.Serialization;
|
|
using Shouldly;
|
|
using Xunit;
|
|
using ZB.MOM.WW.OtOpcUa.AdminUI.Components.Pages.Clusters.Drivers;
|
|
using ZB.MOM.WW.OtOpcUa.Driver.Historian.Wonderware.Client;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.AdminUI.Tests;
|
|
|
|
public sealed class HistorianWonderwareDriverPageFormSerializationTests
|
|
{
|
|
private static readonly JsonSerializerOptions _opts = new()
|
|
{
|
|
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
|
WriteIndented = false,
|
|
};
|
|
|
|
/// <summary>Verifies that a round-trip serialization/deserialization preserves all known fields.</summary>
|
|
[Fact]
|
|
public void RoundTrip_PreservesKnownFields()
|
|
{
|
|
var original = new WonderwareHistorianClientOptions(
|
|
PipeName: "otopcua-historian-prod",
|
|
SharedSecret: "t0ps3cr3t",
|
|
PeerName: "OtOpcUa-Primary",
|
|
ConnectTimeout: TimeSpan.FromSeconds(20),
|
|
CallTimeout: TimeSpan.FromSeconds(60))
|
|
{
|
|
ProbeTimeoutSeconds = 25,
|
|
};
|
|
|
|
var json = JsonSerializer.Serialize(original, _opts);
|
|
var back = JsonSerializer.Deserialize<WonderwareHistorianClientOptions>(json, _opts);
|
|
|
|
back.ShouldNotBeNull();
|
|
back.PipeName.ShouldBe("otopcua-historian-prod");
|
|
back.SharedSecret.ShouldBe("t0ps3cr3t");
|
|
back.PeerName.ShouldBe("OtOpcUa-Primary");
|
|
back.ConnectTimeout.ShouldBe(TimeSpan.FromSeconds(20));
|
|
back.CallTimeout.ShouldBe(TimeSpan.FromSeconds(60));
|
|
back.EffectiveConnectTimeout.ShouldBe(TimeSpan.FromSeconds(20));
|
|
back.EffectiveCallTimeout.ShouldBe(TimeSpan.FromSeconds(60));
|
|
back.ProbeTimeoutSeconds.ShouldBe(25);
|
|
}
|
|
|
|
/// <summary>Verifies that null timeout values fall back to the expected defaults after deserialization.</summary>
|
|
[Fact]
|
|
public void RoundTrip_NullTimeouts_UsesDefaults()
|
|
{
|
|
var original = new WonderwareHistorianClientOptions(
|
|
PipeName: "otopcua-historian",
|
|
SharedSecret: "secret");
|
|
|
|
var json = JsonSerializer.Serialize(original, _opts);
|
|
var back = JsonSerializer.Deserialize<WonderwareHistorianClientOptions>(json, _opts);
|
|
|
|
back.ShouldNotBeNull();
|
|
back.ConnectTimeout.ShouldBeNull();
|
|
back.CallTimeout.ShouldBeNull();
|
|
back.EffectiveConnectTimeout.ShouldBe(TimeSpan.FromSeconds(10));
|
|
back.EffectiveCallTimeout.ShouldBe(TimeSpan.FromSeconds(30));
|
|
}
|
|
|
|
/// <summary>Verifies that unknown JSON properties are silently ignored during deserialization.</summary>
|
|
[Fact]
|
|
public void Deserialize_DropsUnknownFields()
|
|
{
|
|
var jsonWithExtra = """
|
|
{
|
|
"unknownField": "old-value",
|
|
"pipeName": "otopcua-historian",
|
|
"sharedSecret": "s3cr3t",
|
|
"probeTimeoutSeconds": 20
|
|
}
|
|
""";
|
|
|
|
var optsWithSkip = new JsonSerializerOptions(_opts)
|
|
{
|
|
UnmappedMemberHandling = JsonUnmappedMemberHandling.Skip,
|
|
};
|
|
|
|
var back = JsonSerializer.Deserialize<WonderwareHistorianClientOptions>(jsonWithExtra, optsWithSkip);
|
|
back.ShouldNotBeNull();
|
|
back.ProbeTimeoutSeconds.ShouldBe(20);
|
|
back.PipeName.ShouldBe("otopcua-historian");
|
|
}
|
|
|
|
/// <summary>Verifies that the form model FromRecord/ToRecord round-trip preserves all fields losslessly.</summary>
|
|
[Fact]
|
|
public void FormModel_RoundTrip_PreservesAllFields()
|
|
{
|
|
// Construct a record with non-default values for every property and verify
|
|
// that WonderwareHistorianClientFormModel.FromRecord → ToRecord is lossless.
|
|
var original = new WonderwareHistorianClientOptions(
|
|
PipeName: "otopcua-historian-prod",
|
|
SharedSecret: "sup3rs3cr3t",
|
|
PeerName: "OtOpcUa-Redundant",
|
|
ConnectTimeout: TimeSpan.FromSeconds(18),
|
|
CallTimeout: TimeSpan.FromSeconds(45))
|
|
{
|
|
ProbeTimeoutSeconds = 30,
|
|
};
|
|
|
|
var form = HistorianWonderwareDriverPage.WonderwareHistorianClientFormModel.FromRecord(original);
|
|
var result = form.ToRecord();
|
|
|
|
result.PipeName.ShouldBe("otopcua-historian-prod");
|
|
result.SharedSecret.ShouldBe("sup3rs3cr3t");
|
|
result.PeerName.ShouldBe("OtOpcUa-Redundant");
|
|
result.ConnectTimeout.ShouldBe(TimeSpan.FromSeconds(18));
|
|
result.CallTimeout.ShouldBe(TimeSpan.FromSeconds(45));
|
|
result.EffectiveConnectTimeout.ShouldBe(TimeSpan.FromSeconds(18));
|
|
result.EffectiveCallTimeout.ShouldBe(TimeSpan.FromSeconds(45));
|
|
result.ProbeTimeoutSeconds.ShouldBe(30);
|
|
}
|
|
}
|