Files
user-system/internal/service/auth_contact_binding_test.go
long-agent 582ad7a069 test: add comprehensive test coverage and improve code quality
- Add new test files for auth, service, and handler modules
- Improve test organization and coverage
- Refactor code for better maintainability
- Add captcha, settings, stats, and theme handler tests
- Add auth module tests (CAS, OAuth, password, SSO, state)
- Add service layer tests for auth, export, permissions, roles
- All Go tests pass (exit code 0)
- All frontend tests pass (325 tests in 59 files)
2026-04-17 20:43:50 +08:00

433 lines
12 KiB
Go

package service_test
import (
"context"
"testing"
"github.com/user-management-system/internal/auth"
"github.com/user-management-system/internal/cache"
"github.com/user-management-system/internal/domain"
"github.com/user-management-system/internal/service"
)
// =============================================================================
// Auth Contact Binding Tests
// =============================================================================
func setupContactBindingTestEnv(t *testing.T) *authTestEnv {
t.Helper()
env := setupAuthTestEnv(t)
if env == nil {
return nil
}
// Setup email code service
l1Cache := cache.NewL1Cache()
l2Cache := cache.NewRedisCache(false)
cacheManager := cache.NewCacheManager(l1Cache, l2Cache)
emailProvider := &service.MockEmailProvider{}
emailCodeSvc := service.NewEmailCodeService(emailProvider, cacheManager, service.DefaultEmailCodeConfig())
env.authSvc.SetEmailCodeService(emailCodeSvc)
// Setup SMS code service
smsProvider := &service.MockSMSProvider{}
smsCodeSvc := service.NewSMSCodeService(smsProvider, cacheManager, service.DefaultSMSCodeConfig())
env.authSvc.SetSMSCodeService(smsCodeSvc)
return env
}
func TestAuthService_SendEmailBindCode(t *testing.T) {
env := setupContactBindingTestEnv(t)
if env == nil {
return
}
ctx := context.Background()
// Create test user
user := &domain.User{
Username: "binduser",
Password: "$2a$10$hash",
Status: domain.UserStatusActive,
}
env.userSvc.Create(ctx, user)
t.Run("Send email bind code with nil service", func(t *testing.T) {
var nilSvc *service.AuthService
err := nilSvc.SendEmailBindCode(ctx, 1, "test@test.com")
if err == nil {
t.Error("Expected error for nil service")
}
})
t.Run("Send email bind code for non-existent user", func(t *testing.T) {
err := env.authSvc.SendEmailBindCode(ctx, 9999, "test@test.com")
if err == nil {
t.Error("Expected error for non-existent user")
}
})
t.Run("Send email bind code with empty email", func(t *testing.T) {
err := env.authSvc.SendEmailBindCode(ctx, user.ID, "")
if err == nil {
t.Error("Expected error for empty email")
}
})
t.Run("Send email bind code success", func(t *testing.T) {
err := env.authSvc.SendEmailBindCode(ctx, user.ID, "newemail@test.com")
if err != nil {
t.Fatalf("SendEmailBindCode failed: %v", err)
}
})
t.Run("Send email bind code for already bound email", func(t *testing.T) {
email := "alreadybound@test.com"
userWithEmail := &domain.User{
Username: "emailbounduser",
Password: "$2a$10$hash",
Status: domain.UserStatusActive,
Email: &email,
}
env.userSvc.Create(ctx, userWithEmail)
err := env.authSvc.SendEmailBindCode(ctx, userWithEmail.ID, email)
if err == nil {
t.Error("Expected error for already bound email")
}
})
}
func TestAuthService_BindEmail(t *testing.T) {
env := setupContactBindingTestEnv(t)
if env == nil {
return
}
ctx := context.Background()
// Create test user with password
hashedPassword, _ := auth.HashPassword("Password123!")
user := &domain.User{
Username: "bindemailuser",
Password: hashedPassword,
Status: domain.UserStatusActive,
}
env.userSvc.Create(ctx, user)
t.Run("Bind email with nil service", func(t *testing.T) {
var nilSvc *service.AuthService
err := nilSvc.BindEmail(ctx, 1, "test@test.com", "code", "", "")
if err == nil {
t.Error("Expected error for nil service")
}
})
t.Run("Bind email for non-existent user", func(t *testing.T) {
err := env.authSvc.BindEmail(ctx, 9999, "test@test.com", "code", "", "")
if err == nil {
t.Error("Expected error for non-existent user")
}
})
t.Run("Bind email with empty email", func(t *testing.T) {
err := env.authSvc.BindEmail(ctx, user.ID, "", "code", "", "")
if err == nil {
t.Error("Expected error for empty email")
}
})
t.Run("Bind email with wrong password", func(t *testing.T) {
err := env.authSvc.BindEmail(ctx, user.ID, "bindemail@test.com", "123456", "wrongpassword", "")
if err == nil {
t.Error("Expected error for wrong password")
}
})
}
func TestAuthService_UnbindEmail(t *testing.T) {
env := setupContactBindingTestEnv(t)
if env == nil {
return
}
ctx := context.Background()
// Create test user with email and password
hashedPassword, _ := auth.HashPassword("Password123!")
email := "unbind@test.com"
user := &domain.User{
Username: "unbindemailuser",
Password: hashedPassword,
Status: domain.UserStatusActive,
Email: &email,
}
env.userSvc.Create(ctx, user)
t.Run("Unbind email with nil service", func(t *testing.T) {
var nilSvc *service.AuthService
err := nilSvc.UnbindEmail(ctx, 1, "", "")
if err == nil {
t.Error("Expected error for nil service")
}
})
t.Run("Unbind email for non-existent user", func(t *testing.T) {
err := env.authSvc.UnbindEmail(ctx, 9999, "", "")
if err == nil {
t.Error("Expected error for non-existent user")
}
})
t.Run("Unbind email with wrong password", func(t *testing.T) {
err := env.authSvc.UnbindEmail(ctx, user.ID, "wrongpassword", "")
if err == nil {
t.Error("Expected error for wrong password")
}
})
t.Run("Unbind email for user without email", func(t *testing.T) {
userNoEmail := &domain.User{
Username: "noemailuser",
Password: hashedPassword,
Status: domain.UserStatusActive,
}
env.userSvc.Create(ctx, userNoEmail)
err := env.authSvc.UnbindEmail(ctx, userNoEmail.ID, "Password123!", "")
if err == nil {
t.Error("Expected error for user without email")
}
})
}
func TestAuthService_SendPhoneBindCode(t *testing.T) {
env := setupContactBindingTestEnv(t)
if env == nil {
return
}
ctx := context.Background()
// Create test user
user := &domain.User{
Username: "phonebinduser",
Password: "$2a$10$hash",
Status: domain.UserStatusActive,
}
env.userSvc.Create(ctx, user)
t.Run("Send phone bind code with nil service", func(t *testing.T) {
var nilSvc *service.AuthService
_, err := nilSvc.SendPhoneBindCode(ctx, 1, "13800138000")
if err == nil {
t.Error("Expected error for nil service")
}
})
t.Run("Send phone bind code for non-existent user", func(t *testing.T) {
_, err := env.authSvc.SendPhoneBindCode(ctx, 9999, "13800138000")
if err == nil {
t.Error("Expected error for non-existent user")
}
})
t.Run("Send phone bind code with empty phone", func(t *testing.T) {
_, err := env.authSvc.SendPhoneBindCode(ctx, user.ID, "")
if err == nil {
t.Error("Expected error for empty phone")
}
})
t.Run("Send phone bind code success", func(t *testing.T) {
_, err := env.authSvc.SendPhoneBindCode(ctx, user.ID, "13800138001")
if err != nil {
t.Fatalf("SendPhoneBindCode failed: %v", err)
}
})
}
func TestAuthService_BindPhone(t *testing.T) {
env := setupContactBindingTestEnv(t)
if env == nil {
return
}
ctx := context.Background()
// Create test user with password
hashedPassword, _ := auth.HashPassword("Password123!")
user := &domain.User{
Username: "bindphoneuser",
Password: hashedPassword,
Status: domain.UserStatusActive,
}
env.userSvc.Create(ctx, user)
t.Run("Bind phone with nil service", func(t *testing.T) {
var nilSvc *service.AuthService
err := nilSvc.BindPhone(ctx, 1, "13800138000", "code", "", "")
if err == nil {
t.Error("Expected error for nil service")
}
})
t.Run("Bind phone for non-existent user", func(t *testing.T) {
err := env.authSvc.BindPhone(ctx, 9999, "13800138000", "code", "", "")
if err == nil {
t.Error("Expected error for non-existent user")
}
})
t.Run("Bind phone with empty phone", func(t *testing.T) {
err := env.authSvc.BindPhone(ctx, user.ID, "", "code", "", "")
if err == nil {
t.Error("Expected error for empty phone")
}
})
t.Run("Bind phone with wrong password", func(t *testing.T) {
err := env.authSvc.BindPhone(ctx, user.ID, "13800138002", "123456", "wrongpassword", "")
if err == nil {
t.Error("Expected error for wrong password")
}
})
}
func TestAuthService_UnbindPhone(t *testing.T) {
env := setupContactBindingTestEnv(t)
if env == nil {
return
}
ctx := context.Background()
// Create test user with phone and password
hashedPassword, _ := auth.HashPassword("Password123!")
phone := "13900139000"
user := &domain.User{
Username: "unbindphoneuser",
Password: hashedPassword,
Status: domain.UserStatusActive,
Phone: &phone,
}
env.userSvc.Create(ctx, user)
t.Run("Unbind phone with nil service", func(t *testing.T) {
var nilSvc *service.AuthService
err := nilSvc.UnbindPhone(ctx, 1, "", "")
if err == nil {
t.Error("Expected error for nil service")
}
})
t.Run("Unbind phone for non-existent user", func(t *testing.T) {
err := env.authSvc.UnbindPhone(ctx, 9999, "", "")
if err == nil {
t.Error("Expected error for non-existent user")
}
})
t.Run("Unbind phone with wrong password", func(t *testing.T) {
err := env.authSvc.UnbindPhone(ctx, user.ID, "wrongpassword", "")
if err == nil {
t.Error("Expected error for wrong password")
}
})
t.Run("Unbind phone for user without phone", func(t *testing.T) {
userNoPhone := &domain.User{
Username: "nophoneuser",
Password: hashedPassword,
Status: domain.UserStatusActive,
}
env.userSvc.Create(ctx, userNoPhone)
err := env.authSvc.UnbindPhone(ctx, userNoPhone.ID, "Password123!", "")
if err == nil {
t.Error("Expected error for user without phone")
}
})
}
// =============================================================================
// BindEmail Extended Tests
// =============================================================================
func TestAuthService_BindEmail_Extended(t *testing.T) {
env := setupContactBindingTestEnv(t)
if env == nil {
return
}
ctx := context.Background()
hashedPassword, _ := auth.HashPassword("Password123!")
t.Run("BindEmail with nil service", func(t *testing.T) {
var nilSvc *service.AuthService
err := nilSvc.BindEmail(ctx, 1, "test@example.com", "code", "password", "")
if err == nil {
t.Error("Expected error for nil service")
}
})
t.Run("BindEmail for non-existent user", func(t *testing.T) {
err := env.authSvc.BindEmail(ctx, 9999, "test@example.com", "code", "password", "")
if err == nil {
t.Error("Expected error for non-existent user")
}
})
t.Run("BindEmail with empty email", func(t *testing.T) {
user := &domain.User{
Username: "bindemailuser",
Password: hashedPassword,
Status: domain.UserStatusActive,
}
env.userSvc.Create(ctx, user)
err := env.authSvc.BindEmail(ctx, user.ID, "", "code", "Password123!", "")
if err == nil {
t.Error("Expected error for empty email")
}
})
}
// =============================================================================
// BindPhone Extended Tests
// =============================================================================
func TestAuthService_BindPhone_Extended(t *testing.T) {
env := setupContactBindingTestEnv(t)
if env == nil {
return
}
ctx := context.Background()
hashedPassword, _ := auth.HashPassword("Password123!")
t.Run("BindPhone with nil service", func(t *testing.T) {
var nilSvc *service.AuthService
err := nilSvc.BindPhone(ctx, 1, "13800138000", "code", "password", "")
if err == nil {
t.Error("Expected error for nil service")
}
})
t.Run("BindPhone for non-existent user", func(t *testing.T) {
err := env.authSvc.BindPhone(ctx, 9999, "13800138000", "code", "password", "")
if err == nil {
t.Error("Expected error for non-existent user")
}
})
t.Run("BindPhone with empty phone", func(t *testing.T) {
user := &domain.User{
Username: "bindphoneuser",
Password: hashedPassword,
Status: domain.UserStatusActive,
}
env.userSvc.Create(ctx, user)
err := env.authSvc.BindPhone(ctx, user.ID, "", "code", "Password123!", "")
if err == nil {
t.Error("Expected error for empty phone")
}
})
}