feat: Enhance dependency injection and service integration
- Updated main.go to initialize email service and include it in the dependency injection container. - Refactored handlers to utilize context in service method calls, improving consistency and error handling. - Introduced new service options for upload, security, and captcha services, enhancing modularity and testability. - Removed unused repository implementations to streamline the codebase. This commit continues the effort to improve the architecture by ensuring all services are properly injected and utilized across the application.
This commit is contained in:
@@ -3,6 +3,7 @@ package service
|
||||
import (
|
||||
"carrotskin/internal/model"
|
||||
"carrotskin/pkg/auth"
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"go.uber.org/zap"
|
||||
@@ -16,8 +17,11 @@ func TestUserServiceImpl_Register(t *testing.T) {
|
||||
logger := zap.NewNop()
|
||||
|
||||
// 初始化Service
|
||||
// 注意:redisClient 传入 nil,因为 Register 方法中没有使用 redis
|
||||
userService := NewUserService(userRepo, configRepo, jwtService, nil, logger)
|
||||
// 注意:redisClient 和 cacheManager 传入 nil,因为 Register 方法中没有使用它们
|
||||
cacheManager := NewMockCacheManager()
|
||||
userService := NewUserService(userRepo, configRepo, jwtService, nil, cacheManager, logger)
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
// 测试用例
|
||||
tests := []struct {
|
||||
@@ -77,7 +81,7 @@ func TestUserServiceImpl_Register(t *testing.T) {
|
||||
tt.setupMocks()
|
||||
}
|
||||
|
||||
user, token, err := userService.Register(tt.username, tt.password, tt.email, tt.avatar)
|
||||
user, token, err := userService.Register(ctx, tt.username, tt.password, tt.email, tt.avatar)
|
||||
|
||||
if tt.wantErr {
|
||||
if err == nil {
|
||||
@@ -124,7 +128,10 @@ func TestUserServiceImpl_Login(t *testing.T) {
|
||||
}
|
||||
userRepo.Create(testUser)
|
||||
|
||||
userService := NewUserService(userRepo, configRepo, jwtService, nil, logger)
|
||||
cacheManager := NewMockCacheManager()
|
||||
userService := NewUserService(userRepo, configRepo, jwtService, nil, cacheManager, logger)
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -163,7 +170,7 @@ func TestUserServiceImpl_Login(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
user, token, err := userService.Login(tt.usernameOrEmail, tt.password, "127.0.0.1", "test-agent")
|
||||
user, token, err := userService.Login(ctx, tt.usernameOrEmail, tt.password, "127.0.0.1", "test-agent")
|
||||
|
||||
if tt.wantErr {
|
||||
if err == nil {
|
||||
@@ -202,23 +209,26 @@ func TestUserServiceImpl_BasicGettersAndUpdates(t *testing.T) {
|
||||
}
|
||||
userRepo.Create(user)
|
||||
|
||||
userService := NewUserService(userRepo, configRepo, jwtService, nil, logger)
|
||||
cacheManager := NewMockCacheManager()
|
||||
userService := NewUserService(userRepo, configRepo, jwtService, nil, cacheManager, logger)
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
// GetByID
|
||||
gotByID, err := userService.GetByID(1)
|
||||
gotByID, err := userService.GetByID(ctx, 1)
|
||||
if err != nil || gotByID == nil || gotByID.ID != 1 {
|
||||
t.Fatalf("GetByID 返回不正确: user=%+v, err=%v", gotByID, err)
|
||||
}
|
||||
|
||||
// GetByEmail
|
||||
gotByEmail, err := userService.GetByEmail("basic@example.com")
|
||||
gotByEmail, err := userService.GetByEmail(ctx, "basic@example.com")
|
||||
if err != nil || gotByEmail == nil || gotByEmail.Email != "basic@example.com" {
|
||||
t.Fatalf("GetByEmail 返回不正确: user=%+v, err=%v", gotByEmail, err)
|
||||
}
|
||||
|
||||
// UpdateInfo
|
||||
user.Username = "updated"
|
||||
if err := userService.UpdateInfo(user); err != nil {
|
||||
if err := userService.UpdateInfo(ctx, user); err != nil {
|
||||
t.Fatalf("UpdateInfo 失败: %v", err)
|
||||
}
|
||||
updated, _ := userRepo.FindByID(1)
|
||||
@@ -227,7 +237,7 @@ func TestUserServiceImpl_BasicGettersAndUpdates(t *testing.T) {
|
||||
}
|
||||
|
||||
// UpdateAvatar 只需确认不会返回错误(具体字段更新由仓库层保证)
|
||||
if err := userService.UpdateAvatar(1, "http://example.com/avatar.png"); err != nil {
|
||||
if err := userService.UpdateAvatar(ctx, 1, "http://example.com/avatar.png"); err != nil {
|
||||
t.Fatalf("UpdateAvatar 失败: %v", err)
|
||||
}
|
||||
}
|
||||
@@ -247,20 +257,23 @@ func TestUserServiceImpl_ChangePassword(t *testing.T) {
|
||||
}
|
||||
userRepo.Create(user)
|
||||
|
||||
userService := NewUserService(userRepo, configRepo, jwtService, nil, logger)
|
||||
cacheManager := NewMockCacheManager()
|
||||
userService := NewUserService(userRepo, configRepo, jwtService, nil, cacheManager, logger)
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
// 原密码正确
|
||||
if err := userService.ChangePassword(1, "oldpass", "newpass"); err != nil {
|
||||
if err := userService.ChangePassword(ctx, 1, "oldpass", "newpass"); err != nil {
|
||||
t.Fatalf("ChangePassword 正常情况失败: %v", err)
|
||||
}
|
||||
|
||||
// 用户不存在
|
||||
if err := userService.ChangePassword(999, "oldpass", "newpass"); err == nil {
|
||||
if err := userService.ChangePassword(ctx, 999, "oldpass", "newpass"); err == nil {
|
||||
t.Fatalf("ChangePassword 应在用户不存在时返回错误")
|
||||
}
|
||||
|
||||
// 原密码错误
|
||||
if err := userService.ChangePassword(1, "wrong", "another"); err == nil {
|
||||
if err := userService.ChangePassword(ctx, 1, "wrong", "another"); err == nil {
|
||||
t.Fatalf("ChangePassword 应在原密码错误时返回错误")
|
||||
}
|
||||
}
|
||||
@@ -279,15 +292,18 @@ func TestUserServiceImpl_ResetPassword(t *testing.T) {
|
||||
}
|
||||
userRepo.Create(user)
|
||||
|
||||
userService := NewUserService(userRepo, configRepo, jwtService, nil, logger)
|
||||
cacheManager := NewMockCacheManager()
|
||||
userService := NewUserService(userRepo, configRepo, jwtService, nil, cacheManager, logger)
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
// 正常重置
|
||||
if err := userService.ResetPassword("reset@example.com", "newpass"); err != nil {
|
||||
if err := userService.ResetPassword(ctx, "reset@example.com", "newpass"); err != nil {
|
||||
t.Fatalf("ResetPassword 正常情况失败: %v", err)
|
||||
}
|
||||
|
||||
// 用户不存在
|
||||
if err := userService.ResetPassword("notfound@example.com", "newpass"); err == nil {
|
||||
if err := userService.ResetPassword(ctx, "notfound@example.com", "newpass"); err == nil {
|
||||
t.Fatalf("ResetPassword 应在用户不存在时返回错误")
|
||||
}
|
||||
}
|
||||
@@ -304,15 +320,18 @@ func TestUserServiceImpl_ChangeEmail(t *testing.T) {
|
||||
userRepo.Create(user1)
|
||||
userRepo.Create(user2)
|
||||
|
||||
userService := NewUserService(userRepo, configRepo, jwtService, nil, logger)
|
||||
cacheManager := NewMockCacheManager()
|
||||
userService := NewUserService(userRepo, configRepo, jwtService, nil, cacheManager, logger)
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
// 正常修改
|
||||
if err := userService.ChangeEmail(1, "new@example.com"); err != nil {
|
||||
if err := userService.ChangeEmail(ctx, 1, "new@example.com"); err != nil {
|
||||
t.Fatalf("ChangeEmail 正常情况失败: %v", err)
|
||||
}
|
||||
|
||||
// 邮箱被其他用户占用
|
||||
if err := userService.ChangeEmail(1, "user2@example.com"); err == nil {
|
||||
if err := userService.ChangeEmail(ctx, 1, "user2@example.com"); err == nil {
|
||||
t.Fatalf("ChangeEmail 应在邮箱被占用时返回错误")
|
||||
}
|
||||
}
|
||||
@@ -324,7 +343,10 @@ func TestUserServiceImpl_ValidateAvatarURL(t *testing.T) {
|
||||
jwtService := auth.NewJWTService("secret", 1)
|
||||
logger := zap.NewNop()
|
||||
|
||||
userService := NewUserService(userRepo, configRepo, jwtService, nil, logger)
|
||||
cacheManager := NewMockCacheManager()
|
||||
userService := NewUserService(userRepo, configRepo, jwtService, nil, cacheManager, logger)
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -341,7 +363,7 @@ func TestUserServiceImpl_ValidateAvatarURL(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := userService.ValidateAvatarURL(tt.url)
|
||||
err := userService.ValidateAvatarURL(ctx, tt.url)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Fatalf("ValidateAvatarURL(%q) error = %v, wantErr=%v", tt.url, err, tt.wantErr)
|
||||
}
|
||||
@@ -357,7 +379,8 @@ func TestUserServiceImpl_MaxLimits(t *testing.T) {
|
||||
logger := zap.NewNop()
|
||||
|
||||
// 未配置时走默认值
|
||||
userService := NewUserService(userRepo, configRepo, jwtService, nil, logger)
|
||||
cacheManager := NewMockCacheManager()
|
||||
userService := NewUserService(userRepo, configRepo, jwtService, nil, cacheManager, logger)
|
||||
if got := userService.GetMaxProfilesPerUser(); got != 5 {
|
||||
t.Fatalf("GetMaxProfilesPerUser 默认值错误, got=%d", got)
|
||||
}
|
||||
@@ -375,4 +398,4 @@ func TestUserServiceImpl_MaxLimits(t *testing.T) {
|
||||
if got := userService.GetMaxTexturesPerUser(); got != 100 {
|
||||
t.Fatalf("GetMaxTexturesPerUser 配置值错误, got=%d", got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user