using Xunit; using Moq; using Svrnty.MCP.Gateway.Core.Interfaces; using Svrnty.MCP.Gateway.Core.Models; namespace Svrnty.MCP.Gateway.Core.Tests.Interfaces; /// /// Unit tests for IHealthChecker interface contract. /// Tests health check operations and status tracking. /// public class IHealthCheckerTests { [Fact] public async Task CheckHealthAsync_ReturnsHealthStatus() { // Arrange var mockChecker = new Mock(); var serverConfig = new ServerConfig { Id = "server-1", Name = "Test Server", TransportType = "Http", BaseUrl = "http://localhost:5000" }; var expectedStatus = new ServerHealthStatus { ServerId = "server-1", ServerName = "Test Server", IsHealthy = true, LastCheck = DateTime.UtcNow }; mockChecker.Setup(c => c.CheckHealthAsync(serverConfig, It.IsAny())) .ReturnsAsync(expectedStatus); // Act var result = await mockChecker.Object.CheckHealthAsync(serverConfig); // Assert Assert.NotNull(result); Assert.Equal("server-1", result.ServerId); Assert.True(result.IsHealthy); } [Fact] public async Task CheckHealthAsync_WithUnhealthyServer_ReturnsUnhealthyStatus() { // Arrange var mockChecker = new Mock(); var serverConfig = new ServerConfig { Id = "server-2", Name = "Unhealthy Server", TransportType = "Http", BaseUrl = "http://localhost:5001" }; var expectedStatus = new ServerHealthStatus { ServerId = "server-2", ServerName = "Unhealthy Server", IsHealthy = false, LastCheck = DateTime.UtcNow, ErrorMessage = "Connection timeout" }; mockChecker.Setup(c => c.CheckHealthAsync(serverConfig, It.IsAny())) .ReturnsAsync(expectedStatus); // Act var result = await mockChecker.Object.CheckHealthAsync(serverConfig); // Assert Assert.NotNull(result); Assert.Equal("server-2", result.ServerId); Assert.False(result.IsHealthy); Assert.Equal("Connection timeout", result.ErrorMessage); } [Fact] public async Task StartMonitoringAsync_BeginsHealthChecks() { // Arrange var mockChecker = new Mock(); var serverConfigs = new List { new ServerConfig { Id = "server-1", Name = "Server 1", TransportType = "Http", BaseUrl = "http://localhost:5000" } }; mockChecker.Setup(c => c.StartMonitoringAsync(serverConfigs, It.IsAny())) .Returns(Task.CompletedTask); // Act await mockChecker.Object.StartMonitoringAsync(serverConfigs); // Assert mockChecker.Verify(c => c.StartMonitoringAsync(serverConfigs, It.IsAny()), Times.Once); } [Fact] public async Task StopMonitoringAsync_EndsHealthChecks() { // Arrange var mockChecker = new Mock(); mockChecker.Setup(c => c.StopMonitoringAsync(It.IsAny())) .Returns(Task.CompletedTask); // Act await mockChecker.Object.StopMonitoringAsync(); // Assert mockChecker.Verify(c => c.StopMonitoringAsync(It.IsAny()), Times.Once); } [Fact] public async Task GetCurrentHealthAsync_ReturnsAllServerHealth() { // Arrange var mockChecker = new Mock(); var expectedHealth = new List { new ServerHealthStatus { ServerId = "server-1", IsHealthy = true }, new ServerHealthStatus { ServerId = "server-2", IsHealthy = false } }; mockChecker.Setup(c => c.GetCurrentHealthAsync(It.IsAny())) .ReturnsAsync(expectedHealth); // Act var result = await mockChecker.Object.GetCurrentHealthAsync(); // Assert Assert.NotNull(result); Assert.Equal(2, result.Count()); Assert.Contains(result, s => s.ServerId == "server-1" && s.IsHealthy); Assert.Contains(result, s => s.ServerId == "server-2" && !s.IsHealthy); } }