package gameprovider import ( "context" "testing" ) type stubProvider struct { key string name string matchIDs map[int64]bool matchIDsByGame map[string]bool shortcut []RoomGameListItem room []RoomGameListItem state *RoomStateResponse } func (s *stubProvider) Key() string { return s.key } func (s *stubProvider) DisplayName() string { return s.name } func (s *stubProvider) SupportsLaunch(_ context.Context, _ AuthUser, req LaunchRequest) (bool, error) { if req.ID > 0 { if s.matchIDs == nil { return false, nil } return s.matchIDs[req.ID], nil } if s.matchIDsByGame == nil { return false, nil } return s.matchIDsByGame[req.GameID], nil } func (s *stubProvider) ListShortcutGames(context.Context, AuthUser, string) ([]RoomGameListItem, error) { return append([]RoomGameListItem(nil), s.shortcut...), nil } func (s *stubProvider) ListRoomGames(context.Context, AuthUser, string, string) (*RoomGameListResponse, error) { return &RoomGameListResponse{Items: append([]RoomGameListItem(nil), s.room...)}, nil } func (s *stubProvider) GetRoomState(context.Context, AuthUser, string) (*RoomStateResponse, error) { if s.state == nil { return &RoomStateResponse{State: roomStateIdle}, nil } copied := *s.state return &copied, nil } func (s *stubProvider) LaunchGame(context.Context, AuthUser, LaunchRequest, string) (*LaunchResponse, error) { return &LaunchResponse{}, nil } func (s *stubProvider) CloseGame(context.Context, AuthUser, CloseRequest) (*RoomStateResponse, error) { return &RoomStateResponse{}, nil } func TestRegistryResolveIsCaseInsensitive(t *testing.T) { registry := NewRegistry(&stubProvider{key: "BAISHUN", name: "百顺"}) provider, err := registry.Resolve("baishun") if err != nil { t.Fatalf("Resolve() error = %v", err) } if provider.Key() != "BAISHUN" { t.Fatalf("Resolve() key = %q, want %q", provider.Key(), "BAISHUN") } } func TestRegistryResolveMapsLeaderAliasToLingxian(t *testing.T) { registry := NewRegistry(&stubProvider{key: "LINGXIAN", name: "灵仙"}) provider, err := registry.Resolve("LEADER") if err != nil { t.Fatalf("Resolve() error = %v", err) } if provider.Key() != "LINGXIAN" { t.Fatalf("Resolve() key = %q, want %q", provider.Key(), "LINGXIAN") } } func TestRegistryListKeepsRegistrationOrder(t *testing.T) { registry := NewRegistry( &stubProvider{key: "BAISHUN", name: "百顺"}, &stubProvider{key: "LINGXIAN", name: "灵仙"}, ) list := registry.List() if len(list.Items) != 2 { t.Fatalf("List() items = %d, want 2", len(list.Items)) } if list.Items[0].Key != "BAISHUN" || list.Items[1].Key != "LINGXIAN" { t.Fatalf("List() order = %#v", list.Items) } } func TestRegistryListRoomGamesAggregatesAndSorts(t *testing.T) { registry := NewRegistry( &stubProvider{ key: "BAISHUN", name: "百顺", room: []RoomGameListItem{{GameID: "b", Sort: 10}, {GameID: "d", Sort: 10}}, }, &stubProvider{ key: "LINGXIAN", name: "灵仙", room: []RoomGameListItem{{GameID: "a", Sort: 30}, {GameID: "c", Sort: 10}}, }, ) resp, err := registry.ListRoomGames(context.Background(), AuthUser{}, "room-1", "") if err != nil { t.Fatalf("ListRoomGames() error = %v", err) } if len(resp.Items) != 4 { t.Fatalf("ListRoomGames() items = %d, want 4", len(resp.Items)) } got := []string{resp.Items[0].GameID, resp.Items[1].GameID, resp.Items[2].GameID, resp.Items[3].GameID} want := []string{"a", "b", "c", "d"} for i := range want { if got[i] != want[i] { t.Fatalf("ListRoomGames() order = %#v, want %#v", got, want) } } } func TestRegistryLaunchGameResolvesProviderByGameID(t *testing.T) { baishunProvider := &stubProvider{ key: "BAISHUN", name: "百顺", matchIDs: map[int64]bool{101: true}, } lingxianProvider := &stubProvider{ key: "LINGXIAN", name: "灵仙", matchIDs: map[int64]bool{202: true}, } registry := NewRegistry(baishunProvider, lingxianProvider) provider, err := registry.ResolveByLaunchRequest(context.Background(), AuthUser{}, LaunchRequest{ID: 202}) if err != nil { t.Fatalf("ResolveByLaunchRequest() error = %v", err) } if provider.Key() != "LINGXIAN" { t.Fatalf("ResolveByLaunchRequest() key = %q, want %q", provider.Key(), "LINGXIAN") } } func TestRegistryCloseGameUsesMatchingSessionProvider(t *testing.T) { baishunProvider := &stubProvider{ key: "BAISHUN", name: "百顺", state: &RoomStateResponse{RoomID: "room-1", State: "PLAYING", GameSessionID: "bs-session", Provider: "BAISHUN"}, } lingxianProvider := &stubProvider{ key: "LINGXIAN", name: "灵仙", state: &RoomStateResponse{RoomID: "room-1", State: roomStateIdle, Provider: "LINGXIAN"}, } registry := NewRegistry(baishunProvider, lingxianProvider) state, provider, err := registry.resolveProviderByRoomState(context.Background(), AuthUser{}, "room-1", "bs-session") if err != nil { t.Fatalf("resolveProviderByRoomState() error = %v", err) } if provider == nil || provider.Key() != "BAISHUN" { t.Fatalf("resolveProviderByRoomState() provider = %#v", provider) } if state == nil || state.GameSessionID != "bs-session" { t.Fatalf("resolveProviderByRoomState() state = %#v", state) } }