194 lines
6.6 KiB
Go
194 lines
6.6 KiB
Go
package prettyid
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"reflect"
|
|
"strconv"
|
|
"testing"
|
|
|
|
"hyapp-admin-server/internal/integration/userclient"
|
|
|
|
"google.golang.org/grpc/codes"
|
|
"google.golang.org/grpc/status"
|
|
)
|
|
|
|
type fakeGrantTargetResolver struct {
|
|
users map[int64]*userclient.User
|
|
displays map[string]*userclient.UserIdentity
|
|
calls []string
|
|
}
|
|
|
|
type fakeAssignedUserBatchGetter struct {
|
|
calls [][]int64
|
|
err error
|
|
users map[int64]*userclient.User
|
|
}
|
|
|
|
func (f *fakeAssignedUserBatchGetter) BatchGetUsers(_ context.Context, req userclient.BatchGetUsersRequest) (map[int64]*userclient.User, error) {
|
|
f.calls = append(f.calls, append([]int64(nil), req.UserIDs...))
|
|
if f.err != nil {
|
|
return nil, f.err
|
|
}
|
|
return f.users, nil
|
|
}
|
|
|
|
func (f *fakeGrantTargetResolver) GetUser(_ context.Context, req userclient.GetUserRequest) (*userclient.User, error) {
|
|
f.calls = append(f.calls, "get:"+strconv.FormatInt(req.UserID, 10))
|
|
if user := f.users[req.UserID]; user != nil {
|
|
return user, nil
|
|
}
|
|
return nil, status.Error(codes.NotFound, "user not found")
|
|
}
|
|
|
|
func (f *fakeGrantTargetResolver) ResolveDisplayUserID(_ context.Context, req userclient.ResolveDisplayUserIDRequest) (*userclient.UserIdentity, error) {
|
|
f.calls = append(f.calls, "resolve:"+req.DisplayUserID)
|
|
if identity := f.displays[req.DisplayUserID]; identity != nil {
|
|
return identity, nil
|
|
}
|
|
return nil, status.Error(codes.NotFound, "display_user_id not found")
|
|
}
|
|
|
|
func TestAttachAssignedUsersAddsSnapshotsAndSkipsZero(t *testing.T) {
|
|
getter := &fakeAssignedUserBatchGetter{
|
|
users: map[int64]*userclient.User{
|
|
42: {
|
|
Avatar: "https://cdn.example/u42.png",
|
|
DefaultDisplayUserID: "100042",
|
|
DisplayUserID: "VIP42",
|
|
PrettyDisplayUserID: "VIP42",
|
|
UserID: 42,
|
|
Username: "owner42",
|
|
},
|
|
},
|
|
}
|
|
items := []*userclient.PrettyDisplayID{
|
|
{PrettyID: "available", AssignedUserID: 0},
|
|
{PrettyID: "assigned-42", AssignedUserID: 42},
|
|
{PrettyID: "assigned-42-dup", AssignedUserID: 42},
|
|
{PrettyID: "stale-77", AssignedUserID: 77},
|
|
}
|
|
|
|
if err := attachAssignedUsers(context.Background(), getter, "req", items); err != nil {
|
|
t.Fatalf("attachAssignedUsers returned error: %v", err)
|
|
}
|
|
|
|
if want := [][]int64{{42, 77}}; !reflect.DeepEqual(getter.calls, want) {
|
|
t.Fatalf("calls mismatch: got %v want %v", getter.calls, want)
|
|
}
|
|
if items[0].AssignedUser != nil {
|
|
t.Fatalf("zero assigned user should stay empty: %+v", items[0].AssignedUser)
|
|
}
|
|
if items[1].AssignedUser == nil || items[1].AssignedUser.Username != "owner42" || items[1].AssignedUser.DefaultDisplayUserID != "100042" {
|
|
t.Fatalf("assigned snapshot mismatch: %+v", items[1].AssignedUser)
|
|
}
|
|
if items[2].AssignedUser == nil || items[2].AssignedUser.UserID != 42 {
|
|
t.Fatalf("duplicate assigned id should reuse snapshot: %+v", items[2].AssignedUser)
|
|
}
|
|
if items[3].AssignedUser != nil {
|
|
t.Fatalf("missing batch user should stay empty: %+v", items[3].AssignedUser)
|
|
}
|
|
}
|
|
|
|
func TestAttachAssignedUsersReturnsBatchError(t *testing.T) {
|
|
wantErr := errors.New("batch failed")
|
|
err := attachAssignedUsers(context.Background(), &fakeAssignedUserBatchGetter{err: wantErr}, "req", []*userclient.PrettyDisplayID{
|
|
{PrettyID: "assigned", AssignedUserID: 42},
|
|
})
|
|
if !errors.Is(err, wantErr) {
|
|
t.Fatalf("error mismatch: got %v want %v", err, wantErr)
|
|
}
|
|
}
|
|
|
|
func TestResolveGrantTargetUserIDUsesShortDisplayID(t *testing.T) {
|
|
resolver := &fakeGrantTargetResolver{
|
|
users: map[int64]*userclient.User{},
|
|
displays: map[string]*userclient.UserIdentity{
|
|
"163001": {UserID: 312899006709637120, DisplayUserID: "163001"},
|
|
},
|
|
}
|
|
|
|
userID, kind, err := resolveGrantTargetUserID(context.Background(), resolver, "req", "163001")
|
|
if err != nil {
|
|
t.Fatalf("resolveGrantTargetUserID returned error: %v", err)
|
|
}
|
|
if userID != 312899006709637120 || kind != "display_user_id" {
|
|
t.Fatalf("target mismatch: userID=%d kind=%s", userID, kind)
|
|
}
|
|
if want := []string{"resolve:163001"}; !reflect.DeepEqual(resolver.calls, want) {
|
|
t.Fatalf("calls mismatch: got %v want %v", resolver.calls, want)
|
|
}
|
|
}
|
|
|
|
func TestResolveGrantTargetUserIDKeepsLongInternalID(t *testing.T) {
|
|
resolver := &fakeGrantTargetResolver{
|
|
users: map[int64]*userclient.User{
|
|
312899006709637120: {UserID: 312899006709637120, DisplayUserID: "163001"},
|
|
},
|
|
displays: map[string]*userclient.UserIdentity{},
|
|
}
|
|
|
|
userID, kind, err := resolveGrantTargetUserID(context.Background(), resolver, "req", "312899006709637120")
|
|
if err != nil {
|
|
t.Fatalf("resolveGrantTargetUserID returned error: %v", err)
|
|
}
|
|
if userID != 312899006709637120 || kind != "user_id" {
|
|
t.Fatalf("target mismatch: userID=%d kind=%s", userID, kind)
|
|
}
|
|
if want := []string{"get:312899006709637120"}; !reflect.DeepEqual(resolver.calls, want) {
|
|
t.Fatalf("calls mismatch: got %v want %v", resolver.calls, want)
|
|
}
|
|
}
|
|
|
|
func TestResolveGrantTargetUserIDFallsBackForLongDisplayID(t *testing.T) {
|
|
resolver := &fakeGrantTargetResolver{
|
|
users: map[int64]*userclient.User{},
|
|
displays: map[string]*userclient.UserIdentity{
|
|
"312899006709637120": {UserID: 411, DisplayUserID: "312899006709637120"},
|
|
},
|
|
}
|
|
|
|
userID, kind, err := resolveGrantTargetUserID(context.Background(), resolver, "req", "312899006709637120")
|
|
if err != nil {
|
|
t.Fatalf("resolveGrantTargetUserID returned error: %v", err)
|
|
}
|
|
if userID != 411 || kind != "display_user_id" {
|
|
t.Fatalf("target mismatch: userID=%d kind=%s", userID, kind)
|
|
}
|
|
if want := []string{"get:312899006709637120", "resolve:312899006709637120"}; !reflect.DeepEqual(resolver.calls, want) {
|
|
t.Fatalf("calls mismatch: got %v want %v", resolver.calls, want)
|
|
}
|
|
}
|
|
|
|
func TestResolveGrantTargetUserIDAcceptsPrettyDisplayID(t *testing.T) {
|
|
resolver := &fakeGrantTargetResolver{
|
|
users: map[int64]*userclient.User{},
|
|
displays: map[string]*userclient.UserIdentity{
|
|
"VIP2026": {UserID: 88, DisplayUserID: "VIP2026"},
|
|
},
|
|
}
|
|
|
|
userID, kind, err := resolveGrantTargetUserID(context.Background(), resolver, "req", "VIP2026")
|
|
if err != nil {
|
|
t.Fatalf("resolveGrantTargetUserID returned error: %v", err)
|
|
}
|
|
if userID != 88 || kind != "display_user_id" {
|
|
t.Fatalf("target mismatch: userID=%d kind=%s", userID, kind)
|
|
}
|
|
if want := []string{"resolve:VIP2026"}; !reflect.DeepEqual(resolver.calls, want) {
|
|
t.Fatalf("calls mismatch: got %v want %v", resolver.calls, want)
|
|
}
|
|
}
|
|
|
|
func TestResolveGrantTargetUserIDReportsMissingTarget(t *testing.T) {
|
|
resolver := &fakeGrantTargetResolver{
|
|
users: map[int64]*userclient.User{},
|
|
displays: map[string]*userclient.UserIdentity{},
|
|
}
|
|
|
|
_, _, err := resolveGrantTargetUserID(context.Background(), resolver, "req", "163001")
|
|
if err != errGrantTargetNotFound {
|
|
t.Fatalf("error mismatch: got %v want %v", err, errGrantTargetNotFound)
|
|
}
|
|
}
|