Files
easyai-ai-gateway/apps/api/internal/httpapi/public_api_prefix_test.go
easyai 7c5a999e32 feat(api): 统一公开接口为 /api/v1 前缀
将通用生成、Gemini、可灵、火山、健康检查与 OpenAPI 的推荐入口统一到 /api/v1,并保留历史路径作为兼容别名。同步更新代理配置、接入文档、接口清单和前缀回归测试。\n\n验证:go vet ./...;go test ./...;pnpm openapi;pnpm lint;pnpm test;pnpm build;公开 OpenAPI 71 个方法与接口清单机器比对一致。
2026-07-22 08:48:32 +08:00

73 lines
1.7 KiB
Go

package httpapi
import (
"encoding/json"
"strings"
"testing"
gatewaydocs "github.com/easyai/easyai-ai-gateway/apps/api/docs"
)
func TestOpenAPIPublicRoutesUseCanonicalV1Prefix(t *testing.T) {
var document struct {
Paths map[string]any `json:"paths"`
}
if err := json.Unmarshal(gatewaydocs.SwaggerJSON, &document); err != nil {
t.Fatalf("decode embedded OpenAPI document: %v", err)
}
legacyPrefixes := []string{
"/v1/",
"/v1beta/",
"/kling/",
"/upload/",
"/api/v3/",
"/chat/",
"/images/",
"/song/",
"/music/",
"/speech/",
"/voice_clone",
"/tasks",
}
legacyExact := map[string]bool{
"/healthz": true,
"/readyz": true,
"/api-docs-json": true,
"/api-docs-yaml": true,
"/responses": true,
"/embeddings": true,
"/reranks": true,
}
for route := range document.Paths {
if legacyExact[route] {
t.Errorf("legacy public route must not be advertised in OpenAPI: %s", route)
}
for _, prefix := range legacyPrefixes {
if strings.HasPrefix(route, prefix) {
t.Errorf("legacy public route must not be advertised in OpenAPI: %s", route)
}
}
}
required := []string{
"/api/v1/healthz",
"/api/v1/readyz",
"/api/v1/openapi.json",
"/api/v1/chat/completions",
"/api/v1/responses",
"/api/v1/images/generations",
"/api/v1/videos/generations",
"/api/v1/models/{model}:generateContent",
"/api/v1/videos/omni-video",
"/api/v1/kling/v1/videos/omni-video",
"/api/v1/kling/v2/omni-video/{model}",
"/api/v1/contents/generations/tasks",
}
for _, route := range required {
if _, ok := document.Paths[route]; !ok {
t.Errorf("canonical public route missing from OpenAPI: %s", route)
}
}
}