app-cloudep-member-server/pkg/usecase/member_test.go

664 lines
16 KiB
Go
Raw Normal View History

2024-12-30 03:58:14 +00:00
package usecase
import (
"app-cloudep-member-server/pkg/domain"
"app-cloudep-member-server/pkg/domain/config"
"app-cloudep-member-server/pkg/domain/entity"
"app-cloudep-member-server/pkg/domain/member"
"app-cloudep-member-server/pkg/domain/usecase"
mockRepo "app-cloudep-member-server/pkg/mock/repository"
"app-cloudep-member-server/pkg/repository"
"context"
"errors"
"testing"
"code.30cm.net/digimon/library-go/errs"
"code.30cm.net/digimon/library-go/errs/code"
"github.com/stretchr/testify/assert"
"github.com/zeromicro/go-zero/core/stores/mon"
"go.uber.org/mock/gomock"
"google.golang.org/protobuf/proto"
)
func TestCreateUserAccount(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
mockAccountRepository := mockRepo.NewMockAccountRepository(mockCtrl)
uc := MustMemberUseCase(MemberUseCaseParam{
Account: mockAccountRepository,
Config: config.Config{
Bcrypt: struct{ Cost int }{Cost: 10},
},
})
tests := []struct {
name string
req usecase.CreateLoginUserRequest
mockSetup func()
expectErr bool
}{
{
name: "Successful account creation with Digimon platform",
req: usecase.CreateLoginUserRequest{
LoginID: "testuser",
Token: "plaintext-password",
Platform: member.Digimon,
},
mockSetup: func() {
mockAccountRepository.EXPECT().Insert(gomock.Any(), gomock.Any()).Return(nil)
},
expectErr: false,
},
{
name: "Password encryption failure",
req: usecase.CreateLoginUserRequest{
LoginID: "testuser",
Token: "plaintext-password",
Platform: member.Digimon,
},
mockSetup: func() {
HasPasswordFunc = func(password string, cost int) (string, error) {
return "", errors.New("encryption error")
}
},
expectErr: true,
},
{
name: "Duplicate account insertion error",
req: usecase.CreateLoginUserRequest{
LoginID: "testuser",
Token: "plaintext-password",
Platform: member.Digimon,
},
mockSetup: func() {
HasPasswordFunc = func(password string, cost int) (string, error) {
return "encrypted-password", nil
}
mockAccountRepository.EXPECT().Insert(gomock.Any(), gomock.Any()).Return(errors.New("duplicate account"))
},
expectErr: true,
},
{
name: "Successful account creation with non-Digimon platform",
req: usecase.CreateLoginUserRequest{
LoginID: "testuser",
Platform: member.Google,
},
mockSetup: func() {
mockAccountRepository.EXPECT().Insert(gomock.Any(), gomock.Any()).Return(nil)
},
expectErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.mockSetup()
err := uc.CreateUserAccount(context.Background(), tt.req)
if tt.expectErr {
assert.Error(t, err)
} else {
assert.NoError(t, err)
}
})
}
}
func TestGetUIDByAccount(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
mockAccountUIDRepo := mockRepo.NewMockAccountUIDRepository(mockCtrl)
uc := MustMemberUseCase(MemberUseCaseParam{
AccountUID: mockAccountUIDRepo,
Config: config.Config{
Bcrypt: struct{ Cost int }{Cost: 10},
},
})
tests := []struct {
name string
req usecase.GetUIDByAccountRequest
mockSetup func()
wantResp usecase.GetUIDByAccountResponse
wantErr bool
}{
{
name: "Successfully found UID by account",
req: usecase.GetUIDByAccountRequest{
Account: "testuser",
},
mockSetup: func() {
mockAccountUIDRepo.EXPECT().
FindUIDByLoginID(gomock.Any(), "testuser").
Return(&entity.AccountUID{UID: "12345"}, nil)
},
wantResp: usecase.GetUIDByAccountResponse{
UID: "12345",
Account: "testuser",
},
wantErr: false,
},
{
name: "Account not found",
req: usecase.GetUIDByAccountRequest{
Account: "notfounduser",
},
mockSetup: func() {
mockAccountUIDRepo.EXPECT().
FindUIDByLoginID(gomock.Any(), "notfounduser").
Return(nil, errs.NewError(
code.CloudEPMember,
code.CatResource,
domain.FailedFindUIDByLoginIDErrorCode,
"account not found",
))
},
wantResp: usecase.GetUIDByAccountResponse{},
wantErr: true,
},
{
name: "Database error",
req: usecase.GetUIDByAccountRequest{
Account: "erroruser",
},
mockSetup: func() {
mockAccountUIDRepo.EXPECT().
FindUIDByLoginID(gomock.Any(), "erroruser").
Return(nil, errors.New("database error"))
},
wantResp: usecase.GetUIDByAccountResponse{},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.mockSetup()
resp, err := uc.GetUIDByAccount(context.Background(), tt.req)
if tt.wantErr {
assert.Error(t, err)
} else {
assert.NoError(t, err)
assert.Equal(t, tt.wantResp, resp)
}
})
}
}
func TestGetUserAccountInfo(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
mockAccountRepo := mockRepo.NewMockAccountRepository(mockCtrl)
uc := MustMemberUseCase(MemberUseCaseParam{
Account: mockAccountRepo,
Config: config.Config{
Bcrypt: struct{ Cost int }{Cost: 10},
},
})
tests := []struct {
name string
req usecase.GetUIDByAccountRequest
mockSetup func()
expected usecase.GetAccountInfoResponse
wantErr bool
errCode string
}{
{
name: "Successfully found account",
req: usecase.GetUIDByAccountRequest{Account: "testuser"},
mockSetup: func() {
mockAccountRepo.EXPECT().
FindOneByAccount(gomock.Any(), "testuser").
Return(&entity.Account{
LoginID: "testuser",
Platform: 1,
Token: "testtoken",
}, nil)
},
expected: usecase.GetAccountInfoResponse{
Data: usecase.CreateLoginUserRequest{
LoginID: "testuser",
Platform: 1,
Token: "testtoken",
},
},
wantErr: false,
},
{
name: "Account not found",
req: usecase.GetUIDByAccountRequest{Account: "notfounduser"},
mockSetup: func() {
mockAccountRepo.EXPECT().
FindOneByAccount(gomock.Any(), "notfounduser").
Return(nil, mon.ErrNotFound)
},
expected: usecase.GetAccountInfoResponse{},
wantErr: true,
},
{
name: "Database error",
req: usecase.GetUIDByAccountRequest{Account: "erroruser"},
mockSetup: func() {
mockAccountRepo.EXPECT().
FindOneByAccount(gomock.Any(), "erroruser").
Return(nil, errors.New("database error"))
},
expected: usecase.GetAccountInfoResponse{},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.mockSetup()
resp, err := uc.GetUserAccountInfo(context.Background(), tt.req)
if tt.wantErr {
assert.Error(t, err)
} else {
assert.NoError(t, err)
assert.Equal(t, tt.expected, resp)
}
})
}
}
func TestGetUserInfo(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
mockUserRepo := mockRepo.NewMockUserRepository(mockCtrl)
uc := MustMemberUseCase(MemberUseCaseParam{
User: mockUserRepo,
Config: config.Config{
Bcrypt: struct{ Cost int }{Cost: 10},
},
})
tests := []struct {
name string
req usecase.GetUserInfoRequest
mockSetup func()
expected usecase.UserInfo
wantErr bool
errCode string
}{
{
name: "Successfully found user by UID",
req: usecase.GetUserInfoRequest{UID: "testUID"},
mockSetup: func() {
mockUserRepo.EXPECT().
FindOneByUID(gomock.Any(), "testUID").
Return(&entity.User{
UID: "testUID",
Nickname: proto.String("testNick"),
Email: proto.String("test@example.com"),
PreferredLanguage: "en",
}, nil)
},
expected: usecase.UserInfo{
CreateUserInfoRequest: usecase.CreateUserInfoRequest{
UID: "testUID",
Nickname: proto.String("testNick"),
Email: proto.String("test@example.com"),
PreferredLanguage: "en",
},
},
wantErr: false,
},
{
name: "User not found",
req: usecase.GetUserInfoRequest{UID: "nonExistentUID"},
mockSetup: func() {
mockUserRepo.EXPECT().
FindOneByUID(gomock.Any(), "nonExistentUID").
Return(nil, mon.ErrNotFound)
},
expected: usecase.UserInfo{},
wantErr: true,
},
{
name: "Database error while querying user by UID",
req: usecase.GetUserInfoRequest{UID: "errorUID"},
mockSetup: func() {
mockUserRepo.EXPECT().
FindOneByUID(gomock.Any(), "errorUID").
Return(nil, errors.New("database error"))
},
expected: usecase.UserInfo{},
wantErr: true,
},
{
name: "Successfully found user by Nickname",
req: usecase.GetUserInfoRequest{NickName: "testNick"},
mockSetup: func() {
mockUserRepo.EXPECT().
FindOneByNickName(gomock.Any(), "testNick").
Return(&entity.User{
UID: "testUID",
Nickname: proto.String("testNick"),
Email: proto.String("test@example.com"),
}, nil)
},
expected: usecase.UserInfo{
CreateUserInfoRequest: usecase.CreateUserInfoRequest{
UID: "testUID",
Nickname: proto.String("testNick"),
Email: proto.String("test@example.com"),
},
},
wantErr: false,
},
{
name: "Invalid request, no UID or Nickname",
req: usecase.GetUserInfoRequest{},
mockSetup: func() {
// No setup needed for invalid request
},
expected: usecase.UserInfo{},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.mockSetup()
resp, err := uc.GetUserInfo(context.Background(), tt.req)
if tt.wantErr {
assert.Error(t, err)
} else {
assert.NoError(t, err)
assert.Equal(t, tt.expected, resp)
}
})
}
}
func TestUpdateUserToken(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
mockAccountRepo := mockRepo.NewMockAccountRepository(mockCtrl)
uc := MustMemberUseCase(MemberUseCaseParam{
Account: mockAccountRepo,
})
HasPasswordFunc = func(password string, cost int) (string, error) {
if password == "fail" {
return "", errors.New("encryption error")
}
return "encrypted-password", nil
}
tests := []struct {
name string
req usecase.UpdateTokenRequest
mockSetup func()
wantErr bool
errCode string
}{
{
name: "Successful token update",
req: usecase.UpdateTokenRequest{Account: "testAccount", Token: "newPassword"},
mockSetup: func() {
mockAccountRepo.EXPECT().
UpdateTokenByLoginID(gomock.Any(), "testAccount", "encrypted-password").
Return(nil)
},
wantErr: false,
},
{
name: "Password encryption failure",
req: usecase.UpdateTokenRequest{Account: "testAccount", Token: "fail"},
mockSetup: func() {
// No repo call expected
},
wantErr: true,
},
{
name: "Account not found",
req: usecase.UpdateTokenRequest{Account: "nonExistentAccount", Token: "newPassword"},
mockSetup: func() {
mockAccountRepo.EXPECT().
UpdateTokenByLoginID(gomock.Any(), "nonExistentAccount", "encrypted-password").
Return(mon.ErrNotFound)
},
wantErr: true,
},
{
name: "Database error during token update",
req: usecase.UpdateTokenRequest{Account: "errorAccount", Token: "newPassword"},
mockSetup: func() {
mockAccountRepo.EXPECT().
UpdateTokenByLoginID(gomock.Any(), "errorAccount", "encrypted-password").
Return(errors.New("database error"))
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.mockSetup()
err := uc.UpdateUserToken(context.Background(), tt.req)
if tt.wantErr {
assert.Error(t, err)
} else {
assert.NoError(t, err)
}
})
}
}
func TestMemberUseCase_UpdateUserInfo(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
mockUserRepo := mockRepo.NewMockUserRepository(mockCtrl)
uc := MustMemberUseCase(MemberUseCaseParam{
User: mockUserRepo,
})
tests := []struct {
name string
req *usecase.UpdateUserInfoRequest
mockSetup func()
wantErr bool
}{
{
name: "Successful update",
req: &usecase.UpdateUserInfoRequest{
UID: "testUID",
Nickname: proto.String("UpdatedNick"),
FullName: proto.String("Updated Name"),
AvatarURL: proto.String("http://example.com/avatar.png"),
},
mockSetup: func() {
mockUserRepo.EXPECT().
UpdateUserDetailsByUID(gomock.Any(), gomock.Any()).
Return(nil)
},
wantErr: false,
},
{
name: "User not found",
req: &usecase.UpdateUserInfoRequest{
UID: "nonExistentUID",
},
mockSetup: func() {
mockUserRepo.EXPECT().
UpdateUserDetailsByUID(gomock.Any(), gomock.Any()).
Return(repository.ErrNotFound)
},
wantErr: true,
},
{
name: "Database error",
req: &usecase.UpdateUserInfoRequest{
UID: "errorUID",
},
mockSetup: func() {
mockUserRepo.EXPECT().
UpdateUserDetailsByUID(gomock.Any(), gomock.Any()).
Return(errors.New("database error"))
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.mockSetup()
err := uc.UpdateUserInfo(context.Background(), tt.req)
if tt.wantErr {
assert.Error(t, err)
} else {
assert.NoError(t, err)
}
})
}
}
func TestMemberUseCase_UpdateStatus(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
mockUserRepo := mockRepo.NewMockUserRepository(mockCtrl)
uc := MustMemberUseCase(MemberUseCaseParam{
User: mockUserRepo,
})
tests := []struct {
name string
req usecase.UpdateStatusRequest
mockSetup func()
wantErr bool
}{
{
name: "Successful status update",
req: usecase.UpdateStatusRequest{UID: "testUID", Status: member.AccountStatusActive},
mockSetup: func() {
mockUserRepo.EXPECT().
UpdateStatus(gomock.Any(), "testUID", gomock.Any()).
Return(nil)
},
wantErr: false,
},
{
name: "User not found",
req: usecase.UpdateStatusRequest{UID: "nonExistentUID", Status: member.AccountStatusActive},
mockSetup: func() {
mockUserRepo.EXPECT().
UpdateStatus(gomock.Any(), "nonExistentUID", gomock.Any()).
Return(repository.ErrNotFound)
},
wantErr: true,
},
{
name: "Database error",
req: usecase.UpdateStatusRequest{UID: "errorUID", Status: member.AccountStatusUninitialized},
mockSetup: func() {
mockUserRepo.EXPECT().
UpdateStatus(gomock.Any(), "errorUID", gomock.Any()).
Return(errors.New("database error"))
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.mockSetup()
err := uc.UpdateStatus(context.Background(), tt.req)
if tt.wantErr {
assert.Error(t, err)
} else {
assert.NoError(t, err)
}
})
}
}
func TestMemberUseCase_ListMember(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
mockUserRepo := mockRepo.NewMockUserRepository(mockCtrl)
uc := MustMemberUseCase(MemberUseCaseParam{
User: mockUserRepo,
})
tests := []struct {
name string
req usecase.ListUserInfoRequest
mockSetup func()
wantErr bool
}{
{
name: "Successful member listing",
req: usecase.ListUserInfoRequest{
PageSize: 10,
PageIndex: 1,
},
mockSetup: func() {
mockUserRepo.EXPECT().
ListMembers(gomock.Any(), gomock.Any()).
Return([]*entity.User{
{UID: "testUID1"},
{UID: "testUID2"},
}, int64(2), nil)
},
wantErr: false,
},
{
name: "Database error",
req: usecase.ListUserInfoRequest{
PageSize: 10,
PageIndex: 1,
},
mockSetup: func() {
mockUserRepo.EXPECT().
ListMembers(gomock.Any(), gomock.Any()).
Return(nil, int64(0), errors.New("database error"))
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.mockSetup()
resp, err := uc.ListMember(context.Background(), tt.req)
if tt.wantErr {
assert.Error(t, err)
assert.Empty(t, resp.Data)
} else {
assert.NoError(t, err)
assert.NotEmpty(t, resp.Data)
}
})
}
}