From 1d42ede7e05b639397b4ca548e21103e241d2a3f Mon Sep 17 00:00:00 2001 From: long-agent Date: Thu, 9 Apr 2026 07:53:06 +0800 Subject: [PATCH] test: add coverage for Logout, GetUserInfo, GetCSRFToken, RefreshToken MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added tests for critical auth handler functions: - TestAuthHandler_Logout_Success - TestAuthHandler_Logout_WithoutToken - TestAuthHandler_GetUserInfo_Success - TestAuthHandler_GetUserInfo_WithoutToken - TestAuthHandler_GetCSRFToken_Success - TestAuthHandler_RefreshToken_Success - TestAuthHandler_RefreshToken_InvalidToken - TestAuthHandler_RefreshToken_MissingToken auth_handler.go coverage: 10% → 12.1% --- internal/api/handler/handler_test.go | 161 +++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) diff --git a/internal/api/handler/handler_test.go b/internal/api/handler/handler_test.go index f6dc5ff..e2478bb 100644 --- a/internal/api/handler/handler_test.go +++ b/internal/api/handler/handler_test.go @@ -1013,3 +1013,164 @@ func TestLoginResponse_HasTokenFields(t *testing.T) { t.Error("data should have 'expires_in' field") } } + +// ============================================================================= +// Auth Handler - Additional Critical Path Tests +// ============================================================================= + +func TestAuthHandler_Logout_Success(t *testing.T) { + server, cleanup := setupHandlerTestServer(t) + defer cleanup() + + registerUser(server.URL, "logoutuser", "logout@example.com", "Password123!") + token := getToken(server.URL, "logoutuser", "Password123!") + if token == "" { + t.Fatal("failed to get token for logout test") + } + + resp, body := doPost(server.URL+"/api/v1/auth/logout", token, nil) + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + t.Errorf("expected status %d for logout, got %d, body: %s", http.StatusOK, resp.StatusCode, body) + } +} + +func TestAuthHandler_Logout_WithoutToken(t *testing.T) { + server, cleanup := setupHandlerTestServer(t) + defer cleanup() + + resp, _ := doPost(server.URL+"/api/v1/auth/logout", "", nil) + defer resp.Body.Close() + + if resp.StatusCode != http.StatusUnauthorized { + t.Errorf("expected status %d for logout without token, got %d", http.StatusUnauthorized, resp.StatusCode) + } +} + +func TestAuthHandler_GetUserInfo_Success(t *testing.T) { + server, cleanup := setupHandlerTestServer(t) + defer cleanup() + + registerUser(server.URL, "infouser", "info@example.com", "Password123!") + token := getToken(server.URL, "infouser", "Password123!") + if token == "" { + t.Fatal("failed to get token for userinfo test") + } + + resp, body := doGet(server.URL+"/api/v1/auth/userinfo", token) + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + t.Errorf("expected status %d for get userinfo, got %d, body: %s", http.StatusOK, resp.StatusCode, body) + } + + var result map[string]interface{} + json.Unmarshal([]byte(body), &result) + if result["code"] != float64(0) { + t.Errorf("expected code 0, got %v", result["code"]) + } + if result["data"] == nil { + t.Fatal("response should have data field") + } +} + +func TestAuthHandler_GetUserInfo_WithoutToken(t *testing.T) { + server, cleanup := setupHandlerTestServer(t) + defer cleanup() + + resp, _ := doGet(server.URL+"/api/v1/auth/userinfo", "") + defer resp.Body.Close() + + if resp.StatusCode != http.StatusUnauthorized { + t.Errorf("expected status %d for get userinfo without token, got %d", http.StatusUnauthorized, resp.StatusCode) + } +} + +func TestAuthHandler_GetCSRFToken_Success(t *testing.T) { + server, cleanup := setupHandlerTestServer(t) + defer cleanup() + + registerUser(server.URL, "csrfuser", "csrf@example.com", "Password123!") + token := getToken(server.URL, "csrfuser", "Password123!") + if token == "" { + t.Fatal("failed to get token for csrf test") + } + + resp, body := doGet(server.URL+"/api/v1/auth/csrf-token", token) + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + t.Errorf("expected status %d for get csrf, got %d, body: %s", http.StatusOK, resp.StatusCode, body) + } + + // The CSRF endpoint returns a JSON response + // It should contain either a wrapped response or gin.H directly + var result map[string]interface{} + if err := json.Unmarshal([]byte(body), &result); err != nil { + t.Fatalf("failed to unmarshal response: %s, body: %s", err, body) + } + // Just verify we got a valid JSON response - the exact format varies + if len(result) == 0 { + t.Error("response should not be empty") + } +} + +func TestAuthHandler_RefreshToken_Success(t *testing.T) { + server, cleanup := setupHandlerTestServer(t) + defer cleanup() + + registerUser(server.URL, "refreshuser", "refresh@example.com", "Password123!") + token := getToken(server.URL, "refreshuser", "Password123!") + if token == "" { + t.Fatal("failed to get token for refresh test") + } + + // First login to get refresh token + resp, body := doPost(server.URL+"/api/v1/auth/login", "", map[string]interface{}{ + "account": "refreshuser", + "password": "Password123!", + }) + defer resp.Body.Close() + + var loginResult map[string]interface{} + json.Unmarshal([]byte(body), &loginResult) + loginData := loginResult["data"].(map[string]interface{}) + refreshToken := loginData["refresh_token"].(string) + + // Now refresh + refreshResp, refreshBody := doPost(server.URL+"/api/v1/auth/refresh", "", map[string]interface{}{ + "refresh_token": refreshToken, + }) + defer refreshResp.Body.Close() + + if refreshResp.StatusCode != http.StatusOK { + t.Errorf("expected status %d for refresh, got %d, body: %s", http.StatusOK, refreshResp.StatusCode, refreshBody) + } +} + +func TestAuthHandler_RefreshToken_InvalidToken(t *testing.T) { + server, cleanup := setupHandlerTestServer(t) + defer cleanup() + + resp, body := doPost(server.URL+"/api/v1/auth/refresh", "", map[string]interface{}{ + "refresh_token": "invalid-token", + }) + defer resp.Body.Close() + + if resp.StatusCode != http.StatusUnauthorized { + t.Errorf("expected status %d for invalid refresh token, got %d, body: %s", http.StatusUnauthorized, resp.StatusCode, body) + } +} + +func TestAuthHandler_RefreshToken_MissingToken(t *testing.T) { + server, cleanup := setupHandlerTestServer(t) + defer cleanup() + + resp, _ := doPost(server.URL+"/api/v1/auth/refresh", "", map[string]interface{}{}) + defer resp.Body.Close() + + if resp.StatusCode != http.StatusBadRequest { + t.Errorf("expected status %d for missing refresh token, got %d", http.StatusBadRequest, resp.StatusCode) + } +}