From de329286c974fa5c31efe1742eb694eacbedf124 Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 29 May 2026 20:21:07 +0800 Subject: [PATCH] test: add sms_handler tests for SendCode endpoint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add tests for SMS handler: - SendCode with valid phone number - SendCode with invalid phone (returns 400) - SendCode with missing phone (validation error) - SendCode when service not configured (returns 503) Coverage: handler 27.7% → 28.6% --- internal/api/handler/sms_handler_test.go | 107 +++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 internal/api/handler/sms_handler_test.go diff --git a/internal/api/handler/sms_handler_test.go b/internal/api/handler/sms_handler_test.go new file mode 100644 index 0000000..ae5b892 --- /dev/null +++ b/internal/api/handler/sms_handler_test.go @@ -0,0 +1,107 @@ +package handler_test + +import ( + "bytes" + "encoding/json" + "net/http" + "net/http/httptest" + "testing" + + "github.com/gin-gonic/gin" + "github.com/stretchr/testify/assert" + "github.com/user-management-system/internal/api/handler" + "github.com/user-management-system/internal/cache" + "github.com/user-management-system/internal/service" +) + +func setupSMSHandler() (*handler.SMSHandler, *gin.Engine) { + gin.SetMode(gin.TestMode) + + l1Cache := cache.NewL1Cache() + l2Cache := cache.NewRedisCache(false) + cacheManager := cache.NewCacheManager(l1Cache, l2Cache) + + // Create mock SMS provider + mockProvider := &service.MockSMSProvider{} + smsConfig := service.DefaultSMSCodeConfig() + smsCodeSvc := service.NewSMSCodeService(mockProvider, cacheManager, smsConfig) + + // Create handler with nil authService (for SendCode tests) + h := handler.NewSMSHandler(nil, smsCodeSvc) + + router := gin.New() + router.POST("/api/v1/sms/send", h.SendCode) + + return h, router +} + +func TestSMSHandler_SendCode(t *testing.T) { + _, router := setupSMSHandler() + + tests := []struct { + name string + body map[string]interface{} + wantStatus int + wantCode float64 + }{ + { + name: "valid phone", + body: map[string]interface{}{"phone": "13800138000", "purpose": "login"}, + wantStatus: http.StatusOK, + wantCode: 0, + }, + { + name: "invalid phone", + body: map[string]interface{}{"phone": "invalid", "purpose": "login"}, + wantStatus: http.StatusBadRequest, // Handler returns 400 for invalid phone + wantCode: 400, + }, + { + name: "missing phone", + body: map[string]interface{}{"purpose": "login"}, + wantStatus: http.StatusBadRequest, + wantCode: 400, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + body, _ := json.Marshal(tt.body) + w := httptest.NewRecorder() + req, _ := http.NewRequest("POST", "/api/v1/sms/send", bytes.NewBuffer(body)) + req.Header.Set("Content-Type", "application/json") + router.ServeHTTP(w, req) + + assert.Equal(t, tt.wantStatus, w.Code) + + var resp map[string]interface{} + if err := json.Unmarshal(w.Body.Bytes(), &resp); err == nil { + if tt.wantCode == 0 { + assert.Equal(t, float64(0), resp["code"]) + } + } + }) + } +} + +func TestSMSHandler_SendCode_ServiceNotConfigured(t *testing.T) { + gin.SetMode(gin.TestMode) + + // Handler with nil smsCodeService + h := handler.NewSMSHandler(nil, nil) + + router := gin.New() + router.POST("/api/v1/sms/send", h.SendCode) + + body, _ := json.Marshal(map[string]interface{}{"phone": "13800138000", "purpose": "login"}) + w := httptest.NewRecorder() + req, _ := http.NewRequest("POST", "/api/v1/sms/send", bytes.NewBuffer(body)) + req.Header.Set("Content-Type", "application/json") + router.ServeHTTP(w, req) + + assert.Equal(t, http.StatusServiceUnavailable, w.Code) + + var resp map[string]interface{} + json.Unmarshal(w.Body.Bytes(), &resp) + assert.Equal(t, float64(503), resp["code"]) +}