[feature/backend] registration control
This commit is contained in:
parent
86ab334bc9
commit
a853374009
5 changed files with 142 additions and 49 deletions
|
@ -33,6 +33,15 @@ func (s *AuthHandlerTestSuite) SetupTest() {
|
|||
JWT: config.JWTConfig{
|
||||
Secret: "test-secret",
|
||||
},
|
||||
Auth: config.AuthConfig{
|
||||
Registration: struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
Message string `yaml:"message"`
|
||||
}{
|
||||
Enabled: true,
|
||||
Message: "Registration is disabled",
|
||||
},
|
||||
},
|
||||
}, s.service)
|
||||
s.router = gin.New()
|
||||
}
|
||||
|
@ -45,6 +54,13 @@ func TestAuthHandlerSuite(t *testing.T) {
|
|||
suite.Run(t, new(AuthHandlerTestSuite))
|
||||
}
|
||||
|
||||
type ErrorResponse struct {
|
||||
Error struct {
|
||||
Code string `json:"code"`
|
||||
Message string `json:"message"`
|
||||
} `json:"error"`
|
||||
}
|
||||
|
||||
func (s *AuthHandlerTestSuite) TestRegister() {
|
||||
testCases := []struct {
|
||||
name string
|
||||
|
@ -52,6 +68,7 @@ func (s *AuthHandlerTestSuite) TestRegister() {
|
|||
setupMock func()
|
||||
expectedStatus int
|
||||
expectedError string
|
||||
registration bool
|
||||
}{
|
||||
{
|
||||
name: "成功注册",
|
||||
|
@ -74,6 +91,20 @@ func (s *AuthHandlerTestSuite) TestRegister() {
|
|||
Return([]*ent.Role{{ID: 1, Name: "contributor"}}, nil)
|
||||
},
|
||||
expectedStatus: http.StatusCreated,
|
||||
registration: true,
|
||||
},
|
||||
{
|
||||
name: "注册功能已禁用",
|
||||
request: RegisterRequest{
|
||||
Username: "testuser",
|
||||
Email: "test@example.com",
|
||||
Password: "password123",
|
||||
Role: "contributor",
|
||||
},
|
||||
setupMock: func() {},
|
||||
expectedStatus: http.StatusForbidden,
|
||||
expectedError: "Registration is disabled",
|
||||
registration: false,
|
||||
},
|
||||
{
|
||||
name: "无效的邮箱格式",
|
||||
|
@ -86,6 +117,7 @@ func (s *AuthHandlerTestSuite) TestRegister() {
|
|||
setupMock: func() {},
|
||||
expectedStatus: http.StatusBadRequest,
|
||||
expectedError: "Key: 'RegisterRequest.Email' Error:Field validation for 'Email' failed on the 'email' tag",
|
||||
registration: true,
|
||||
},
|
||||
{
|
||||
name: "密码太短",
|
||||
|
@ -98,6 +130,7 @@ func (s *AuthHandlerTestSuite) TestRegister() {
|
|||
setupMock: func() {},
|
||||
expectedStatus: http.StatusBadRequest,
|
||||
expectedError: "Key: 'RegisterRequest.Password' Error:Field validation for 'Password' failed on the 'min' tag",
|
||||
registration: true,
|
||||
},
|
||||
{
|
||||
name: "无效的角色",
|
||||
|
@ -110,11 +143,15 @@ func (s *AuthHandlerTestSuite) TestRegister() {
|
|||
setupMock: func() {},
|
||||
expectedStatus: http.StatusBadRequest,
|
||||
expectedError: "Key: 'RegisterRequest.Role' Error:Field validation for 'Role' failed on the 'oneof' tag",
|
||||
registration: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
s.Run(tc.name, func() {
|
||||
// 设置注册功能状态
|
||||
s.handler.config.Auth.Registration.Enabled = tc.registration
|
||||
|
||||
// 设置 mock
|
||||
tc.setupMock()
|
||||
|
||||
|
@ -132,10 +169,10 @@ func (s *AuthHandlerTestSuite) TestRegister() {
|
|||
// 验证响应
|
||||
s.Equal(tc.expectedStatus, w.Code)
|
||||
if tc.expectedError != "" {
|
||||
var response map[string]string
|
||||
var response ErrorResponse
|
||||
err := json.Unmarshal(w.Body.Bytes(), &response)
|
||||
s.NoError(err)
|
||||
s.Contains(response["error"], tc.expectedError)
|
||||
s.Contains(response.Error.Message, tc.expectedError)
|
||||
} else {
|
||||
var response AuthResponse
|
||||
err := json.Unmarshal(w.Body.Bytes(), &response)
|
||||
|
@ -147,6 +184,8 @@ func (s *AuthHandlerTestSuite) TestRegister() {
|
|||
}
|
||||
|
||||
func (s *AuthHandlerTestSuite) TestLogin() {
|
||||
hashedPassword, _ := bcrypt.GenerateFromPassword([]byte("password123"), bcrypt.DefaultCost)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
request LoginRequest
|
||||
|
@ -161,35 +200,28 @@ func (s *AuthHandlerTestSuite) TestLogin() {
|
|||
Password: "password123",
|
||||
},
|
||||
setupMock: func() {
|
||||
// 使用 bcrypt 生成正确的密码哈希
|
||||
hashedPassword, _ := bcrypt.GenerateFromPassword([]byte("password123"), bcrypt.DefaultCost)
|
||||
user := &ent.User{
|
||||
ID: 1,
|
||||
Username: "testuser",
|
||||
PasswordHash: string(hashedPassword),
|
||||
}
|
||||
s.service.EXPECT().
|
||||
GetUserByUsername(gomock.Any(), "testuser").
|
||||
Return(user, nil)
|
||||
Return(&ent.User{
|
||||
ID: 1,
|
||||
Username: "testuser",
|
||||
PasswordHash: string(hashedPassword),
|
||||
}, nil)
|
||||
s.service.EXPECT().
|
||||
GetUserRoles(gomock.Any(), user.ID).
|
||||
Return([]*ent.Role{{Name: "admin"}}, nil)
|
||||
GetUserRoles(gomock.Any(), 1).
|
||||
Return([]*ent.Role{{ID: 1, Name: "contributor"}}, nil)
|
||||
},
|
||||
expectedStatus: http.StatusOK,
|
||||
},
|
||||
{
|
||||
name: "无效的用户名",
|
||||
request: LoginRequest{
|
||||
Username: "invalid",
|
||||
Username: "te",
|
||||
Password: "password123",
|
||||
},
|
||||
setupMock: func() {
|
||||
s.service.EXPECT().
|
||||
GetUserByUsername(gomock.Any(), "invalid").
|
||||
Return(nil, fmt.Errorf("user not found"))
|
||||
},
|
||||
expectedStatus: http.StatusUnauthorized,
|
||||
expectedError: "Invalid username or password",
|
||||
setupMock: func() {},
|
||||
expectedStatus: http.StatusBadRequest,
|
||||
expectedError: "Key: 'LoginRequest.Username' Error:Field validation for 'Username' failed on the 'min' tag",
|
||||
},
|
||||
{
|
||||
name: "用户不存在",
|
||||
|
@ -209,19 +241,16 @@ func (s *AuthHandlerTestSuite) TestLogin() {
|
|||
name: "密码错误",
|
||||
request: LoginRequest{
|
||||
Username: "testuser",
|
||||
Password: "wrong-password",
|
||||
Password: "wrongpassword",
|
||||
},
|
||||
setupMock: func() {
|
||||
// 使用 bcrypt 生成正确的密码哈希
|
||||
hashedPassword, _ := bcrypt.GenerateFromPassword([]byte("password123"), bcrypt.DefaultCost)
|
||||
user := &ent.User{
|
||||
ID: 1,
|
||||
Username: "testuser",
|
||||
PasswordHash: string(hashedPassword),
|
||||
}
|
||||
s.service.EXPECT().
|
||||
GetUserByUsername(gomock.Any(), "testuser").
|
||||
Return(user, nil)
|
||||
Return(&ent.User{
|
||||
ID: 1,
|
||||
Username: "testuser",
|
||||
PasswordHash: string(hashedPassword),
|
||||
}, nil)
|
||||
},
|
||||
expectedStatus: http.StatusUnauthorized,
|
||||
expectedError: "Invalid username or password",
|
||||
|
@ -233,18 +262,15 @@ func (s *AuthHandlerTestSuite) TestLogin() {
|
|||
Password: "password123",
|
||||
},
|
||||
setupMock: func() {
|
||||
// 使用 bcrypt 生成正确的密码哈希
|
||||
hashedPassword, _ := bcrypt.GenerateFromPassword([]byte("password123"), bcrypt.DefaultCost)
|
||||
user := &ent.User{
|
||||
ID: 1,
|
||||
Username: "testuser",
|
||||
PasswordHash: string(hashedPassword),
|
||||
}
|
||||
s.service.EXPECT().
|
||||
GetUserByUsername(gomock.Any(), "testuser").
|
||||
Return(user, nil)
|
||||
Return(&ent.User{
|
||||
ID: 1,
|
||||
Username: "testuser",
|
||||
PasswordHash: string(hashedPassword),
|
||||
}, nil)
|
||||
s.service.EXPECT().
|
||||
GetUserRoles(gomock.Any(), user.ID).
|
||||
GetUserRoles(gomock.Any(), 1).
|
||||
Return(nil, fmt.Errorf("failed to get roles"))
|
||||
},
|
||||
expectedStatus: http.StatusInternalServerError,
|
||||
|
@ -271,10 +297,10 @@ func (s *AuthHandlerTestSuite) TestLogin() {
|
|||
// 验证响应
|
||||
s.Equal(tc.expectedStatus, w.Code)
|
||||
if tc.expectedError != "" {
|
||||
var response map[string]string
|
||||
var response ErrorResponse
|
||||
err := json.Unmarshal(w.Body.Bytes(), &response)
|
||||
s.NoError(err)
|
||||
s.Contains(response["error"], tc.expectedError)
|
||||
s.Contains(response.Error.Message, tc.expectedError)
|
||||
} else {
|
||||
var response AuthResponse
|
||||
err := json.Unmarshal(w.Body.Bytes(), &response)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue