using FluentAssertions; using FreeCode.Mcp; using Xunit; namespace FreeCode.Tests.Integration; public sealed class McpIntegrationTests { [Fact] public async Task ConnectServersAsync_WithNoConfig_NoConnections() { using var testHome = new TestHomeDirectoryScope(); var sut = new McpClientManager(); await sut.ConnectServersAsync(); sut.GetConnections().Should().BeEmpty(); } [Fact] public async Task GetToolsAsync_NoConnections_EmptyList() { using var testHome = new TestHomeDirectoryScope(); var sut = new McpClientManager(); var tools = await sut.GetToolsAsync(); tools.Should().BeEmpty(); } [Fact] public async Task GetCommandsAsync_NoConnections_EmptyList() { using var testHome = new TestHomeDirectoryScope(); var sut = new McpClientManager(); var commands = await sut.GetCommandsAsync(); commands.Should().BeEmpty(); } [Fact] public async Task ListResourcesAsync_NoConnections_EmptyList() { using var testHome = new TestHomeDirectoryScope(); var sut = new McpClientManager(); var resources = await sut.ListResourcesAsync(); resources.Should().BeEmpty(); } [Fact] public void GetConnections_InitiallyEmpty() { using var testHome = new TestHomeDirectoryScope(); var sut = new McpClientManager(); sut.GetConnections().Should().BeEmpty(); } [Fact] public async Task DisconnectServerAsync_UnknownServer_NoThrow() { using var testHome = new TestHomeDirectoryScope(); var sut = new McpClientManager(); var act = () => sut.DisconnectServerAsync("missing"); await act.Should().NotThrowAsync(); } [Fact] public async Task ReconnectServerAsync_UnknownServer_NoThrow() { using var testHome = new TestHomeDirectoryScope(); var sut = new McpClientManager(); var act = () => sut.ReconnectServerAsync("missing"); await act.Should().NotThrowAsync(); } [Fact] public async Task AuthenticateServerAsync_UnknownServer_ThrowsKeyNotFound() { using var testHome = new TestHomeDirectoryScope(); var sut = new McpClientManager(); var act = () => sut.AuthenticateServerAsync("missing"); await act.Should().ThrowAsync(); } [Fact] public async Task ReadResourceAsync_UnknownServer_ThrowsKeyNotFound() { using var testHome = new TestHomeDirectoryScope(); var sut = new McpClientManager(); var act = () => sut.ReadResourceAsync("missing", "resource://test"); await act.Should().ThrowAsync(); } [Fact] public async Task ReloadAsync_NoConnections_NoThrow() { using var testHome = new TestHomeDirectoryScope(); var sut = new McpClientManager(); var act = () => sut.ReloadAsync(); await act.Should().NotThrowAsync(); } } internal sealed class TestHomeDirectoryScope : IDisposable { private readonly string _originalHome; private readonly string? _originalUserProfile; private readonly string _temporaryHome; public TestHomeDirectoryScope() { _originalHome = Environment.GetEnvironmentVariable("HOME") ?? string.Empty; _originalUserProfile = Environment.GetEnvironmentVariable("USERPROFILE"); _temporaryHome = Path.Combine(Path.GetTempPath(), "free-code-integration-home-" + Guid.NewGuid().ToString("N")); Directory.CreateDirectory(_temporaryHome); Environment.SetEnvironmentVariable("HOME", _temporaryHome); Environment.SetEnvironmentVariable("USERPROFILE", _temporaryHome); } public void Dispose() { Environment.SetEnvironmentVariable("HOME", string.IsNullOrEmpty(_originalHome) ? null : _originalHome); Environment.SetEnvironmentVariable("USERPROFILE", _originalUserProfile); if (Directory.Exists(_temporaryHome)) { Directory.Delete(_temporaryHome, recursive: true); } } }