Skip to content

Commit c4fd9d9

Browse files
Test resource functionality
1 parent 36592a6 commit c4fd9d9

File tree

2 files changed

+93
-8
lines changed

2 files changed

+93
-8
lines changed

internal/handlers/chat.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,13 @@ func callToolError(err error) json.RawMessage {
5050
}
5151

5252
// HandleChats processes chat interactions through HTTP POST requests,
53-
// managing both new chat creation and message handling. It supports two input methods:
53+
// managing both new chat creation and message handling. It supports three input methods:
5454
// 1. Regular messages via the "message" form field
5555
// 2. Predefined prompts via "prompt_name" and "prompt_args" form fields
56+
// 3. Attached resources via the "attached_resources" JSON array of resource URIs
57+
//
58+
// When resources are attached, they're processed and appended to the latest user message.
59+
// Resources are retrieved from registered MCP clients based on their URIs.
5660
//
5761
// The handler expects an optional "chat_id" field. If no chat_id is provided,
5862
// it creates a new chat session. For new chats, it asynchronously generates a title
@@ -64,8 +68,8 @@ func callToolError(err error) json.RawMessage {
6468
// generation that will be streamed via Server-Sent Events (SSE).
6569
//
6670
// The function returns appropriate HTTP error responses for invalid methods, missing required fields,
67-
// or internal processing errors. For successful requests, it renders the appropriate templates
68-
// with messages marked with correct streaming states.
71+
// resource processing failures, or internal processing errors. For successful requests, it renders
72+
// the appropriate templates with messages marked with correct streaming states.
6973
func (m Main) HandleChats(w http.ResponseWriter, r *http.Request) {
7074
if r.Method != http.MethodPost {
7175
m.logger.Error("Method not allowed", slog.String("method", r.Method))

internal/handlers/main_test.go

Lines changed: 86 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,9 @@ type mockMCPClient struct {
4040
resources []mcp.Resource
4141
prompts []mcp.Prompt
4242

43-
getPromptResult mcp.GetPromptResult
44-
callToolResult mcp.CallToolResult
43+
getPromptResult mcp.GetPromptResult
44+
callToolResult mcp.CallToolResult
45+
readResourceFunc func(uri string) (mcp.ReadResourceResult, error)
4546

4647
err error
4748
}
@@ -135,7 +136,7 @@ func TestHandleChats(t *testing.T) {
135136
messages: map[string][]models.Message{},
136137
}
137138

138-
// Setup MCP client with prompt support for testing prompt functionality
139+
// Setup MCP client with prompt and resource support
139140
mcpClient := &mockMCPClient{
140141
serverInfo: mcp.Info{
141142
Name: "Test Server",
@@ -168,6 +169,39 @@ func TestHandleChats(t *testing.T) {
168169
},
169170
IsError: false,
170171
},
172+
resourceServerSupported: true,
173+
resources: []mcp.Resource{
174+
{URI: "file:///test.txt"},
175+
{URI: "workspace:///sample.go"},
176+
},
177+
readResourceFunc: func(uri string) (mcp.ReadResourceResult, error) {
178+
switch uri {
179+
case "file:///test.txt":
180+
return mcp.ReadResourceResult{
181+
Contents: []mcp.ResourceContents{
182+
{
183+
URI: uri,
184+
MimeType: "text/plain",
185+
Text: "This is a test file",
186+
},
187+
},
188+
}, nil
189+
case "workspace:///sample.go":
190+
return mcp.ReadResourceResult{
191+
Contents: []mcp.ResourceContents{
192+
{
193+
URI: uri,
194+
MimeType: "text/x-go",
195+
Text: "package main\n\nfunc main() {\n\tfmt.Println(\"Hello\")\n}",
196+
},
197+
},
198+
}, nil
199+
case "error:///resource":
200+
return mcp.ReadResourceResult{}, fmt.Errorf("failed to read resource")
201+
default:
202+
return mcp.ReadResourceResult{}, fmt.Errorf("resource not found")
203+
}
204+
},
171205
}
172206

173207
tests := []struct {
@@ -221,6 +255,37 @@ func TestHandleChats(t *testing.T) {
221255
formData: `prompt_name=unknown_prompt&prompt_args={"key":"value"}`,
222256
wantStatus: http.StatusInternalServerError,
223257
},
258+
// Resource handling test cases
259+
{
260+
name: "Message with valid attached resources",
261+
method: http.MethodPost,
262+
formData: `message=Check these files&attached_resources=["file:///test.txt","workspace:///sample.go"]`,
263+
wantStatus: http.StatusOK,
264+
},
265+
{
266+
name: "Invalid JSON in attached resources",
267+
method: http.MethodPost,
268+
formData: `message=Bad JSON&attached_resources=[invalid"json]`,
269+
wantStatus: http.StatusBadRequest,
270+
},
271+
{
272+
name: "Resource not found",
273+
method: http.MethodPost,
274+
formData: `message=Missing resource&attached_resources=["unknown:///file.txt"]`,
275+
wantStatus: http.StatusInternalServerError,
276+
},
277+
{
278+
name: "Error reading resource",
279+
method: http.MethodPost,
280+
formData: `message=Error case&attached_resources=["error:///resource"]`,
281+
wantStatus: http.StatusInternalServerError,
282+
},
283+
{
284+
name: "Empty attached resources array",
285+
method: http.MethodPost,
286+
formData: `message=No attachments&attached_resources=[]`,
287+
wantStatus: http.StatusOK,
288+
},
224289
// Test cases for error paths
225290
{
226291
name: "Store error when adding message",
@@ -675,8 +740,24 @@ func (m *mockMCPClient) ListResources(_ context.Context, _ mcp.ListResourcesPara
675740
return mcp.ListResourcesResult{Resources: m.resources}, nil
676741
}
677742

678-
func (m *mockMCPClient) ReadResource(_ context.Context, _ mcp.ReadResourceParams) (mcp.ReadResourceResult, error) {
679-
return mcp.ReadResourceResult{}, nil
743+
func (m *mockMCPClient) ReadResource(_ context.Context, params mcp.ReadResourceParams) (mcp.ReadResourceResult, error) {
744+
if m.err != nil {
745+
return mcp.ReadResourceResult{}, m.err
746+
}
747+
748+
if m.readResourceFunc != nil {
749+
return m.readResourceFunc(params.URI)
750+
}
751+
752+
return mcp.ReadResourceResult{
753+
Contents: []mcp.ResourceContents{
754+
{
755+
URI: params.URI,
756+
MimeType: "text/plain",
757+
Text: "Mock resource content",
758+
},
759+
},
760+
}, nil
680761
}
681762

682763
func (m *mockMCPClient) ListPrompts(_ context.Context, _ mcp.ListPromptsParams) (mcp.ListPromptResult, error) {

0 commit comments

Comments
 (0)