package tools_test import ( "context" "encoding/json" "errors" "net/http" "net/http/httptest" "testing" "gitea.d-ma.be/mathias/gitea-mcp/internal/allowlist" "gitea.d-ma.be/mathias/gitea-mcp/internal/gitea" "gitea.d-ma.be/mathias/gitea-mcp/internal/tools" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestCodeSearchSingleRepo(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, "/api/v1/repos/mathias/infra/search", r.URL.Path) assert.Equal(t, "ListRepos", r.URL.Query().Get("q")) assert.Equal(t, "code", r.URL.Query().Get("type")) w.Header().Set("Content-Type", "application/json") _, _ = w.Write([]byte(`{ "data":[{ "path":"internal/gitea/repos.go", "snippet":"func (c *Client) ListRepos", "html_url":"http://gitea.example.com/mathias/infra/src/branch/main/internal/gitea/repos.go", "score":3.0 }], "ok":true }`)) })) defer srv.Close() tool := tools.NewCodeSearch(gitea.NewClient(srv.URL, "tok"), allowlist.New([]string{"mathias"})) out, err := tool.Call(context.Background(), json.RawMessage(`{"q":"ListRepos","owner":"mathias","repo":"infra"}`)) require.NoError(t, err) var result struct { Results []struct { Repo string `json:"repo"` Path string `json:"path"` Snippet string `json:"snippet"` Score float64 `json:"score"` } `json:"results"` } require.NoError(t, json.Unmarshal(out, &result)) require.Len(t, result.Results, 1) assert.Equal(t, "mathias/infra", result.Results[0].Repo) assert.Equal(t, "internal/gitea/repos.go", result.Results[0].Path) assert.Equal(t, "func (c *Client) ListRepos", result.Results[0].Snippet) } func TestCodeSearchAllowlistRejects(t *testing.T) { tool := tools.NewCodeSearch(gitea.NewClient("http://unused", ""), allowlist.New([]string{"mathias"})) _, err := tool.Call(context.Background(), json.RawMessage(`{"q":"foo","owner":"evil","repo":"infra"}`)) require.Error(t, err) } func TestCodeSearchRequiresQ(t *testing.T) { tool := tools.NewCodeSearch(gitea.NewClient("http://unused", ""), allowlist.New([]string{"mathias"})) _, err := tool.Call(context.Background(), json.RawMessage(`{"owner":"mathias","repo":"infra"}`)) require.Error(t, err) assert.True(t, errors.Is(err, gitea.ErrValidation)) } func TestCodeSearchFanOutNotYetImplemented(t *testing.T) { tool := tools.NewCodeSearch(gitea.NewClient("http://unused", ""), allowlist.New([]string{"mathias"})) _, err := tool.Call(context.Background(), json.RawMessage(`{"q":"foo","owner":"mathias"}`)) require.Error(t, err) assert.True(t, errors.Is(err, gitea.ErrValidation)) }