package profile import ( "context" "crypto/md5" "fmt" "testing" "github.com/youruser/base/internal/svc" "github.com/youruser/base/internal/types" "github.com/youruser/base/model" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) // Ensure imports are used var _ = svc.ServiceContext{} var _ = types.ChangePasswordRequest{} // TestChangePassword_Success 测试成功修改密码 func TestChangePassword_Success(t *testing.T) { svcCtx, cleanup := setupTestDB(t) defer cleanup() // 创建测试用户,密码为 "password" user := createTestUser(t, svcCtx.DB) // 设置上下文,包含用户ID ctx := context.WithValue(context.Background(), "userId", user.Id) // 创建 Logic 实例 logic := NewChangePasswordLogic(ctx, svcCtx) // 准备修改密码请求数据 req := &types.ChangePasswordRequest{ OldPassword: "password", NewPassword: "newpassword123", } // 执行测试 resp, err := logic.ChangePassword(req) // 验证结果 require.NoError(t, err) require.NotNil(t, resp) assert.Equal(t, 200, resp.Code) assert.Equal(t, "修改密码成功", resp.Message) // 验证数据库中的密码已更新 updatedUser, err := model.FindOne(context.Background(), svcCtx.DB, user.Id) require.NoError(t, err) newEncrypted := fmt.Sprintf("%x", md5.Sum([]byte(req.NewPassword))) assert.Equal(t, newEncrypted, updatedUser.Password) } // TestChangePassword_WrongOldPassword 测试旧密码错误 func TestChangePassword_WrongOldPassword(t *testing.T) { svcCtx, cleanup := setupTestDB(t) defer cleanup() // 创建测试用户 user := createTestUser(t, svcCtx.DB) // 设置上下文,包含用户ID ctx := context.WithValue(context.Background(), "userId", user.Id) // 创建 Logic 实例 logic := NewChangePasswordLogic(ctx, svcCtx) // 准备修改密码请求数据 - 使用错误的旧密码 req := &types.ChangePasswordRequest{ OldPassword: "wrongpassword", NewPassword: "newpassword123", } // 执行测试 resp, err := logic.ChangePassword(req) // 验证结果 require.NoError(t, err) require.NotNil(t, resp) assert.Equal(t, 400, resp.Code) assert.Equal(t, "旧密码错误", resp.Message) // 验证数据库中的密码没有改变 updatedUser, err := model.FindOne(context.Background(), svcCtx.DB, user.Id) require.NoError(t, err) assert.Equal(t, user.Password, updatedUser.Password) } // TestChangePassword_NoUserIdInContext 测试上下文中没有用户ID func TestChangePassword_NoUserIdInContext(t *testing.T) { svcCtx, cleanup := setupTestDB(t) defer cleanup() // 创建测试用户 createTestUser(t, svcCtx.DB) // 设置上下文,不包含用户ID ctx := context.Background() // 创建 Logic 实例 logic := NewChangePasswordLogic(ctx, svcCtx) // 准备修改密码请求数据 req := &types.ChangePasswordRequest{ OldPassword: "password", NewPassword: "newpassword123", } // 执行测试 resp, err := logic.ChangePassword(req) // 验证结果 - 应该返回错误 require.Error(t, err) require.Nil(t, resp) assert.Contains(t, err.Error(), "未获取到用户信息") } // TestChangePassword_InvalidUserIdType 测试用户ID类型错误 func TestChangePassword_InvalidUserIdType(t *testing.T) { svcCtx, cleanup := setupTestDB(t) defer cleanup() // 创建测试用户 createTestUser(t, svcCtx.DB) // 设置上下文,用户ID类型错误 ctx := context.WithValue(context.Background(), "userId", "invalid") // 创建 Logic 实例 logic := NewChangePasswordLogic(ctx, svcCtx) // 准备修改密码请求数据 req := &types.ChangePasswordRequest{ OldPassword: "password", NewPassword: "newpassword123", } // 执行测试 resp, err := logic.ChangePassword(req) // 验证结果 - 应该返回错误 require.Error(t, err) require.Nil(t, resp) assert.Contains(t, err.Error(), "用户ID格式错误") } // TestChangePassword_UserNotFound 测试用户不存在 func TestChangePassword_UserNotFound(t *testing.T) { svcCtx, cleanup := setupTestDB(t) defer cleanup() // 设置上下文,使用不存在的用户ID ctx := context.WithValue(context.Background(), "userId", int64(99999)) // 创建 Logic 实例 logic := NewChangePasswordLogic(ctx, svcCtx) // 准备修改密码请求数据 req := &types.ChangePasswordRequest{ OldPassword: "password", NewPassword: "newpassword123", } // 执行测试 resp, err := logic.ChangePassword(req) // 验证结果 - 应该返回错误 require.Error(t, err) require.Nil(t, resp) assert.Contains(t, err.Error(), "用户不存在") } // TestChangePassword_SamePassword 测试使用相同的新密码 func TestChangePassword_SamePassword(t *testing.T) { svcCtx, cleanup := setupTestDB(t) defer cleanup() // 创建测试用户 user := createTestUser(t, svcCtx.DB) // 设置上下文,包含用户ID ctx := context.WithValue(context.Background(), "userId", user.Id) // 创建 Logic 实例 logic := NewChangePasswordLogic(ctx, svcCtx) // 准备修改密码请求数据 - 新密码与旧密码相同 req := &types.ChangePasswordRequest{ OldPassword: "password", NewPassword: "password", } // 执行测试 - 虽然相同,但从逻辑上应该允许 resp, err := logic.ChangePassword(req) // 验证结果 require.NoError(t, err) require.NotNil(t, resp) assert.Equal(t, 200, resp.Code) // 验证密码加密后的值仍然一致 updatedUser, err := model.FindOne(context.Background(), svcCtx.DB, user.Id) require.NoError(t, err) assert.Equal(t, user.Password, updatedUser.Password) } // TestChangePassword_MultipleChanges 测试多次修改密码 func TestChangePassword_MultipleChanges(t *testing.T) { svcCtx, cleanup := setupTestDB(t) defer cleanup() // 创建测试用户 user := createTestUser(t, svcCtx.DB) // 设置上下文,包含用户ID ctx := context.WithValue(context.Background(), "userId", user.Id) passwords := []string{"password", "newpass1", "newpass2", "newpass3"} for i := 0; i < len(passwords)-1; i++ { logic := NewChangePasswordLogic(ctx, svcCtx) req := &types.ChangePasswordRequest{ OldPassword: passwords[i], NewPassword: passwords[i+1], } resp, err := logic.ChangePassword(req) require.NoError(t, err, "Failed at iteration %d", i) require.NotNil(t, resp) assert.Equal(t, 200, resp.Code) // 验证密码已更新 updatedUser, err := model.FindOne(context.Background(), svcCtx.DB, user.Id) require.NoError(t, err) expectedEncrypted := fmt.Sprintf("%x", md5.Sum([]byte(passwords[i+1]))) assert.Equal(t, expectedEncrypted, updatedUser.Password) } } // BenchmarkChangePassword 性能测试 func BenchmarkChangePassword(b *testing.B) { svcCtx, _ := setupTestDB(&testing.T{}) defer func() { sqlDB, _ := svcCtx.DB.DB() if sqlDB != nil { sqlDB.Close() } }() // 创建测试用户 user := createTestUser(&testing.T{}, svcCtx.DB) // 设置上下文,包含用户ID ctx := context.WithValue(context.Background(), "userId", user.Id) // 准备修改密码请求数据 req := &types.ChangePasswordRequest{ OldPassword: "password", NewPassword: "newpassword123", } b.ResetTimer() for i := 0; i < b.N; i++ { logic := NewChangePasswordLogic(ctx, svcCtx) _, _ = logic.ChangePassword(req) } }