Skip to main content
Glama

MCPJungle mcp gateway

by mcpjungle
Mozilla Public License 2.0
638
  • Apple
tool_group_test.go•9.52 kB
package client import ( "encoding/json" "net/http" "net/http/httptest" "strings" "testing" "github.com/mcpjungle/mcpjungle/pkg/types" ) func TestCreateToolGroup(t *testing.T) { t.Parallel() t.Run("successful creation", func(t *testing.T) { expectedResponse := &types.CreateToolGroupResponse{ ToolGroupEndpoints: &types.ToolGroupEndpoints{ StreamableHTTPEndpoint: "/api/v0/tool-groups/test-group", SSEEndpoint: "/api/v0/tool-groups/test-group/sse", SSEMessageEndpoint: "/api/v0/tool-groups/test-group/sse/message", }, } server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Verify request method and path if r.Method != http.MethodPost { t.Errorf("Expected POST method, got %s", r.Method) } if !strings.HasSuffix(r.URL.Path, "/tool-groups") { t.Errorf("Expected path to end with /tool-groups, got %s", r.URL.Path) } // Verify content type contentType := r.Header.Get("Content-Type") if contentType != "application/json" { t.Errorf("Expected Content-Type application/json, got %s", contentType) } // Verify request body var toolGroup types.ToolGroup if err := json.NewDecoder(r.Body).Decode(&toolGroup); err != nil { t.Fatalf("Failed to decode request body: %v", err) } if toolGroup.Name != "test-group" { t.Errorf("Expected Name 'test-group', got %s", toolGroup.Name) } // Return success response w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) _ = json.NewEncoder(w).Encode(expectedResponse) })) defer server.Close() client := NewClient(server.URL, "test-token", &http.Client{}) toolGroup := &types.ToolGroup{ Name: "test-group", Description: "Test tool group", IncludedTools: []string{"tool1", "tool2"}, } response, err := client.CreateToolGroup(toolGroup) if err != nil { t.Fatalf("Unexpected error: %v", err) } if response.StreamableHTTPEndpoint != expectedResponse.StreamableHTTPEndpoint { t.Errorf("Expected StreamableHTTPEndpoint %s, got %s", expectedResponse.StreamableHTTPEndpoint, response.StreamableHTTPEndpoint) } }) t.Run("server error response", func(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusBadRequest) _, _ = w.Write([]byte("Invalid tool group configuration")) })) defer server.Close() client := NewClient(server.URL, "test-token", &http.Client{}) toolGroup := &types.ToolGroup{ Name: "test-group", Description: "Test tool group", IncludedTools: []string{"tool1"}, } response, err := client.CreateToolGroup(toolGroup) if err == nil { t.Error("Expected error, got nil") } if response != nil { t.Error("Expected nil response on error") } expectedError := "request failed with status: 400, message: Invalid tool group configuration" if !strings.Contains(err.Error(), expectedError) { t.Errorf("Expected error to contain %s, got %s", expectedError, err.Error()) } }) } func TestGetToolGroup(t *testing.T) { t.Parallel() t.Run("successful retrieval", func(t *testing.T) { expectedGroup := &types.ToolGroup{ Name: "test-group", Description: "Test tool group", IncludedTools: []string{"tool1", "tool2"}, } server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Verify request method and path if r.Method != http.MethodGet { t.Errorf("Expected GET method, got %s", r.Method) } if !strings.HasSuffix(r.URL.Path, "/tool-groups/test-group") { t.Errorf("Expected path to end with /tool-groups/test-group, got %s", r.URL.Path) } // Return success response w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) _ = json.NewEncoder(w).Encode(expectedGroup) })) defer server.Close() client := NewClient(server.URL, "test-token", &http.Client{}) group, err := client.GetToolGroup("test-group") if err != nil { t.Fatalf("Unexpected error: %v", err) } if group.Name != expectedGroup.Name { t.Errorf("Expected Name %s, got %s", expectedGroup.Name, group.Name) } if group.Description != expectedGroup.Description { t.Errorf("Expected Description %s, got %s", expectedGroup.Description, group.Description) } if len(group.IncludedTools) != len(expectedGroup.IncludedTools) { t.Errorf("Expected IncludedTools length %d, got %d", len(expectedGroup.IncludedTools), len(group.IncludedTools)) } }) t.Run("group not found", func(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNotFound) _, _ = w.Write([]byte("Tool group not found")) })) defer server.Close() client := NewClient(server.URL, "test-token", &http.Client{}) group, err := client.GetToolGroup("non-existent-group") if err == nil { t.Error("Expected error, got nil") } if group != nil { t.Error("Expected nil group on error") } expectedError := "request failed with status: 404, message: Tool group not found" if !strings.Contains(err.Error(), expectedError) { t.Errorf("Expected error to contain %s, got %s", expectedError, err.Error()) } }) } func TestDeleteToolGroup(t *testing.T) { t.Parallel() t.Run("successful deletion", func(t *testing.T) { groupName := "test-group" server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Verify request method and path if r.Method != "DELETE" { t.Errorf("Expected DELETE method, got %s", r.Method) } expectedPath := "/api/v0/tool-groups/" + groupName if !strings.HasSuffix(r.URL.Path, expectedPath) { t.Errorf("Expected path to end with %s, got %s", expectedPath, r.URL.Path) } // Return success response w.WriteHeader(http.StatusNoContent) })) defer server.Close() client := NewClient(server.URL, "test-token", &http.Client{}) err := client.DeleteToolGroup(groupName) if err != nil { t.Fatalf("Unexpected error: %v", err) } }) t.Run("group not found", func(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNotFound) _, _ = w.Write([]byte("Tool group not found")) })) defer server.Close() client := NewClient(server.URL, "test-token", &http.Client{}) err := client.DeleteToolGroup("non-existent-group") if err == nil { t.Error("Expected error, got nil") } expectedError := "request failed with status: 404, message: Tool group not found" if !strings.Contains(err.Error(), expectedError) { t.Errorf("Expected error to contain %s, got %s", expectedError, err.Error()) } }) } func TestListToolGroups(t *testing.T) { t.Parallel() t.Run("successful list", func(t *testing.T) { expectedGroups := []*types.ToolGroup{ { Name: "group1", Description: "First group", IncludedTools: []string{"tool1"}, }, { Name: "group2", Description: "Second group", IncludedTools: []string{"tool2", "tool3"}, }, } server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Verify request method and path if r.Method != http.MethodGet { t.Errorf("Expected GET method, got %s", r.Method) } if !strings.HasSuffix(r.URL.Path, "/tool-groups") { t.Errorf("Expected path to end with /tool-groups, got %s", r.URL.Path) } // Return success response w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) _ = json.NewEncoder(w).Encode(expectedGroups) })) defer server.Close() client := NewClient(server.URL, "test-token", &http.Client{}) groups, err := client.ListToolGroups() if err != nil { t.Fatalf("Unexpected error: %v", err) } if len(groups) != len(expectedGroups) { t.Errorf("Expected %d groups, got %d", len(expectedGroups), len(groups)) } for i, group := range groups { if group.Name != expectedGroups[i].Name { t.Errorf("Expected group[%d].Name %s, got %s", i, expectedGroups[i].Name, group.Name) } } }) t.Run("empty list", func(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) _, _ = w.Write([]byte("[]")) })) defer server.Close() client := NewClient(server.URL, "test-token", &http.Client{}) groups, err := client.ListToolGroups() if err != nil { t.Fatalf("Unexpected error: %v", err) } if len(groups) != 0 { t.Errorf("Expected empty list, got %d groups", len(groups)) } }) t.Run("server error response", func(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusInternalServerError) _, _ = w.Write([]byte("Internal server error")) })) defer server.Close() client := NewClient(server.URL, "test-token", &http.Client{}) groups, err := client.ListToolGroups() if err == nil { t.Error("Expected error, got nil") } if groups != nil { t.Error("Expected nil groups on error") } expectedError := "request failed with status: 500, message: Internal server error" if !strings.Contains(err.Error(), expectedError) { t.Errorf("Expected error to contain %s, got %s", expectedError, err.Error()) } }) }

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/mcpjungle/MCPJungle'

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