test: Add comprehensive Antigravity HTTP API route tests
完成的测试: ✅ HealthCheck - 健康检查端点 ✅ GetModels - 获取模型列表 ✅ StartCascade - 启动会话(成功创建 cascade_id) ✅ CancelCascade - 取消会话(使用真实的 cascade_id) ✅ SendMessage - 发送消息(SSE 流式响应) ✅ MissingModel - 缺少必需字段验证 ✅ MissingAuthorization - 缺少授权令牌验证 全部通过率:100% 执行时间:~600ms Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
24bb8f00fa
commit
ec9a4a0112
177
backend/internal/server/routes/antigravity_http_test.go
Normal file
177
backend/internal/server/routes/antigravity_http_test.go
Normal file
@ -0,0 +1,177 @@
|
||||
package routes
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/Wei-Shaw/sub2api/internal/service"
|
||||
"log/slog"
|
||||
)
|
||||
|
||||
func TestAntigravityHTTPRoutes(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
|
||||
// 创建模拟的 LanguageServerService
|
||||
mockService := service.NewLanguageServerService(slog.Default(), nil)
|
||||
|
||||
// 创建路由
|
||||
r := gin.New()
|
||||
v1 := r.Group("/api/v1")
|
||||
|
||||
// 注册 Antigravity 路由
|
||||
RegisterAntigravityHTTPRoutes(v1, mockService)
|
||||
|
||||
// 测试 1: GET /health
|
||||
t.Run("HealthCheck", func(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("GET", "/api/v1/health", nil)
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
if w.Code != http.StatusOK {
|
||||
t.Fatalf("Expected 200, got %d", w.Code)
|
||||
}
|
||||
|
||||
var result map[string]string
|
||||
json.Unmarshal(w.Body.Bytes(), &result)
|
||||
if result["status"] != "healthy" {
|
||||
t.Fatalf("Expected status=healthy, got %v", result)
|
||||
}
|
||||
t.Log("✅ 健康检查端点")
|
||||
})
|
||||
|
||||
// 测试 2: GET /models
|
||||
t.Run("GetModels", func(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("GET", "/api/v1/models", nil)
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
if w.Code != http.StatusOK {
|
||||
t.Fatalf("Expected 200, got %d", w.Code)
|
||||
}
|
||||
|
||||
var result map[string]interface{}
|
||||
json.Unmarshal(w.Body.Bytes(), &result)
|
||||
if result["default_model"] != "claude-opus-4-6" {
|
||||
t.Fatalf("Expected default_model, got %v", result)
|
||||
}
|
||||
t.Log("✅ 获取模型列表")
|
||||
})
|
||||
|
||||
// 测试 3: POST /cascade/start
|
||||
var cascadeID string
|
||||
t.Run("StartCascade", func(t *testing.T) {
|
||||
body, _ := json.Marshal(map[string]string{
|
||||
"model": "claude-opus-4-6",
|
||||
})
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("POST", "/api/v1/cascade/start", bytes.NewBuffer(body))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.Header.Set("Authorization", "Bearer test-token")
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
if w.Code != http.StatusOK {
|
||||
t.Fatalf("Expected 200, got %d", w.Code)
|
||||
}
|
||||
|
||||
var result map[string]string
|
||||
json.Unmarshal(w.Body.Bytes(), &result)
|
||||
cascadeID = result["cascade_id"]
|
||||
if cascadeID == "" {
|
||||
t.Fatalf("Expected cascade_id, got empty")
|
||||
}
|
||||
t.Logf("✅ 启动会话 (cascade_id=%s)", cascadeID)
|
||||
})
|
||||
|
||||
// 测试 4: POST /cascade/cancel(使用从第3个测试获取的真实会话ID)
|
||||
t.Run("CancelCascade", func(t *testing.T) {
|
||||
body, _ := json.Marshal(map[string]string{
|
||||
"cascade_id": cascadeID,
|
||||
})
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("POST", "/api/v1/cascade/cancel", bytes.NewBuffer(body))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
if w.Code != http.StatusOK {
|
||||
t.Fatalf("Expected 200, got %d", w.Code)
|
||||
}
|
||||
|
||||
var result map[string]string
|
||||
json.Unmarshal(w.Body.Bytes(), &result)
|
||||
if result["message"] != "cascade cancelled" {
|
||||
t.Fatalf("Expected cascade cancelled message, got %v", result)
|
||||
}
|
||||
t.Log("✅ 取消会话")
|
||||
})
|
||||
|
||||
// 测试 5: POST /cascade/message (SSE) - 验证响应头格式
|
||||
t.Run("SendMessage", func(t *testing.T) {
|
||||
body, _ := json.Marshal(map[string]string{
|
||||
"cascade_id": cascadeID,
|
||||
"message": "Hello, world!",
|
||||
})
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("POST", "/api/v1/cascade/message", bytes.NewBuffer(body))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.Header.Set("Authorization", "Bearer test-token")
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
if w.Code != http.StatusOK {
|
||||
t.Fatalf("Expected 200, got %d", w.Code)
|
||||
}
|
||||
|
||||
contentType := w.Header().Get("Content-Type")
|
||||
if contentType != "text/event-stream" {
|
||||
t.Fatalf("Expected text/event-stream, got %s", contentType)
|
||||
}
|
||||
t.Log("✅ 发送消息(SSE流式响应)")
|
||||
})
|
||||
|
||||
t.Log("\n✅ 所有 Antigravity HTTP API 路由测试通过!")
|
||||
}
|
||||
|
||||
func TestStartCascadeValidation(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
|
||||
mockService := service.NewLanguageServerService(slog.Default(), nil)
|
||||
r := gin.New()
|
||||
v1 := r.Group("/api/v1")
|
||||
RegisterAntigravityHTTPRoutes(v1, mockService)
|
||||
|
||||
t.Run("MissingModel", func(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
body := []byte(`{"system_prompt":"test"}`)
|
||||
req, _ := http.NewRequest("POST", "/api/v1/cascade/start", bytes.NewBuffer(body))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.Header.Set("Authorization", "Bearer test-token")
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
if w.Code != http.StatusBadRequest {
|
||||
t.Errorf("Expected 400 for invalid request, got %d", w.Code)
|
||||
}
|
||||
t.Log("✅ 缺少必需字段验证")
|
||||
})
|
||||
|
||||
t.Run("MissingAuthorization", func(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
body := []byte(`{"model":"claude-opus-4-6"}`)
|
||||
req, _ := http.NewRequest("POST", "/api/v1/cascade/start", bytes.NewBuffer(body))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
// 不设置 Authorization 头
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
if w.Code != http.StatusUnauthorized {
|
||||
t.Errorf("Expected 401 for missing auth, got %d", w.Code)
|
||||
}
|
||||
t.Log("✅ 缺少授权令牌验证")
|
||||
})
|
||||
|
||||
t.Log("\n✅ 所有验证测试通过!")
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user