475 lines
11 KiB
Go
475 lines
11 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 SetupTestPermissionRepository(db string) (repository.PermissionRepository, 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 := PermissionRepositoryParam{
|
|
Conf: conf,
|
|
}
|
|
repo := NewPermissionRepository(param)
|
|
_, _ = repo.Index20250214UP(context.Background())
|
|
|
|
return repo, tearDown, nil
|
|
}
|
|
|
|
// 測試 Insert
|
|
func TestPermissionRepository_Insert(t *testing.T) {
|
|
repo, tearDown, err := SetupTestPermissionRepository("testDB")
|
|
assert.NoError(t, err)
|
|
defer tearDown()
|
|
|
|
testCases := []struct {
|
|
name string
|
|
input entity.Permission
|
|
expectErr bool
|
|
}{
|
|
{
|
|
name: "成功插入",
|
|
input: entity.Permission{
|
|
Name: "test-permission",
|
|
HTTPMethod: "GET",
|
|
HTTPPath: "/test",
|
|
Status: 1,
|
|
Type: permission.BackendUser,
|
|
},
|
|
expectErr: false,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
err := repo.Insert(context.Background(), tc.input)
|
|
if tc.expectErr {
|
|
assert.NotNil(t, err, "應該要返回錯誤")
|
|
} else {
|
|
assert.Nil(t, err, "不應該返回錯誤")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestPermissionRepository_Update(t *testing.T) {
|
|
repo, tearDown, err := SetupTestPermissionRepository("testDB")
|
|
assert.NoError(t, err)
|
|
defer tearDown()
|
|
|
|
// 先插入一條測試數據
|
|
existingPermission := entity.Permission{
|
|
Name: "original-permission",
|
|
HTTPMethod: "GET",
|
|
HTTPPath: "/original",
|
|
Status: 1,
|
|
Type: permission.BackendUser,
|
|
}
|
|
err = repo.Insert(context.Background(), existingPermission)
|
|
assert.Nil(t, err, "插入初始數據失敗")
|
|
|
|
// 取得剛插入的 ID
|
|
found, err := repo.FindOne(context.Background(), repository.PermissionQuery{
|
|
HTTPMethod: existingPermission.HTTPMethod,
|
|
HTTPPath: existingPermission.HTTPPath,
|
|
})
|
|
assert.Nil(t, err, "應該能找到插入的權限")
|
|
id := found.ID.Hex()
|
|
|
|
testCases := []struct {
|
|
name string
|
|
id string
|
|
updateReq repository.UpdatePermission
|
|
expectErr bool
|
|
}{
|
|
{
|
|
name: "成功更新名稱",
|
|
id: id,
|
|
updateReq: repository.UpdatePermission{
|
|
Name: ToPointer("updated-name"),
|
|
},
|
|
expectErr: false,
|
|
},
|
|
{
|
|
name: "成功更新 HTTP 方法",
|
|
id: id,
|
|
updateReq: repository.UpdatePermission{
|
|
HTTPMethod: ToPointer("PUT"),
|
|
},
|
|
expectErr: false,
|
|
},
|
|
{
|
|
name: "成功更新 HTTP 路徑",
|
|
id: id,
|
|
updateReq: repository.UpdatePermission{
|
|
HTTPPath: ToPointer("/updated-path"),
|
|
},
|
|
expectErr: false,
|
|
},
|
|
{
|
|
name: "成功更新狀態",
|
|
id: id,
|
|
updateReq: repository.UpdatePermission{
|
|
Status: ToPointer(permission.Open),
|
|
},
|
|
expectErr: false,
|
|
},
|
|
{
|
|
name: "成功更新多個欄位",
|
|
id: id,
|
|
updateReq: repository.UpdatePermission{
|
|
Name: ToPointer("multi-updated"),
|
|
HTTPMethod: ToPointer("PATCH"),
|
|
HTTPPath: ToPointer("/multi-update"),
|
|
Status: ToPointer(permission.Close),
|
|
},
|
|
expectErr: false,
|
|
},
|
|
{
|
|
name: "更新失敗 - 錯誤的 ObjectID",
|
|
id: "invalid",
|
|
updateReq: repository.UpdatePermission{
|
|
Name: ToPointer("invalid-update"),
|
|
},
|
|
expectErr: true,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
err := repo.Update(context.Background(), tc.id, tc.updateReq)
|
|
if tc.expectErr {
|
|
assert.NotNil(t, err, "應該要返回錯誤")
|
|
} else {
|
|
assert.Nil(t, err, "不應該返回錯誤")
|
|
|
|
// 確保更新後的資料正確
|
|
updated, err := repo.GetAll(context.Background(), nil)
|
|
assert.Nil(t, err, "應該能找到更新後的權限")
|
|
|
|
if tc.updateReq.Name != nil {
|
|
assert.Equal(t, *tc.updateReq.Name, updated[0].Name, "名稱應該被更新")
|
|
}
|
|
if tc.updateReq.HTTPMethod != nil {
|
|
assert.Equal(t, *tc.updateReq.HTTPMethod, updated[0].HTTPMethod, "HTTP 方法應該被更新")
|
|
}
|
|
if tc.updateReq.HTTPPath != nil {
|
|
assert.Equal(t, *tc.updateReq.HTTPPath, updated[0].HTTPPath, "HTTP 路徑應該被更新")
|
|
}
|
|
if tc.updateReq.Status != nil {
|
|
assert.Equal(t, *tc.updateReq.Status, updated[0].Status, "狀態應該被更新")
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// 測試 Delete 方法
|
|
func TestPermissionRepository_Delete(t *testing.T) {
|
|
repo, tearDown, err := SetupTestPermissionRepository("testDB")
|
|
assert.NoError(t, err)
|
|
defer tearDown()
|
|
|
|
// 插入測試數據
|
|
permission := entity.Permission{
|
|
ID: primitive.NewObjectID(),
|
|
Name: "delete-test",
|
|
HTTPMethod: "DELETE",
|
|
HTTPPath: "/test-delete",
|
|
Status: 1,
|
|
}
|
|
|
|
err = repo.Insert(context.Background(), permission)
|
|
assert.NoError(t, err, "插入測試數據時不應發生錯誤")
|
|
|
|
testCases := []struct {
|
|
name string
|
|
id string
|
|
expectErr bool
|
|
}{
|
|
{
|
|
name: "成功刪除存在的權限",
|
|
id: permission.ID.Hex(),
|
|
expectErr: false,
|
|
},
|
|
{
|
|
name: "刪除不存在的權限",
|
|
id: primitive.NewObjectID().Hex(),
|
|
expectErr: false, // MongoDB 刪除不存在的 ID 仍然不會報錯
|
|
},
|
|
{
|
|
name: "刪除無效的 ObjectID",
|
|
id: "invalid-object-id",
|
|
expectErr: true,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
err := repo.Delete(context.Background(), tc.id)
|
|
if tc.expectErr {
|
|
assert.Error(t, err, "應該返回錯誤")
|
|
} else {
|
|
assert.NoError(t, err, "不應該返回錯誤")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// 測試 GetAll 方法
|
|
func TestPermissionRepository_GetAll(t *testing.T) {
|
|
repo, tearDown, err := SetupTestPermissionRepository("testDB")
|
|
assert.NoError(t, err)
|
|
defer tearDown()
|
|
|
|
// 插入測試數據
|
|
testPermissions := []entity.Permission{
|
|
{
|
|
ID: primitive.NewObjectID(),
|
|
Name: "read",
|
|
HTTPMethod: "GET",
|
|
HTTPPath: "/read",
|
|
Status: permission.Open,
|
|
},
|
|
{
|
|
ID: primitive.NewObjectID(),
|
|
Name: "write",
|
|
HTTPMethod: "POST",
|
|
HTTPPath: "/write",
|
|
Status: permission.Close,
|
|
},
|
|
}
|
|
|
|
for _, p := range testPermissions {
|
|
err := repo.Insert(context.Background(), p)
|
|
assert.NoError(t, err, "插入測試數據時不應該發生錯誤")
|
|
}
|
|
|
|
testCases := []struct {
|
|
name string
|
|
status *permission.Status
|
|
expectLen int
|
|
expectErr bool
|
|
}{
|
|
{
|
|
name: "查詢所有權限",
|
|
status: nil,
|
|
expectLen: 2,
|
|
expectErr: false,
|
|
},
|
|
{
|
|
name: "查詢開啟的權限",
|
|
status: ToPointer(permission.Open),
|
|
expectLen: 1,
|
|
expectErr: false,
|
|
},
|
|
{
|
|
name: "查詢關閉的權限",
|
|
status: ToPointer(permission.Close),
|
|
expectLen: 1,
|
|
expectErr: false,
|
|
},
|
|
{
|
|
name: "查詢不存在的權限狀態",
|
|
status: ToPointer(permission.Status(-1)),
|
|
expectLen: 0,
|
|
expectErr: false,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
result, err := repo.GetAll(context.Background(), tc.status)
|
|
if tc.expectErr {
|
|
assert.Error(t, err, "應該返回錯誤")
|
|
} else {
|
|
assert.NoError(t, err, "不應該返回錯誤")
|
|
assert.Len(t, result, tc.expectLen, "查詢結果數量不符合預期")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// 測試 GetAllIntoIDMap 方法
|
|
func TestPermissionRepository_GetAllIntoIDMap(t *testing.T) {
|
|
repo, tearDown, err := SetupTestPermissionRepository("testDB")
|
|
assert.NoError(t, err)
|
|
defer tearDown()
|
|
|
|
// 插入測試數據
|
|
testPermissions := []entity.Permission{
|
|
{
|
|
ID: primitive.NewObjectID(),
|
|
Name: "read",
|
|
HTTPMethod: "GET",
|
|
HTTPPath: "/read",
|
|
Status: permission.Open,
|
|
},
|
|
{
|
|
ID: primitive.NewObjectID(),
|
|
Name: "write",
|
|
HTTPMethod: "POST",
|
|
HTTPPath: "/write",
|
|
Status: permission.Close,
|
|
},
|
|
}
|
|
|
|
for _, p := range testPermissions {
|
|
err := repo.Insert(context.Background(), p)
|
|
assert.NoError(t, err, "插入測試數據時不應該發生錯誤")
|
|
}
|
|
|
|
testCases := []struct {
|
|
name string
|
|
status *permission.Status
|
|
expectLen int
|
|
expectErr bool
|
|
}{
|
|
{
|
|
name: "查詢所有權限並轉為 Map",
|
|
status: nil,
|
|
expectLen: 2,
|
|
expectErr: false,
|
|
},
|
|
{
|
|
name: "查詢開啟的權限並轉為 Map",
|
|
status: ToPointer(permission.Open),
|
|
expectLen: 1,
|
|
expectErr: false,
|
|
},
|
|
{
|
|
name: "查詢關閉的權限並轉為 Map",
|
|
status: ToPointer(permission.Close),
|
|
expectLen: 1,
|
|
expectErr: false,
|
|
},
|
|
{
|
|
name: "查詢不存在的權限狀態並轉為 Map",
|
|
status: ToPointer(permission.Status(-1)),
|
|
expectLen: 0,
|
|
expectErr: false,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
result, err := repo.GetAllIntoIDMap(context.Background(), tc.status)
|
|
if tc.expectErr {
|
|
assert.Error(t, err, "應該返回錯誤")
|
|
} else {
|
|
assert.NoError(t, err, "不應該返回錯誤")
|
|
assert.Len(t, result, tc.expectLen, "查詢結果數量不符合預期")
|
|
|
|
// 確保 Map 的 key 是權限名稱
|
|
for key, permission := range result {
|
|
assert.Equal(t, key, permission.Name, "Map 的 Key 應該與 Name 相符")
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestPermissionRepository_FindByNames(t *testing.T) {
|
|
repo, tearDown, err := SetupTestPermissionRepository("testDB")
|
|
assert.NoError(t, err)
|
|
defer tearDown()
|
|
|
|
// 測試數據
|
|
testPermissions := []entity.Permission{
|
|
{
|
|
ID: primitive.NewObjectID(),
|
|
Name: "read-data",
|
|
HTTPMethod: "GET",
|
|
HTTPPath: "/data",
|
|
Status: 1,
|
|
},
|
|
{
|
|
ID: primitive.NewObjectID(),
|
|
Name: "write-data",
|
|
HTTPMethod: "POST",
|
|
HTTPPath: "/data",
|
|
Status: 1,
|
|
},
|
|
}
|
|
|
|
// 插入測試數據
|
|
for _, perm := range testPermissions {
|
|
err := repo.Insert(context.Background(), perm)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
testCases := []struct {
|
|
name string
|
|
input []string
|
|
expectLen int
|
|
expectErr bool
|
|
}{
|
|
{
|
|
name: "成功查詢單個名稱",
|
|
input: []string{"read-data"},
|
|
expectLen: 1,
|
|
expectErr: false,
|
|
},
|
|
{
|
|
name: "成功查詢多個名稱",
|
|
input: []string{"read-data", "write-data"},
|
|
expectLen: 2,
|
|
expectErr: false,
|
|
},
|
|
{
|
|
name: "查詢名稱不存在時應返回空結果",
|
|
input: []string{"unknown-permission"},
|
|
expectLen: 0,
|
|
expectErr: false,
|
|
},
|
|
{
|
|
name: "當查詢發生錯誤時,應返回錯誤",
|
|
input: nil, // 無效查詢
|
|
expectLen: 0,
|
|
expectErr: true,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
result, err := repo.FindByNames(context.Background(), tc.input)
|
|
|
|
if tc.expectErr {
|
|
assert.Error(t, err, "應該返回錯誤")
|
|
} else {
|
|
assert.NoError(t, err, "不應該返回錯誤")
|
|
assert.Len(t, result, tc.expectLen, "返回的數據長度應符合預期")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func ToPointer[T any](v T) *T {
|
|
return &v
|
|
}
|