546 lines
12 KiB
Go
546 lines
12 KiB
Go
package repository
|
|
|
|
import (
|
|
"backend/pkg/permission/domain"
|
|
"backend/pkg/permission/domain/entity"
|
|
domainRepo "backend/pkg/permission/domain/repository"
|
|
"context"
|
|
"fmt"
|
|
"github.com/alicebob/miniredis/v2"
|
|
"github.com/zeromicro/go-zero/core/stores/redis"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"github.com/zeromicro/go-zero/core/stores/cache"
|
|
"go.mongodb.org/mongo-driver/v2/bson"
|
|
|
|
mgo "backend/pkg/library/mongo"
|
|
)
|
|
|
|
func setupUserRoleRepo(db string) (domainRepo.UserRoleRepository, func(), error) {
|
|
h, p, tearDown, err := startMongoContainer()
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
s, _ := miniredis.Run()
|
|
|
|
conf := &mgo.Conf{
|
|
Schema: mongoSchema,
|
|
Host: fmt.Sprintf("%s:%s", h, p),
|
|
Database: db,
|
|
MaxStaleness: 300,
|
|
MaxPoolSize: 100,
|
|
MinPoolSize: 100,
|
|
MaxConnIdleTime: 300,
|
|
Compressors: []string{},
|
|
EnableStandardReadWriteSplitMode: false,
|
|
ConnectTimeoutMs: 3000,
|
|
}
|
|
|
|
cacheConf := cache.CacheConf{
|
|
cache.NodeConf{
|
|
RedisConf: redis.RedisConf{
|
|
Host: s.Addr(),
|
|
Type: redis.NodeType,
|
|
},
|
|
Weight: 100,
|
|
},
|
|
}
|
|
|
|
cacheOpts := []cache.Option{
|
|
cache.WithExpiry(1000 * time.Microsecond),
|
|
cache.WithNotFoundExpiry(1000 * time.Microsecond),
|
|
}
|
|
|
|
param := UserRoleRepositoryParam{
|
|
Conf: conf,
|
|
CacheConf: cacheConf,
|
|
CacheOpts: cacheOpts,
|
|
}
|
|
repo := NewUserRoleRepository(param)
|
|
_, _ = repo.Index20251009004UP(context.Background())
|
|
|
|
return repo, tearDown, nil
|
|
}
|
|
|
|
func TestUserRoleRepository_CreateAndGet(t *testing.T) {
|
|
repo, tearDown, err := setupUserRoleRepo("testDB")
|
|
defer tearDown()
|
|
assert.NoError(t, err)
|
|
|
|
ctx := context.Background()
|
|
|
|
tests := []struct {
|
|
name string
|
|
userRole *entity.UserRole
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "成功創建使用者角色",
|
|
userRole: &entity.UserRole{
|
|
ID: bson.NewObjectID(),
|
|
Brand: "brand1",
|
|
UID: "user123",
|
|
RoleID: "ROLE0000000001",
|
|
Status: domain.RecordActive,
|
|
},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "創建另一個使用者角色",
|
|
userRole: &entity.UserRole{
|
|
ID: bson.NewObjectID(),
|
|
Brand: "brand2",
|
|
UID: "user456",
|
|
RoleID: "ROLE0000000002",
|
|
Status: domain.RecordActive,
|
|
},
|
|
wantErr: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
err := repo.Create(ctx, tt.userRole)
|
|
|
|
if tt.wantErr {
|
|
assert.Error(t, err)
|
|
} else {
|
|
assert.NoError(t, err)
|
|
|
|
// 驗證可以找到創建的使用者角色
|
|
retrieved, err := repo.Get(ctx, tt.userRole.UID)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, tt.userRole.UID, retrieved.UID)
|
|
assert.Equal(t, tt.userRole.RoleID, retrieved.RoleID)
|
|
assert.Equal(t, tt.userRole.Brand, retrieved.Brand)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestUserRoleRepository_Get(t *testing.T) {
|
|
repo, tearDown, err := setupUserRoleRepo("testDB")
|
|
defer tearDown()
|
|
assert.NoError(t, err)
|
|
|
|
ctx := context.Background()
|
|
|
|
// 準備測試數據
|
|
testUserRole := &entity.UserRole{
|
|
ID: bson.NewObjectID(),
|
|
Brand: "brand1",
|
|
UID: "user123",
|
|
RoleID: "ROLE0000000001",
|
|
Status: domain.RecordActive,
|
|
}
|
|
err = repo.Create(ctx, testUserRole)
|
|
require.NoError(t, err)
|
|
|
|
tests := []struct {
|
|
name string
|
|
uid string
|
|
wantErr error
|
|
check func(*testing.T, *entity.UserRole)
|
|
}{
|
|
{
|
|
name: "找到存在的使用者角色",
|
|
uid: "user123",
|
|
wantErr: nil,
|
|
check: func(t *testing.T, ur *entity.UserRole) {
|
|
assert.Equal(t, "ROLE0000000001", ur.RoleID)
|
|
assert.Equal(t, "brand1", ur.Brand)
|
|
},
|
|
},
|
|
{
|
|
name: "不存在的使用者",
|
|
uid: "user999",
|
|
wantErr: ErrNotFound,
|
|
check: nil,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
ur, err := repo.Get(ctx, tt.uid)
|
|
|
|
if tt.wantErr != nil {
|
|
assert.ErrorIs(t, err, tt.wantErr)
|
|
assert.Nil(t, ur)
|
|
} else {
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, ur)
|
|
if tt.check != nil {
|
|
tt.check(t, ur)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestUserRoleRepository_Update(t *testing.T) {
|
|
repo, tearDown, err := setupUserRoleRepo("testDB")
|
|
defer tearDown()
|
|
assert.NoError(t, err)
|
|
ctx := context.Background()
|
|
|
|
// 準備測試數據
|
|
testUserRole := &entity.UserRole{
|
|
ID: bson.NewObjectID(),
|
|
Brand: "brand1",
|
|
UID: "user123",
|
|
RoleID: "ROLE0000000001",
|
|
Status: domain.RecordActive,
|
|
}
|
|
err = repo.Create(ctx, testUserRole)
|
|
require.NoError(t, err)
|
|
|
|
tests := []struct {
|
|
name string
|
|
uid string
|
|
newRoleID string
|
|
wantErr error
|
|
check func(*testing.T, *entity.UserRole)
|
|
}{
|
|
{
|
|
name: "成功更新角色",
|
|
uid: "user123",
|
|
newRoleID: "ROLE0000000002",
|
|
wantErr: nil,
|
|
check: func(t *testing.T, ur *entity.UserRole) {
|
|
assert.Equal(t, "ROLE0000000002", ur.RoleID)
|
|
},
|
|
},
|
|
{
|
|
name: "更新不存在的使用者",
|
|
uid: "user999",
|
|
newRoleID: "ROLE0000000003",
|
|
wantErr: ErrNotFound,
|
|
check: nil,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
ur, err := repo.Update(ctx, tt.uid, tt.newRoleID)
|
|
|
|
if tt.wantErr != nil {
|
|
assert.ErrorIs(t, err, tt.wantErr)
|
|
assert.Nil(t, ur)
|
|
} else {
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, ur)
|
|
if tt.check != nil {
|
|
tt.check(t, ur)
|
|
}
|
|
|
|
// 驗證更新
|
|
retrieved, err := repo.Get(ctx, tt.uid)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, tt.newRoleID, retrieved.RoleID)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestUserRoleRepository_Delete(t *testing.T) {
|
|
repo, tearDown, err := setupUserRoleRepo("testDB")
|
|
defer tearDown()
|
|
assert.NoError(t, err)
|
|
|
|
ctx := context.Background()
|
|
|
|
// 準備測試數據
|
|
testUserRole := &entity.UserRole{
|
|
ID: bson.NewObjectID(),
|
|
Brand: "brand1",
|
|
UID: "user123",
|
|
RoleID: "ROLE0000000001",
|
|
Status: domain.RecordActive,
|
|
}
|
|
err = repo.Create(ctx, testUserRole)
|
|
require.NoError(t, err)
|
|
|
|
t.Run("刪除使用者角色", func(t *testing.T) {
|
|
err := repo.Delete(ctx, testUserRole.UID)
|
|
assert.NoError(t, err)
|
|
|
|
// 驗證已被刪除
|
|
_, err = repo.Get(ctx, testUserRole.UID)
|
|
assert.ErrorIs(t, err, ErrNotFound)
|
|
})
|
|
|
|
t.Run("刪除不存在的使用者", func(t *testing.T) {
|
|
err := repo.Delete(ctx, "user999")
|
|
assert.NoError(t, err) // 刪除不存在的記錄不應該報錯
|
|
})
|
|
}
|
|
|
|
func TestUserRoleRepository_GetByRoleID(t *testing.T) {
|
|
repo, tearDown, err := setupUserRoleRepo("testDB")
|
|
defer tearDown()
|
|
assert.NoError(t, err)
|
|
|
|
ctx := context.Background()
|
|
|
|
// 準備測試數據
|
|
testUserRoles := []*entity.UserRole{
|
|
{
|
|
ID: bson.NewObjectID(),
|
|
Brand: "brand1",
|
|
UID: "user1",
|
|
RoleID: "ROLE0000000001",
|
|
Status: domain.RecordActive,
|
|
},
|
|
{
|
|
ID: bson.NewObjectID(),
|
|
Brand: "brand1",
|
|
UID: "user2",
|
|
RoleID: "ROLE0000000001",
|
|
Status: domain.RecordActive,
|
|
},
|
|
{
|
|
ID: bson.NewObjectID(),
|
|
Brand: "brand2",
|
|
UID: "user3",
|
|
RoleID: "ROLE0000000002",
|
|
Status: domain.RecordActive,
|
|
},
|
|
}
|
|
|
|
for _, ur := range testUserRoles {
|
|
err := repo.Create(ctx, ur)
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
roleID string
|
|
wantCount int
|
|
}{
|
|
{
|
|
name: "找到多個使用者",
|
|
roleID: "ROLE0000000001",
|
|
wantCount: 2,
|
|
},
|
|
{
|
|
name: "找到單一使用者",
|
|
roleID: "ROLE0000000002",
|
|
wantCount: 1,
|
|
},
|
|
{
|
|
name: "不存在的角色",
|
|
roleID: "ROLE9999999999",
|
|
wantCount: 0,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
userRoles, err := repo.GetByRoleID(ctx, tt.roleID)
|
|
|
|
assert.NoError(t, err)
|
|
assert.Len(t, userRoles, tt.wantCount)
|
|
|
|
for _, ur := range userRoles {
|
|
assert.Equal(t, tt.roleID, ur.RoleID)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestUserRoleRepository_List(t *testing.T) {
|
|
repo, tearDown, err := setupUserRoleRepo("testDB")
|
|
defer tearDown()
|
|
assert.NoError(t, err)
|
|
ctx := context.Background()
|
|
|
|
// 準備測試數據
|
|
testUserRoles := []*entity.UserRole{
|
|
{
|
|
ID: bson.NewObjectID(),
|
|
Brand: "brand1",
|
|
UID: "user1",
|
|
RoleID: "ROLE0000000001",
|
|
Status: domain.RecordActive,
|
|
},
|
|
{
|
|
ID: bson.NewObjectID(),
|
|
Brand: "brand1",
|
|
UID: "user2",
|
|
RoleID: "ROLE0000000002",
|
|
Status: domain.RecordActive,
|
|
},
|
|
{
|
|
ID: bson.NewObjectID(),
|
|
Brand: "brand2",
|
|
UID: "user3",
|
|
RoleID: "ROLE0000000001",
|
|
Status: domain.RecordInactive,
|
|
},
|
|
}
|
|
|
|
for _, ur := range testUserRoles {
|
|
err := repo.Create(ctx, ur)
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
filter domainRepo.UserRoleFilter
|
|
wantCount int
|
|
}{
|
|
{
|
|
name: "列出所有使用者角色",
|
|
filter: domainRepo.UserRoleFilter{},
|
|
wantCount: 3,
|
|
},
|
|
{
|
|
name: "按 Brand 過濾",
|
|
filter: domainRepo.UserRoleFilter{
|
|
Brand: "brand1",
|
|
},
|
|
wantCount: 2,
|
|
},
|
|
{
|
|
name: "按 RoleID 過濾",
|
|
filter: domainRepo.UserRoleFilter{
|
|
RoleID: "ROLE0000000001",
|
|
},
|
|
wantCount: 2,
|
|
},
|
|
{
|
|
name: "組合過濾",
|
|
filter: domainRepo.UserRoleFilter{
|
|
Brand: "brand1",
|
|
RoleID: "ROLE0000000001",
|
|
},
|
|
wantCount: 1,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
userRoles, err := repo.List(ctx, tt.filter)
|
|
|
|
assert.NoError(t, err)
|
|
assert.Len(t, userRoles, tt.wantCount)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestUserRoleRepository_CountByRoleID(t *testing.T) {
|
|
repo, tearDown, err := setupUserRoleRepo("testDB")
|
|
defer tearDown()
|
|
assert.NoError(t, err)
|
|
|
|
ctx := context.Background()
|
|
|
|
// 準備測試數據
|
|
testUserRoles := []*entity.UserRole{
|
|
{ID: bson.NewObjectID(), Brand: "brand1", UID: "user1", RoleID: "ROLE0000000001", Status: domain.RecordActive},
|
|
{ID: bson.NewObjectID(), Brand: "brand1", UID: "user2", RoleID: "ROLE0000000001", Status: domain.RecordActive},
|
|
{ID: bson.NewObjectID(), Brand: "brand1", UID: "user3", RoleID: "ROLE0000000001", Status: domain.RecordActive},
|
|
{ID: bson.NewObjectID(), Brand: "brand2", UID: "user4", RoleID: "ROLE0000000002", Status: domain.RecordActive},
|
|
{ID: bson.NewObjectID(), Brand: "brand2", UID: "user5", RoleID: "ROLE0000000002", Status: domain.RecordActive},
|
|
}
|
|
|
|
for _, ur := range testUserRoles {
|
|
err := repo.Create(ctx, ur)
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
roleIDs []string
|
|
wantCount map[string]int
|
|
}{
|
|
{
|
|
name: "統計多個角色",
|
|
roleIDs: []string{"ROLE0000000001", "ROLE0000000002"},
|
|
wantCount: map[string]int{
|
|
"ROLE0000000001": 3,
|
|
"ROLE0000000002": 2,
|
|
},
|
|
},
|
|
{
|
|
name: "統計單一角色",
|
|
roleIDs: []string{"ROLE0000000001"},
|
|
wantCount: map[string]int{
|
|
"ROLE0000000001": 3,
|
|
},
|
|
},
|
|
{
|
|
name: "統計不存在的角色",
|
|
roleIDs: []string{"ROLE9999999999"},
|
|
wantCount: map[string]int{
|
|
"ROLE9999999999": 0,
|
|
},
|
|
},
|
|
{
|
|
name: "混合存在和不存在的角色",
|
|
roleIDs: []string{"ROLE0000000001", "ROLE9999999999"},
|
|
wantCount: map[string]int{
|
|
"ROLE0000000001": 3,
|
|
"ROLE9999999999": 0,
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
counts, err := repo.CountByRoleID(ctx, tt.roleIDs)
|
|
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, tt.wantCount, counts)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestUserRoleRepository_Exists(t *testing.T) {
|
|
repo, tearDown, err := setupUserRoleRepo("testDB")
|
|
defer tearDown()
|
|
assert.NoError(t, err)
|
|
|
|
ctx := context.Background()
|
|
|
|
// 準備測試數據
|
|
testUserRole := &entity.UserRole{
|
|
ID: bson.NewObjectID(),
|
|
Brand: "brand1",
|
|
UID: "user123",
|
|
RoleID: "ROLE0000000001",
|
|
Status: domain.RecordActive,
|
|
}
|
|
err = repo.Create(ctx, testUserRole)
|
|
require.NoError(t, err)
|
|
|
|
tests := []struct {
|
|
name string
|
|
uid string
|
|
exists bool
|
|
}{
|
|
{
|
|
name: "存在的使用者角色",
|
|
uid: "user123",
|
|
exists: true,
|
|
},
|
|
{
|
|
name: "不存在的使用者",
|
|
uid: "user999",
|
|
exists: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
exists, err := repo.Exists(ctx, tt.uid)
|
|
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, tt.exists, exists)
|
|
})
|
|
}
|
|
}
|