using System.Text.Json; using ZB.MOM.WW.ScadaBridge.Commons.Messages.Management; namespace ZB.MOM.WW.ScadaBridge.Commons.Tests.Messages; /// /// Regression tests for Commons-008 — /// previously declared its bindings as IReadOnlyList<(string, int)>. /// A ValueTuple serializes as Item1/Item2 and cannot evolve /// additively (REQ-COM-5a). It is now a named record. /// public class ConnectionBindingSerializationTests { [Fact] public void ConnectionBinding_SerializesWithNamedProperties() { var json = JsonSerializer.Serialize(new ConnectionBinding("Temperature", 42)); using var doc = JsonDocument.Parse(json); Assert.Equal(JsonValueKind.String, doc.RootElement.GetProperty("AttributeName").ValueKind); Assert.Equal("Temperature", doc.RootElement.GetProperty("AttributeName").GetString()); Assert.Equal(42, doc.RootElement.GetProperty("DataConnectionId").GetInt32()); // The ValueTuple failure mode: Item1/Item2 must NOT appear. Assert.False(doc.RootElement.TryGetProperty("Item1", out _)); Assert.False(doc.RootElement.TryGetProperty("Item2", out _)); } [Fact] public void SetConnectionBindingsCommand_RoundTripsThroughJson() { var original = new SetConnectionBindingsCommand( 7, new List { new("Speed", 5), new("Mode", 11), }); var json = JsonSerializer.Serialize(original); var deserialized = JsonSerializer.Deserialize(json); Assert.NotNull(deserialized); Assert.Equal(7, deserialized!.InstanceId); Assert.Equal(2, deserialized.Bindings.Count); Assert.Equal("Speed", deserialized.Bindings[0].AttributeName); Assert.Equal(5, deserialized.Bindings[0].DataConnectionId); Assert.Equal("Mode", deserialized.Bindings[1].AttributeName); Assert.Equal(11, deserialized.Bindings[1].DataConnectionId); // ConnectionBinding is a record: each element compares by value. Assert.Equal(original.Bindings, deserialized.Bindings); } [Fact] public void Roundtrip_preserves_override_when_set() { var original = new ConnectionBinding("Speed", 7, "ns=2;s=Pump1.Speed"); var json = JsonSerializer.Serialize(original); var roundtripped = JsonSerializer.Deserialize(json); Assert.NotNull(roundtripped); Assert.Equal(original, roundtripped); Assert.Equal("ns=2;s=Pump1.Speed", roundtripped!.DataSourceReferenceOverride); } [Fact] public void Roundtrip_defaults_override_to_null_when_absent() { // Older site builds will not emit the new field — deserialization // must produce a null override and equal an explicit-null instance. const string legacyJson = """{"AttributeName":"Speed","DataConnectionId":7}"""; var deserialized = JsonSerializer.Deserialize(legacyJson); Assert.NotNull(deserialized); Assert.Equal("Speed", deserialized!.AttributeName); Assert.Equal(7, deserialized.DataConnectionId); Assert.Null(deserialized.DataSourceReferenceOverride); } }