package regionblock import ( "context" "errors" "reflect" "testing" "hyapp-admin-server/internal/integration/userclient" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) type fakeWhitelistCacheUserClient struct { userclient.Client called bool err error resolveErr error users map[int64]*userclient.User identities map[string]*userclient.UserIdentity } func (f *fakeWhitelistCacheUserClient) RefreshLoginRiskWhitelistCache(_ context.Context, req userclient.RefreshLoginRiskWhitelistCacheRequest) (*userclient.LoginRiskWhitelistCacheSnapshot, error) { f.called = true if req.RequestID != "req-refresh" || req.Caller != "admin-server" { return nil, errors.New("unexpected refresh request") } if f.err != nil { return nil, f.err } return &userclient.LoginRiskWhitelistCacheSnapshot{Refreshed: true, UserWhitelistCount: 2}, nil } func (f *fakeWhitelistCacheUserClient) ResolveDisplayUserID(_ context.Context, req userclient.ResolveDisplayUserIDRequest) (*userclient.UserIdentity, error) { if req.RequestID != "req-refresh" || req.Caller != "admin-server" { return nil, errors.New("unexpected resolve request") } if f.resolveErr != nil { return nil, f.resolveErr } if identity := f.identities[req.DisplayUserID]; identity != nil { return identity, nil } return nil, status.Error(codes.NotFound, "display user id not found") } func (f *fakeWhitelistCacheUserClient) GetUser(_ context.Context, req userclient.GetUserRequest) (*userclient.User, error) { if req.RequestID != "req-refresh" || req.Caller != "admin-server" { return nil, errors.New("unexpected get user request") } if user := f.users[req.UserID]; user != nil { return user, nil } return nil, status.Error(codes.NotFound, "user not found") } func TestNormalizeUserIDWhitelistResolvesDisplayIDsAndInternalIDs(t *testing.T) { service := NewService(nil, &fakeWhitelistCacheUserClient{ users: map[int64]*userclient.User{ 990000: {UserID: 990000}, }, identities: map[string]*userclient.UserIdentity{ "VIP2026": {UserID: 900025, DisplayUserID: "VIP2026"}, "123456789012": {UserID: 900026, DisplayUserID: "123456789012"}, }, }) got, err := service.normalizeUserIDWhitelist(context.Background(), "req-refresh", []string{" VIP2026 ", "123456789012", "990000", "VIP2026"}) if err != nil { t.Fatalf("normalize user whitelist failed: %v", err) } want := []int64{900025, 900026, 990000} if !reflect.DeepEqual(got, want) { t.Fatalf("normalized user whitelist = %+v, want %+v", got, want) } } func TestNormalizeUserIDWhitelistRejectsInvalidID(t *testing.T) { service := NewService(nil, &fakeWhitelistCacheUserClient{}) for _, raw := range [][]string{{""}, {"0"}, {"-1"}, {"VIP-2026"}, {"123456"}} { if _, err := service.normalizeUserIDWhitelist(context.Background(), "req-refresh", raw); !errors.Is(err, errInvalidPayload) { t.Fatalf("normalize %v error = %v, want errInvalidPayload", raw, err) } } } func TestNormalizeUserIDWhitelistKeepsUserServiceError(t *testing.T) { upstreamErr := status.Error(codes.Unavailable, "user-service unavailable") service := NewService(nil, &fakeWhitelistCacheUserClient{resolveErr: upstreamErr}) _, err := service.normalizeUserIDWhitelist(context.Background(), "req-refresh", []string{"VIP2026"}) if !errors.Is(err, upstreamErr) { t.Fatalf("normalize error = %v, want upstream error", err) } if errors.Is(err, errInvalidPayload) { t.Fatalf("normalize error = %v, should not be mapped to invalid payload", err) } } func TestRefreshWhitelistCacheMapsUserServiceError(t *testing.T) { client := &fakeWhitelistCacheUserClient{err: errors.New("rpc down")} service := NewService(nil, client) err := service.refreshWhitelistCache(context.Background(), "req-refresh") if !client.called { t.Fatal("expected refresh rpc to be called") } if !errors.Is(err, errWhitelistCacheRefresh) { t.Fatalf("refresh error = %v, want errWhitelistCacheRefresh", err) } }