120 lines
3.4 KiB
Go
120 lines
3.4 KiB
Go
|
package usecase
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"net/http"
|
||
|
"testing"
|
||
|
"time"
|
||
|
|
||
|
"code.30cm.net/digimon/app-cloudep-permission-server/pkg/domain/entity"
|
||
|
"code.30cm.net/digimon/app-cloudep-permission-server/pkg/domain/permission"
|
||
|
mock "code.30cm.net/digimon/app-cloudep-permission-server/pkg/mock/repository"
|
||
|
"code.30cm.net/digimon/app-cloudep-permission-server/pkg/repository"
|
||
|
"github.com/alicebob/miniredis/v2"
|
||
|
"github.com/stretchr/testify/assert"
|
||
|
"github.com/zeromicro/go-zero/core/stores/redis"
|
||
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
||
|
"go.uber.org/mock/gomock"
|
||
|
)
|
||
|
|
||
|
func setupMiniRedis() (*miniredis.Miniredis, *redis.Redis) {
|
||
|
// 啟動 setupMiniRedis 作為模擬的 Redis 服務
|
||
|
mr, err := miniredis.Run()
|
||
|
if err != nil {
|
||
|
panic("failed to start miniRedis: " + err.Error())
|
||
|
}
|
||
|
|
||
|
// 使用 setupMiniRedis 的地址配置 go-zero Redis 客戶端
|
||
|
redisConf := redis.RedisConf{
|
||
|
Host: mr.Addr(),
|
||
|
Type: "node",
|
||
|
}
|
||
|
r := redis.MustNewRedis(redisConf)
|
||
|
|
||
|
return mr, r
|
||
|
}
|
||
|
|
||
|
func TestNewRBACUseCase_LoadPolicy(t *testing.T) {
|
||
|
// 固定發行者設定,測試中會用來驗證 claims.Issuer
|
||
|
mockCtrl := gomock.NewController(t)
|
||
|
defer mockCtrl.Finish()
|
||
|
|
||
|
// 準備測試資料
|
||
|
permID, _ := primitive.ObjectIDFromHex("507f1f77bcf86cd799439011")
|
||
|
permissionData := entity.Permission{
|
||
|
ID: permID,
|
||
|
Parent: "",
|
||
|
Name: "read_perm",
|
||
|
HTTPMethod: http.MethodGet,
|
||
|
HTTPPath: "/resource",
|
||
|
Status: permission.Open, // 1: 啟用
|
||
|
// 其他欄位可以隨便填上
|
||
|
CreateAt: time.Now().Unix(),
|
||
|
UpdateAt: time.Now().Unix(),
|
||
|
}
|
||
|
|
||
|
roleID, _ := primitive.ObjectIDFromHex("507f1f77bcf86cd799439012")
|
||
|
roleData := &entity.Role{
|
||
|
ID: roleID,
|
||
|
Name: "test_role",
|
||
|
UID: "role1",
|
||
|
ClientID: "client1",
|
||
|
Status: permission.Open,
|
||
|
CreateAt: time.Now().Unix(),
|
||
|
UpdateAt: time.Now().Unix(),
|
||
|
}
|
||
|
|
||
|
rolePermissionData := &entity.RolePermission{
|
||
|
// 這裡 RoleID 與 PermissionID 皆以 Hex 字串儲存
|
||
|
RoleID: roleID.Hex(),
|
||
|
PermissionID: permID.Hex(),
|
||
|
CreateAt: time.Now().Unix(),
|
||
|
UpdateAt: time.Now().Unix(),
|
||
|
}
|
||
|
|
||
|
// 建立 mock 物件,並設定期望值
|
||
|
permissionRepo := mock.NewMockPermissionRepository(mockCtrl)
|
||
|
roleRepo := mock.NewMockRoleRepository(mockCtrl)
|
||
|
rolePermissionRepo := mock.NewMockRolePermissionRepository(mockCtrl)
|
||
|
ctx := context.Background()
|
||
|
permissionRepo.EXPECT().
|
||
|
GetAll(ctx, nil).
|
||
|
Return([]entity.Permission{permissionData}, nil)
|
||
|
|
||
|
roleRepo.EXPECT().
|
||
|
All(ctx, nil).
|
||
|
Return([]*entity.Role{roleData}, nil)
|
||
|
|
||
|
rolePermissionRepo.EXPECT().
|
||
|
Get(ctx, roleID.Hex()).
|
||
|
Return([]*entity.RolePermission{rolePermissionData}, nil)
|
||
|
|
||
|
// 建立 miniRedis 與 adapter
|
||
|
mr, rdb := setupMiniRedis()
|
||
|
defer mr.Close()
|
||
|
|
||
|
adapter, err := repository.NewRBACAdapter(repository.RBACAdapterParam{Redis: rdb})
|
||
|
assert.NoError(t, err)
|
||
|
|
||
|
// 建立 RBACUseCase 測試實例
|
||
|
uc := NewRBACUseCase(RBACUseCaseParam{
|
||
|
ModulePath: "../../etc/rbac.conf", // 注意:確認路徑下有對應的模型檔
|
||
|
permissionRepo: permissionRepo,
|
||
|
roleRepo: roleRepo,
|
||
|
rolePermission: rolePermissionRepo,
|
||
|
RBACRedisAdapter: adapter,
|
||
|
})
|
||
|
|
||
|
// 載入 policy
|
||
|
err = uc.LoadPolicy(ctx)
|
||
|
assert.NoError(t, err)
|
||
|
|
||
|
// 接下來測試 casbin 是否能正確檢查該權限
|
||
|
status, err := uc.Check(ctx, roleData.Name, permissionData.HTTPPath, permissionData.HTTPMethod)
|
||
|
assert.NoError(t, err)
|
||
|
assert.True(t, status.Allow)
|
||
|
// 預期 PermissionName 為 "read_perm"
|
||
|
assert.Equal(t, "read_perm", status.Select.PermissionName)
|
||
|
|
||
|
}
|