using Shouldly; using Xunit; using ZB.MOM.WW.OtOpcUa.Configuration.Entities; using ZB.MOM.WW.OtOpcUa.Configuration.Enums; using ZB.MOM.WW.OtOpcUa.Configuration.Validation; namespace ZB.MOM.WW.OtOpcUa.Configuration.Tests; /// /// Characterization net (R2-11) pinning the DraftValidator Galaxy rule's explicit-FullName /// semantics across the golden TagConfig corpus BEFORE the private FullName reader is delegated to /// TagConfigIntent.Parse(...).ExplicitFullName. Distinct from the walker/composer raw-blob /// fallback: GalaxyTagMissingReference fires whenever the TagConfig has no usable /// explicit string FullName — i.e. absent / non-string / whitespace / non-object / /// malformed — and does NOT fire only when a non-blank string FullName is present. Must be green on /// the unmodified tree and stay green through the swap. /// public sealed class DraftValidatorGalaxyFullNameCorpusTests { [Theory] // Present, non-blank string FullName → rule does NOT fire [InlineData("{\"FullName\":\"X.Y\"}", false)] [InlineData("{\"FullName\":\"A.B\",\"region\":\"Coils\"}", false)] // Absent / non-string / whitespace / non-object / malformed → rule FIRES [InlineData("{}", true)] [InlineData("{\"region\":\"HoldingRegisters\"}", true)] [InlineData("{\"FullName\":123}", true)] [InlineData("{\"FullName\":\" \"}", true)] [InlineData("[1,2]", true)] [InlineData("not json {", true)] public void Galaxy_missing_reference_fires_iff_no_explicit_string_FullName(string tagConfig, bool shouldFire) { var draft = new DraftSnapshot { GenerationId = 1, ClusterId = "c", DriverInstances = [ new DriverInstance { DriverInstanceId = "d-galaxy", ClusterId = "c", NamespaceId = "ns-1", Name = "Galaxy", DriverType = "GalaxyMxGateway", DriverConfig = "{}", }, ], Tags = [ new Tag { TagId = "tag-galaxytag", DriverInstanceId = "d-galaxy", EquipmentId = "eq-1", Name = "galaxytag", FolderPath = null, DataType = "Float", AccessLevel = TagAccessLevel.Read, TagConfig = tagConfig, }, ], }; var fired = DraftValidator.Validate(draft) .Any(e => e.Code == "GalaxyTagMissingReference" && e.Context == "tag-galaxytag"); fired.ShouldBe(shouldFire); } }