hi-server/internal/logic/public/user/bindInviteCodeLogic_test.go

137 lines
3.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package user
import (
"context"
"testing"
"github.com/perfect-panel/server/internal/model/user"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/internal/types"
"github.com/perfect-panel/server/pkg/constant"
"github.com/perfect-panel/server/pkg/xerr"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
"gorm.io/gorm"
)
// MockUserModel 只实现 bindInviteCodeLogic 需要的方法
type MockUserModel struct {
user.Model // 为了满足接口定义,嵌入 user.Model未实现的方法会 panic
users map[int64]*user.User
}
func (m *MockUserModel) FindOneByReferCode(ctx context.Context, referCode string) (*user.User, error) {
for _, u := range m.users {
if u.ReferCode == referCode {
return u, nil
}
}
return nil, gorm.ErrRecordNotFound
}
func (m *MockUserModel) Update(ctx context.Context, data *user.User, tx ...*gorm.DB) error {
m.users[data.Id] = data
return nil
}
func TestBindInviteCodeLogic_BindInviteCode(t *testing.T) {
tests := []struct {
name string
currentUser user.User // 使用值类型,在 Run 中取地址,避免共享
initUsers map[int64]*user.User
inviteCode string
expectError bool
expectedCode uint32
expectedMsg string
}{
{
name: "成功绑定邀请码",
currentUser: user.User{Id: 1, ReferCode: "CODE1", RefererId: 0},
initUsers: map[int64]*user.User{
1: {Id: 1, ReferCode: "CODE1", RefererId: 0},
2: {Id: 2, ReferCode: "CODE2", RefererId: 0},
},
inviteCode: "CODE2",
expectError: false,
},
{
name: "邀请码不存在",
currentUser: user.User{Id: 1, ReferCode: "CODE1", RefererId: 0},
initUsers: map[int64]*user.User{
1: {Id: 1, ReferCode: "CODE1", RefererId: 0},
},
inviteCode: "INVALID",
expectError: true,
expectedCode: xerr.InviteCodeError,
expectedMsg: "无邀请码",
},
{
name: "不允许绑定自己",
currentUser: user.User{Id: 1, ReferCode: "CODE1", RefererId: 0},
initUsers: map[int64]*user.User{
1: {Id: 1, ReferCode: "CODE1", RefererId: 0},
},
inviteCode: "CODE1",
expectError: true,
expectedCode: xerr.InviteCodeError,
expectedMsg: "不允许绑定自己",
},
{
name: "用户已经绑定过",
currentUser: user.User{Id: 3, ReferCode: "CODE3", RefererId: 2},
initUsers: map[int64]*user.User{
3: {Id: 3, ReferCode: "CODE3", RefererId: 2},
2: {Id: 2, ReferCode: "CODE2", RefererId: 0},
},
inviteCode: "CODE2",
expectError: true,
expectedCode: xerr.UserExist,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// 初始化 Mock 数据
mockModel := &MockUserModel{
users: tt.initUsers,
}
svcCtx := &svc.ServiceContext{
UserModel: mockModel,
}
// 确保 User 对象在 Mock DB 中也存在Update操作需要
// 其实 MockUserModel.Update 会更新 map所以这里不需要额外操作
// 只要 initUsers 配置正确即可。
// 将当前用户注入 context (使用拷贝的指针)
u := tt.currentUser
ctx := context.WithValue(context.Background(), constant.CtxKeyUser, &u)
l := NewBindInviteCodeLogic(ctx, svcCtx)
err := l.BindInviteCode(&types.BindInviteCodeRequest{InviteCode: tt.inviteCode})
if tt.expectError {
assert.Error(t, err)
cause := errors.Cause(err)
codeErr, ok := cause.(*xerr.CodeError)
if !ok {
// handle error
} else {
assert.Equal(t, tt.expectedCode, codeErr.GetErrCode())
if tt.expectedMsg != "" {
assert.Contains(t, codeErr.GetErrMsg(), tt.expectedMsg)
}
}
if tt.expectedMsg != "" {
assert.Contains(t, err.Error(), tt.expectedMsg)
}
} else {
assert.NoError(t, err)
if tt.name == "成功绑定邀请码" {
assert.Equal(t, int64(2), mockModel.users[1].RefererId)
}
}
})
}
}