Skip to main content
Glama
resources_test.go7 kB
package resources import ( "context" "encoding/json" "testing" "github.com/luno/luno-mcp/internal/config" "github.com/mark3labs/mcp-go/mcp" "github.com/stretchr/testify/assert" ) const ( expectedMIMEType = "application/json" expectedNameFmt = "Expected name %q, got %q" ) func TestNewWalletResource(t *testing.T) { resource := NewWalletResource() assert.Equal(t, WalletResourceURI, resource.URI) assert.Equal(t, "Luno Wallets", resource.Name) assert.Equal(t, expectedMIMEType, resource.MIMEType) } func TestNewTransactionsResource(t *testing.T) { resource := NewTransactionsResource() assert.Equal(t, TransactionsResourceURI, resource.URI) assert.Equal(t, "Luno Transactions", resource.Name) assert.Equal(t, expectedMIMEType, resource.MIMEType) } func TestNewAccountTemplate(t *testing.T) { expectedJSON := `{ "uriTemplate": "luno://accounts/{id}", "name": "Luno Account", "description": "Returns details for a specific Luno account" }` template := NewAccountTemplate() actualJSON, err := json.Marshal(template) assert.NoError(t, err) // Compare JSON structures directly. Can't create an expected object as the fields can only be set internally. assert.JSONEq(t, expectedJSON, string(actualJSON)) } func TestExtractAccountID(t *testing.T) { tests := []struct { name string uri string expected string }{ {"valid account URI", "luno://accounts/1234567890", "1234567890"}, {"empty URI", "", ""}, {"invalid format", "luno://accounts", ""}, {"short URI", "luno://", ""}, {"no account ID", "luno://accounts/", ""}, {"different resource", "luno://wallets/123", "123"}, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { result := extractAccountID(tc.uri) assert.Equal(t, tc.expected, result) }) } } // TestHandleWalletResourceStructure tests that the wallet resource handler can be created and handles nil config func TestHandleWalletResourceStructure(t *testing.T) { handler := HandleWalletResource(nil) assert.NotNil(t, handler, "HandleWalletResource should return a non-nil handler") // Verify handler returns error with nil config req := mcp.ReadResourceRequest{ Params: struct { URI string `json:"uri"` Arguments map[string]any `json:"arguments,omitempty"` }{ URI: WalletResourceURI, }, } result, err := handler(context.Background(), req) assert.Error(t, err) assert.Nil(t, result) } // TestHandleTransactionsResourceStructure tests the transactions resource handler structure func TestHandleTransactionsResourceStructure(t *testing.T) { handler := HandleTransactionsResource(nil) assert.NotNil(t, handler, "HandleTransactionsResource should return a non-nil handler") } // TestHandleAccountTemplateStructure tests the account template handler structure func TestHandleAccountTemplateStructure(t *testing.T) { handler := HandleAccountTemplate(nil) assert.NotNil(t, handler, "HandleAccountTemplate should return a non-nil handler") } // createTestConfig creates a minimal configuration for testing with a nil Luno client. // This configuration will cause handlers to return errors when invoked, which is useful // for testing error handling paths. func createTestConfig() *config.Config { // For testing, we create a config with a nil client // In real integration tests, this would be a properly configured client return &config.Config{ LunoClient: nil, } } // TestHandleWalletResourceIntegration tests the wallet resource handler structure and behavior func TestHandleWalletResourceIntegration(t *testing.T) { tests := []struct { name string config *config.Config expectError bool }{ { name: "nil config", config: nil, expectError: true, }, { name: "config with nil client", config: createTestConfig(), expectError: true, }, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { handler := HandleWalletResource(tc.config) assert.NotNil(t, handler, "HandleWalletResource should return a non-nil handler") req := mcp.ReadResourceRequest{ Params: struct { URI string `json:"uri"` Arguments map[string]any `json:"arguments,omitempty"` }{ URI: WalletResourceURI, }, } result, err := handler(context.Background(), req) if tc.expectError { assert.Error(t, err) assert.Nil(t, result) } else { assert.NoError(t, err) assert.NotNil(t, result) } }) } } // TestHandleTransactionsResourceIntegration tests the transactions resource handler structure and behavior func TestHandleTransactionsResourceIntegration(t *testing.T) { tests := []struct { name string config *config.Config expectError bool }{ { name: "nil config", config: nil, expectError: true, }, { name: "config with nil client", config: createTestConfig(), expectError: true, }, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { handler := HandleTransactionsResource(tc.config) assert.NotNil(t, handler, "HandleTransactionsResource should return a non-nil handler") req := mcp.ReadResourceRequest{ Params: struct { URI string `json:"uri"` Arguments map[string]any `json:"arguments,omitempty"` }{ URI: TransactionsResourceURI, }, } result, err := handler(context.Background(), req) if tc.expectError { assert.Error(t, err) assert.Nil(t, result) } else { assert.NoError(t, err) assert.NotNil(t, result) } }) } } // TestHandleAccountTemplateIntegration tests the account template handler structure and behavior func TestHandleAccountTemplateIntegration(t *testing.T) { tests := []struct { name string config *config.Config uri string expectError bool }{ { name: "nil config", config: nil, uri: "luno://accounts/1234567890", expectError: true, }, { name: "config with nil client", config: createTestConfig(), uri: "luno://accounts/1234567890", expectError: true, }, { name: "invalid URI format", config: createTestConfig(), uri: "invalid://uri", expectError: true, }, { name: "empty account ID", config: createTestConfig(), uri: "luno://accounts/", expectError: true, }, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { handler := HandleAccountTemplate(tc.config) assert.NotNil(t, handler, "HandleAccountTemplate should return a non-nil handler") req := mcp.ReadResourceRequest{ Params: struct { URI string `json:"uri"` Arguments map[string]any `json:"arguments,omitempty"` }{ URI: tc.uri, }, } result, err := handler(context.Background(), req) if tc.expectError { assert.Error(t, err) assert.Nil(t, result) } else { assert.NoError(t, err) assert.NotNil(t, result) } }) } }

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