package mcpclient_test import ( "context" "encoding/json" "errors" "io" "net/http" "net/http/httptest" "testing" "github.com/mathiasbq/supervisor/internal/mcpclient" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestCallTool_Success(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, http.MethodPost, r.Method) assert.Equal(t, "Bearer tok", r.Header.Get("Authorization")) b, _ := io.ReadAll(r.Body) var got map[string]any _ = json.Unmarshal(b, &got) assert.Equal(t, "tools/call", got["method"]) params := got["params"].(map[string]any) assert.Equal(t, "x_y", params["name"]) w.Header().Set("Content-Type", "application/json") _, _ = w.Write([]byte(`{"jsonrpc":"2.0","id":1,"result":{"content":[{"type":"text","text":"{\"ok\":true,\"n\":7}"}]}}`)) })) defer srv.Close() c := mcpclient.New(srv.URL, "tok") var out struct { OK bool `json:"ok"` N int `json:"n"` } err := c.CallTool(context.Background(), "x_y", map[string]any{"a": 1}, &out) require.NoError(t, err) assert.True(t, out.OK) assert.Equal(t, 7, out.N) } func TestCallTool_RPCError(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.Header().Set("Content-Type", "application/json") _, _ = w.Write([]byte(`{"jsonrpc":"2.0","id":1,"error":{"code":-32003,"message":"already exists"}}`)) })) defer srv.Close() c := mcpclient.New(srv.URL, "") err := c.CallTool(context.Background(), "x", nil, nil) require.Error(t, err) var me *mcpclient.Error require.True(t, errors.As(err, &me)) assert.Equal(t, -32003, me.Code) assert.Contains(t, me.Message, "already exists") } func TestCallTool_HTTPError(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusUnauthorized) _, _ = w.Write([]byte(`unauthorized`)) })) defer srv.Close() c := mcpclient.New(srv.URL, "") err := c.CallTool(context.Background(), "x", nil, nil) require.Error(t, err) assert.Contains(t, err.Error(), "401") } func TestCallTool_NilResult(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.Header().Set("Content-Type", "application/json") _, _ = w.Write([]byte(`{"jsonrpc":"2.0","id":1,"result":{"content":[{"type":"text","text":"{}"}]}}`)) })) defer srv.Close() c := mcpclient.New(srv.URL, "") require.NoError(t, c.CallTool(context.Background(), "x", nil, nil)) }