Skip to content

Commit ccc3a6a

Browse files
committed
tests
1 parent a2c288a commit ccc3a6a

File tree

2 files changed

+663
-0
lines changed

2 files changed

+663
-0
lines changed

coderd/mcp/mcp_e2e_test.go

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1215,6 +1215,155 @@ func TestMCPHTTP_E2E_OAuth2_EndToEnd(t *testing.T) {
12151215
})
12161216
}
12171217

1218+
func TestMCPHTTP_E2E_ChatGPTEndpoint(t *testing.T) {
1219+
t.Parallel()
1220+
1221+
// Setup Coder server with authentication
1222+
coderClient, closer, api := coderdtest.NewWithAPI(t, &coderdtest.Options{
1223+
IncludeProvisionerDaemon: true,
1224+
})
1225+
defer closer.Close()
1226+
1227+
user := coderdtest.CreateFirstUser(t, coderClient)
1228+
1229+
// Create template and workspace for testing search functionality
1230+
version := coderdtest.CreateTemplateVersion(t, coderClient, user.OrganizationID, nil)
1231+
coderdtest.AwaitTemplateVersionJobCompleted(t, coderClient, version.ID)
1232+
template := coderdtest.CreateTemplate(t, coderClient, user.OrganizationID, version.ID)
1233+
1234+
// Create MCP client pointing to the ChatGPT endpoint
1235+
mcpURL := api.AccessURL.String() + "/api/experimental/mcp/chatgpt"
1236+
1237+
// Configure client with authentication headers using RFC 6750 Bearer token
1238+
mcpClient, err := mcpclient.NewStreamableHttpClient(mcpURL,
1239+
transport.WithHTTPHeaders(map[string]string{
1240+
"Authorization": "Bearer " + coderClient.SessionToken(),
1241+
}))
1242+
require.NoError(t, err)
1243+
defer func() {
1244+
if closeErr := mcpClient.Close(); closeErr != nil {
1245+
t.Logf("Failed to close MCP client: %v", closeErr)
1246+
}
1247+
}()
1248+
1249+
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
1250+
defer cancel()
1251+
1252+
// Start client
1253+
err = mcpClient.Start(ctx)
1254+
require.NoError(t, err)
1255+
1256+
// Initialize connection
1257+
initReq := mcp.InitializeRequest{
1258+
Params: mcp.InitializeParams{
1259+
ProtocolVersion: mcp.LATEST_PROTOCOL_VERSION,
1260+
ClientInfo: mcp.Implementation{
1261+
Name: "test-chatgpt-client",
1262+
Version: "1.0.0",
1263+
},
1264+
},
1265+
}
1266+
1267+
result, err := mcpClient.Initialize(ctx, initReq)
1268+
require.NoError(t, err)
1269+
require.Equal(t, mcpserver.MCPServerName, result.ServerInfo.Name)
1270+
require.Equal(t, mcp.LATEST_PROTOCOL_VERSION, result.ProtocolVersion)
1271+
require.NotNil(t, result.Capabilities)
1272+
1273+
// Test tool listing - should only have search and fetch tools for ChatGPT
1274+
tools, err := mcpClient.ListTools(ctx, mcp.ListToolsRequest{})
1275+
require.NoError(t, err)
1276+
require.NotEmpty(t, tools.Tools)
1277+
1278+
// Verify we have exactly the ChatGPT tools and no others
1279+
var foundTools []string
1280+
for _, tool := range tools.Tools {
1281+
foundTools = append(foundTools, tool.Name)
1282+
}
1283+
1284+
// ChatGPT endpoint should only expose search and fetch tools
1285+
assert.Contains(t, foundTools, toolsdk.ToolNameChatGPTSearch, "Should have ChatGPT search tool")
1286+
assert.Contains(t, foundTools, toolsdk.ToolNameChatGPTFetch, "Should have ChatGPT fetch tool")
1287+
assert.Len(t, foundTools, 2, "ChatGPT endpoint should only expose search and fetch tools")
1288+
1289+
// Should NOT have other tools that are available in the standard endpoint
1290+
assert.NotContains(t, foundTools, toolsdk.ToolNameGetAuthenticatedUser, "Should not have authenticated user tool")
1291+
assert.NotContains(t, foundTools, toolsdk.ToolNameListWorkspaces, "Should not have list workspaces tool")
1292+
1293+
t.Logf("ChatGPT endpoint tools: %v", foundTools)
1294+
1295+
// Test search tool - search for templates
1296+
var searchTool *mcp.Tool
1297+
for _, tool := range tools.Tools {
1298+
if tool.Name == toolsdk.ToolNameChatGPTSearch {
1299+
searchTool = &tool
1300+
break
1301+
}
1302+
}
1303+
require.NotNil(t, searchTool, "Expected to find search tool")
1304+
1305+
// Execute search for templates
1306+
searchReq := mcp.CallToolRequest{
1307+
Params: mcp.CallToolParams{
1308+
Name: searchTool.Name,
1309+
Arguments: map[string]any{
1310+
"query": "templates",
1311+
},
1312+
},
1313+
}
1314+
1315+
searchResult, err := mcpClient.CallTool(ctx, searchReq)
1316+
require.NoError(t, err)
1317+
require.NotEmpty(t, searchResult.Content)
1318+
1319+
// Verify the search result contains our template
1320+
assert.Len(t, searchResult.Content, 1)
1321+
if textContent, ok := searchResult.Content[0].(mcp.TextContent); ok {
1322+
assert.Equal(t, "text", textContent.Type)
1323+
assert.Contains(t, textContent.Text, template.ID.String(), "Search result should contain our test template")
1324+
t.Logf("Search result: %s", textContent.Text)
1325+
} else {
1326+
t.Errorf("Expected TextContent type, got %T", searchResult.Content[0])
1327+
}
1328+
1329+
// Test fetch tool
1330+
var fetchTool *mcp.Tool
1331+
for _, tool := range tools.Tools {
1332+
if tool.Name == toolsdk.ToolNameChatGPTFetch {
1333+
fetchTool = &tool
1334+
break
1335+
}
1336+
}
1337+
require.NotNil(t, fetchTool, "Expected to find fetch tool")
1338+
1339+
// Execute fetch for the template
1340+
fetchReq := mcp.CallToolRequest{
1341+
Params: mcp.CallToolParams{
1342+
Name: fetchTool.Name,
1343+
Arguments: map[string]any{
1344+
"id": fmt.Sprintf("template:%s", template.ID.String()),
1345+
},
1346+
},
1347+
}
1348+
1349+
fetchResult, err := mcpClient.CallTool(ctx, fetchReq)
1350+
require.NoError(t, err)
1351+
require.NotEmpty(t, fetchResult.Content)
1352+
1353+
// Verify the fetch result contains template details
1354+
assert.Len(t, fetchResult.Content, 1)
1355+
if textContent, ok := fetchResult.Content[0].(mcp.TextContent); ok {
1356+
assert.Equal(t, "text", textContent.Type)
1357+
assert.Contains(t, textContent.Text, template.Name, "Fetch result should contain template name")
1358+
assert.Contains(t, textContent.Text, template.ID.String(), "Fetch result should contain template ID")
1359+
t.Logf("Fetch result contains template data")
1360+
} else {
1361+
t.Errorf("Expected TextContent type, got %T", fetchResult.Content[0])
1362+
}
1363+
1364+
t.Logf("ChatGPT endpoint E2E test successful: search and fetch tools working correctly")
1365+
}
1366+
12181367
// Helper function to parse URL safely in tests
12191368
func mustParseURL(t *testing.T, rawURL string) *url.URL {
12201369
u, err := url.Parse(rawURL)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy