Files
hyperguild/internal/mcpclient/client_test.go
T
mathiasandClaude Sonnet 5 b600cc986c
CI / Lint / Test / Vet (push) Failing after 5s
CI / Mirror to GitHub (push) Has been skipped
chore(module): rename module github.com/mathiasbq/supervisor -> git.d-ma.be/mathias/hyperguild (#42)
Aligns module path with canonical Gitea source (infra ADR-0004) and
repo name. Binary only, no downstream consumers.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Roq1ajWKR5f1hG5Df9wC6A
2026-07-26 23:37:11 +02:00

93 lines
2.8 KiB
Go

package mcpclient_test
import (
"context"
"encoding/json"
"errors"
"io"
"net/http"
"net/http/httptest"
"testing"
"git.d-ma.be/mathias/hyperguild/internal/mcpclient"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestNew_EmptyTokenFailsFast(t *testing.T) {
c, err := mcpclient.New("http://example.invalid", "")
require.Error(t, err)
require.Nil(t, c)
require.ErrorIs(t, err, mcpclient.ErrTokenRequired)
}
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, err := mcpclient.New(srv.URL, "tok")
require.NoError(t, err)
var out struct {
OK bool `json:"ok"`
N int `json:"n"`
}
require.NoError(t, c.CallTool(context.Background(), "x_y", map[string]any{"a": 1}, &out))
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, err := mcpclient.New(srv.URL, "test")
require.NoError(t, err)
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, err := mcpclient.New(srv.URL, "test")
require.NoError(t, err)
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, err := mcpclient.New(srv.URL, "test")
require.NoError(t, err)
require.NoError(t, c.CallTool(context.Background(), "x", nil, nil))
}