using Moq;
using OpenHarbor.MCP.Client.Core.Abstractions;
using OpenHarbor.MCP.Client.Core.Exceptions;
using OpenHarbor.MCP.Client.Core.Models;
using OpenHarbor.MCP.Client.Infrastructure;
using Xunit;
namespace OpenHarbor.MCP.Client.Core.Tests.Infrastructure;
///
/// Unit tests for McpClient following TDD approach.
/// Tests client initialization, server management, and tool operations.
///
public class McpClientTests
{
[Fact]
public void Constructor_WithServerConfigs_CreatesClient()
{
// Arrange
var configs = new List
{
CreateTestConfig("server1"),
CreateTestConfig("server2")
};
// Act
var client = new McpClient(configs);
// Assert
Assert.NotNull(client);
}
[Fact]
public async Task ConnectAllAsync_WithMultipleServers_ConnectsAll()
{
// Arrange
var configs = new List
{
CreateTestConfig("server1"),
CreateTestConfig("server2")
};
var client = new McpClient(configs);
// Act
await client.ConnectAllAsync();
// Assert
var servers = await client.GetConnectedServersAsync();
Assert.Equal(2, servers.Count());
}
[Fact]
public async Task DisconnectAllAsync_AfterConnect_DisconnectsAll()
{
// Arrange
var configs = new List { CreateTestConfig("server1") };
var client = new McpClient(configs);
await client.ConnectAllAsync();
// Act
await client.DisconnectAllAsync();
// Assert
var servers = await client.GetConnectedServersAsync();
Assert.Empty(servers);
}
[Fact]
public async Task GetConnectedServersAsync_WithNoServers_ReturnsEmpty()
{
// Arrange
var client = new McpClient(new List());
// Act
var servers = await client.GetConnectedServersAsync();
// Assert
Assert.Empty(servers);
}
[Fact]
public async Task ListToolsAsync_WithNonExistentServer_ThrowsServerNotFoundException()
{
// Arrange
var client = new McpClient(new List());
// Act & Assert
await Assert.ThrowsAsync(
async () => await client.ListToolsAsync("non-existent-server")
);
}
[Fact]
public async Task CallToolAsync_WithNonExistentServer_ThrowsServerNotFoundException()
{
// Arrange
var client = new McpClient(new List());
// Act & Assert
await Assert.ThrowsAsync(
async () => await client.CallToolAsync("non-existent-server", "test_tool")
);
}
[Fact]
public async Task PingAsync_WithNonExistentServer_ThrowsServerNotFoundException()
{
// Arrange
var client = new McpClient(new List());
// Act & Assert
await Assert.ThrowsAsync(
async () => await client.PingAsync("non-existent-server")
);
}
[Fact]
public async Task DisposeAsync_AfterConnect_DisposesCleanly()
{
// Arrange
var configs = new List { CreateTestConfig("server1") };
var client = new McpClient(configs);
await client.ConnectAllAsync();
// Act
await client.DisposeAsync();
// Assert
var servers = await client.GetConnectedServersAsync();
Assert.Empty(servers);
}
[Fact]
public async Task ListToolsAsync_WithConnectedServer_ReturnsTools()
{
// Arrange
var configs = new List { CreateTestConfig("server1") };
var client = new McpClient(configs);
await client.ConnectAllAsync();
// Act
var tools = await client.ListToolsAsync("server1");
// Assert
Assert.NotNull(tools);
}
[Fact]
public async Task CallToolAsync_WithConnectedServer_ReturnsResult()
{
// Arrange
var configs = new List { CreateTestConfig("server1") };
var client = new McpClient(configs);
await client.ConnectAllAsync();
// Act
var result = await client.CallToolAsync("server1", "test_tool");
// Assert
Assert.NotNull(result);
}
private static McpServerConfig CreateTestConfig(string name)
{
return new McpServerConfig
{
Name = name,
Transport = new StdioTransportConfig
{
Type = "Stdio",
Command = "echo",
Args = new[] { "test" }
}
};
}
}