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) }