You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

179 lines
5.4 KiB

package auth_test
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"testing"
"time"
"task-track-backend/internal/config"
"task-track-backend/internal/router"
"task-track-backend/pkg/database"
)
func TestAuthUserFullFlow(t *testing.T) {
cfg := config.Load()
db, err := database.Init(cfg.Database)
if err != nil {
t.Fatalf("数据库连接失败: %v", err)
}
r := router.Setup(db)
username := "testuser_api"
password := "testpass123"
email := "testuser_api@example.com"
var userID uint
var token string
// 注册前彻底物理删除测试用户,避免唯一索引冲突
db.Unscoped().Exec("DELETE FROM users WHERE username = ?", username)
// 1. 先尝试通过用户名查找用户(用 /api/users?username=xxx 更优,但此项目无此接口,只能用 /api/users + 遍历或注册后获取)
// 先尝试登录,能登录说明用户存在
loginBody := map[string]interface{}{
"username": username,
"password": password,
}
loginJSON, _ := json.Marshal(loginBody)
w := httptest.NewRecorder()
req, _ := http.NewRequest("POST", "/api/auth/login", bytes.NewReader(loginJSON))
req.Header.Set("Content-Type", "application/json")
r.ServeHTTP(w, req)
if w.Code == 200 {
// 登录成功,用户已存在
var loginResp struct {
Data struct {
Token string `json:"token"`
User struct {
ID uint `json:"id"`
} `json:"user"`
} `json:"data"`
}
_ = json.Unmarshal(w.Body.Bytes(), &loginResp)
token = loginResp.Data.Token
userID = loginResp.Data.User.ID
// update_user
updateBody := map[string]interface{}{
"real_name": "API测试用户",
"email": "updated_" + email,
}
updateJSON, _ := json.Marshal(updateBody)
w2 := httptest.NewRecorder()
req2, _ := http.NewRequest("POST", fmt.Sprintf("/api/users/update/%d", userID), bytes.NewReader(updateJSON))
req2.Header.Set("Content-Type", "application/json")
req2.Header.Set("Authorization", "Bearer "+token)
r.ServeHTTP(w2, req2)
if w2.Code != 200 {
t.Fatalf("update_user 失败: %d, %s", w2.Code, w2.Body.String())
}
// delete_user
w3 := httptest.NewRecorder()
req3, _ := http.NewRequest("POST", fmt.Sprintf("/api/users/delete/%d", userID), nil)
req3.Header.Set("Authorization", "Bearer "+token)
r.ServeHTTP(w3, req3)
if w3.Code != 200 {
t.Fatalf("delete_user 失败: %d, %s", w3.Code, w3.Body.String())
}
}
// 2. 注册用户
registerBody := map[string]interface{}{
"username": username,
"password": password,
"email": email,
}
registerJSON, _ := json.Marshal(registerBody)
w = httptest.NewRecorder()
req, _ = http.NewRequest("POST", "/api/auth/register", bytes.NewReader(registerJSON))
req.Header.Set("Content-Type", "application/json")
r.ServeHTTP(w, req)
if w.Code != 201 {
t.Fatalf("注册用户失败,状态码: %d, 响应: %s", w.Code, w.Body.String())
}
// 注册后调试:输出数据库密码字段
var dbUser struct{ Password string }
db.Raw("SELECT password FROM users WHERE username = ?", username).Scan(&dbUser)
t.Logf("注册后数据库密码字段: %s", dbUser.Password)
// 避免极端情况下事务未提交,sleep 100ms
time.Sleep(100 * time.Millisecond)
// 3. 登录
t.Logf("登录请求体: %+v", loginBody)
loginJSON, _ = json.Marshal(loginBody)
w = httptest.NewRecorder()
req, _ = http.NewRequest("POST", "/api/auth/login", bytes.NewReader(loginJSON))
req.Header.Set("Content-Type", "application/json")
r.ServeHTTP(w, req)
if w.Code != 200 {
t.Fatalf("用户登录失败,状态码: %d, 响应: %s", w.Code, w.Body.String())
}
var loginResp struct {
Data struct {
Token string `json:"token"`
User struct {
ID uint `json:"id"`
} `json:"user"`
} `json:"data"`
}
_ = json.Unmarshal(w.Body.Bytes(), &loginResp)
token = loginResp.Data.Token
userID = loginResp.Data.User.ID
// 4. 获取我的信息
w = httptest.NewRecorder()
req, _ = http.NewRequest("GET", "/api/auth/me", nil)
req.Header.Set("Authorization", "Bearer "+token)
r.ServeHTTP(w, req)
if w.Code != 200 {
t.Fatalf("获取我的信息失败,状态码: %d, 响应: %s", w.Code, w.Body.String())
}
// 5. 用户登出
w = httptest.NewRecorder()
req, _ = http.NewRequest("POST", "/api/auth/logout", nil)
req.Header.Set("Authorization", "Bearer "+token)
r.ServeHTTP(w, req)
if w.Code != 200 {
t.Fatalf("用户登出失败,状态码: %d, 响应: %s", w.Code, w.Body.String())
}
// 6. update_user
updateBody := map[string]interface{}{
"real_name": "API测试用户2",
"email": "updated2_" + email,
}
updateJSON, _ := json.Marshal(updateBody)
w = httptest.NewRecorder()
req, _ = http.NewRequest("POST", fmt.Sprintf("/api/users/update/%d", userID), bytes.NewReader(updateJSON))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer "+token)
r.ServeHTTP(w, req)
if w.Code != 200 {
t.Fatalf("update_user 失败: %d, %s", w.Code, w.Body.String())
}
// 7. get_user
w = httptest.NewRecorder()
req, _ = http.NewRequest("GET", fmt.Sprintf("/api/users/%d", userID), nil)
req.Header.Set("Authorization", "Bearer "+token)
r.ServeHTTP(w, req)
if w.Code != 200 {
t.Fatalf("get_user 失败: %d, %s", w.Code, w.Body.String())
}
// 8. delete_user
w = httptest.NewRecorder()
req, _ = http.NewRequest("POST", fmt.Sprintf("/api/users/delete/%d", userID), nil)
req.Header.Set("Authorization", "Bearer "+token)
r.ServeHTTP(w, req)
if w.Code != 200 {
t.Fatalf("delete_user 失败: %d, %s", w.Code, w.Body.String())
}
}