import Foundation import Testing @testable import MCP @Suite("Server Tests") struct ServerTests { @Test("Start and stop server") func testServerStartAndStop() async throws { let transport = MockTransport() let server = Server(name: "TestServer", version: "1.0") #expect(await transport.isConnected == false) try await server.start(transport: transport) #expect(await transport.isConnected == true) await server.stop() #expect(await transport.isConnected == false) } @Test("Initialize request handling") func testServerHandleInitialize() async throws { let transport = MockTransport() // Queue an initialize request try await transport.queue( request: Initialize.request( .init( protocolVersion: Version.latest, capabilities: .init(), clientInfo: .init(name: "TestClient", version: "1.0") ) )) // Start the server let server: Server = Server( name: "TestServer", version: "1.0" ) try await server.start(transport: transport) // Wait for message processing and response try await Task.sleep(nanoseconds: 10_000_000) // 10ms #expect(await transport.sentMessages.count == 1) let messages = await transport.sentMessages if let response = messages.first { #expect(response.contains("serverInfo")) } // Clean up await server.stop() await transport.disconnect() } @Test("Initialize hook - successful") func testInitializeHookSuccess() async throws { let transport = MockTransport() actor TestState { var hookCalled = false func setHookCalled() { hookCalled = true } func wasHookCalled() -> Bool { hookCalled } } let state = TestState() let server = Server(name: "TestServer", version: "1.0") // Start with the hook directly try await server.start(transport: transport) { clientInfo, capabilities in #expect(clientInfo.name == "TestClient") #expect(clientInfo.version == "1.0") await state.setHookCalled() } // Wait for server to initialize try await Task.sleep(for: .milliseconds(10)) // Queue an initialize request try await transport.queue( request: Initialize.request( .init( protocolVersion: Version.latest, capabilities: .init(), clientInfo: .init(name: "TestClient", version: "1.0") ) )) // Wait for message processing and hook execution try await Task.sleep(for: .milliseconds(500)) #expect(await state.wasHookCalled() == true) #expect(await transport.sentMessages.count >= 1) let messages = await transport.sentMessages if let response = messages.first { #expect(response.contains("serverInfo")) } await server.stop() await transport.disconnect() } @Test("Initialize hook - rejection") func testInitializeHookRejection() async throws { let transport = MockTransport() let server = Server(name: "TestServer", version: "1.0") try await server.start(transport: transport) { clientInfo, _ in if clientInfo.name == "BlockedClient" { throw MCPError.invalidRequest("Client not allowed") } } // Wait for server to initialize try await Task.sleep(nanoseconds: 10_000_000) // 10ms // Queue an initialize request from blocked client try await transport.queue( request: Initialize.request( .init( protocolVersion: Version.latest, capabilities: .init(), clientInfo: .init(name: "BlockedClient", version: "1.0") ) )) // Wait for message processing try await Task.sleep(nanoseconds: 200_000_000) // 200ms #expect(await transport.sentMessages.count >= 1) let messages = await transport.sentMessages if let response = messages.first { #expect(response.contains("error")) #expect(response.contains("Client not allowed")) } await server.stop() await transport.disconnect() } }