using System.Text; using System.Text.Json; using Shouldly; using Xunit; using ZB.MOM.WW.OtOpcUa.Runtime.Drivers; namespace ZB.MOM.WW.OtOpcUa.Runtime.Tests.Drivers; public sealed class DeploymentArtifactTests { [Fact] public void Empty_blob_returns_empty_list() { DeploymentArtifact.ParseDriverInstances(ReadOnlySpan.Empty).ShouldBeEmpty(); } [Fact] public void Malformed_json_returns_empty_list() { DeploymentArtifact.ParseDriverInstances(Encoding.UTF8.GetBytes("not json")).ShouldBeEmpty(); } [Fact] public void Snapshot_without_DriverInstances_returns_empty() { var blob = Encoding.UTF8.GetBytes("{\"Clusters\":[]}"); DeploymentArtifact.ParseDriverInstances(blob).ShouldBeEmpty(); } [Fact] public void Parses_driver_instances_from_composer_shaped_blob() { // Mirrors the shape ConfigComposer.SnapshotAndFlattenAsync emits — Pascal-case fields // serialised directly off the EF entity. var rowId = Guid.NewGuid(); var blob = JsonSerializer.SerializeToUtf8Bytes(new { DriverInstances = new[] { new { DriverInstanceRowId = rowId, DriverInstanceId = "DI-modbus-1", Name = "Modbus Line A", DriverType = "Modbus", Enabled = true, DriverConfig = "{\"host\":\"127.0.0.1\"}", }, new { DriverInstanceRowId = Guid.NewGuid(), DriverInstanceId = "DI-disabled", Name = "Decommissioned", DriverType = "AbCip", Enabled = false, DriverConfig = "{}", }, }, }); var specs = DeploymentArtifact.ParseDriverInstances(blob); specs.Count.ShouldBe(2); specs[0].DriverInstanceRowId.ShouldBe(rowId); specs[0].DriverInstanceId.ShouldBe("DI-modbus-1"); specs[0].DriverType.ShouldBe("Modbus"); specs[0].Enabled.ShouldBeTrue(); specs[0].DriverConfig.ShouldContain("127.0.0.1"); specs[1].Enabled.ShouldBeFalse(); } [Fact] public void ParseComposition_returns_empty_for_empty_blob() { var c = DeploymentArtifact.ParseComposition(ReadOnlySpan.Empty); c.EquipmentNodes.ShouldBeEmpty(); c.DriverInstancePlans.ShouldBeEmpty(); c.ScriptedAlarmPlans.ShouldBeEmpty(); } [Fact] public void ParseComposition_reads_all_three_entity_classes_sorted_by_id() { var blob = JsonSerializer.SerializeToUtf8Bytes(new { Equipment = new[] { new { EquipmentId = "eq-z", MachineCode = "Z", UnsLineId = "line-1" }, new { EquipmentId = "eq-a", MachineCode = "A", UnsLineId = "line-1" }, }, DriverInstances = new[] { new { DriverInstanceId = "drv-1", DriverType = "Modbus", DriverConfig = "{}" }, }, ScriptedAlarms = new[] { new { ScriptedAlarmId = "alarm-1", EquipmentId = "eq-a", PredicateScriptId = "script-1", MessageTemplate = "high", }, }, }); var c = DeploymentArtifact.ParseComposition(blob); c.EquipmentNodes.Select(e => e.EquipmentId).ShouldBe(new[] { "eq-a", "eq-z" }); c.DriverInstancePlans.Single().DriverInstanceId.ShouldBe("drv-1"); c.ScriptedAlarmPlans.Single().ScriptedAlarmId.ShouldBe("alarm-1"); } [Fact] public void Spec_missing_required_fields_is_dropped() { var blob = JsonSerializer.SerializeToUtf8Bytes(new { DriverInstances = new object[] { new { Name = "no-id" }, new { DriverInstanceId = "DI-ok", DriverType = "Modbus", DriverConfig = "{}", }, }, }); var specs = DeploymentArtifact.ParseDriverInstances(blob); specs.Single().DriverInstanceId.ShouldBe("DI-ok"); } }