Skip to main content
Glama
server_test.go4.12 kB
package server import ( "context" "testing" "github.com/luno/luno-go" "github.com/luno/luno-mcp/internal/config" "github.com/mark3labs/mcp-go/mcp" // Added import mcpserver "github.com/mark3labs/mcp-go/server" "github.com/stretchr/testify/require" ) const ( testServerName = "test-server" testServerWithHooks = "test-server-with-hooks" testServerMultiHooks = "test-server-multi-hooks" testVersion1 = "1.0.0" testVersion2 = "1.0.1" testVersion3 = "1.0.2" testVersion4 = "0.0.1" ) func TestNewMCPServer(t *testing.T) { tests := []struct { name string srvName string version string hooks []*mcpserver.Hooks }{ { name: "creates server without hooks", srvName: testServerName, version: testVersion1, hooks: nil, }, { name: "creates server with single hook", srvName: testServerWithHooks, version: testVersion2, hooks: []*mcpserver.Hooks{ func() *mcpserver.Hooks { h := &mcpserver.Hooks{} h.AddBeforeAny(func(ctx context.Context, id any, method mcp.MCPMethod, message any) { // Intentionally empty - testing hook registration, not hook execution. }) return h }(), }, }, { name: "creates server with multiple distinct hook objects", srvName: testServerMultiHooks, version: testVersion3, hooks: []*mcpserver.Hooks{ func() *mcpserver.Hooks { // Corresponds to original OnAnyHookFunc h := &mcpserver.Hooks{} h.AddBeforeAny(func(ctx context.Context, id any, method mcp.MCPMethod, message any) { // Intentionally empty - testing hook registration, not hook execution. }) return h }(), func() *mcpserver.Hooks { // Corresponds to original BeforeAnyHookFunc h := &mcpserver.Hooks{} h.AddBeforeAny(func(ctx context.Context, id any, method mcp.MCPMethod, message any) { // Intentionally empty - testing hook registration, not hook execution. }) return h }(), func() *mcpserver.Hooks { // Corresponds to original AfterAnyHookFunc, using AddOnSuccess for generality h := &mcpserver.Hooks{} h.AddOnSuccess(func(ctx context.Context, id any, method mcp.MCPMethod, message any, result any) { // Intentionally empty - testing hook registration, not hook execution. }) return h }(), func() *mcpserver.Hooks { // Corresponds to original OnErrorHookFunc h := &mcpserver.Hooks{} h.AddOnError(func(ctx context.Context, id any, method mcp.MCPMethod, message any, err error) { // Intentionally empty - testing hook registration, not hook execution. }) return h }(), }, }, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { lunoClient := luno.NewClient() cfg := &config.Config{LunoClient: lunoClient} server := NewMCPServer(tc.srvName, tc.version, cfg, tc.hooks...) require.NotNil(t, server, "NewMCPServer should return non-nil server") // These should not panic registerResources(server, cfg) registerTools(server, cfg) }) } } func TestServeSSEIntegration(t *testing.T) { tests := []struct { name string address string errorMsg string }{ { name: "invalid address format", address: "invalid:address", errorMsg: "lookup tcp/address: unknown port", }, { name: "invalid port", address: "localhost:99999", errorMsg: "invalid port", }, { name: "bind to used port", address: "localhost:80", // Typically requires root privileges errorMsg: "bind: permission denied", }, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { // Create a proper MCP server for testing lunoClient := luno.NewClient() cfg := &config.Config{LunoClient: lunoClient} server := NewMCPServer("test-sse-server", "1.0.0", cfg) // Set up context with or without timeout ctx := context.Background() // Test ServeSSE functionality err := ServeSSE(ctx, server, tc.address) if tc.errorMsg != "" { require.Error(t, err) require.Contains(t, err.Error(), tc.errorMsg) } else { require.NoError(t, err) } }) } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/luno/luno-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server