Files
MCP/pkg/gitea/rest_test.go
T
Lunny Xiao 6744cab627 feat(gitea): support extra outbound HTTP headers via GITEA_EXTRA_HEADERS
Add a GITEA_EXTRA_HEADERS environment variable that accepts a JSON
object of header name/value pairs (e.g. Cloudflare Access
credentials) and applies them to every outbound request to Gitea,
both the raw pkg/gitea.DoJSON/DoBytes path and the SDK-backed
pkg/gitea.NewClient path, without overriding Authorization,
Content-Type, or Accept.

Co-Authored-By: Codet <codet@commitgo.dev> (GPT-5-Codex)
2026-08-23 23:33:36 -07:00

106 lines
2.9 KiB
Go

package gitea
import (
"context"
"errors"
"io"
"net/http"
"net/http/httptest"
"strings"
"testing"
mcpContext "gitea.com/gitea/gitea-mcp/pkg/context"
"gitea.com/gitea/gitea-mcp/pkg/flag"
)
func TestTokenFromContext(t *testing.T) {
orig := flag.Token
defer func() { flag.Token = orig }()
flag.Token = "flag-token"
t.Run("context token wins", func(t *testing.T) {
ctx := context.WithValue(context.Background(), mcpContext.TokenContextKey, "ctx-token")
if got := tokenFromContext(ctx); got != "ctx-token" {
t.Fatalf("tokenFromContext() = %q, want %q", got, "ctx-token")
}
})
t.Run("fallback to flag token", func(t *testing.T) {
ctx := context.Background()
if got := tokenFromContext(ctx); got != "flag-token" {
t.Fatalf("tokenFromContext() = %q, want %q", got, "flag-token")
}
})
}
func TestDoJSON_LimitsErrorResponseBody(t *testing.T) {
payload := strings.Repeat("x", errBodySnippetSize+100)
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusBadRequest)
_, _ = io.WriteString(w, payload)
}))
defer srv.Close()
origHost := flag.Host
defer func() { flag.Host = origHost }()
flag.Host = srv.URL
status, err := DoJSON(context.Background(), http.MethodGet, "repos/owner/repo", nil, nil, nil)
if err == nil {
t.Fatal("expected error")
}
if status != http.StatusBadRequest {
t.Fatalf("expected status %d, got %d", http.StatusBadRequest, status)
}
var httpErr *HTTPError
if !errors.As(err, &httpErr) {
t.Fatalf("expected HTTPError, got %T", err)
}
if len(httpErr.Body) != errBodySnippetSize {
t.Fatalf("expected body length %d, got %d", errBodySnippetSize, len(httpErr.Body))
}
}
func TestDoJSON_SendsExtraHeaders(t *testing.T) {
var gotClientID, gotAuthorization string
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
gotClientID = r.Header.Get("CF-Access-Client-Id")
gotAuthorization = r.Header.Get("Authorization")
w.WriteHeader(http.StatusOK)
_, _ = io.WriteString(w, "{}")
}))
defer srv.Close()
origHost := flag.Host
origToken := flag.Token
origExtraHeaders := flag.ExtraHeaders
defer func() {
flag.Host = origHost
flag.Token = origToken
flag.ExtraHeaders = origExtraHeaders
}()
flag.Host = srv.URL
flag.Token = "the-token"
flag.ExtraHeaders = http.Header{
"Cf-Access-Client-Id": []string{"client-id"},
"Authorization": []string{"should-not-override"},
}
var out map[string]any
status, err := DoJSON(context.Background(), http.MethodGet, "repos/owner/repo", nil, nil, &out)
if err != nil {
t.Fatalf("DoJSON returned error: %v", err)
}
if status != http.StatusOK {
t.Fatalf("expected status %d, got %d", http.StatusOK, status)
}
if gotClientID != "client-id" {
t.Fatalf("CF-Access-Client-Id header = %q, want %q", gotClientID, "client-id")
}
if gotAuthorization != "token the-token" {
t.Fatalf("Authorization header = %q, want %q", gotAuthorization, "token the-token")
}
}