Files
gitea-mcp/internal/tools/registry_test.go
T
mathiasandClaude Opus 4.8 e2594f45f2 refactor(tools): extract RegisterAll shared tool registration
main.go and tests now share one registration list so a tool wired in one
place cannot silently go missing from the other. Adds a dispatch round-trip
test asserting every registered tool resolves and ships a parseable schema.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 09:52:29 +02:00

59 lines
2.1 KiB
Go

package tools_test
import (
"context"
"encoding/json"
"errors"
"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/registry"
"gitea.d-ma.be/mathias/gitea-mcp/internal/tools"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// buildRegistry wires the full tool set exactly as main.go does, against an
// unroutable gitea base URL so any handler that reaches the network fails fast
// (connection refused) rather than hanging.
func buildRegistry() *registry.Registry {
reg := registry.New()
c := gitea.NewClient("http://127.0.0.1:1", "")
a := allowlist.New([]string{"mathias"})
tools.RegisterAll(reg, c, a, "http://127.0.0.1:1", "mathias", "template-go-web")
return reg
}
// Every registered tool must be dispatchable and advertise a parseable input
// schema. This is the regression guard for #36's whole class: a tool that is
// wired up but unroutable (or ships a malformed schema) fails CI here instead
// of 404ing a live caller.
func TestEveryRegisteredToolIsDispatchable(t *testing.T) {
reg := buildRegistry()
descs := reg.Tools()
require.NotEmpty(t, descs)
for _, d := range descs {
t.Run(d.Name, func(t *testing.T) {
require.NotEmpty(t, d.Name, "tool has empty name")
assert.True(t, json.Valid(d.InputSchema),
"tool %q ships invalid JSON input schema", d.Name)
// Dispatch with empty args. We do not care whether the call
// succeeds (most fail allowlist/validation/network) — only that
// the name resolves to a handler. ErrToolNotFound here means the
// tool advertised a name the dispatcher cannot route.
_, err := reg.Dispatch(context.Background(), d.Name, json.RawMessage(`{}`))
assert.False(t, errors.Is(err, registry.ErrToolNotFound),
"registered tool %q does not dispatch", d.Name)
})
}
}
// Lock the tool count so an accidental drop of a registration in RegisterAll
// (the single source main.go and this test share) fails loudly.
func TestRegisteredToolCount(t *testing.T) {
assert.Len(t, buildRegistry().Tools(), 38)
}