test: add comprehensive test coverage and improve code quality
- Add new test files for auth, service, and handler modules - Improve test organization and coverage - Refactor code for better maintainability - Add captcha, settings, stats, and theme handler tests - Add auth module tests (CAS, OAuth, password, SSO, state) - Add service layer tests for auth, export, permissions, roles - All Go tests pass (exit code 0) - All frontend tests pass (325 tests in 59 files)
This commit is contained in:
146
internal/api/handler/captcha_handler_test.go
Normal file
146
internal/api/handler/captcha_handler_test.go
Normal file
@@ -0,0 +1,146 @@
|
||||
package handler_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/user-management-system/internal/api/handler"
|
||||
"github.com/user-management-system/internal/cache"
|
||||
"github.com/user-management-system/internal/service"
|
||||
)
|
||||
|
||||
// =============================================================================
|
||||
// Captcha Handler Tests - TDD approach
|
||||
// =============================================================================
|
||||
|
||||
func TestCaptchaHandler_GenerateCaptcha(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
|
||||
l1Cache := cache.NewL1Cache()
|
||||
l2Cache := cache.NewRedisCache(false)
|
||||
cacheManager := cache.NewCacheManager(l1Cache, l2Cache)
|
||||
captchaSvc := service.NewCaptchaService(cacheManager)
|
||||
h := handler.NewCaptchaHandler(captchaSvc)
|
||||
|
||||
t.Run("生成验证码成功", func(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Request = httptest.NewRequest("GET", "/api/v1/captcha/generate", nil)
|
||||
|
||||
h.GenerateCaptcha(c)
|
||||
|
||||
if w.Code != http.StatusOK {
|
||||
t.Errorf("期望状态码 %d, 得到 %d", http.StatusOK, w.Code)
|
||||
}
|
||||
|
||||
var resp map[string]interface{}
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil {
|
||||
t.Fatalf("解析响应失败: %v", err)
|
||||
}
|
||||
|
||||
if resp["code"].(float64) != 0 {
|
||||
t.Errorf("期望 code=0, 得到 %v", resp["code"])
|
||||
}
|
||||
|
||||
data := resp["data"].(map[string]interface{})
|
||||
if data["captcha_id"] == "" {
|
||||
t.Error("captcha_id 不应为空")
|
||||
}
|
||||
if data["image"] == "" {
|
||||
t.Error("image 不应为空")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestCaptchaHandler_VerifyCaptcha(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
|
||||
l1Cache := cache.NewL1Cache()
|
||||
l2Cache := cache.NewRedisCache(false)
|
||||
cacheManager := cache.NewCacheManager(l1Cache, l2Cache)
|
||||
captchaSvc := service.NewCaptchaService(cacheManager)
|
||||
h := handler.NewCaptchaHandler(captchaSvc)
|
||||
|
||||
t.Run("验证成功", func(t *testing.T) {
|
||||
// 先生成验证码
|
||||
result, _ := captchaSvc.Generate(nil)
|
||||
// 从缓存获取答案
|
||||
cachedVal, ok := cacheManager.Get(nil, "captcha:"+result.CaptchaID)
|
||||
if !ok {
|
||||
t.Fatal("验证码未存储到缓存")
|
||||
}
|
||||
answer := cachedVal.(string)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
body := `{"captcha_id":"` + result.CaptchaID + `","answer":"` + answer + `"}`
|
||||
c.Request = httptest.NewRequest("POST", "/api/v1/captcha/verify", nil)
|
||||
c.Request.Body = io.NopCloser(bytes.NewReader([]byte(body)))
|
||||
c.Request.Header.Set("Content-Type", "application/json")
|
||||
|
||||
h.VerifyCaptcha(c)
|
||||
|
||||
if w.Code != http.StatusOK {
|
||||
t.Errorf("期望状态码 %d, 得到 %d", http.StatusOK, w.Code)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("验证失败-错误答案", func(t *testing.T) {
|
||||
result, _ := captchaSvc.Generate(nil)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
body := `{"captcha_id":"` + result.CaptchaID + `","answer":"wrong"}`
|
||||
c.Request = httptest.NewRequest("POST", "/api/v1/captcha/verify", nil)
|
||||
c.Request.Body = io.NopCloser(bytes.NewReader([]byte(body)))
|
||||
c.Request.Header.Set("Content-Type", "application/json")
|
||||
|
||||
h.VerifyCaptcha(c)
|
||||
|
||||
if w.Code != http.StatusBadRequest {
|
||||
t.Errorf("期望状态码 %d, 得到 %d", http.StatusBadRequest, w.Code)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("验证失败-缺少参数", func(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
body := `{"captcha_id":""}`
|
||||
c.Request = httptest.NewRequest("POST", "/api/v1/captcha/verify", nil)
|
||||
c.Request.Body = io.NopCloser(bytes.NewReader([]byte(body)))
|
||||
c.Request.Header.Set("Content-Type", "application/json")
|
||||
|
||||
h.VerifyCaptcha(c)
|
||||
|
||||
if w.Code != http.StatusBadRequest {
|
||||
t.Errorf("期望状态码 %d, 得到 %d", http.StatusBadRequest, w.Code)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestCaptchaHandler_GetCaptchaImage(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
|
||||
l1Cache := cache.NewL1Cache()
|
||||
l2Cache := cache.NewRedisCache(false)
|
||||
cacheManager := cache.NewCacheManager(l1Cache, l2Cache)
|
||||
captchaSvc := service.NewCaptchaService(cacheManager)
|
||||
h := handler.NewCaptchaHandler(captchaSvc)
|
||||
|
||||
t.Run("获取验证码图片", func(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Request = httptest.NewRequest("GET", "/api/v1/captcha/image?captcha_id=test", nil)
|
||||
|
||||
h.GetCaptchaImage(c)
|
||||
|
||||
if w.Code != http.StatusOK {
|
||||
t.Errorf("期望状态码 %d, 得到 %d", http.StatusOK, w.Code)
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user