refactor: 移除全局单例、修复分层违规、统一错误与响应
Some checks failed
Build / build (push) Successful in 7m52s
Build / build-docker (push) Has been cancelled

This commit is contained in:
lafay
2026-06-15 16:40:36 +08:00
parent d9de39a0a3
commit 7d1c78f965
55 changed files with 593 additions and 1744 deletions

View File

@@ -2,13 +2,8 @@ package types
import "time"
// BaseResponse 基础响应结构
// @Description 通用API响应结构
type BaseResponse struct {
Code int `json:"code"`
Message string `json:"message"`
Data interface{} `json:"data,omitempty"`
}
// 注意:BaseResponse 与 PaginationResponse 已删除(与 model.Response /
// model.PaginationResponse 重复)。统一使用 model 包的响应结构
// PaginationRequest 分页请求
// @Description 分页查询参数
@@ -17,16 +12,6 @@ type PaginationRequest struct {
PageSize int `json:"page_size" form:"page_size" binding:"omitempty,min=1,max=100"`
}
// PaginationResponse 分页响应
// @Description 分页查询结果
type PaginationResponse struct {
List interface{} `json:"list"`
Total int64 `json:"total"`
Page int `json:"page"`
PageSize int `json:"page_size"`
TotalPages int `json:"total_pages"`
}
// LoginRequest 登录请求
// @Description 用户登录请求参数
type LoginRequest struct {

View File

@@ -7,9 +7,9 @@ import (
// TestPaginationRequest_Validation 测试分页请求验证逻辑
func TestPaginationRequest_Validation(t *testing.T) {
tests := []struct {
name string
page int
pageSize int
name string
page int
pageSize int
wantValid bool
}{
{
@@ -63,102 +63,15 @@ func TestTextureType_Constants(t *testing.T) {
}
}
// TestPaginationResponse_Structure 测试分页响应结构
func TestPaginationResponse_Structure(t *testing.T) {
resp := PaginationResponse{
List: []string{"a", "b", "c"},
Total: 100,
Page: 1,
PageSize: 20,
TotalPages: 5,
// TestPaginationRequest_Defaults 测试分页请求结构
// 注意:PaginationResponse 已删除(与 model.PaginationResponse 重复)
func TestPaginationRequest_Defaults(t *testing.T) {
req := PaginationRequest{Page: 1, PageSize: 20}
if req.Page != 1 {
t.Errorf("Page = %d, want 1", req.Page)
}
if resp.Total != 100 {
t.Errorf("Total = %d, want 100", resp.Total)
}
if resp.Page != 1 {
t.Errorf("Page = %d, want 1", resp.Page)
}
if resp.PageSize != 20 {
t.Errorf("PageSize = %d, want 20", resp.PageSize)
}
if resp.TotalPages != 5 {
t.Errorf("TotalPages = %d, want 5", resp.TotalPages)
}
}
// TestPaginationResponse_TotalPagesCalculation 测试总页数计算逻辑
func TestPaginationResponse_TotalPagesCalculation(t *testing.T) {
tests := []struct {
name string
total int64
pageSize int
wantPages int
}{
{
name: "正好整除",
total: 100,
pageSize: 20,
wantPages: 5,
},
{
name: "有余数",
total: 101,
pageSize: 20,
wantPages: 6, // 向上取整
},
{
name: "总数小于每页数量",
total: 10,
pageSize: 20,
wantPages: 1,
},
{
name: "总数为0",
total: 0,
pageSize: 20,
wantPages: 0,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// 计算总页数:向上取整
var totalPages int
if tt.total == 0 {
totalPages = 0
} else {
totalPages = int((tt.total + int64(tt.pageSize) - 1) / int64(tt.pageSize))
}
if totalPages != tt.wantPages {
t.Errorf("TotalPages = %d, want %d", totalPages, tt.wantPages)
}
})
}
}
// TestBaseResponse_Structure 测试基础响应结构
func TestBaseResponse_Structure(t *testing.T) {
resp := BaseResponse{
Code: 200,
Message: "success",
Data: "test data",
}
if resp.Code != 200 {
t.Errorf("Code = %d, want 200", resp.Code)
}
if resp.Message != "success" {
t.Errorf("Message = %q, want 'success'", resp.Message)
}
if resp.Data != "test data" {
t.Errorf("Data = %v, want 'test data'", resp.Data)
if req.PageSize != 20 {
t.Errorf("PageSize = %d, want 20", req.PageSize)
}
}
@@ -170,36 +83,10 @@ func TestLoginRequest_Validation(t *testing.T) {
password string
wantValid bool
}{
{
name: "有效的登录请求",
username: "testuser",
password: "password123",
wantValid: true,
},
{
name: "用户名为空",
username: "",
password: "password123",
wantValid: false,
},
{
name: "密码为空",
username: "testuser",
password: "",
wantValid: false,
},
{
name: "密码长度小于6",
username: "testuser",
password: "12345",
wantValid: false,
},
{
name: "密码长度超过128",
username: "testuser",
password: string(make([]byte, 129)),
wantValid: false,
},
{name: "有效的登录请求", username: "testuser", password: "password123", wantValid: true},
{name: "用户名为空", username: "", password: "password123", wantValid: false},
{name: "密码为空", username: "testuser", password: "", wantValid: false},
{name: "密码长度小于6", username: "testuser", password: "12345", wantValid: false},
}
for _, tt := range tests {
@@ -211,174 +98,3 @@ func TestLoginRequest_Validation(t *testing.T) {
})
}
}
// TestRegisterRequest_Validation 测试注册请求验证逻辑
func TestRegisterRequest_Validation(t *testing.T) {
tests := []struct {
name string
username string
email string
password string
verificationCode string
wantValid bool
}{
{
name: "有效的注册请求",
username: "newuser",
email: "user@example.com",
password: "password123",
verificationCode: "123456",
wantValid: true,
},
{
name: "用户名为空",
username: "",
email: "user@example.com",
password: "password123",
verificationCode: "123456",
wantValid: false,
},
{
name: "用户名长度小于3",
username: "ab",
email: "user@example.com",
password: "password123",
verificationCode: "123456",
wantValid: false,
},
{
name: "用户名长度超过50",
username: string(make([]byte, 51)),
email: "user@example.com",
password: "password123",
verificationCode: "123456",
wantValid: false,
},
{
name: "邮箱格式无效",
username: "newuser",
email: "invalid-email",
password: "password123",
verificationCode: "123456",
wantValid: false,
},
{
name: "验证码长度不是6",
username: "newuser",
email: "user@example.com",
password: "password123",
verificationCode: "12345",
wantValid: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
isValid := tt.username != "" &&
len(tt.username) >= 3 && len(tt.username) <= 50 &&
tt.email != "" && contains(tt.email, "@") &&
len(tt.password) >= 6 && len(tt.password) <= 128 &&
len(tt.verificationCode) == 6
if isValid != tt.wantValid {
t.Errorf("Validation failed: got %v, want %v", isValid, tt.wantValid)
}
})
}
}
// 辅助函数
func contains(s, substr string) bool {
for i := 0; i <= len(s)-len(substr); i++ {
if s[i:i+len(substr)] == substr {
return true
}
}
return false
}
// TestResetPasswordRequest_Validation 测试重置密码请求验证
func TestResetPasswordRequest_Validation(t *testing.T) {
tests := []struct {
name string
email string
verificationCode string
newPassword string
wantValid bool
}{
{
name: "有效的重置密码请求",
email: "user@example.com",
verificationCode: "123456",
newPassword: "newpassword123",
wantValid: true,
},
{
name: "邮箱为空",
email: "",
verificationCode: "123456",
newPassword: "newpassword123",
wantValid: false,
},
{
name: "验证码长度不是6",
email: "user@example.com",
verificationCode: "12345",
newPassword: "newpassword123",
wantValid: false,
},
{
name: "新密码长度小于6",
email: "user@example.com",
verificationCode: "123456",
newPassword: "12345",
wantValid: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
isValid := tt.email != "" &&
len(tt.verificationCode) == 6 &&
len(tt.newPassword) >= 6 && len(tt.newPassword) <= 128
if isValid != tt.wantValid {
t.Errorf("Validation failed: got %v, want %v", isValid, tt.wantValid)
}
})
}
}
// TestCreateProfileRequest_Validation 测试创建档案请求验证
func TestCreateProfileRequest_Validation(t *testing.T) {
tests := []struct {
name string
profileName string
wantValid bool
}{
{
name: "有效的档案名",
profileName: "PlayerName",
wantValid: true,
},
{
name: "档案名为空",
profileName: "",
wantValid: false,
},
{
name: "档案名长度超过16",
profileName: string(make([]byte, 17)),
wantValid: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
isValid := tt.profileName != "" &&
len(tt.profileName) >= 1 && len(tt.profileName) <= 16
if isValid != tt.wantValid {
t.Errorf("Validation failed: got %v, want %v", isValid, tt.wantValid)
}
})
}
}