Skip to content

Commit 78fc5e0

Browse files
authored
Merge branch 'main' into clarify-docs
2 parents faf32f4 + 3762542 commit 78fc5e0

File tree

1 file changed

+113
-0
lines changed

1 file changed

+113
-0
lines changed
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package api_test
2+
3+
import (
4+
"net/http"
5+
"net/http/httptest"
6+
"os"
7+
"path/filepath"
8+
"sort"
9+
"testing"
10+
11+
"github.com/danielgtaylor/huma/v2"
12+
"github.com/danielgtaylor/huma/v2/adapters/humago"
13+
"github.com/stretchr/testify/assert"
14+
"github.com/stretchr/testify/require"
15+
"gopkg.in/yaml.v3"
16+
17+
"github.com/modelcontextprotocol/registry/internal/api/router"
18+
"github.com/modelcontextprotocol/registry/internal/config"
19+
)
20+
21+
// OpenAPISpec represents the minimal structure we need to compare paths
22+
type OpenAPISpec struct {
23+
Paths map[string]interface{} `yaml:"paths"`
24+
}
25+
26+
func TestOpenAPIEndpointCompliance(t *testing.T) {
27+
// Load reference schema from docs
28+
referenceSchemaPath := filepath.Join("..", "..", "docs", "reference", "api", "openapi.yaml")
29+
referenceData, err := os.ReadFile(referenceSchemaPath)
30+
require.NoError(t, err, "Failed to read reference OpenAPI schema at %s", referenceSchemaPath)
31+
32+
var referenceSpec OpenAPISpec
33+
err = yaml.Unmarshal(referenceData, &referenceSpec)
34+
require.NoError(t, err, "Failed to parse reference OpenAPI schema")
35+
36+
// Create test API using the same pattern as other tests
37+
mux := http.NewServeMux()
38+
api := humago.New(mux, huma.DefaultConfig("Test API", "1.0.0"))
39+
40+
// Create minimal config for testing
41+
cfg := &config.Config{
42+
JWTPrivateKey: "0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20", // 32-byte hex key
43+
}
44+
45+
// Register V0 routes exactly like production does
46+
router.RegisterV0Routes(api, cfg, nil, nil) // nil service and metrics for schema testing
47+
48+
// Get the OpenAPI schema
49+
req := httptest.NewRequest(http.MethodGet, "/openapi.yaml", nil)
50+
w := httptest.NewRecorder()
51+
mux.ServeHTTP(w, req)
52+
53+
require.Equal(t, http.StatusOK, w.Code, "OpenAPI endpoint should return 200")
54+
55+
var servedSpec OpenAPISpec
56+
err = yaml.Unmarshal(w.Body.Bytes(), &servedSpec)
57+
require.NoError(t, err, "Failed to parse served OpenAPI schema")
58+
59+
// Extract and sort paths for comparison
60+
referencePaths := extractAndSortPaths(referenceSpec.Paths)
61+
servedPaths := extractAndSortPaths(servedSpec.Paths)
62+
63+
// Find missing paths
64+
missing := []string{}
65+
for _, refPath := range referencePaths {
66+
found := false
67+
for _, servedPath := range servedPaths {
68+
if refPath == servedPath {
69+
found = true
70+
break
71+
}
72+
}
73+
if !found {
74+
missing = append(missing, refPath)
75+
}
76+
}
77+
78+
// Assert all reference paths are implemented
79+
assert.Empty(t, missing, "All reference endpoints should be implemented. Missing: %v", missing)
80+
81+
// Log success and additional endpoints for visibility
82+
if len(missing) == 0 {
83+
t.Logf("✅ All %d reference endpoints are implemented", len(referencePaths))
84+
85+
// Count extra endpoints
86+
extra := []string{}
87+
for _, servedPath := range servedPaths {
88+
found := false
89+
for _, refPath := range referencePaths {
90+
if servedPath == refPath {
91+
found = true
92+
break
93+
}
94+
}
95+
if !found {
96+
extra = append(extra, servedPath)
97+
}
98+
}
99+
100+
if len(extra) > 0 {
101+
t.Logf("+ %d additional endpoints in served API: %v", len(extra), extra)
102+
}
103+
}
104+
}
105+
106+
func extractAndSortPaths(paths map[string]interface{}) []string {
107+
keys := make([]string, 0, len(paths))
108+
for path := range paths {
109+
keys = append(keys, path)
110+
}
111+
sort.Strings(keys)
112+
return keys
113+
}

0 commit comments

Comments
 (0)