2026-06-12 19:37:04 +08:00

229 lines
6.5 KiB
Go

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 TestRegistryResolveMapsHotgameAliases(t *testing.T) {
registry := NewRegistry(&stubProvider{key: "HOTGAME", name: "热游"})
for _, alias := range []string{"HOTGAME", "hot_game", "REYOU", "lalu"} {
provider, err := registry.Resolve(alias)
if err != nil {
t.Fatalf("Resolve(%q) error = %v", alias, err)
}
if provider.Key() != "HOTGAME" {
t.Fatalf("Resolve(%q) key = %q, want HOTGAME", alias, provider.Key())
}
}
}
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 TestRegistryListRoomGamesReturnsEmptyForHardcodedTestUser(t *testing.T) {
registry := NewRegistry(&stubProvider{
key: "BAISHUN",
name: "百顺",
room: []RoomGameListItem{{GameID: "a", Sort: 30}},
})
resp, err := registry.ListRoomGames(
context.Background(),
AuthUser{UserID: 2061394478798794754},
"room-1",
"",
)
if err != nil {
t.Fatalf("ListRoomGames() error = %v", err)
}
if len(resp.Items) != 0 {
t.Fatalf("ListRoomGames() items = %d, want 0", len(resp.Items))
}
}
func TestRegistryListShortcutGamesReturnsEmptyForHardcodedTestUser(t *testing.T) {
registry := NewRegistry(&stubProvider{
key: "BAISHUN",
name: "百顺",
shortcut: []RoomGameListItem{{GameID: "a", Sort: 30}},
})
items, err := registry.ListShortcutGames(
context.Background(),
AuthUser{UserID: 2061394478798794754},
"room-1",
)
if err != nil {
t.Fatalf("ListShortcutGames() error = %v", err)
}
if len(items) != 0 {
t.Fatalf("ListShortcutGames() items = %d, want 0", len(items))
}
}
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)
}
}