using System; using System.Net; using System.Net.Http; using System.Threading.Tasks; using Shouldly; using Xunit; using ZB.MOM.WW.LmxOpcUa.Host.Status; using ZB.MOM.WW.LmxOpcUa.Tests.Helpers; namespace ZB.MOM.WW.LmxOpcUa.Tests.Status { public class StatusWebServerTests : IDisposable { private readonly StatusWebServer _server; private readonly HttpClient _client; private readonly int _port; public StatusWebServerTests() { _port = new Random().Next(18000, 19000); var reportService = new StatusReportService(new HealthCheckService(), 10); var mxClient = new FakeMxAccessClient(); reportService.SetComponents(mxClient, null, null, null); _server = new StatusWebServer(reportService, _port); _server.Start(); _client = new HttpClient { BaseAddress = new Uri($"http://localhost:{_port}") }; } public void Dispose() { _client.Dispose(); _server.Dispose(); } [Fact] public async Task Root_ReturnsHtml200() { var response = await _client.GetAsync("/"); response.StatusCode.ShouldBe(HttpStatusCode.OK); response.Content.Headers.ContentType?.MediaType.ShouldBe("text/html"); } [Fact] public async Task ApiStatus_ReturnsJson200() { var response = await _client.GetAsync("/api/status"); response.StatusCode.ShouldBe(HttpStatusCode.OK); response.Content.Headers.ContentType?.MediaType.ShouldBe("application/json"); } [Fact] public async Task ApiHealth_Returns200WhenHealthy() { var response = await _client.GetAsync("/api/health"); // FakeMxAccessClient starts as Connected → healthy response.StatusCode.ShouldBe(HttpStatusCode.OK); var body = await response.Content.ReadAsStringAsync(); body.ShouldContain("healthy"); } [Fact] public async Task UnknownPath_Returns404() { var response = await _client.GetAsync("/unknown"); response.StatusCode.ShouldBe(HttpStatusCode.NotFound); } [Fact] public async Task PostMethod_Returns405() { var response = await _client.PostAsync("/", new StringContent("")); response.StatusCode.ShouldBe(HttpStatusCode.MethodNotAllowed); } [Fact] public async Task CacheHeaders_Present() { var response = await _client.GetAsync("/"); response.Headers.CacheControl?.NoCache.ShouldBe(true); response.Headers.CacheControl?.NoStore.ShouldBe(true); } [Fact] public void StartStop_DoesNotThrow() { var server2 = new StatusWebServer( new StatusReportService(new HealthCheckService(), 10), new Random().Next(19000, 20000)); server2.Start(); server2.IsRunning.ShouldBe(true); server2.Stop(); } } }