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 IGatewayRouter interface following TDD approach. /// Tests routing behavior and contract compliance. /// public class IGatewayRouterTests { [Fact] public async Task RouteAsync_WithValidRequest_ReturnsResponse() { // Arrange var mockRouter = new Mock(); var request = new GatewayRequest { ToolName = "test_tool", Arguments = new Dictionary { { "key", "value" } } }; var expectedResponse = new GatewayResponse { Success = true, Result = new Dictionary { { "data", "result" } } }; mockRouter .Setup(r => r.RouteAsync(It.IsAny(), It.IsAny())) .ReturnsAsync(expectedResponse); // Act var response = await mockRouter.Object.RouteAsync(request, CancellationToken.None); // Assert Assert.NotNull(response); Assert.True(response.Success); Assert.NotNull(response.Result); mockRouter.Verify(r => r.RouteAsync(request, It.IsAny()), Times.Once); } [Fact] public async Task RouteAsync_WithCancellationToken_PropagatesToken() { // Arrange var mockRouter = new Mock(); var request = new GatewayRequest { ToolName = "cancel_test" }; var cts = new CancellationTokenSource(); mockRouter .Setup(r => r.RouteAsync(It.IsAny(), It.IsAny())) .ReturnsAsync(new GatewayResponse { Success = true }); // Act await mockRouter.Object.RouteAsync(request, cts.Token); // Assert mockRouter.Verify(r => r.RouteAsync(request, cts.Token), Times.Once); } [Fact] public async Task GetServerHealthAsync_ReturnsHealthStatuses() { // Arrange var mockRouter = new Mock(); var healthStatuses = new List { new ServerHealthStatus { ServerId = "server-1", IsHealthy = true, ResponseTime = TimeSpan.FromMilliseconds(25) }, new ServerHealthStatus { ServerId = "server-2", IsHealthy = false, ErrorMessage = "Timeout" } }; mockRouter .Setup(r => r.GetServerHealthAsync(It.IsAny())) .ReturnsAsync(healthStatuses); // Act var result = await mockRouter.Object.GetServerHealthAsync(CancellationToken.None); // 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); } [Fact] public async Task RegisterServerAsync_AddsServerConfiguration() { // Arrange var mockRouter = new Mock(); var serverConfig = new ServerConfig { Id = "new-server", Name = "New MCP Server", TransportType = "Stdio" }; mockRouter .Setup(r => r.RegisterServerAsync(It.IsAny(), It.IsAny())) .Returns(Task.CompletedTask); // Act await mockRouter.Object.RegisterServerAsync(serverConfig, CancellationToken.None); // Assert mockRouter.Verify(r => r.RegisterServerAsync(serverConfig, It.IsAny()), Times.Once); } [Fact] public async Task UnregisterServerAsync_RemovesServerConfiguration() { // Arrange var mockRouter = new Mock(); var serverId = "remove-server"; mockRouter .Setup(r => r.UnregisterServerAsync(It.IsAny(), It.IsAny())) .ReturnsAsync(true); // Act var result = await mockRouter.Object.UnregisterServerAsync(serverId, CancellationToken.None); // Assert Assert.True(result); mockRouter.Verify(r => r.UnregisterServerAsync(serverId, It.IsAny()), Times.Once); } }