sub2api/backend/internal/service/antigravity_test_http_flow_test.go
win 9da079a5ee
Some checks failed
Security Scan / backend-security (push) Failing after 3s
Security Scan / frontend-security (push) Failing after 5s
CI / test (push) Failing after 3s
CI / frontend (push) Failing after 3s
CI / golangci-lint (push) Failing after 3s
CI / windsurf-platform (macos-latest) (push) Has been cancelled
CI / windsurf-platform (windows-latest) (push) Has been cancelled
x
2026-04-27 19:01:41 +08:00

189 lines
4.9 KiB
Go
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package service
import (
"bytes"
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
"github.com/gin-gonic/gin"
)
// TestHTTPResponseFlow 测试完整的 HTTP 请求-响应流,看客户端会收到什么
func TestHTTPResponseFlow(t *testing.T) {
t.Log("🔥 模拟完整的 HTTP 请求-响应流...")
t.Log("")
// 创建一个模拟的服务
gin.SetMode(gin.TestMode)
router := gin.New()
// 模拟账号测试端点
router.POST("/api/v1/admin/accounts/:id/test", func(c *gin.Context) {
// 模拟返回错误的情况
// 设置 SSE 头
c.Header("Content-Type", "text/event-stream")
c.Header("Cache-Control", "no-cache")
c.Header("Connection", "keep-alive")
c.Header("X-Accel-Buffering", "no")
c.Status(http.StatusOK)
// 发送测试开始事件
event1 := map[string]interface{}{
"type": "test_start",
"model": "claude-opus-4-6",
}
jsonData1, _ := json.Marshal(event1)
c.Writer.WriteString("data: " + string(jsonData1) + "\n\n")
c.Writer.Flush()
// 模拟一个错误:比如 "INVALID_TOKEN" 或其他上游错误
// 这里我们故意测试不同的错误信息来看 curl 会显示什么
errorMessages := []string{
"INVALID_TOKEN",
"INTERNAL_ERROR",
"Invalid authentication credentials",
"Th", // 测试短错误
"IT", // 直接测试 "IT"
}
selectedError := errorMessages[3] // 选择第 4 个:这应该显示为 "Th" 而不是 "IT"
event2 := map[string]interface{}{
"type": "error",
"error": selectedError,
"success": false,
}
jsonData2, _ := json.Marshal(event2)
c.Writer.WriteString("data: " + string(jsonData2) + "\n\n")
c.Writer.Flush()
// 发送完成事件
event3 := map[string]interface{}{
"type": "test_complete",
"success": false,
}
jsonData3, _ := json.Marshal(event3)
c.Writer.WriteString("data: " + string(jsonData3) + "\n\n")
c.Writer.Flush()
t.Logf("📤 服务器发送的错误: '%s'", selectedError)
})
// 测试 1: 发送 HTTP 请求
t.Run("SendRequestAndCheckResponse", func(t *testing.T) {
t.Log("步骤 1: 发送 HTTP 请求...")
req := httptest.NewRequest("POST", "/api/v1/admin/accounts/68/test",
bytes.NewReader([]byte(`{"model_id":"claude-opus-4-6"}`)))
req.Header.Set("Content-Type", "application/json")
w := httptest.NewRecorder()
router.ServeHTTP(w, req)
t.Log("✅ 请求已发送")
t.Log("")
// 步骤 2: 检查响应
t.Log("步骤 2: 分析 HTTP 响应...")
t.Logf(" HTTP Status: %d", w.Code)
t.Logf(" Content-Type: %s", w.Header().Get("Content-Type"))
t.Log("")
// 步骤 3: 读取 SSE 响应
t.Log("步骤 3: 读取 SSE 事件...")
body := w.Body.String()
t.Logf(" 响应总长度: %d 字节", len(body))
t.Log("")
// 解析 SSE 事件
lines := bytes.Split([]byte(body), []byte("\n\n"))
for i, line := range lines {
if len(line) == 0 {
continue
}
// 去掉 "data: " 前缀
if bytes.HasPrefix(line, []byte("data: ")) {
data := bytes.TrimPrefix(line, []byte("data: "))
var event map[string]interface{}
err := json.Unmarshal(data, &event)
if err != nil {
t.Logf(" 事件 %d: [解析失败] %v", i, err)
continue
}
t.Logf(" 事件 %d:", i)
t.Logf(" type: %v", event["type"])
if errMsg, ok := event["error"]; ok {
t.Logf(" error: %v (长度: %d)", errMsg, len(errMsg.(string)))
// 这就是 curl 会看到的错误信息
errStr := errMsg.(string)
if errStr == "IT" {
t.Logf(" ✓ 发现 'IT' 错误!")
} else if errStr == "Th" {
t.Logf(" 这是 'Th' 而不是 'IT'")
} else {
t.Logf(" 实际错误: '%s'", errStr)
}
}
if model, ok := event["model"]; ok {
t.Logf(" model: %v", model)
}
}
}
t.Log("")
t.Log("📋 完整的原始响应:")
t.Logf("%s", body)
})
// 测试 2: 模拟真实的 curl 请求
t.Run("SimulateRealCurlRequest", func(t *testing.T) {
t.Log("步骤: 模拟真实 curl 命令...")
t.Log("")
// 发送请求
req := httptest.NewRequest("POST", "/api/v1/admin/accounts/68/test",
bytes.NewReader([]byte(`{"model_id":"claude-opus-4-6","prompt":""}`)))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer test-token")
w := httptest.NewRecorder()
router.ServeHTTP(w, req)
// 模拟 curl 读取响应
body := w.Body.String()
t.Log("curl 会看到:")
t.Log("```")
t.Log(body)
t.Log("```")
})
}
// 辅助函数:提取 SSE 事件中的错误信息
func extractErrorFromSSE(sseBody string) string {
lines := bytes.Split([]byte(sseBody), []byte("\n\n"))
for _, line := range lines {
if bytes.HasPrefix(line, []byte("data: ")) {
data := bytes.TrimPrefix(line, []byte("data: "))
var event map[string]interface{}
if err := json.Unmarshal(data, &event); err != nil {
continue
}
if errMsg, ok := event["error"]; ok {
return errMsg.(string)
}
}
}
return ""
}