userListLogic_test.go 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. package user
  2. import (
  3. "errors"
  4. "testing"
  5. "time"
  6. productMemberModel "perms-system-server/internal/model/productmember"
  7. "perms-system-server/internal/response"
  8. "perms-system-server/internal/svc"
  9. "perms-system-server/internal/testutil"
  10. "perms-system-server/internal/testutil/ctxhelper"
  11. "perms-system-server/internal/types"
  12. "github.com/stretchr/testify/assert"
  13. "github.com/stretchr/testify/require"
  14. )
  15. // TC-0176: 含productCode
  16. func TestUserList_WithProductCode(t *testing.T) {
  17. ctx := ctxhelper.SuperAdminCtx()
  18. svcCtx := svc.NewServiceContext(testutil.GetTestConfig())
  19. conn := testutil.GetTestSqlConn()
  20. username := testutil.UniqueId()
  21. userId := insertTestUser(t, ctx, username, testutil.HashPassword("pass"))
  22. productCode := testutil.UniqueId()
  23. now := time.Now().Unix()
  24. memberRes, err := svcCtx.SysProductMemberModel.Insert(ctx, &productMemberModel.SysProductMember{
  25. ProductCode: productCode,
  26. UserId: userId,
  27. MemberType: "ADMIN",
  28. Status: 1,
  29. CreateTime: now,
  30. UpdateTime: now,
  31. })
  32. require.NoError(t, err)
  33. memberId, _ := memberRes.LastInsertId()
  34. t.Cleanup(func() {
  35. testutil.CleanTable(ctx, conn, "`sys_product_member`", memberId)
  36. testutil.CleanTable(ctx, conn, "`sys_user`", userId)
  37. })
  38. logic := NewUserListLogic(ctx, svcCtx)
  39. resp, err := logic.UserList(&types.UserListReq{
  40. ProductCode: productCode,
  41. Page: 1,
  42. PageSize: 100,
  43. })
  44. require.NoError(t, err)
  45. require.NotNil(t, resp)
  46. assert.Greater(t, resp.Total, int64(0))
  47. items := resp.List.([]types.UserItem)
  48. found := false
  49. for _, item := range items {
  50. if item.Id == userId {
  51. found = true
  52. assert.Equal(t, "ADMIN", item.MemberType)
  53. break
  54. }
  55. }
  56. assert.True(t, found, "should find the inserted user in the list")
  57. }
  58. // TC-0177: 不含productCode
  59. func TestUserList_WithoutProductCode(t *testing.T) {
  60. ctx := ctxhelper.SuperAdminCtx()
  61. svcCtx := svc.NewServiceContext(testutil.GetTestConfig())
  62. conn := testutil.GetTestSqlConn()
  63. username := testutil.UniqueId()
  64. userId := insertTestUser(t, ctx, username, testutil.HashPassword("pass"))
  65. t.Cleanup(func() { testutil.CleanTable(ctx, conn, "`sys_user`", userId) })
  66. logic := NewUserListLogic(ctx, svcCtx)
  67. resp, err := logic.UserList(&types.UserListReq{
  68. Page: 1,
  69. PageSize: 100,
  70. })
  71. require.NoError(t, err)
  72. require.NotNil(t, resp)
  73. items := resp.List.([]types.UserItem)
  74. for _, item := range items {
  75. if item.Id == userId {
  76. assert.Equal(t, "", item.MemberType)
  77. return
  78. }
  79. }
  80. t.Fatal("should find inserted user in the list")
  81. }
  82. // TC-0178: pageSize超过上限
  83. func TestUserList_PageSizeOver100_Capped(t *testing.T) {
  84. ctx := ctxhelper.SuperAdminCtx()
  85. svcCtx := svc.NewServiceContext(testutil.GetTestConfig())
  86. logic := NewUserListLogic(ctx, svcCtx)
  87. resp, err := logic.UserList(&types.UserListReq{
  88. Page: 1,
  89. PageSize: 200,
  90. })
  91. require.NoError(t, err)
  92. require.NotNil(t, resp)
  93. items := resp.List.([]types.UserItem)
  94. assert.LessOrEqual(t, len(items), 100)
  95. }
  96. // TC-0179: 用户不在产品中
  97. func TestUserList_PartialNonMember(t *testing.T) {
  98. ctx := ctxhelper.SuperAdminCtx()
  99. svcCtx := svc.NewServiceContext(testutil.GetTestConfig())
  100. conn := testutil.GetTestSqlConn()
  101. now := time.Now().Unix()
  102. u1Name := testutil.UniqueId()
  103. u1Id := insertTestUser(t, ctx, u1Name, testutil.HashPassword("pass"))
  104. u2Name := testutil.UniqueId()
  105. u2Id := insertTestUser(t, ctx, u2Name, testutil.HashPassword("pass"))
  106. productCode := testutil.UniqueId()
  107. memberRes, err := svcCtx.SysProductMemberModel.Insert(ctx, &productMemberModel.SysProductMember{
  108. ProductCode: productCode,
  109. UserId: u1Id,
  110. MemberType: "MEMBER",
  111. Status: 1,
  112. CreateTime: now,
  113. UpdateTime: now,
  114. })
  115. require.NoError(t, err)
  116. memberId, _ := memberRes.LastInsertId()
  117. t.Cleanup(func() {
  118. testutil.CleanTable(ctx, conn, "`sys_product_member`", memberId)
  119. testutil.CleanTable(ctx, conn, "`sys_user`", u1Id, u2Id)
  120. })
  121. logic := NewUserListLogic(ctx, svcCtx)
  122. resp, err := logic.UserList(&types.UserListReq{
  123. ProductCode: productCode,
  124. Page: 1,
  125. PageSize: 100,
  126. })
  127. require.NoError(t, err)
  128. require.NotNil(t, resp)
  129. items := resp.List.([]types.UserItem)
  130. for _, item := range items {
  131. if item.Id == u1Id {
  132. assert.Equal(t, "MEMBER", item.MemberType)
  133. }
  134. if item.Id == u2Id {
  135. assert.Equal(t, "", item.MemberType)
  136. }
  137. }
  138. }
  139. // TC-0205: 非超管用户仅能看到产品成员(#1修复验证)
  140. func TestUserList_NonSuperAdminOnlySeeProductMembers(t *testing.T) {
  141. svcCtx := svc.NewServiceContext(testutil.GetTestConfig())
  142. conn := testutil.GetTestSqlConn()
  143. superCtx := ctxhelper.SuperAdminCtx()
  144. now := time.Now().Unix()
  145. productCode := testutil.UniqueId()
  146. memberName := testutil.UniqueId()
  147. memberId := insertTestUser(t, superCtx, memberName, testutil.HashPassword("pass"))
  148. nonMemberName := testutil.UniqueId()
  149. nonMemberId := insertTestUser(t, superCtx, nonMemberName, testutil.HashPassword("pass"))
  150. pmRes, err := svcCtx.SysProductMemberModel.Insert(superCtx, &productMemberModel.SysProductMember{
  151. ProductCode: productCode,
  152. UserId: memberId,
  153. MemberType: "MEMBER",
  154. Status: 1,
  155. CreateTime: now,
  156. UpdateTime: now,
  157. })
  158. require.NoError(t, err)
  159. pmId, _ := pmRes.LastInsertId()
  160. t.Cleanup(func() {
  161. testutil.CleanTable(superCtx, conn, "`sys_product_member`", pmId)
  162. testutil.CleanTable(superCtx, conn, "`sys_user`", memberId, nonMemberId)
  163. })
  164. ctx := ctxhelper.AdminCtx(productCode)
  165. logic := NewUserListLogic(ctx, svcCtx)
  166. resp, err := logic.UserList(&types.UserListReq{
  167. ProductCode: productCode,
  168. Page: 1,
  169. PageSize: 100,
  170. })
  171. require.NoError(t, err)
  172. require.NotNil(t, resp)
  173. items := resp.List.([]types.UserItem)
  174. for _, item := range items {
  175. assert.NotEqual(t, nonMemberId, item.Id,
  176. "non-member user should NOT appear in product user list for non-super-admin (audit #1)")
  177. }
  178. }
  179. // TC-0206: 非超管不带productCode时返回403
  180. func TestUserList_NonSuperAdminWithoutProductCode_Rejected(t *testing.T) {
  181. ctx := ctxhelper.AdminCtx("test_product")
  182. svcCtx := svc.NewServiceContext(testutil.GetTestConfig())
  183. logic := NewUserListLogic(ctx, svcCtx)
  184. _, err := logic.UserList(&types.UserListReq{
  185. Page: 1,
  186. PageSize: 10,
  187. })
  188. require.Error(t, err)
  189. var ce *response.CodeError
  190. require.True(t, errors.As(err, &ce))
  191. assert.Equal(t, 403, ce.Code())
  192. assert.Contains(t, ce.Error(), "非超管用户必须指定产品编码")
  193. }
  194. // TC-0207: 非超管访问其他产品数据被拒绝
  195. func TestUserList_NonSuperAdminWrongProductCode_Rejected(t *testing.T) {
  196. ctx := ctxhelper.AdminCtx("product_a")
  197. svcCtx := svc.NewServiceContext(testutil.GetTestConfig())
  198. logic := NewUserListLogic(ctx, svcCtx)
  199. _, err := logic.UserList(&types.UserListReq{
  200. ProductCode: "product_b",
  201. Page: 1,
  202. PageSize: 10,
  203. })
  204. require.Error(t, err)
  205. var ce *response.CodeError
  206. require.True(t, errors.As(err, &ce))
  207. assert.Equal(t, 403, ce.Code())
  208. assert.Contains(t, ce.Error(), "无权访问该产品的数据")
  209. }