package main import ( "bytes" "encoding/json" "fmt" "io" "net/http" "testing" "time" ) // TestAuthValidate 测试token验证API func TestAuthValidate(t *testing.T) { // 获取svc-code服务地址 svcCodeURL := "http://localhost:8020" // 检查服务是否运行 if !checkServiceRunningForValidateTest(t, svcCodeURL) { t.Skipf("svc-code服务未运行在 %s,跳过测试", svcCodeURL) } // 1. 用户登录获取token token, err := loginForValidateTest(t, svcCodeURL) if err != nil { t.Fatalf("登录失败: %v", err) } t.Logf("获取到Token: %s...", token[:minValidateInt(20, len(token))]) // 2. 验证token有效性 userInfo, err := validateToken(t, svcCodeURL, token) if err != nil { t.Fatalf("token验证失败: %v", err) } // 3. 验证用户信息 t.Logf("token验证成功,用户信息: %v", userInfo) if userInfo["user_id"] != "test-user-001" { t.Errorf("预期user_id为'test-user-001',得到 %v", userInfo["user_id"]) } if userInfo["authenticated"] != true { t.Error("authenticated字段应为true") } // 4. 测试无效token t.Run("InvalidToken", func(t *testing.T) { testInvalidToken(t, svcCodeURL) }) // 5. 测试缺失token t.Run("MissingToken", func(t *testing.T) { testMissingToken(t, svcCodeURL) }) } // validateToken 验证token并返回用户信息 func validateToken(t *testing.T, svcCodeURL, token string) (map[string]interface{}, error) { url := svcCodeURL + "/api/auth/validate" req, err := http.NewRequest("POST", url, nil) if err != nil { return nil, fmt.Errorf("创建请求失败: %w", err) } req.Header.Set("Authorization", "Bearer "+token) req.Header.Set("Content-Type", "application/json") client := &http.Client{Timeout: 10 * time.Second} resp, err := client.Do(req) if err != nil { return nil, fmt.Errorf("HTTP请求失败: %w", err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { bodyBytes, _ := io.ReadAll(resp.Body) return nil, fmt.Errorf("token验证失败 (状态码 %d): %s", resp.StatusCode, string(bodyBytes)) } var result struct { Success bool `json:"success"` Data map[string]interface{} `json:"data"` Message string `json:"message"` } bodyBytes, _ := io.ReadAll(resp.Body) if err := json.Unmarshal(bodyBytes, &result); err != nil { return nil, fmt.Errorf("解析响应失败: %w", err) } if !result.Success { return nil, fmt.Errorf("token验证失败: %s", result.Message) } return result.Data, nil } // testInvalidToken 测试无效token func testInvalidToken(t *testing.T, svcCodeURL string) { invalidToken := "invalid.token.here" _, err := validateToken(t, svcCodeURL, invalidToken) if err == nil { t.Error("无效token应该验证失败,但成功了") } else { t.Logf("无效token验证失败(预期): %v", err) } } // testMissingToken 测试缺失token func testMissingToken(t *testing.T, svcCodeURL string) { url := svcCodeURL + "/api/auth/validate" req, err := http.NewRequest("POST", url, nil) if err != nil { t.Fatalf("创建请求失败: %v", err) } req.Header.Set("Content-Type", "application/json") // 不设置Authorization头 client := &http.Client{Timeout: 10 * time.Second} resp, err := client.Do(req) if err != nil { t.Fatalf("HTTP请求失败: %v", err) } defer resp.Body.Close() // 缺少token应该返回401或400 if resp.StatusCode == http.StatusOK { // 如果是200,检查响应内容 bodyBytes, _ := io.ReadAll(resp.Body) var result map[string]interface{} if err := json.Unmarshal(bodyBytes, &result); err == nil { if success, ok := result["success"].(bool); ok && success { t.Error("缺失token应该验证失败,但成功了") } else { t.Logf("缺失token验证失败(预期): %v", result) } } } else { t.Logf("缺失token返回状态码 %d(预期)", resp.StatusCode) } } // loginForValidateTest 登录获取token(验证测试专用) func loginForValidateTest(t *testing.T, svcCodeURL string) (string, error) { loginURL := svcCodeURL + "/api/auth/login" loginData := map[string]string{ "user_id": "test-user-001", "password": "password123", } jsonData, _ := json.Marshal(loginData) resp, err := http.Post(loginURL, "application/json", bytes.NewBuffer(jsonData)) if err != nil { return "", fmt.Errorf("登录请求失败: %v", err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { bodyBytes, _ := io.ReadAll(resp.Body) return "", fmt.Errorf("登录失败 (状态码 %d): %s", resp.StatusCode, string(bodyBytes)) } var result struct { Success bool `json:"success"` Data string `json:"data"` Message string `json:"message"` } bodyBytes, _ := io.ReadAll(resp.Body) if err := json.Unmarshal(bodyBytes, &result); err != nil { return "", fmt.Errorf("解析响应失败: %v", err) } if !result.Success { return "", fmt.Errorf("登录失败: %s", result.Message) } return result.Data, nil } // checkServiceRunningForValidateTest 检查服务是否运行(验证测试专用) func checkServiceRunningForValidateTest(t *testing.T, url string) bool { client := &http.Client{Timeout: 3 * time.Second} resp, err := client.Get(url + "/api/health") if err != nil { // 尝试其他端点 resp, err = client.Get(url) if err != nil { return false } } defer resp.Body.Close() return resp.StatusCode == http.StatusOK || resp.StatusCode == 404 } // minValidateInt 返回两个整数的最小值(验证测试专用) func minValidateInt(a, b int) int { if a < b { return a } return b }