using Shouldly; using Xunit; using ZB.MOM.WW.MxGateway.Contracts.Proto.Galaxy; using ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Browse; namespace ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests.Browse; /// The platform-only query the driver seeds its ScanState probe watcher from. public sealed class GatewayGalaxyPlatformSourceTests { private static GalaxyObject Obj(string tag, params string[] chain) { var o = new GalaxyObject { TagName = tag }; o.TemplateChain.Add(chain); return o; } /// Every request carries the platform template filter, no attributes, and the page size; replies are re-filtered. [Fact] public async Task Requests_filter_on_platform_templates_without_attributes_and_replies_are_refiltered() { var requests = new List(); Task Discover(DiscoverHierarchyRequest req, CancellationToken ct) { requests.Add(req); var reply = new DiscoverHierarchyReply(); if (req.PageToken == "") { reply.Objects.Add([Obj("Plat01", "$WinPlatform"), Obj("Tank01", "$UserDefined")]); reply.NextPageToken = "p2"; } else { reply.Objects.Add([Obj("Eng01", "$AppEngine", "$WinPlatform"), Obj("Plat01", "$WinPlatform"), Obj("", "$WinPlatform")]); } return Task.FromResult(reply); } var names = await GatewayGalaxyPlatformSource.QueryAsync(Discover, pageSize: 50, CancellationToken.None); names.ShouldBe(["Plat01", "Eng01"]); requests.Count.ShouldBe(2); requests.ShouldAllBe(r => r.PageSize == 50 && r.IncludeAttributes == false); requests.ShouldAllBe(r => r.TemplateChainContains.Contains("$WinPlatform") && r.TemplateChainContains.Contains("$AppEngine")); } /// A gateway that strips the template chain is trusted to have filtered server-side. [Fact] public async Task Objects_without_a_template_chain_are_kept() { Task Discover(DiscoverHierarchyRequest req, CancellationToken ct) { var reply = new DiscoverHierarchyReply(); reply.Objects.Add(new GalaxyObject { TagName = "Plat01" }); return Task.FromResult(reply); } (await GatewayGalaxyPlatformSource.QueryAsync(Discover, pageSize: 0, CancellationToken.None)).ShouldBe(["Plat01"]); } }