package tools_test import ( "context" "encoding/json" "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 TestWorkflowRunListTool(t *testing.T) { tests := []struct { name string input string wantQuery map[string]string notQuery []string respBody string assert func(t *testing.T, out string) }{ { name: "happy path defaults", input: `{"owner":"mathias","name":"gitea-mcp"}`, wantQuery: map[string]string{"page": "1", "limit": "10"}, respBody: `{"total_count":2,"workflow_runs":[{"id":823,"status":"completed","conclusion":"success","head_sha":"dc907fb"},{"id":822,"status":"completed","conclusion":"success","head_sha":"c4bd339"}]}`, assert: func(t *testing.T, out string) { assert.Contains(t, out, `"id":823`) assert.Contains(t, out, `"total":2`) }, }, { name: "head_sha short filter", input: `{"owner":"mathias","name":"gitea-mcp","head_sha":"dc907fb"}`, wantQuery: map[string]string{"head_sha": "dc907fb"}, respBody: `{"total_count":1,"workflow_runs":[{"id":823,"status":"completed","conclusion":"success","head_sha":"dc907fb"}]}`, assert: func(t *testing.T, out string) { assert.Contains(t, out, `"id":823`) }, }, { name: "status filter", input: `{"owner":"mathias","name":"gitea-mcp","status":"in_progress"}`, wantQuery: map[string]string{"status": "in_progress"}, respBody: `{"total_count":0,"workflow_runs":[]}`, assert: func(t *testing.T, out string) { assert.Contains(t, out, `"runs":[]`) }, }, { name: "status=all is no-op", input: `{"owner":"mathias","name":"gitea-mcp","status":"all"}`, notQuery: []string{"status"}, respBody: `{"total_count":0,"workflow_runs":[]}`, assert: func(t *testing.T, out string) {}, }, { name: "branch filter", input: `{"owner":"mathias","name":"gitea-mcp","branch":"main"}`, wantQuery: map[string]string{"branch": "main"}, respBody: `{"total_count":0,"workflow_runs":[]}`, assert: func(t *testing.T, out string) {}, }, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, http.MethodGet, r.Method) assert.Equal(t, "/api/v1/repos/mathias/gitea-mcp/actions/runs", r.URL.Path) q := r.URL.Query() for k, v := range tc.wantQuery { assert.Equal(t, v, q.Get(k), "query param %q", k) } for _, k := range tc.notQuery { assert.Equal(t, "", q.Get(k), "query param %q should be absent", k) } w.Header().Set("Content-Type", "application/json") _, _ = w.Write([]byte(tc.respBody)) })) defer srv.Close() tool := tools.NewWorkflowRunList(gitea.NewClient(srv.URL, "tok"), allowlist.New([]string{"mathias"})) out, err := tool.Call(context.Background(), json.RawMessage(tc.input)) require.NoError(t, err) tc.assert(t, string(out)) }) } } func TestWorkflowRunListAllowlistRejects(t *testing.T) { tool := tools.NewWorkflowRunList(gitea.NewClient("http://unused", ""), allowlist.New([]string{"mathias"})) _, err := tool.Call(context.Background(), json.RawMessage(`{"owner":"evil","name":"x"}`)) require.Error(t, err) }