| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- package role
- import (
- "context"
- "errors"
- "testing"
- "perms-system-server/internal/consts"
- "perms-system-server/internal/loaders"
- "perms-system-server/internal/middleware"
- roleModel "perms-system-server/internal/model/role"
- "perms-system-server/internal/testutil/mocks"
- "perms-system-server/internal/types"
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
- "github.com/zeromicro/go-zero/core/stores/sqlx"
- "go.uber.org/mock/gomock"
- )
- // ---------------------------------------------------------------------------
- // 覆盖目标:审计第 6 轮 M-4 修复回归 —— 角色更新 / 角色权限绑定的 post-commit 缓存清理
- // 必须是 "尽力而为":事务已 COMMIT 成功后,任何缓存清理路径的失败只应记 Errorf,
- // 不得把 degraded 成功映射成 5xx 让客户端误触发重试。
- //
- // 场景:事务外 `FindUserIdsByRoleId` 返回 err。
- // 期望:handler 仍返回 nil,200 OK;客户端无须重试;旧缓存最终靠 TTL 过期兜底。
- // ---------------------------------------------------------------------------
- func adminCtx(productCode string) context.Context {
- return middleware.WithUserDetails(context.Background(), &loaders.UserDetails{
- UserId: 1,
- Username: "admin",
- IsSuperAdmin: true,
- MemberType: consts.MemberTypeAdmin,
- Status: consts.StatusEnabled,
- ProductCode: productCode,
- })
- }
- // TC-0858: BindRolePerms —— tx 成功、FindUserIdsByRoleId 抛 err,logic 返回 nil。
- func TestBindRolePerms_PostCommitUserIdsError_StaysSuccess(t *testing.T) {
- ctrl := gomock.NewController(t)
- t.Cleanup(ctrl.Finish)
- roleMock := mocks.NewMockSysRoleModel(ctrl)
- rpMock := mocks.NewMockSysRolePermModel(ctrl)
- urMock := mocks.NewMockSysUserRoleModel(ctrl)
- roleMock.EXPECT().FindOne(gomock.Any(), int64(7)).
- Return(&roleModel.SysRole{Id: 7, ProductCode: "pc_m4", PermsLevel: 50, Status: 1}, nil)
- // 审计 M-R10-2:existing 读 + diff + delete/insert 全部收敛进事务;事务首步 LockByIdTx 锁 sys_role 行。
- rpMock.EXPECT().TransactCtx(gomock.Any(), gomock.Any()).
- DoAndReturn(func(ctx context.Context, fn func(context.Context, sqlx.Session) error) error {
- return fn(ctx, nil)
- })
- roleMock.EXPECT().LockByIdTx(gomock.Any(), nil, int64(7)).
- Return(&roleModel.SysRole{Id: 7, ProductCode: "pc_m4", PermsLevel: 50, Status: 1}, nil)
- rpMock.EXPECT().FindPermIdsByRoleIdTx(gomock.Any(), nil, int64(7)).Return([]int64{1}, nil)
- rpMock.EXPECT().DeleteByRoleIdAndPermIdsTx(gomock.Any(), nil, int64(7), []int64{1}).
- Return(nil)
- // 关键断言:post-commit FindUserIdsByRoleId 返回 err,logic 必须吞掉 err。
- urMock.EXPECT().FindUserIdsByRoleId(gomock.Any(), int64(7)).
- Return(nil, errors.New("redis/db transient error"))
- svcCtx := mocks.NewMockServiceContext(mocks.MockModels{
- Role: roleMock, RolePerm: rpMock, UserRole: urMock,
- })
- err := NewBindRolePermsLogic(adminCtx("pc_m4"), svcCtx).BindRolePerms(&types.BindPermsReq{
- RoleId: 7, PermIds: []int64{},
- })
- require.NoError(t, err,
- "M-4:post-commit 缓存步骤的 transient err 不应把 degraded 成功映射成 500")
- }
- // TC-0859: UpdateRole —— UpdateWithOptLock 成功,FindUserIdsByRoleId 失败,handler 返回 nil。
- func TestUpdateRole_PostCommitUserIdsError_StaysSuccess(t *testing.T) {
- ctrl := gomock.NewController(t)
- t.Cleanup(ctrl.Finish)
- roleMock := mocks.NewMockSysRoleModel(ctrl)
- urMock := mocks.NewMockSysUserRoleModel(ctrl)
- roleMock.EXPECT().FindOne(gomock.Any(), int64(9)).
- Return(&roleModel.SysRole{
- Id: 9, ProductCode: "pc_m4u", Name: "before",
- PermsLevel: 50, Status: consts.StatusEnabled, UpdateTime: 100,
- }, nil)
- // UpdateWithOptLock 成功;签名:UpdateWithOptLock(ctx, role, prevUpdateTime)。
- roleMock.EXPECT().UpdateWithOptLock(gomock.Any(), gomock.Any(), int64(100)).Return(nil)
- // 关键断言:post-commit transient err 不应导致 handler 失败。
- urMock.EXPECT().FindUserIdsByRoleId(gomock.Any(), int64(9)).
- Return(nil, errors.New("boom"))
- svcCtx := mocks.NewMockServiceContext(mocks.MockModels{
- Role: roleMock, UserRole: urMock,
- })
- err := NewUpdateRoleLogic(adminCtx("pc_m4u"), svcCtx).UpdateRole(&types.UpdateRoleReq{
- Id: 9, Name: "after", Remark: "r", PermsLevel: 60, Status: 0,
- })
- assert.NoError(t, err,
- "M-4:UpdateRole 已提交成功,post-commit 缓存失败只记日志,handler 必须返回 nil")
- }
|