using System.Text.Json; using Shouldly; using Xunit; using ZB.MOM.WW.OtOpcUa.Runtime.Drivers; namespace ZB.MOM.WW.OtOpcUa.Runtime.Tests.Drivers; /// /// Verifies the artifact-decode mirror () /// admits a Galaxy alias tag — an equipment-scoped tag (non-null EquipmentId) bound to a /// GalaxyMxGateway driver in a SystemPlatform-kind namespace — into the decoded /// EquipmentTags with byte-parity to the live-edit composer path: same FullName, EquipmentId, /// DriverInstanceId, Name, DataType. The composer broadens the same filter by DriverType, so both /// data-contract sites must agree on which tags qualify. /// public sealed class DeploymentArtifactAliasParityTests { /// An artifact JSON blob with a GalaxyMxGateway driver in a SystemPlatform (Kind=1) /// namespace and one equipment-scoped alias tag (EquipmentId set, FolderPath null, FullName = the /// Galaxy ref). Decode must surface the alias in EquipmentTags carrying its driver-side FullName. [Fact] public void ParseComposition_admits_galaxy_alias_tag_in_equipment_tags() { var blob = JsonSerializer.SerializeToUtf8Bytes(new { Namespaces = new[] { new { NamespaceId = "ns-sp", Kind = 1 }, // NamespaceKind.SystemPlatform }, DriverInstances = new[] { new { DriverInstanceId = "drv-galaxy", DriverType = "GalaxyMxGateway", DriverConfig = "{}", NamespaceId = "ns-sp" }, }, Tags = new object[] { new { TagId = "tag-alias", DriverInstanceId = "drv-galaxy", EquipmentId = "eq-1", Name = "TestChangingInt", FolderPath = (string?)null, DataType = "Int32", TagConfig = "{\"FullName\":\"TestMachine_020.TestChangingInt\"}", }, }, }); var c = DeploymentArtifact.ParseComposition(blob); var alias = c.EquipmentTags.ShouldHaveSingleItem(); alias.TagId.ShouldBe("tag-alias"); alias.EquipmentId.ShouldBe("eq-1"); alias.DriverInstanceId.ShouldBe("drv-galaxy"); alias.Name.ShouldBe("TestChangingInt"); alias.DataType.ShouldBe("Int32"); alias.FolderPath.ShouldBe(string.Empty); alias.FullName.ShouldBe("TestMachine_020.TestChangingInt"); } /// An equipment-scoped tag bound to a non-Galaxy driver in a SystemPlatform namespace is /// NOT a Galaxy alias and must stay excluded from EquipmentTags — the broadened clause keys on the /// GalaxyMxGateway DriverType, not on the namespace kind, so the contract narrows correctly. [Fact] public void ParseComposition_excludes_non_galaxy_systemplatform_equipment_tag() { var blob = JsonSerializer.SerializeToUtf8Bytes(new { Namespaces = new[] { new { NamespaceId = "ns-sp", Kind = 1 }, // NamespaceKind.SystemPlatform }, DriverInstances = new[] { new { DriverInstanceId = "drv-modbus", DriverType = "Modbus", DriverConfig = "{}", NamespaceId = "ns-sp" }, }, Tags = new object[] { new { TagId = "tag-x", DriverInstanceId = "drv-modbus", EquipmentId = "eq-1", Name = "Source", FolderPath = (string?)null, DataType = "Int32", TagConfig = "{\"FullName\":\"TestMachine_020.Source\"}", }, }, }); var c = DeploymentArtifact.ParseComposition(blob); c.EquipmentTags.ShouldBeEmpty(); } }