using System; using Shouldly; using Xunit; using ZB.MOM.WW.LmxOpcUa.Host.Domain; using ZB.MOM.WW.LmxOpcUa.Host.GalaxyRepository; using ZB.MOM.WW.LmxOpcUa.Host.Metrics; using ZB.MOM.WW.LmxOpcUa.Host.Status; using ZB.MOM.WW.LmxOpcUa.Tests.Helpers; namespace ZB.MOM.WW.LmxOpcUa.Tests.Status { /// /// Verifies the HTML, JSON, and health snapshots generated for the operator status dashboard. /// public class StatusReportServiceTests { /// /// Confirms that the generated HTML contains every dashboard panel expected by operators. /// [Fact] public void GenerateHtml_ContainsAllPanels() { var sut = CreateService(); var html = sut.GenerateHtml(); html.ShouldContain("Connection"); html.ShouldContain("Health"); html.ShouldContain("Subscriptions"); html.ShouldContain("Galaxy Info"); html.ShouldContain("Operations"); html.ShouldContain("Footer"); } /// /// Confirms that the generated HTML includes the configured auto-refresh meta tag. /// [Fact] public void GenerateHtml_ContainsMetaRefresh() { var sut = CreateService(); var html = sut.GenerateHtml(); html.ShouldContain("meta http-equiv='refresh' content='10'"); } /// /// Confirms that the connection panel renders the current runtime connection state. /// [Fact] public void GenerateHtml_ConnectionPanel_ShowsState() { var sut = CreateService(); var html = sut.GenerateHtml(); html.ShouldContain("Connected"); } /// /// Confirms that the Galaxy panel renders the bridged Galaxy name. /// [Fact] public void GenerateHtml_GalaxyPanel_ShowsName() { var sut = CreateService(); var html = sut.GenerateHtml(); html.ShouldContain("TestGalaxy"); } /// /// Confirms that the operations table renders the expected performance metric headers. /// [Fact] public void GenerateHtml_OperationsTable_ShowsHeaders() { var sut = CreateService(); var html = sut.GenerateHtml(); html.ShouldContain("Count"); html.ShouldContain("Success Rate"); html.ShouldContain("Avg (ms)"); html.ShouldContain("Min (ms)"); html.ShouldContain("Max (ms)"); html.ShouldContain("P95 (ms)"); } /// /// Confirms that the footer renders timestamp and version information. /// [Fact] public void GenerateHtml_Footer_ContainsTimestampAndVersion() { var sut = CreateService(); var html = sut.GenerateHtml(); html.ShouldContain("Generated:"); html.ShouldContain("Version:"); } /// /// Confirms that the generated JSON includes the major dashboard sections. /// [Fact] public void GenerateJson_Deserializes() { var sut = CreateService(); var json = sut.GenerateJson(); json.ShouldNotBeNullOrWhiteSpace(); json.ShouldContain("Connection"); json.ShouldContain("Health"); json.ShouldContain("Subscriptions"); json.ShouldContain("Galaxy"); json.ShouldContain("Operations"); json.ShouldContain("Footer"); } /// /// Confirms that the report service reports healthy when the runtime connection is up. /// [Fact] public void IsHealthy_WhenConnected_ReturnsTrue() { var sut = CreateService(); sut.IsHealthy().ShouldBe(true); } /// /// Confirms that the report service reports unhealthy when the runtime connection is down. /// [Fact] public void IsHealthy_WhenDisconnected_ReturnsFalse() { var mxClient = new FakeMxAccessClient { State = ConnectionState.Disconnected }; var sut = new StatusReportService(new HealthCheckService(), 10); sut.SetComponents(mxClient, null, null, null); sut.IsHealthy().ShouldBe(false); } /// /// Creates a status report service preloaded with representative runtime, Galaxy, and metrics data. /// /// A configured status report service for dashboard assertions. private static StatusReportService CreateService() { var mxClient = new FakeMxAccessClient(); using var metrics = new PerformanceMetrics(); metrics.RecordOperation("Read", TimeSpan.FromMilliseconds(10)); metrics.RecordOperation("Write", TimeSpan.FromMilliseconds(20)); var galaxyStats = new GalaxyRepositoryStats { GalaxyName = "TestGalaxy", DbConnected = true, LastDeployTime = new DateTime(2024, 6, 1), ObjectCount = 42, AttributeCount = 200, LastRebuildTime = DateTime.UtcNow }; var sut = new StatusReportService(new HealthCheckService(), 10); sut.SetComponents(mxClient, metrics, galaxyStats, null); return sut; } } }