package user import ( "database/sql" "errors" "testing" "time" userModel "perms-system-server/internal/model/user" "perms-system-server/internal/model/userrole" "perms-system-server/internal/response" "perms-system-server/internal/svc" "perms-system-server/internal/testutil" "perms-system-server/internal/testutil/ctxhelper" "perms-system-server/internal/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) // TC-0181: 正常查询 —— 超管在具体产品上下文下仅应返回该产品下的 roleIds(audit M-3 修复后的行为) func TestUserDetail_Success(t *testing.T) { ctx := ctxhelper.SuperAdminCtx() svcCtx := svc.NewServiceContext(testutil.GetTestConfig()) conn := testutil.GetTestSqlConn() username := testutil.UniqueId() userId := insertTestUser(t, ctx, 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) 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, }) 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`", roleInCurrent1, roleInCurrent2, roleInOther) testutil.CleanTable(ctx, conn, "`sys_user`", userId) }) logic := NewUserDetailLogic(ctx, svcCtx) resp, err := logic.UserDetail(&types.UserDetailReq{Id: userId}) require.NoError(t, err) require.NotNil(t, resp) 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 (audit M-3)") } // TC-0182: 正常查询-含Avatar func TestUserDetail_WithAvatar(t *testing.T) { ctx := ctxhelper.SuperAdminCtx() svcCtx := svc.NewServiceContext(testutil.GetTestConfig()) conn := testutil.GetTestSqlConn() userId := insertTestUserFull(t, ctx, &userModel.SysUser{ Username: testutil.UniqueId(), Password: testutil.HashPassword("pass"), Nickname: "avatar_user", Avatar: sql.NullString{String: "https://example.com/avatar.png", Valid: true}, IsSuperAdmin: 2, MustChangePassword: 2, Status: 1, }) t.Cleanup(func() { testutil.CleanTable(ctx, conn, "`sys_user`", userId) }) logic := NewUserDetailLogic(ctx, svcCtx) resp, err := logic.UserDetail(&types.UserDetailReq{Id: userId}) require.NoError(t, err) require.NotNil(t, resp) assert.Equal(t, "https://example.com/avatar.png", resp.Avatar) } // TC-0183: 不存在 func TestUserDetail_NotFound(t *testing.T) { ctx := ctxhelper.SuperAdminCtx() svcCtx := svc.NewServiceContext(testutil.GetTestConfig()) logic := NewUserDetailLogic(ctx, svcCtx) _, err := logic.UserDetail(&types.UserDetailReq{Id: 999999999}) require.Error(t, err) var codeErr *response.CodeError require.True(t, errors.As(err, &codeErr)) assert.Equal(t, 404, codeErr.Code()) assert.Equal(t, "用户不存在", codeErr.Error()) }