bindRolesLogic_mock_test.go 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. package user
  2. import (
  3. "context"
  4. "errors"
  5. "testing"
  6. memberModel "perms-system-server/internal/model/productmember"
  7. roleModel "perms-system-server/internal/model/role"
  8. userModel "perms-system-server/internal/model/user"
  9. "perms-system-server/internal/testutil/ctxhelper"
  10. "perms-system-server/internal/testutil/mocks"
  11. "perms-system-server/internal/types"
  12. "github.com/stretchr/testify/assert"
  13. "github.com/zeromicro/go-zero/core/stores/sqlx"
  14. "go.uber.org/mock/gomock"
  15. )
  16. // TC-0187: 事务回滚
  17. func TestBindRoles_Mock_BatchInsertFail(t *testing.T) {
  18. ctrl := gomock.NewController(t)
  19. defer ctrl.Finish()
  20. dbErr := errors.New("db error")
  21. mockUser := mocks.NewMockSysUserModel(ctrl)
  22. mockUser.EXPECT().FindOne(gomock.Any(), int64(1)).
  23. Return(&userModel.SysUser{Id: 1}, nil)
  24. mockPM := mocks.NewMockSysProductMemberModel(ctrl)
  25. mockPM.EXPECT().FindOneByProductCodeUserId(gomock.Any(), "test_product", int64(1)).
  26. Return(&memberModel.SysProductMember{Id: 1, ProductCode: "test_product", UserId: 1, Status: 1}, nil)
  27. // 审计 M-R10-2:事务首步 FindOneForUpdateTx 锁 sys_product_member 行
  28. mockPM.EXPECT().FindOneForUpdateTx(gomock.Any(), nil, int64(1)).
  29. Return(&memberModel.SysProductMember{Id: 1, ProductCode: "test_product", UserId: 1, Status: 1}, nil)
  30. mockRole := mocks.NewMockSysRoleModel(ctrl)
  31. mockRole.EXPECT().FindByIds(gomock.Any(), []int64{10, 20}).
  32. Return([]*roleModel.SysRole{
  33. {Id: 10, ProductCode: "test_product", Status: 1},
  34. {Id: 20, ProductCode: "test_product", Status: 1},
  35. }, nil)
  36. mockUR := mocks.NewMockSysUserRoleModel(ctrl)
  37. mockUR.EXPECT().FindRoleIdsByUserIdForProductTx(gomock.Any(), nil, int64(1), "test_product").Return([]int64{}, nil)
  38. mockUR.EXPECT().TableName().Return("`sys_user_role`").AnyTimes()
  39. mockUR.EXPECT().TransactCtx(gomock.Any(), gomock.Any()).
  40. DoAndReturn(func(ctx context.Context, fn func(context.Context, sqlx.Session) error) error {
  41. return fn(ctx, nil)
  42. })
  43. // audit M-2 修复:循环 DELETE 替换为批量 DeleteByUserIdAndRoleIdsTx;toRemove 为空时也被调用
  44. mockUR.EXPECT().DeleteByUserIdAndRoleIdsTx(gomock.Any(), nil, int64(1), []int64(nil)).Return(nil)
  45. mockUR.EXPECT().BatchInsertWithTx(gomock.Any(), nil, gomock.Any()).Return(dbErr)
  46. svcCtx := mocks.NewMockServiceContext(mocks.MockModels{
  47. User: mockUser,
  48. Role: mockRole,
  49. UserRole: mockUR,
  50. ProductMember: mockPM,
  51. })
  52. logic := NewBindRolesLogic(ctxhelper.SuperAdminCtx(), svcCtx)
  53. err := logic.BindRoles(&types.BindRolesReq{
  54. UserId: 1,
  55. RoleIds: []int64{10, 20},
  56. })
  57. assert.Error(t, err)
  58. assert.ErrorIs(t, err, dbErr)
  59. }