package handler import ( "bytes" "encoding/json" "net/http" "net/http/httptest" "testing" "github.com/gin-gonic/gin" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/wangjia/jiu/backend/internal/service" "github.com/wangjia/jiu/backend/testutil" ) func init() { gin.SetMode(gin.TestMode) testutil.InitConfig() } func newTestAuthRouter(t *testing.T) (*gin.Engine, *gin.Engine) { db := testutil.SetupTestDB() hotel := testutil.CreateTestHotel(db, "AUTHTEST") testutil.CreateTestUser(db, hotel.ID, "admin", "password123", "admin") testutil.CreateTestUser(db, hotel.ID, "disabled", "password123", "operator") // 禁用该用户 db.Exec("UPDATE users SET is_active = 0 WHERE username = 'disabled' AND hotel_id = ?", hotel.ID) svc := service.NewAuthService(db) h := NewAuthHandler(svc) r := gin.New() r.POST("/api/v1/auth/login", h.Login) r.POST("/api/v1/auth/refresh", h.Refresh) return r, nil } func TestAuthHandler_Login_Success(t *testing.T) { db := testutil.SetupTestDB() hotel := testutil.CreateTestHotel(db, "AH001") testutil.CreateTestUser(db, hotel.ID, "admin", "password123", "admin") svc := service.NewAuthService(db) h := NewAuthHandler(svc) r := gin.New() r.POST("/api/v1/auth/login", h.Login) body := map[string]string{ "hotel_code": "AH001", "username": "admin", "password": "password123", } bodyBytes, _ := json.Marshal(body) w := httptest.NewRecorder() req, _ := http.NewRequest("POST", "/api/v1/auth/login", bytes.NewBuffer(bodyBytes)) req.Header.Set("Content-Type", "application/json") r.ServeHTTP(w, req) assert.Equal(t, http.StatusOK, w.Code) var resp map[string]interface{} require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp)) data := resp["data"].(map[string]interface{}) assert.NotEmpty(t, data["access_token"]) assert.NotEmpty(t, data["refresh_token"]) } func TestAuthHandler_Login_WrongPassword(t *testing.T) { db := testutil.SetupTestDB() hotel := testutil.CreateTestHotel(db, "AH002") testutil.CreateTestUser(db, hotel.ID, "admin", "password123", "admin") svc := service.NewAuthService(db) h := NewAuthHandler(svc) r := gin.New() r.POST("/api/v1/auth/login", h.Login) body := map[string]string{ "hotel_code": "AH002", "username": "admin", "password": "wrongpassword", } bodyBytes, _ := json.Marshal(body) w := httptest.NewRecorder() req, _ := http.NewRequest("POST", "/api/v1/auth/login", bytes.NewBuffer(bodyBytes)) req.Header.Set("Content-Type", "application/json") r.ServeHTTP(w, req) assert.Equal(t, http.StatusUnauthorized, w.Code) } func TestAuthHandler_Login_MissingFields(t *testing.T) { db := testutil.SetupTestDB() svc := service.NewAuthService(db) h := NewAuthHandler(svc) r := gin.New() r.POST("/api/v1/auth/login", h.Login) // 缺少必填字段 body := map[string]string{ "hotel_code": "AH003", } bodyBytes, _ := json.Marshal(body) w := httptest.NewRecorder() req, _ := http.NewRequest("POST", "/api/v1/auth/login", bytes.NewBuffer(bodyBytes)) req.Header.Set("Content-Type", "application/json") r.ServeHTTP(w, req) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestAuthHandler_Refresh_Success(t *testing.T) { db := testutil.SetupTestDB() hotel := testutil.CreateTestHotel(db, "AH004") testutil.CreateTestUser(db, hotel.ID, "admin", "password123", "admin") svc := service.NewAuthService(db) h := NewAuthHandler(svc) r := gin.New() r.POST("/api/v1/auth/login", h.Login) r.POST("/api/v1/auth/refresh", h.Refresh) // 先登录获取 token loginBody := map[string]string{ "hotel_code": "AH004", "username": "admin", "password": "password123", } loginBytes, _ := json.Marshal(loginBody) w := httptest.NewRecorder() req, _ := http.NewRequest("POST", "/api/v1/auth/login", bytes.NewBuffer(loginBytes)) req.Header.Set("Content-Type", "application/json") r.ServeHTTP(w, req) var loginResp map[string]interface{} json.Unmarshal(w.Body.Bytes(), &loginResp) data := loginResp["data"].(map[string]interface{}) refreshToken := data["refresh_token"].(string) // 刷新 token refreshBody := map[string]string{"refresh_token": refreshToken} refreshBytes, _ := json.Marshal(refreshBody) w2 := httptest.NewRecorder() req2, _ := http.NewRequest("POST", "/api/v1/auth/refresh", bytes.NewBuffer(refreshBytes)) req2.Header.Set("Content-Type", "application/json") r.ServeHTTP(w2, req2) assert.Equal(t, http.StatusOK, w2.Code) var resp map[string]interface{} json.Unmarshal(w2.Body.Bytes(), &resp) newData := resp["data"].(map[string]interface{}) assert.NotEmpty(t, newData["access_token"]) } func TestAuthHandler_Refresh_InvalidToken(t *testing.T) { db := testutil.SetupTestDB() svc := service.NewAuthService(db) h := NewAuthHandler(svc) r := gin.New() r.POST("/api/v1/auth/refresh", h.Refresh) body := map[string]string{"refresh_token": "invalid.token.here"} bodyBytes, _ := json.Marshal(body) w := httptest.NewRecorder() req, _ := http.NewRequest("POST", "/api/v1/auth/refresh", bytes.NewBuffer(bodyBytes)) req.Header.Set("Content-Type", "application/json") r.ServeHTTP(w, req) assert.Equal(t, http.StatusUnauthorized, w.Code) }