updateDeptLogic_mock_test.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. package dept
  2. import (
  3. "testing"
  4. deptModel "perms-system-server/internal/model/dept"
  5. "perms-system-server/internal/testutil/ctxhelper"
  6. "perms-system-server/internal/testutil/mocks"
  7. "perms-system-server/internal/types"
  8. "github.com/stretchr/testify/assert"
  9. "go.uber.org/mock/gomock"
  10. )
  11. // TC-0105: UpdateDept 只清理自身部门用户缓存,不再级联到子部门 (audit M-5 修复验证)
  12. func TestUpdateDept_Mock_CascadeCacheClean(t *testing.T) {
  13. ctrl := gomock.NewController(t)
  14. defer ctrl.Finish()
  15. parentDeptId := int64(10)
  16. mockDept := mocks.NewMockSysDeptModel(ctrl)
  17. mockDept.EXPECT().FindOne(gomock.Any(), parentDeptId).
  18. Return(&deptModel.SysDept{
  19. Id: parentDeptId,
  20. Name: "Parent",
  21. Path: "/10/",
  22. DeptType: "NORMAL",
  23. Status: 1,
  24. UpdateTime: 1000,
  25. }, nil)
  26. // 修复后:使用乐观锁 UpdateWithOptLock,且不再调用 FindByPathPrefix
  27. mockDept.EXPECT().UpdateWithOptLock(gomock.Any(), gomock.Any(), int64(1000)).Return(nil)
  28. mockUser := mocks.NewMockSysUserModel(ctrl)
  29. // 修复后:仅查询目标部门直属用户,不再级联查询子部门用户
  30. mockUser.EXPECT().FindIdsByDeptId(gomock.Any(), parentDeptId).
  31. Return([]int64{100, 101}, nil)
  32. // 下面两个调用不应发生(gomock 默认严格,未声明调用即失败)
  33. svcCtx := mocks.NewMockServiceContext(mocks.MockModels{
  34. Dept: mockDept,
  35. User: mockUser,
  36. })
  37. ctx := ctxhelper.SuperAdminCtx()
  38. logic := NewUpdateDeptLogic(ctx, svcCtx)
  39. err := logic.UpdateDept(&types.UpdateDeptReq{
  40. Id: parentDeptId,
  41. Name: "Parent Updated",
  42. DeptType: "DEV",
  43. })
  44. assert.NoError(t, err)
  45. }
  46. // TC-0714: UpdateDept 当 deptType 与 status 都未变化时,不触发任何缓存清理 (audit M-5)
  47. func TestUpdateDept_Mock_NoCacheCleanWhenUnchanged(t *testing.T) {
  48. ctrl := gomock.NewController(t)
  49. defer ctrl.Finish()
  50. deptId := int64(11)
  51. mockDept := mocks.NewMockSysDeptModel(ctrl)
  52. mockDept.EXPECT().FindOne(gomock.Any(), deptId).
  53. Return(&deptModel.SysDept{
  54. Id: deptId,
  55. Name: "Old",
  56. Path: "/11/",
  57. DeptType: "NORMAL",
  58. Status: 1,
  59. UpdateTime: 2000,
  60. }, nil)
  61. mockDept.EXPECT().UpdateWithOptLock(gomock.Any(), gomock.Any(), int64(2000)).Return(nil)
  62. mockUser := mocks.NewMockSysUserModel(ctrl)
  63. // 不应调用 FindIdsByDeptId — 未设置期望,任何调用都会 FAIL
  64. svcCtx := mocks.NewMockServiceContext(mocks.MockModels{
  65. Dept: mockDept,
  66. User: mockUser,
  67. })
  68. ctx := ctxhelper.SuperAdminCtx()
  69. logic := NewUpdateDeptLogic(ctx, svcCtx)
  70. err := logic.UpdateDept(&types.UpdateDeptReq{
  71. Id: deptId,
  72. Name: "New Name",
  73. DeptType: "NORMAL", // 与原值一致
  74. Status: 1, // 与原值一致
  75. })
  76. assert.NoError(t, err)
  77. }
  78. // TC-0715: UpdateDept 乐观锁冲突时返回 409 ErrConflict (audit M-5 乐观锁补充)
  79. func TestUpdateDept_Mock_OptLockConflict(t *testing.T) {
  80. ctrl := gomock.NewController(t)
  81. defer ctrl.Finish()
  82. deptId := int64(12)
  83. mockDept := mocks.NewMockSysDeptModel(ctrl)
  84. mockDept.EXPECT().FindOne(gomock.Any(), deptId).
  85. Return(&deptModel.SysDept{
  86. Id: deptId,
  87. Name: "Old",
  88. Path: "/12/",
  89. DeptType: "NORMAL",
  90. Status: 1,
  91. UpdateTime: 3000,
  92. }, nil)
  93. // 模拟并发:另一事务已更新该行,updateTime 不再匹配
  94. mockDept.EXPECT().UpdateWithOptLock(gomock.Any(), gomock.Any(), int64(3000)).
  95. Return(deptModel.ErrUpdateConflict)
  96. svcCtx := mocks.NewMockServiceContext(mocks.MockModels{
  97. Dept: mockDept,
  98. })
  99. ctx := ctxhelper.SuperAdminCtx()
  100. logic := NewUpdateDeptLogic(ctx, svcCtx)
  101. err := logic.UpdateDept(&types.UpdateDeptReq{
  102. Id: deptId,
  103. Name: "new",
  104. })
  105. assert.Error(t, err)
  106. // 期望 409 Conflict
  107. assert.Contains(t, err.Error(), "数据已被其他操作修改")
  108. }