|
|
@@ -22,16 +22,59 @@ import (
|
|
|
"github.com/stretchr/testify/require"
|
|
|
)
|
|
|
|
|
|
-func TestUserDetail_Success(t *testing.T) {
|
|
|
- ctx := ctxhelper.SuperAdminCtx()
|
|
|
+// TC-1267: 超管不传 productCode → roleIds 含目标用户所有产品角色(全量)
|
|
|
+func TestUserDetail_SuperAdmin_NoProductCode_ReturnsAllRoles(t *testing.T) {
|
|
|
svcCtx := svc.NewServiceContext(testutil.GetTestConfig())
|
|
|
conn := testutil.GetTestSqlConn()
|
|
|
|
|
|
+ // 超管 ctx 中 ProductCode 为空,模拟真实超管登录态
|
|
|
+ ctx := ctxhelper.CustomCtx(&loaders.UserDetails{
|
|
|
+ UserId: 1,
|
|
|
+ Username: "superadmin",
|
|
|
+ IsSuperAdmin: true,
|
|
|
+ MemberType: consts.MemberTypeSuperAdmin,
|
|
|
+ Status: consts.StatusEnabled,
|
|
|
+ ProductCode: "",
|
|
|
+ })
|
|
|
+
|
|
|
username := testutil.UniqueId()
|
|
|
- userId := insertTestUser(t, ctx, username, testutil.HashPassword("pass"))
|
|
|
+ userId := insertTestUser(t, ctxhelper.SuperAdminCtx(), username, testutil.HashPassword("pass"))
|
|
|
+
|
|
|
+ roleInP1 := insertTestRole(t, svcCtx, "test_product", 1)
|
|
|
+ roleInP2 := insertTestRole(t, svcCtx, "other_product", 1)
|
|
|
+
|
|
|
+ now := time.Now().Unix()
|
|
|
+ var roleRecordIds []int64
|
|
|
+ for _, roleId := range []int64{roleInP1, roleInP2} {
|
|
|
+ res, err := svcCtx.SysUserRoleModel.Insert(ctxhelper.SuperAdminCtx(), &userrole.SysUserRole{
|
|
|
+ UserId: userId, RoleId: roleId, CreateTime: now, UpdateTime: now,
|
|
|
+ })
|
|
|
+ require.NoError(t, err)
|
|
|
+ id, _ := res.LastInsertId()
|
|
|
+ roleRecordIds = append(roleRecordIds, id)
|
|
|
+ }
|
|
|
+
|
|
|
+ t.Cleanup(func() {
|
|
|
+ testutil.CleanTable(ctx, conn, "`sys_user_role`", roleRecordIds...)
|
|
|
+ testutil.CleanTable(ctx, conn, "`sys_role`", roleInP1, roleInP2)
|
|
|
+ testutil.CleanTable(ctx, conn, "`sys_user`", userId)
|
|
|
+ })
|
|
|
+
|
|
|
+ resp, err := NewUserDetailLogic(ctx, svcCtx).UserDetail(&types.UserDetailReq{Id: userId})
|
|
|
+ require.NoError(t, err)
|
|
|
+ assert.ElementsMatch(t, []int64{roleInP1, roleInP2}, resp.RoleIds,
|
|
|
+ "超管不传 productCode 时应返回全量角色(跨产品)")
|
|
|
+}
|
|
|
+
|
|
|
+// TC-1268: 超管传 productCode → roleIds 只含该产品角色
|
|
|
+func TestUserDetail_SuperAdmin_WithProductCode_FiltersRoles(t *testing.T) {
|
|
|
+ svcCtx := svc.NewServiceContext(testutil.GetTestConfig())
|
|
|
+ conn := testutil.GetTestSqlConn()
|
|
|
+ superCtx := ctxhelper.SuperAdminCtx()
|
|
|
+
|
|
|
+ username := testutil.UniqueId()
|
|
|
+ userId := insertTestUser(t, superCtx, username, testutil.HashPassword("pass"))
|
|
|
|
|
|
- // 插入两条"当前产品"下的真实 sys_role 以及一条属于其它产品的 sys_role,
|
|
|
- // 用户同时绑定这三个角色。超管在 test_product 上下文下应当只看到前两个。
|
|
|
roleInCurrent1 := insertTestRole(t, svcCtx, "test_product", 1)
|
|
|
roleInCurrent2 := insertTestRole(t, svcCtx, "test_product", 1)
|
|
|
roleInOther := insertTestRole(t, svcCtx, "other_product", 1)
|
|
|
@@ -39,11 +82,8 @@ func TestUserDetail_Success(t *testing.T) {
|
|
|
now := time.Now().Unix()
|
|
|
var roleRecordIds []int64
|
|
|
for _, roleId := range []int64{roleInCurrent1, roleInCurrent2, roleInOther} {
|
|
|
- res, err := svcCtx.SysUserRoleModel.Insert(ctx, &userrole.SysUserRole{
|
|
|
- UserId: userId,
|
|
|
- RoleId: roleId,
|
|
|
- CreateTime: now,
|
|
|
- UpdateTime: now,
|
|
|
+ res, err := svcCtx.SysUserRoleModel.Insert(superCtx, &userrole.SysUserRole{
|
|
|
+ UserId: userId, RoleId: roleId, CreateTime: now, UpdateTime: now,
|
|
|
})
|
|
|
require.NoError(t, err)
|
|
|
id, _ := res.LastInsertId()
|
|
|
@@ -51,21 +91,64 @@ func TestUserDetail_Success(t *testing.T) {
|
|
|
}
|
|
|
|
|
|
t.Cleanup(func() {
|
|
|
- testutil.CleanTable(ctx, conn, "`sys_user_role`", roleRecordIds...)
|
|
|
- testutil.CleanTable(ctx, conn, "`sys_role`", roleInCurrent1, roleInCurrent2, roleInOther)
|
|
|
- testutil.CleanTable(ctx, conn, "`sys_user`", userId)
|
|
|
+ testutil.CleanTable(superCtx, conn, "`sys_user_role`", roleRecordIds...)
|
|
|
+ testutil.CleanTable(superCtx, conn, "`sys_role`", roleInCurrent1, roleInCurrent2, roleInOther)
|
|
|
+ testutil.CleanTable(superCtx, conn, "`sys_user`", userId)
|
|
|
})
|
|
|
|
|
|
- logic := NewUserDetailLogic(ctx, svcCtx)
|
|
|
- resp, err := logic.UserDetail(&types.UserDetailReq{Id: userId})
|
|
|
+ resp, err := NewUserDetailLogic(superCtx, svcCtx).UserDetail(&types.UserDetailReq{
|
|
|
+ Id: userId,
|
|
|
+ ProductCode: "test_product",
|
|
|
+ })
|
|
|
require.NoError(t, err)
|
|
|
- require.NotNil(t, resp)
|
|
|
+ assert.ElementsMatch(t, []int64{roleInCurrent1, roleInCurrent2}, resp.RoleIds,
|
|
|
+ "超管传 productCode 时只返回该产品下的角色")
|
|
|
+ assert.NotContains(t, resp.RoleIds, roleInOther,
|
|
|
+ "其他产品的角色不应出现在结果中")
|
|
|
+}
|
|
|
+
|
|
|
+// TC-1269: 非超管不传 productCode → roleIds 只含 JWT context 产品角色;req.productCode 被忽略
|
|
|
+func TestUserDetail_NonSuperAdmin_UsesCtxProductCode(t *testing.T) {
|
|
|
+ svcCtx := svc.NewServiceContext(testutil.GetTestConfig())
|
|
|
+ conn := testutil.GetTestSqlConn()
|
|
|
+ superCtx := ctxhelper.SuperAdminCtx()
|
|
|
+
|
|
|
+ productCode := "test_product"
|
|
|
+ username := testutil.UniqueId()
|
|
|
+ userId := insertTestUser(t, superCtx, username, testutil.HashPassword("pass"))
|
|
|
+ mId := insertTestMember(t, svcCtx, productCode, userId)
|
|
|
+
|
|
|
+ roleInCtx := insertTestRole(t, svcCtx, productCode, 1)
|
|
|
+ roleInOther := insertTestRole(t, svcCtx, "other_product", 1)
|
|
|
|
|
|
- assert.Equal(t, userId, resp.Id)
|
|
|
- assert.Equal(t, username, resp.Username)
|
|
|
- // 修复后:超管在产品上下文里只看到 test_product 的角色;other_product 的角色不应返回
|
|
|
- assert.ElementsMatch(t, []int64{roleInCurrent1, roleInCurrent2}, resp.RoleIds)
|
|
|
- assert.NotContains(t, resp.RoleIds, roleInOther, "超管在具体产品上下文不应返回其它产品的 roleIds")
|
|
|
+ now := time.Now().Unix()
|
|
|
+ var roleRecordIds []int64
|
|
|
+ for _, roleId := range []int64{roleInCtx, roleInOther} {
|
|
|
+ res, err := svcCtx.SysUserRoleModel.Insert(superCtx, &userrole.SysUserRole{
|
|
|
+ UserId: userId, RoleId: roleId, CreateTime: now, UpdateTime: now,
|
|
|
+ })
|
|
|
+ require.NoError(t, err)
|
|
|
+ id, _ := res.LastInsertId()
|
|
|
+ roleRecordIds = append(roleRecordIds, id)
|
|
|
+ }
|
|
|
+
|
|
|
+ t.Cleanup(func() {
|
|
|
+ testutil.CleanTable(superCtx, conn, "`sys_user_role`", roleRecordIds...)
|
|
|
+ testutil.CleanTable(superCtx, conn, "`sys_product_member`", mId)
|
|
|
+ testutil.CleanTable(superCtx, conn, "`sys_role`", roleInCtx, roleInOther)
|
|
|
+ testutil.CleanTable(superCtx, conn, "`sys_user`", userId)
|
|
|
+ })
|
|
|
+
|
|
|
+ // ADMIN ctx productCode="test_product",req 里传 "other_product" 应被忽略
|
|
|
+ ctx := ctxhelper.AdminCtx(productCode)
|
|
|
+ resp, err := NewUserDetailLogic(ctx, svcCtx).UserDetail(&types.UserDetailReq{
|
|
|
+ Id: userId,
|
|
|
+ ProductCode: "other_product", // 非超管时此字段应被忽略
|
|
|
+ })
|
|
|
+ require.NoError(t, err)
|
|
|
+ assert.ElementsMatch(t, []int64{roleInCtx}, resp.RoleIds,
|
|
|
+ "非超管始终用 JWT context productCode,req.productCode 应被忽略")
|
|
|
+ assert.NotContains(t, resp.RoleIds, roleInOther)
|
|
|
}
|
|
|
|
|
|
// TC-0182: 正常查询-含Avatar
|