Files
junhong_cmp_fiber/tests/unit/role_service_test.go
huang 028cfaa7aa feat: 实现权限检查功能并添加Redis缓存优化
- 完成 CheckPermission 方法的完整实现(账号→角色→权限查询链)
- 实现 Redis 缓存机制,大幅提升权限查询性能(~12倍提升)
- 自动缓存失效:角色/权限变更时清除相关用户缓存
- 新增完整的单元测试和集成测试(10个测试用例全部通过)
- 添加权限检查使用文档和缓存机制说明
- 归档 implement-permission-check OpenSpec 提案

性能优化:
- 首次查询: ~18ms(3次DB查询 + 1次Redis写入)
- 缓存命中: ~1.5ms(1次Redis查询)
- TTL: 30分钟,自动失效机制保证数据一致性
2026-01-16 18:15:32 +08:00

183 lines
5.3 KiB
Go

package unit
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/break/junhong_cmp_fiber/internal/model"
"github.com/break/junhong_cmp_fiber/internal/service/role"
"github.com/break/junhong_cmp_fiber/internal/store/postgres"
"github.com/break/junhong_cmp_fiber/pkg/constants"
"github.com/break/junhong_cmp_fiber/tests/testutils"
)
func TestRoleService_AssignPermissions_ValidateAvailableForRoleTypes(t *testing.T) {
db, redisClient := testutils.SetupTestDB(t)
defer testutils.TeardownTestDB(t, db, redisClient)
roleStore := postgres.NewRoleStore(db)
permStore := postgres.NewPermissionStore(db)
rolePermStore := postgres.NewRolePermissionStore(db, redisClient)
service := role.New(roleStore, permStore, rolePermStore)
ctx := createContextWithUserID(1)
platformRole := &model.Role{
RoleName: "平台管理员",
RoleDesc: "平台角色",
RoleType: 1,
Status: constants.StatusEnabled,
BaseModel: model.BaseModel{
Creator: 1,
Updater: 1,
},
}
err := roleStore.Create(ctx, platformRole)
require.NoError(t, err)
customerRole := &model.Role{
RoleName: "客户管理员",
RoleDesc: "客户角色",
RoleType: 2,
Status: constants.StatusEnabled,
BaseModel: model.BaseModel{
Creator: 1,
Updater: 1,
},
}
err = roleStore.Create(ctx, customerRole)
require.NoError(t, err)
platformPerm := &model.Permission{
PermName: "平台权限",
PermCode: "platform:manage",
PermType: 1,
Platform: "all",
AvailableForRoleTypes: "1",
Status: constants.StatusEnabled,
BaseModel: model.BaseModel{
Creator: 1,
Updater: 1,
},
}
err = permStore.Create(ctx, platformPerm)
require.NoError(t, err)
customerPerm := &model.Permission{
PermName: "客户权限",
PermCode: "customer:manage",
PermType: 1,
Platform: "all",
AvailableForRoleTypes: "2",
Status: constants.StatusEnabled,
BaseModel: model.BaseModel{
Creator: 1,
Updater: 1,
},
}
err = permStore.Create(ctx, customerPerm)
require.NoError(t, err)
commonPerm := &model.Permission{
PermName: "通用权限",
PermCode: "common:view",
PermType: 1,
Platform: "all",
AvailableForRoleTypes: "1,2",
Status: constants.StatusEnabled,
BaseModel: model.BaseModel{
Creator: 1,
Updater: 1,
},
}
err = permStore.Create(ctx, commonPerm)
require.NoError(t, err)
t.Run("为平台角色分配平台权限-成功", func(t *testing.T) {
rps, err := service.AssignPermissions(ctx, platformRole.ID, []uint{platformPerm.ID})
require.NoError(t, err)
assert.NotEmpty(t, rps)
})
t.Run("为平台角色分配通用权限-成功", func(t *testing.T) {
rps, err := service.AssignPermissions(ctx, platformRole.ID, []uint{commonPerm.ID})
require.NoError(t, err)
assert.NotEmpty(t, rps)
})
t.Run("为平台角色分配客户专用权限-失败", func(t *testing.T) {
_, err := service.AssignPermissions(ctx, platformRole.ID, []uint{customerPerm.ID})
require.Error(t, err)
assert.Contains(t, err.Error(), "不适用于此角色类型")
})
t.Run("为客户角色分配客户权限-成功", func(t *testing.T) {
rps, err := service.AssignPermissions(ctx, customerRole.ID, []uint{customerPerm.ID})
require.NoError(t, err)
assert.NotEmpty(t, rps)
})
t.Run("为客户角色分配平台专用权限-失败", func(t *testing.T) {
_, err := service.AssignPermissions(ctx, customerRole.ID, []uint{platformPerm.ID})
require.Error(t, err)
assert.Contains(t, err.Error(), "不适用于此角色类型")
})
t.Run("批量分配权限时部分不匹配-失败", func(t *testing.T) {
_, err := service.AssignPermissions(ctx, platformRole.ID, []uint{platformPerm.ID, customerPerm.ID})
require.Error(t, err)
assert.Contains(t, err.Error(), "不适用于此角色类型")
})
}
func TestRoleService_UpdateStatus(t *testing.T) {
db, redisClient := testutils.SetupTestDB(t)
defer testutils.TeardownTestDB(t, db, redisClient)
roleStore := postgres.NewRoleStore(db)
permStore := postgres.NewPermissionStore(db)
rolePermStore := postgres.NewRolePermissionStore(db, redisClient)
service := role.New(roleStore, permStore, rolePermStore)
ctx := createContextWithUserID(1)
testRole := &model.Role{
RoleName: "测试角色",
RoleDesc: "用于测试状态切换",
RoleType: 1,
Status: constants.StatusEnabled,
BaseModel: model.BaseModel{
Creator: 1,
Updater: 1,
},
}
err := roleStore.Create(ctx, testRole)
require.NoError(t, err)
t.Run("禁用角色", func(t *testing.T) {
err := service.UpdateStatus(ctx, testRole.ID, constants.StatusDisabled)
require.NoError(t, err)
role, err := roleStore.GetByID(ctx, testRole.ID)
require.NoError(t, err)
assert.Equal(t, constants.StatusDisabled, role.Status)
})
t.Run("启用角色", func(t *testing.T) {
err := service.UpdateStatus(ctx, testRole.ID, constants.StatusEnabled)
require.NoError(t, err)
role, err := roleStore.GetByID(ctx, testRole.ID)
require.NoError(t, err)
assert.Equal(t, constants.StatusEnabled, role.Status)
})
t.Run("更新不存在的角色-失败", func(t *testing.T) {
err := service.UpdateStatus(ctx, 99999, constants.StatusEnabled)
require.Error(t, err)
assert.Contains(t, err.Error(), "角色不存在")
})
}