package mcpserver import ( "context" "encoding/json" "net/http" "net/http/httptest" "strings" "testing" "github.com/mark3labs/mcp-go/mcp" "git.wntrmute.dev/mc/mcq/internal/client" ) func testClient(t *testing.T) *client.Client { t.Helper() mux := http.NewServeMux() mux.HandleFunc("GET /v1/documents", func(w http.ResponseWriter, _ *http.Request) { w.Header().Set("Content-Type", "application/json") _ = json.NewEncoder(w).Encode(map[string]any{ "documents": []client.Document{ {ID: 1, Slug: "doc-1", Title: "First Doc", Body: "# First\nContent", PushedBy: "admin", PushedAt: "2026-01-01T00:00:00Z"}, }, }) }) mux.HandleFunc("GET /v1/documents/{slug}", func(w http.ResponseWriter, r *http.Request) { slug := r.PathValue("slug") if slug == "missing" { w.WriteHeader(http.StatusNotFound) return } w.Header().Set("Content-Type", "application/json") _ = json.NewEncoder(w).Encode(client.Document{ID: 1, Slug: slug, Title: "Test Doc", Body: "# Test\nContent"}) }) mux.HandleFunc("PUT /v1/documents/{slug}", func(w http.ResponseWriter, r *http.Request) { slug := r.PathValue("slug") var req struct { Title string `json:"title"` Body string `json:"body"` } _ = json.NewDecoder(r.Body).Decode(&req) w.Header().Set("Content-Type", "application/json") _ = json.NewEncoder(w).Encode(client.Document{ID: 1, Slug: slug, Title: req.Title, Body: req.Body, PushedBy: "admin"}) }) mux.HandleFunc("DELETE /v1/documents/{slug}", func(w http.ResponseWriter, r *http.Request) { slug := r.PathValue("slug") if slug == "missing" { w.WriteHeader(http.StatusNotFound) return } w.WriteHeader(http.StatusNoContent) }) ts := httptest.NewServer(mux) t.Cleanup(ts.Close) return client.New(ts.URL, "test-token", client.WithHTTPClient(ts.Client())) } func TestPushDocumentHandler(t *testing.T) { c := testClient(t) handler := pushDocumentHandler(c) result, err := handler(context.Background(), mcp.CallToolRequest{ Params: mcp.CallToolParams{ Name: "push_document", Arguments: map[string]any{"slug": "test-doc", "title": "Test", "body": "# Test\nContent"}, }, }) if err != nil { t.Fatalf("push handler: %v", err) } if result.IsError { t.Fatalf("unexpected tool error: %v", result.Content) } text := result.Content[0].(mcp.TextContent).Text if !strings.Contains(text, "test-doc") { t.Fatalf("expected slug in response, got: %s", text) } } func TestListDocumentsHandler(t *testing.T) { c := testClient(t) handler := listDocumentsHandler(c) result, err := handler(context.Background(), mcp.CallToolRequest{}) if err != nil { t.Fatalf("list handler: %v", err) } if result.IsError { t.Fatalf("unexpected tool error: %v", result.Content) } text := result.Content[0].(mcp.TextContent).Text if !strings.Contains(text, "doc-1") { t.Fatalf("expected doc slug in response, got: %s", text) } } func TestGetDocumentHandler(t *testing.T) { c := testClient(t) handler := getDocumentHandler(c) result, err := handler(context.Background(), mcp.CallToolRequest{ Params: mcp.CallToolParams{ Name: "get_document", Arguments: map[string]any{"slug": "test-doc"}, }, }) if err != nil { t.Fatalf("get handler: %v", err) } if result.IsError { t.Fatalf("unexpected tool error: %v", result.Content) } text := result.Content[0].(mcp.TextContent).Text if !strings.Contains(text, "# Test") { t.Fatalf("expected markdown body, got: %s", text) } } func TestDeleteDocumentHandler(t *testing.T) { c := testClient(t) handler := deleteDocumentHandler(c) result, err := handler(context.Background(), mcp.CallToolRequest{ Params: mcp.CallToolParams{ Name: "delete_document", Arguments: map[string]any{"slug": "test-doc"}, }, }) if err != nil { t.Fatalf("delete handler: %v", err) } if result.IsError { t.Fatalf("unexpected tool error: %v", result.Content) } text := result.Content[0].(mcp.TextContent).Text if !strings.Contains(text, "Deleted") { t.Fatalf("expected deletion confirmation, got: %s", text) } } func TestDeleteDocumentNotFound(t *testing.T) { c := testClient(t) handler := deleteDocumentHandler(c) result, err := handler(context.Background(), mcp.CallToolRequest{ Params: mcp.CallToolParams{ Name: "delete_document", Arguments: map[string]any{"slug": "missing"}, }, }) if err != nil { t.Fatalf("delete handler: %v", err) } if !result.IsError { t.Fatal("expected tool error for missing document") } } func TestNewCreatesServer(t *testing.T) { c := testClient(t) s := New(c, "test") if s == nil { t.Fatal("expected non-nil server") } }