543 lines
12 KiB
Go
543 lines
12 KiB
Go
package repository
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"testing"
|
|
|
|
"code.30cm.net/digimon/app-cloudep-permission-server/pkg/domain/entity"
|
|
"code.30cm.net/digimon/app-cloudep-permission-server/pkg/domain/permission"
|
|
"code.30cm.net/digimon/app-cloudep-permission-server/pkg/domain/repository"
|
|
mgo "code.30cm.net/digimon/library-go/mongo"
|
|
"github.com/stretchr/testify/assert"
|
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
|
)
|
|
|
|
func SetupTestRoleRepository(db string) (repository.RoleRepository, func(), error) {
|
|
h, p, tearDown, err := startMongoContainer()
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
conf := &mgo.Conf{
|
|
Schema: Schema,
|
|
Host: fmt.Sprintf("%s:%s", h, p),
|
|
Database: db,
|
|
MaxStaleness: 300,
|
|
MaxPoolSize: 100,
|
|
MinPoolSize: 100,
|
|
MaxConnIdleTime: 300,
|
|
Compressors: []string{},
|
|
EnableStandardReadWriteSplitMode: false,
|
|
ConnectTimeoutMs: 3000,
|
|
}
|
|
|
|
param := RoleRepositoryParam{
|
|
Conf: conf,
|
|
}
|
|
repo := NewRoleRepository(param)
|
|
_, _ = repo.Index20250224UP(context.Background())
|
|
|
|
return repo, tearDown, nil
|
|
}
|
|
|
|
func TestRoleRepository_Create(t *testing.T) {
|
|
repo, tearDown, err := SetupTestRoleRepository("testDB")
|
|
assert.NoError(t, err)
|
|
defer tearDown()
|
|
|
|
testCases := []struct {
|
|
name string
|
|
input *entity.Role
|
|
expectErr bool
|
|
}{
|
|
{
|
|
name: "成功建立新的角色",
|
|
input: &entity.Role{
|
|
Name: "Admin",
|
|
UID: "user123",
|
|
ClientID: "client456",
|
|
Status: 1,
|
|
},
|
|
expectErr: false,
|
|
},
|
|
{
|
|
name: "自動生成 ID 及時間戳",
|
|
input: &entity.Role{
|
|
Name: "User",
|
|
UID: "user789",
|
|
ClientID: "client987",
|
|
Status: 1,
|
|
},
|
|
expectErr: false,
|
|
},
|
|
{
|
|
name: "當角色為 nil 時應返回錯誤",
|
|
input: nil,
|
|
expectErr: true,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
err := repo.Create(context.Background(), tc.input)
|
|
|
|
if tc.expectErr {
|
|
assert.Error(t, err, "應該返回錯誤")
|
|
} else {
|
|
assert.NoError(t, err, "不應該返回錯誤")
|
|
assert.NotEqual(t, primitive.NilObjectID, tc.input.ID, "應該自動生成 ObjectID")
|
|
assert.True(t, tc.input.CreateAt > 0, "應該自動設定 CreateAt")
|
|
assert.True(t, tc.input.UpdateAt > 0, "應該自動設定 UpdateAt")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRoleRepository_Update(t *testing.T) {
|
|
repo, tearDown, err := SetupTestRoleRepository("testDB")
|
|
assert.NoError(t, err)
|
|
defer tearDown()
|
|
|
|
// 預先建立一個角色
|
|
existingRole := &entity.Role{
|
|
Name: "Old Name",
|
|
UID: "old_uid",
|
|
ClientID: "old_client_id",
|
|
Status: 1,
|
|
}
|
|
err = repo.Create(context.Background(), existingRole)
|
|
assert.NoError(t, err)
|
|
|
|
newName := "New Name"
|
|
newStatus := permission.Close
|
|
newUID := "new_uid"
|
|
newClientID := "new_client_id"
|
|
|
|
testCases := []struct {
|
|
name string
|
|
input repository.UpdateReq
|
|
expectErr bool
|
|
}{
|
|
{
|
|
name: "成功更新角色",
|
|
input: repository.UpdateReq{
|
|
ID: existingRole.ID.Hex(),
|
|
Name: &newName,
|
|
Status: &newStatus,
|
|
UID: &newUID,
|
|
ClientID: &newClientID,
|
|
},
|
|
expectErr: false,
|
|
},
|
|
{
|
|
name: "更新部分欄位",
|
|
input: repository.UpdateReq{
|
|
ID: existingRole.ID.Hex(),
|
|
Name: &newName,
|
|
Status: &newStatus,
|
|
},
|
|
expectErr: false,
|
|
},
|
|
{
|
|
name: "無效的 ObjectID 應返回錯誤",
|
|
input: repository.UpdateReq{
|
|
ID: "invalid_object_id",
|
|
},
|
|
expectErr: true,
|
|
},
|
|
{
|
|
name: "當 UpdateOne 失敗時應返回錯誤",
|
|
input: repository.UpdateReq{
|
|
ID: primitive.NewObjectID().Hex(), // 模擬一個不存在的 ID
|
|
},
|
|
expectErr: false,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
err := repo.Update(context.Background(), tc.input)
|
|
|
|
if tc.expectErr {
|
|
assert.Error(t, err, "應該返回錯誤")
|
|
} else {
|
|
assert.NoError(t, err, "不應該返回錯誤")
|
|
|
|
// 驗證更新結果
|
|
updatedRole, err := repo.GetByID(context.Background(), existingRole.ID.Hex())
|
|
assert.NoError(t, err)
|
|
if tc.input.Name != nil {
|
|
assert.Equal(t, *tc.input.Name, updatedRole.Name, "名稱應該被更新")
|
|
}
|
|
if tc.input.Status != nil {
|
|
assert.Equal(t, *tc.input.Status, updatedRole.Status, "狀態應該被更新")
|
|
}
|
|
if tc.input.UID != nil {
|
|
assert.Equal(t, *tc.input.UID, updatedRole.UID, "UID 應該被更新")
|
|
}
|
|
if tc.input.ClientID != nil {
|
|
assert.Equal(t, *tc.input.ClientID, updatedRole.ClientID, "ClientID 應該被更新")
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRoleRepository_Delete(t *testing.T) {
|
|
repo, tearDown, err := SetupTestRoleRepository("testDB")
|
|
assert.NoError(t, err)
|
|
defer tearDown()
|
|
|
|
// 預先建立一個角色
|
|
existingRole := &entity.Role{
|
|
Name: "Test Role",
|
|
UID: "test_uid",
|
|
ClientID: "test_client_id",
|
|
Status: 1,
|
|
}
|
|
err = repo.Create(context.Background(), existingRole)
|
|
assert.NoError(t, err)
|
|
|
|
testCases := []struct {
|
|
name string
|
|
inputID string
|
|
expectErr bool
|
|
}{
|
|
{
|
|
name: "成功刪除角色",
|
|
inputID: existingRole.ID.Hex(),
|
|
expectErr: false,
|
|
},
|
|
{
|
|
name: "刪除不存在的角色不應報錯",
|
|
inputID: primitive.NewObjectID().Hex(),
|
|
expectErr: false,
|
|
},
|
|
{
|
|
name: "無效的 ObjectID 應返回錯誤",
|
|
inputID: "invalid_object_id",
|
|
expectErr: true,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
err := repo.Delete(context.Background(), tc.inputID)
|
|
|
|
if tc.expectErr {
|
|
assert.Error(t, err, "應該返回錯誤")
|
|
} else {
|
|
assert.NoError(t, err, "不應該返回錯誤")
|
|
|
|
// 驗證角色是否已刪除
|
|
if tc.inputID == existingRole.ID.Hex() {
|
|
_, err := repo.GetByID(context.Background(), existingRole.ID.Hex())
|
|
assert.Error(t, err, "應該找不到該角色")
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRoleRepository_All(t *testing.T) {
|
|
repo, tearDown, err := SetupTestRoleRepository("testDB")
|
|
assert.NoError(t, err)
|
|
defer tearDown()
|
|
|
|
clientID1 := "client_1"
|
|
clientID2 := "client_2"
|
|
|
|
// 預先建立角色資料
|
|
roles := []*entity.Role{
|
|
{
|
|
ID: primitive.NewObjectID(),
|
|
Name: "Admin",
|
|
UID: "admin_uid",
|
|
ClientID: clientID1,
|
|
Status: 1,
|
|
},
|
|
{
|
|
ID: primitive.NewObjectID(),
|
|
Name: "User",
|
|
UID: "user_uid",
|
|
ClientID: clientID1,
|
|
Status: 1,
|
|
},
|
|
{
|
|
ID: primitive.NewObjectID(),
|
|
Name: "Manager",
|
|
UID: "manager_uid",
|
|
ClientID: clientID2,
|
|
Status: 1,
|
|
},
|
|
}
|
|
|
|
// 插入測試資料
|
|
for _, role := range roles {
|
|
err := repo.Create(context.Background(), role)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
testCases := []struct {
|
|
name string
|
|
clientID *string
|
|
expectLen int
|
|
expectErr bool
|
|
}{
|
|
{
|
|
name: "查詢所有角色",
|
|
clientID: nil,
|
|
expectLen: len(roles),
|
|
expectErr: false,
|
|
},
|
|
{
|
|
name: "根據 clientID 查詢角色",
|
|
clientID: &clientID1,
|
|
expectLen: 2,
|
|
expectErr: false,
|
|
},
|
|
{
|
|
name: "clientID 無匹配時應返回空",
|
|
clientID: new(string),
|
|
expectLen: 0,
|
|
expectErr: false,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
result, err := repo.All(context.Background(), tc.clientID)
|
|
|
|
if tc.expectErr {
|
|
assert.Error(t, err, "應該返回錯誤")
|
|
} else {
|
|
assert.NoError(t, err, "不應該返回錯誤")
|
|
assert.Len(t, result, tc.expectLen, "返回的角色數量應符合預期")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRoleRepository_GetByUID(t *testing.T) {
|
|
repo, tearDown, err := SetupTestRoleRepository("testDB")
|
|
assert.NoError(t, err)
|
|
defer tearDown()
|
|
|
|
// 預先建立測試角色
|
|
existingRole := &entity.Role{
|
|
ID: primitive.NewObjectID(),
|
|
Name: "Admin",
|
|
UID: "admin_uid",
|
|
ClientID: "client_1",
|
|
Status: 1,
|
|
}
|
|
|
|
err = repo.Create(context.Background(), existingRole)
|
|
assert.NoError(t, err)
|
|
|
|
testCases := []struct {
|
|
name string
|
|
uid string
|
|
expectErr bool
|
|
expectNil bool
|
|
}{
|
|
{
|
|
name: "成功查詢角色",
|
|
uid: "admin_uid",
|
|
expectErr: false,
|
|
expectNil: false,
|
|
},
|
|
{
|
|
name: "查詢不存在的角色",
|
|
uid: "non_existent_uid",
|
|
expectErr: true,
|
|
expectNil: true,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
result, err := repo.GetByUID(context.Background(), tc.uid)
|
|
|
|
if tc.expectErr {
|
|
assert.Error(t, err, "應該返回錯誤")
|
|
} else {
|
|
assert.NoError(t, err, "不應該返回錯誤")
|
|
}
|
|
|
|
if tc.expectNil {
|
|
assert.Nil(t, result, "應該返回 nil")
|
|
} else {
|
|
assert.NotNil(t, result, "不應該返回 nil")
|
|
assert.Equal(t, existingRole.UID, result.UID, "UID 應相符")
|
|
assert.Equal(t, existingRole.Name, result.Name, "名稱應相符")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRoleRepository_GetByID(t *testing.T) {
|
|
repo, tearDown, err := SetupTestRoleRepository("testDB")
|
|
assert.NoError(t, err)
|
|
defer tearDown()
|
|
|
|
// 預先建立測試角色
|
|
existingRole := &entity.Role{
|
|
ID: primitive.NewObjectID(),
|
|
Name: "Admin",
|
|
UID: "admin_uid",
|
|
ClientID: "client_1",
|
|
Status: 1,
|
|
}
|
|
|
|
err = repo.Create(context.Background(), existingRole)
|
|
assert.NoError(t, err)
|
|
|
|
testCases := []struct {
|
|
name string
|
|
id string
|
|
expectErr bool
|
|
expectNil bool
|
|
}{
|
|
{
|
|
name: "成功查詢角色",
|
|
id: existingRole.ID.Hex(),
|
|
expectErr: false,
|
|
expectNil: false,
|
|
},
|
|
{
|
|
name: "查詢不存在的角色",
|
|
id: primitive.NewObjectID().Hex(),
|
|
expectErr: true,
|
|
expectNil: true,
|
|
},
|
|
{
|
|
name: "提供無效的 ObjectID",
|
|
id: "invalid_id",
|
|
expectErr: true,
|
|
expectNil: true,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
result, err := repo.GetByID(context.Background(), tc.id)
|
|
|
|
if tc.expectErr {
|
|
assert.Error(t, err, "應該返回錯誤")
|
|
} else {
|
|
assert.NoError(t, err, "不應該返回錯誤")
|
|
}
|
|
|
|
if tc.expectNil {
|
|
assert.Nil(t, result, "應該返回 nil")
|
|
} else {
|
|
assert.NotNil(t, result, "不應該返回 nil")
|
|
assert.Equal(t, existingRole.ID, result.ID, "ID 應相符")
|
|
assert.Equal(t, existingRole.Name, result.Name, "名稱應相符")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRoleRepository_List(t *testing.T) {
|
|
repo, tearDown, err := SetupTestRoleRepository("testDB")
|
|
assert.NoError(t, err)
|
|
defer tearDown()
|
|
|
|
// 預先建立測試角色
|
|
roles := []*entity.Role{
|
|
{
|
|
ID: primitive.NewObjectID(),
|
|
Name: "Admin",
|
|
UID: "admin_uid",
|
|
ClientID: "client_1",
|
|
Status: 1,
|
|
},
|
|
{
|
|
ID: primitive.NewObjectID(),
|
|
Name: "User",
|
|
UID: "user_uid",
|
|
ClientID: "client_1",
|
|
Status: 1,
|
|
},
|
|
{
|
|
ID: primitive.NewObjectID(),
|
|
Name: "Guest",
|
|
UID: "guest_uid",
|
|
ClientID: "client_2",
|
|
Status: 0,
|
|
},
|
|
}
|
|
|
|
// 插入測試資料
|
|
for _, role := range roles {
|
|
err := repo.Create(context.Background(), role)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
testCases := []struct {
|
|
name string
|
|
query repository.ListQuery
|
|
expectLen int
|
|
expectErr bool
|
|
}{
|
|
{
|
|
name: "查詢所有角色",
|
|
query: repository.ListQuery{PageSize: 10, PageIndex: 1},
|
|
expectLen: 3,
|
|
expectErr: false,
|
|
},
|
|
{
|
|
name: "篩選名稱為 Admin",
|
|
query: repository.ListQuery{Name: ToPointer("Admin"), PageSize: 10, PageIndex: 1},
|
|
expectLen: 1,
|
|
expectErr: false,
|
|
},
|
|
{
|
|
name: "篩選特定 ClientID",
|
|
query: repository.ListQuery{ClientID: ToPointer("client_1"), PageSize: 10, PageIndex: 1},
|
|
expectLen: 2,
|
|
expectErr: false,
|
|
},
|
|
{
|
|
name: "篩選啟用 (Status=1) 的角色",
|
|
query: repository.ListQuery{Status: ToPointer(permission.Open), PageSize: 10, PageIndex: 1},
|
|
expectLen: 2,
|
|
expectErr: false,
|
|
},
|
|
{
|
|
name: "篩選特定 UID",
|
|
query: repository.ListQuery{UID: ToPointer("guest_uid"), PageSize: 10, PageIndex: 1},
|
|
expectLen: 1,
|
|
expectErr: false,
|
|
},
|
|
{
|
|
name: "測試分頁 PageSize=1, PageIndex=1",
|
|
query: repository.ListQuery{PageSize: 1, PageIndex: 1},
|
|
expectLen: 1,
|
|
expectErr: false,
|
|
},
|
|
{
|
|
name: "查詢無符合條件的角色",
|
|
query: repository.ListQuery{Name: ToPointer("NonExist"), PageSize: 10, PageIndex: 1},
|
|
expectLen: 0,
|
|
expectErr: false,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
result, _, err := repo.List(context.Background(), tc.query)
|
|
|
|
if tc.expectErr {
|
|
assert.Error(t, err, "應該返回錯誤")
|
|
} else {
|
|
assert.NoError(t, err, "不應該返回錯誤")
|
|
assert.Len(t, result, tc.expectLen, "返回的角色數量應符合預期")
|
|
}
|
|
})
|
|
}
|
|
}
|