using System.Collections.Generic; using System.Threading.Tasks; using Shouldly; using Xunit; using ZB.MOM.WW.LmxOpcUa.Host; using ZB.MOM.WW.LmxOpcUa.Host.Configuration; using ZB.MOM.WW.LmxOpcUa.Host.Domain; using ZB.MOM.WW.LmxOpcUa.Tests.Helpers; namespace ZB.MOM.WW.LmxOpcUa.Tests.Wiring { /// /// Verifies: OpcUaService Start() creates and wires all components with fakes. /// public class ServiceStartupSequenceTest { /// /// Confirms that startup with fake dependencies creates the expected bridge components and state. /// [Fact] public void Start_WithFakes_AllComponentsCreated() { var config = new AppConfiguration { OpcUa = new OpcUaConfiguration { Port = 14840, GalaxyName = "TestGalaxy", EndpointPath = "/LmxOpcUa" }, MxAccess = new MxAccessConfiguration { ClientName = "Test" }, GalaxyRepository = new GalaxyRepositoryConfiguration(), Dashboard = new DashboardConfiguration { Enabled = false } // Don't start HTTP listener in tests }; var proxy = new FakeMxProxy(); var repo = new FakeGalaxyRepository { Hierarchy = new List { new GalaxyObjectInfo { GobjectId = 1, TagName = "TestObj", BrowseName = "TestObj", ParentGobjectId = 0, IsArea = false } }, Attributes = new List { new GalaxyAttributeInfo { GobjectId = 1, TagName = "TestObj", AttributeName = "TestAttr", FullTagReference = "TestObj.TestAttr", MxDataType = 5, IsArray = false } } }; var service = new OpcUaService(config, proxy, repo); service.Start(); try { // Verify all components were created service.MxClient.ShouldNotBeNull(); service.MxClient!.State.ShouldBe(ConnectionState.Connected); service.Metrics.ShouldNotBeNull(); service.ServerHost.ShouldNotBeNull(); service.ChangeDetectionInstance.ShouldNotBeNull(); service.GalaxyStatsInstance.ShouldNotBeNull(); service.GalaxyStatsInstance!.GalaxyName.ShouldBe("TestGalaxy"); service.GalaxyStatsInstance.DbConnected.ShouldBe(true); service.StatusReportInstance.ShouldNotBeNull(); // Dashboard disabled → no web server service.StatusWeb.ShouldBeNull(); // MxProxy should have been registered proxy.IsRegistered.ShouldBe(true); } finally { service.Stop(); } } /// /// Confirms that when MXAccess is initially unavailable, the background monitor reconnects it later. /// [Fact] public async Task Start_WhenMxAccessIsInitiallyDown_MonitorReconnectsInBackground() { var config = new AppConfiguration { OpcUa = new OpcUaConfiguration { Port = 14841, GalaxyName = "TestGalaxy", EndpointPath = "/LmxOpcUa" }, MxAccess = new MxAccessConfiguration { ClientName = "Test", MonitorIntervalSeconds = 1, AutoReconnect = true }, GalaxyRepository = new GalaxyRepositoryConfiguration(), Dashboard = new DashboardConfiguration { Enabled = false } }; var proxy = new FakeMxProxy { ShouldFailRegister = true }; var repo = new FakeGalaxyRepository { Hierarchy = new List { new GalaxyObjectInfo { GobjectId = 1, TagName = "TestObj", BrowseName = "TestObj", ParentGobjectId = 0, IsArea = false } }, Attributes = new List { new GalaxyAttributeInfo { GobjectId = 1, TagName = "TestObj", AttributeName = "TestAttr", FullTagReference = "TestObj.TestAttr", MxDataType = 5, IsArray = false } } }; var service = new OpcUaService(config, proxy, repo); service.Start(); try { service.ServerHost.ShouldNotBeNull(); service.MxClient.ShouldNotBeNull(); service.MxClient!.State.ShouldBe(ConnectionState.Error); proxy.ShouldFailRegister = false; await Task.Delay(2500); service.MxClient.State.ShouldBe(ConnectionState.Connected); proxy.RegisterCallCount.ShouldBeGreaterThan(1); } finally { service.Stop(); } } } }