backend/pkg/permission/usecase/role_usecase_test.go

412 lines
10 KiB
Go

package usecase
import (
"backend/pkg/permission/domain"
"backend/pkg/permission/domain/entity"
"backend/pkg/permission/domain/usecase"
mockRepo "backend/pkg/permission/mock/repository"
mockUC "backend/pkg/permission/mock/usecase"
"context"
"errors"
"testing"
"github.com/stretchr/testify/assert"
"go.mongodb.org/mongo-driver/v2/bson"
"go.uber.org/mock/gomock"
)
func stringPtr(s string) *string {
return &s
}
func TestRoleUseCase_Create(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
mockRoleRepo := mockRepo.NewMockRoleRepository(mockCtrl)
mockUserRoleRepo := mockRepo.NewMockUserRoleRepository(mockCtrl)
mockRolePermUC := mockUC.NewMockRolePermissionUseCase(mockCtrl)
uc := NewRoleUseCase(RoleUseCaseParam{
RoleRepo: mockRoleRepo,
UserRoleRepo: mockUserRoleRepo,
RolePermUseCase: mockRolePermUC,
})
ctx := context.Background()
tests := []struct {
name string
req usecase.CreateRoleRequest
mockSetup func()
wantErr bool
}{
{
name: "成功創建角色",
req: usecase.CreateRoleRequest{
ClientID: 1,
Name: "管理員",
},
mockSetup: func() {
mockRoleRepo.EXPECT().NextID(ctx).Return(int64(1), nil)
mockRoleRepo.EXPECT().Create(ctx, gomock.Any()).Return(nil)
role := &entity.Role{
ID: bson.NewObjectID(),
UID: "ROLE0000000001",
ClientID: 1,
Name: "管理員",
Status: domain.RecordActive,
}
mockRoleRepo.EXPECT().GetByUID(ctx, gomock.Any()).Return(role, nil)
mockRolePermUC.EXPECT().GetByRoleUID(ctx, gomock.Any()).Return(nil, nil)
},
wantErr: false,
},
{
name: "NextID 失敗",
req: usecase.CreateRoleRequest{
ClientID: 1,
Name: "管理員",
},
mockSetup: func() {
mockRoleRepo.EXPECT().NextID(ctx).Return(int64(0), errors.New("db error"))
},
wantErr: true,
},
{
name: "Create 失敗",
req: usecase.CreateRoleRequest{
ClientID: 1,
Name: "管理員",
},
mockSetup: func() {
mockRoleRepo.EXPECT().NextID(ctx).Return(int64(1), nil)
mockRoleRepo.EXPECT().Create(ctx, gomock.Any()).Return(errors.New("db error"))
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.mockSetup()
result, err := uc.Create(ctx, tt.req)
if tt.wantErr {
assert.Error(t, err)
assert.Nil(t, result)
} else {
assert.NoError(t, err)
assert.NotNil(t, result)
}
})
}
}
func TestRoleUseCase_Update(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
mockRoleRepo := mockRepo.NewMockRoleRepository(mockCtrl)
mockUserRoleRepo := mockRepo.NewMockUserRoleRepository(mockCtrl)
mockRolePermUC := mockUC.NewMockRolePermissionUseCase(mockCtrl)
uc := NewRoleUseCase(RoleUseCaseParam{
RoleRepo: mockRoleRepo,
UserRoleRepo: mockUserRoleRepo,
RolePermUseCase: mockRolePermUC,
})
ctx := context.Background()
tests := []struct {
name string
uid string
req usecase.UpdateRoleRequest
mockSetup func()
wantErr bool
}{
{
name: "成功更新角色",
uid: "ROLE0000000001",
req: usecase.UpdateRoleRequest{
Name: stringPtr("新管理員"),
},
mockSetup: func() {
role := &entity.Role{
ID: bson.NewObjectID(),
UID: "ROLE0000000001",
ClientID: 1,
Name: "管理員",
Status: domain.RecordActive,
}
mockRoleRepo.EXPECT().GetByUID(ctx, "ROLE0000000001").Return(role, nil)
mockRoleRepo.EXPECT().Update(ctx, gomock.Any()).Return(nil)
mockRoleRepo.EXPECT().GetByUID(ctx, "ROLE0000000001").Return(role, nil)
mockRolePermUC.EXPECT().GetByRoleUID(ctx, "ROLE0000000001").Return(nil, nil)
},
wantErr: false,
},
{
name: "角色不存在",
uid: "ROLE9999999999",
req: usecase.UpdateRoleRequest{
Name: stringPtr("新管理員"),
},
mockSetup: func() {
mockRoleRepo.EXPECT().GetByUID(ctx, "ROLE9999999999").Return(nil, errors.New("not found"))
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.mockSetup()
result, err := uc.Update(ctx, tt.uid, tt.req)
if tt.wantErr {
assert.Error(t, err)
assert.Nil(t, result)
} else {
assert.NoError(t, err)
assert.NotNil(t, result)
}
})
}
}
func TestRoleUseCase_Delete(t *testing.T) {
ctx := context.Background()
tests := []struct {
name string
uid string
mockSetup func(*mockRepo.MockRoleRepository, *mockRepo.MockUserRoleRepository)
wantErr bool
}{
{
name: "成功刪除角色",
uid: "ROLE0000000001",
mockSetup: func(mockRoleRepo *mockRepo.MockRoleRepository, mockUserRoleRepo *mockRepo.MockUserRoleRepository) {
role := &entity.Role{
ID: bson.NewObjectID(),
UID: "ROLE0000000001",
ClientID: 1,
Name: "管理員",
Status: domain.RecordActive,
}
mockRoleRepo.EXPECT().GetByUID(ctx, "ROLE0000000001").Return(role, nil)
mockUserRoleRepo.EXPECT().GetByRoleID(ctx, "ROLE0000000001").Return([]*entity.UserRole{}, nil)
mockRoleRepo.EXPECT().Delete(ctx, "ROLE0000000001").Return(nil)
},
wantErr: false,
},
{
name: "角色不存在",
uid: "ROLE9999999999",
mockSetup: func(mockRoleRepo *mockRepo.MockRoleRepository, mockUserRoleRepo *mockRepo.MockUserRoleRepository) {
mockRoleRepo.EXPECT().GetByUID(ctx, "ROLE9999999999").Return(nil, errors.New("not found"))
},
wantErr: true,
},
{
name: "角色正在使用中",
uid: "ROLE0000000001",
mockSetup: func(mockRoleRepo *mockRepo.MockRoleRepository, mockUserRoleRepo *mockRepo.MockUserRoleRepository) {
role := &entity.Role{
ID: bson.NewObjectID(),
UID: "ROLE0000000001",
ClientID: 1,
Name: "管理員",
Status: domain.RecordActive,
}
mockRoleRepo.EXPECT().GetByUID(ctx, "ROLE0000000001").Return(role, nil)
mockUserRoleRepo.EXPECT().GetByRoleID(ctx, "ROLE0000000001").Return([]*entity.UserRole{
{UID: "user1"},
{UID: "user2"},
}, nil)
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// 為每個測試案例創建新的 mock controller 和 usecase 實例
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
mockRoleRepo := mockRepo.NewMockRoleRepository(mockCtrl)
mockUserRoleRepo := mockRepo.NewMockUserRoleRepository(mockCtrl)
mockRolePermUC := mockUC.NewMockRolePermissionUseCase(mockCtrl)
tt.mockSetup(mockRoleRepo, mockUserRoleRepo)
uc := NewRoleUseCase(RoleUseCaseParam{
RoleRepo: mockRoleRepo,
UserRoleRepo: mockUserRoleRepo,
RolePermUseCase: mockRolePermUC,
})
err := uc.Delete(ctx, tt.uid)
if tt.wantErr {
assert.Error(t, err)
} else {
assert.NoError(t, err)
}
})
}
}
func TestRoleUseCase_Get(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
mockRoleRepo := mockRepo.NewMockRoleRepository(mockCtrl)
mockUserRoleRepo := mockRepo.NewMockUserRoleRepository(mockCtrl)
mockRolePermUC := mockUC.NewMockRolePermissionUseCase(mockCtrl)
uc := NewRoleUseCase(RoleUseCaseParam{
RoleRepo: mockRoleRepo,
UserRoleRepo: mockUserRoleRepo,
RolePermUseCase: mockRolePermUC,
})
ctx := context.Background()
tests := []struct {
name string
uid string
mockSetup func()
wantNil bool
wantErr bool
}{
{
name: "成功獲取角色",
uid: "ROLE0000000001",
mockSetup: func() {
role := &entity.Role{
ID: bson.NewObjectID(),
UID: "ROLE0000000001",
ClientID: 1,
Name: "管理員",
Status: domain.RecordActive,
}
mockRoleRepo.EXPECT().GetByUID(ctx, "ROLE0000000001").Return(role, nil)
mockRolePermUC.EXPECT().GetByRoleUID(ctx, "ROLE0000000001").Return(nil, nil)
},
wantNil: false,
wantErr: false,
},
{
name: "角色不存在",
uid: "ROLE9999999999",
mockSetup: func() {
mockRoleRepo.EXPECT().GetByUID(ctx, "ROLE9999999999").Return(nil, errors.New("not found"))
},
wantNil: true,
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.mockSetup()
result, err := uc.Get(ctx, tt.uid)
if tt.wantErr {
assert.Error(t, err)
} else {
assert.NoError(t, err)
}
if tt.wantNil {
assert.Nil(t, result)
} else {
assert.NotNil(t, result)
}
})
}
}
func TestRoleUseCase_List(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
mockRoleRepo := mockRepo.NewMockRoleRepository(mockCtrl)
mockUserRoleRepo := mockRepo.NewMockUserRoleRepository(mockCtrl)
mockRolePermUC := mockUC.NewMockRolePermissionUseCase(mockCtrl)
uc := NewRoleUseCase(RoleUseCaseParam{
RoleRepo: mockRoleRepo,
UserRoleRepo: mockUserRoleRepo,
RolePermUseCase: mockRolePermUC,
})
ctx := context.Background()
tests := []struct {
name string
filter usecase.RoleFilterRequest
mockSetup func()
wantCount int
wantErr bool
}{
{
name: "成功列出所有角色",
filter: usecase.RoleFilterRequest{
ClientID: 1,
},
mockSetup: func() {
roles := []*entity.Role{
{ID: bson.NewObjectID(), UID: "ROLE0000000001", Name: "管理員", Status: domain.RecordActive},
{ID: bson.NewObjectID(), UID: "ROLE0000000002", Name: "用戶", Status: domain.RecordActive},
}
mockRoleRepo.EXPECT().List(ctx, gomock.Any()).Return(roles, nil)
mockRolePermUC.EXPECT().GetByRoleUID(ctx, gomock.Any()).Return(nil, nil).Times(2)
},
wantCount: 2,
wantErr: false,
},
{
name: "沒有角色",
filter: usecase.RoleFilterRequest{
ClientID: 999,
},
mockSetup: func() {
mockRoleRepo.EXPECT().List(ctx, gomock.Any()).Return([]*entity.Role{}, nil)
},
wantCount: 0,
wantErr: false,
},
{
name: "Repository 錯誤",
filter: usecase.RoleFilterRequest{
ClientID: 1,
},
mockSetup: func() {
mockRoleRepo.EXPECT().List(ctx, gomock.Any()).Return(nil, errors.New("db error"))
},
wantCount: 0,
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.mockSetup()
result, err := uc.List(ctx, tt.filter)
if tt.wantErr {
assert.Error(t, err)
} else {
assert.NoError(t, err)
assert.Len(t, result, tt.wantCount)
}
})
}
}