userProductsLogic_mock_test.go 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. package member
  2. import (
  3. "errors"
  4. "testing"
  5. "perms-system-server/internal/consts"
  6. "perms-system-server/internal/loaders"
  7. productModel "perms-system-server/internal/model/product"
  8. "perms-system-server/internal/model/productmember"
  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/stretchr/testify/require"
  14. "go.uber.org/mock/gomock"
  15. )
  16. // TC-1274: 超管查询多产品(mock),正常返回
  17. func TestUserProducts_Mock_SuperAdmin_OK(t *testing.T) {
  18. ctrl := gomock.NewController(t)
  19. defer ctrl.Finish()
  20. mockPM := mocks.NewMockSysProductMemberModel(ctrl)
  21. mockPM.EXPECT().FindByUserId(gomock.Any(), int64(10)).Return([]*productmember.SysProductMember{
  22. {ProductCode: "crm", UserId: 10, MemberType: "MEMBER", Status: 1},
  23. {ProductCode: "oa", UserId: 10, MemberType: "ADMIN", Status: 1},
  24. }, nil)
  25. mockProd := mocks.NewMockSysProductModel(ctrl)
  26. mockProd.EXPECT().FindOneByCode(gomock.Any(), "crm").Return(&productModel.SysProduct{Code: "crm", Name: "CRM系统"}, nil)
  27. mockProd.EXPECT().FindOneByCode(gomock.Any(), "oa").Return(&productModel.SysProduct{Code: "oa", Name: "OA系统"}, nil)
  28. svcCtx := mocks.NewMockServiceContext(mocks.MockModels{
  29. ProductMember: mockPM,
  30. Product: mockProd,
  31. })
  32. logic := NewUserProductsLogic(ctxhelper.SuperAdminCtx(), svcCtx)
  33. resp, err := logic.UserProducts(&types.UserProductsReq{UserId: 10})
  34. require.NoError(t, err)
  35. require.Len(t, resp.List, 2)
  36. assert.Equal(t, "crm", resp.List[0].ProductCode)
  37. assert.Equal(t, "CRM系统", resp.List[0].ProductName)
  38. assert.Equal(t, "MEMBER", resp.List[0].MemberType)
  39. assert.Equal(t, "oa", resp.List[1].ProductCode)
  40. assert.Equal(t, "ADMIN", resp.List[1].MemberType)
  41. }
  42. // TC-1275: 本人查询自己的产品列表(mock),正常返回
  43. func TestUserProducts_Mock_Self_OK(t *testing.T) {
  44. ctrl := gomock.NewController(t)
  45. defer ctrl.Finish()
  46. mockPM := mocks.NewMockSysProductMemberModel(ctrl)
  47. mockPM.EXPECT().FindByUserId(gomock.Any(), int64(20)).Return([]*productmember.SysProductMember{
  48. {ProductCode: "crm", UserId: 20, MemberType: "MEMBER", Status: 1},
  49. }, nil)
  50. mockProd := mocks.NewMockSysProductModel(ctrl)
  51. mockProd.EXPECT().FindOneByCode(gomock.Any(), "crm").Return(&productModel.SysProduct{Code: "crm", Name: "CRM系统"}, nil)
  52. svcCtx := mocks.NewMockServiceContext(mocks.MockModels{
  53. ProductMember: mockPM,
  54. Product: mockProd,
  55. })
  56. ctx := ctxhelper.CustomCtx(&loaders.UserDetails{
  57. UserId: 20,
  58. Username: "user20",
  59. IsSuperAdmin: false,
  60. MemberType: consts.MemberTypeMember,
  61. Status: consts.StatusEnabled,
  62. ProductCode: "crm",
  63. })
  64. logic := NewUserProductsLogic(ctx, svcCtx)
  65. resp, err := logic.UserProducts(&types.UserProductsReq{UserId: 20})
  66. require.NoError(t, err)
  67. require.Len(t, resp.List, 1)
  68. assert.Equal(t, "crm", resp.List[0].ProductCode)
  69. }
  70. // TC-1276: 非超管查询他人产品列表(mock),返回 403
  71. func TestUserProducts_Mock_OtherUser_Forbidden(t *testing.T) {
  72. ctrl := gomock.NewController(t)
  73. defer ctrl.Finish()
  74. svcCtx := mocks.NewMockServiceContext(mocks.MockModels{})
  75. ctx := ctxhelper.CustomCtx(&loaders.UserDetails{
  76. UserId: 20,
  77. Username: "user20",
  78. IsSuperAdmin: false,
  79. MemberType: consts.MemberTypeMember,
  80. Status: consts.StatusEnabled,
  81. ProductCode: "crm",
  82. })
  83. logic := NewUserProductsLogic(ctx, svcCtx)
  84. resp, err := logic.UserProducts(&types.UserProductsReq{UserId: 99})
  85. assert.Nil(t, resp)
  86. assert.Error(t, err)
  87. assert.Contains(t, err.Error(), "无权查看他人")
  88. }
  89. // TC-1277: FindByUserId 数据库错误,向上透传(mock)
  90. func TestUserProducts_Mock_DBError(t *testing.T) {
  91. ctrl := gomock.NewController(t)
  92. defer ctrl.Finish()
  93. dbErr := errors.New("db error")
  94. mockPM := mocks.NewMockSysProductMemberModel(ctrl)
  95. mockPM.EXPECT().FindByUserId(gomock.Any(), int64(10)).Return(nil, dbErr)
  96. svcCtx := mocks.NewMockServiceContext(mocks.MockModels{
  97. ProductMember: mockPM,
  98. })
  99. logic := NewUserProductsLogic(ctxhelper.SuperAdminCtx(), svcCtx)
  100. resp, err := logic.UserProducts(&types.UserProductsReq{UserId: 10})
  101. assert.Nil(t, resp)
  102. assert.ErrorIs(t, err, dbErr)
  103. }
  104. // TC-1278: 产品查询失败时跳过该条记录(mock,容错)
  105. func TestUserProducts_Mock_ProductNotFound_Skip(t *testing.T) {
  106. ctrl := gomock.NewController(t)
  107. defer ctrl.Finish()
  108. mockPM := mocks.NewMockSysProductMemberModel(ctrl)
  109. mockPM.EXPECT().FindByUserId(gomock.Any(), int64(10)).Return([]*productmember.SysProductMember{
  110. {ProductCode: "crm", UserId: 10, MemberType: "MEMBER", Status: 1},
  111. {ProductCode: "ghost", UserId: 10, MemberType: "MEMBER", Status: 1},
  112. }, nil)
  113. mockProd := mocks.NewMockSysProductModel(ctrl)
  114. mockProd.EXPECT().FindOneByCode(gomock.Any(), "crm").Return(&productModel.SysProduct{Code: "crm", Name: "CRM系统"}, nil)
  115. mockProd.EXPECT().FindOneByCode(gomock.Any(), "ghost").Return(nil, errors.New("not found"))
  116. svcCtx := mocks.NewMockServiceContext(mocks.MockModels{
  117. ProductMember: mockPM,
  118. Product: mockProd,
  119. })
  120. logic := NewUserProductsLogic(ctxhelper.SuperAdminCtx(), svcCtx)
  121. resp, err := logic.UserProducts(&types.UserProductsReq{UserId: 10})
  122. require.NoError(t, err)
  123. require.Len(t, resp.List, 1)
  124. assert.Equal(t, "crm", resp.List[0].ProductCode)
  125. }
  126. // TC-1279: 用户未加入任何产品,返回空列表(mock)
  127. func TestUserProducts_Mock_Empty(t *testing.T) {
  128. ctrl := gomock.NewController(t)
  129. defer ctrl.Finish()
  130. mockPM := mocks.NewMockSysProductMemberModel(ctrl)
  131. mockPM.EXPECT().FindByUserId(gomock.Any(), int64(10)).Return([]*productmember.SysProductMember{}, nil)
  132. svcCtx := mocks.NewMockServiceContext(mocks.MockModels{
  133. ProductMember: mockPM,
  134. })
  135. logic := NewUserProductsLogic(ctxhelper.SuperAdminCtx(), svcCtx)
  136. resp, err := logic.UserProducts(&types.UserProductsReq{UserId: 10})
  137. require.NoError(t, err)
  138. assert.Empty(t, resp.List)
  139. }