330 lines
9.9 KiB
Go
330 lines
9.9 KiB
Go
package lingxian
|
|
|
|
import (
|
|
"chatapp3-golang/internal/config"
|
|
"chatapp3-golang/internal/model"
|
|
"chatapp3-golang/internal/service/gameprovider"
|
|
"context"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"net/url"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"gorm.io/driver/sqlite"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
func TestSyncAdminGamesFetchesCatalogAndImportsUnifiedList(t *testing.T) {
|
|
ctx := context.Background()
|
|
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
|
|
if err != nil {
|
|
t.Fatalf("open sqlite: %v", err)
|
|
}
|
|
if err := db.AutoMigrate(
|
|
&model.LingxianProviderConfig{},
|
|
&model.LingxianGameCatalog{},
|
|
&model.SysGameListConfig{},
|
|
&model.SysGameListVendorExt{},
|
|
); err != nil {
|
|
t.Fatalf("migrate: %v", err)
|
|
}
|
|
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
_, _ = w.Write([]byte(`[{"gameId":"1","name":"Fruit Party","title":"水果奇缘","ver":11,"full_url":"https://example.test/full.html","half_url":"https://example.test/half.html"}]`))
|
|
}))
|
|
defer server.Close()
|
|
|
|
now := time.Now()
|
|
if err := db.Create(&model.LingxianProviderConfig{
|
|
ID: 1,
|
|
SysOrigin: "LIKEI",
|
|
Profile: profileProd,
|
|
Active: true,
|
|
GameListURL: server.URL,
|
|
AppKey: "test-key",
|
|
CreateTime: now,
|
|
UpdateTime: now,
|
|
}).Error; err != nil {
|
|
t.Fatalf("seed provider: %v", err)
|
|
}
|
|
|
|
service := NewService(config.Config{HTTP: config.HTTPConfig{Timeout: time.Second}}, db, nil)
|
|
resp, err := service.SyncAdminGames(ctx, SyncCatalogRequest{SysOrigin: "LIKEI", Profile: profileProd})
|
|
if err != nil {
|
|
t.Fatalf("SyncAdminGames: %v", err)
|
|
}
|
|
if resp.Imported != 1 {
|
|
t.Fatalf("imported = %d, want 1", resp.Imported)
|
|
}
|
|
|
|
var cfg model.SysGameListConfig
|
|
if err := db.Where("sys_origin = ? AND game_origin = ? AND game_id = ?", "LIKEI", vendorType, "1").First(&cfg).Error; err != nil {
|
|
t.Fatalf("unified config missing: %v", err)
|
|
}
|
|
var ext model.SysGameListVendorExt
|
|
if err := db.Where("game_list_config_id = ? AND vendor_type = ? AND profile = ?", cfg.ID, vendorType, profileProd).First(&ext).Error; err != nil {
|
|
t.Fatalf("vendor ext missing: %v", err)
|
|
}
|
|
if ext.VendorGameID != "1" || ext.PackageURL != "https://example.test/full.html" {
|
|
t.Fatalf("vendor ext = %#v", ext)
|
|
}
|
|
if !cfg.Showcase {
|
|
t.Fatalf("showcase = false, want true by default")
|
|
}
|
|
}
|
|
|
|
func TestImportCatalogGamesCanDefaultToHidden(t *testing.T) {
|
|
ctx := context.Background()
|
|
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
|
|
if err != nil {
|
|
t.Fatalf("open sqlite: %v", err)
|
|
}
|
|
if err := db.AutoMigrate(
|
|
&model.LingxianProviderConfig{},
|
|
&model.LingxianGameCatalog{},
|
|
&model.SysGameListConfig{},
|
|
&model.SysGameListVendorExt{},
|
|
); err != nil {
|
|
t.Fatalf("migrate: %v", err)
|
|
}
|
|
|
|
now := time.Now()
|
|
if err := db.Create(&model.LingxianProviderConfig{
|
|
ID: 11,
|
|
SysOrigin: "LIKEI",
|
|
Profile: profileProd,
|
|
Active: true,
|
|
AppKey: "test-key",
|
|
TestUID: "test-uid",
|
|
TestToken: "test-token",
|
|
TestRoomID: "test-room",
|
|
CreateTime: now,
|
|
UpdateTime: now,
|
|
}).Error; err != nil {
|
|
t.Fatalf("seed provider: %v", err)
|
|
}
|
|
if err := db.Create(&model.LingxianGameCatalog{
|
|
ID: 12,
|
|
SysOrigin: "LIKEI",
|
|
Profile: profileProd,
|
|
InternalGameID: "lx_2",
|
|
VendorGameID: "2",
|
|
Name: "Hidden Lingxian",
|
|
Status: catalogEnabled,
|
|
CreateTime: now,
|
|
UpdateTime: now,
|
|
}).Error; err != nil {
|
|
t.Fatalf("seed catalog: %v", err)
|
|
}
|
|
|
|
service := NewService(config.Config{HTTP: config.HTTPConfig{Timeout: time.Second}}, db, nil)
|
|
resp, err := service.ImportCatalogGames(ctx, "LIKEI", profileProd, []string{"2"}, false)
|
|
if err != nil {
|
|
t.Fatalf("ImportCatalogGames: %v", err)
|
|
}
|
|
if resp.Imported != 1 {
|
|
t.Fatalf("imported = %d, want 1", resp.Imported)
|
|
}
|
|
|
|
var cfg model.SysGameListConfig
|
|
if err := db.Where("sys_origin = ? AND game_origin = ? AND game_id = ?", "LIKEI", vendorType, "lx_2").First(&cfg).Error; err != nil {
|
|
t.Fatalf("unified config missing: %v", err)
|
|
}
|
|
if cfg.Showcase {
|
|
t.Fatalf("showcase = true, want false")
|
|
}
|
|
}
|
|
|
|
func TestSaveProviderConfigPersistsTestRoomID(t *testing.T) {
|
|
ctx := context.Background()
|
|
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
|
|
if err != nil {
|
|
t.Fatalf("open sqlite: %v", err)
|
|
}
|
|
if err := db.AutoMigrate(&model.LingxianProviderConfig{}); err != nil {
|
|
t.Fatalf("migrate: %v", err)
|
|
}
|
|
|
|
service := NewService(config.Config{HTTP: config.HTTPConfig{Timeout: time.Second}}, db, nil)
|
|
saved, err := service.SaveProviderConfig(ctx, SaveProviderConfigRequest{
|
|
SysOrigin: "LIKEI",
|
|
Profile: profileProd,
|
|
GameListURL: "https://example.test/list.json",
|
|
AppKey: "test-key",
|
|
TestUID: "test-uid",
|
|
TestToken: "test-token",
|
|
TestRoomID: "test-room",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("SaveProviderConfig: %v", err)
|
|
}
|
|
if saved.TestRoomID != "test-room" {
|
|
t.Fatalf("saved testRoomId = %q, want test-room", saved.TestRoomID)
|
|
}
|
|
|
|
runtimeCfg, err := service.resolveRuntimeConfigForProfile(ctx, "LIKEI", profileProd)
|
|
if err != nil {
|
|
t.Fatalf("resolveRuntimeConfigForProfile: %v", err)
|
|
}
|
|
if runtimeCfg.TestRoomID != "test-room" {
|
|
t.Fatalf("runtime testRoomId = %q, want test-room", runtimeCfg.TestRoomID)
|
|
}
|
|
}
|
|
|
|
func TestAppProviderUsesHalfURLForHalfScreenGames(t *testing.T) {
|
|
ctx := context.Background()
|
|
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
|
|
if err != nil {
|
|
t.Fatalf("open sqlite: %v", err)
|
|
}
|
|
if err := db.AutoMigrate(
|
|
&model.LingxianProviderConfig{},
|
|
&model.LingxianGameCatalog{},
|
|
&model.SysGameListConfig{},
|
|
&model.SysGameListVendorExt{},
|
|
); err != nil {
|
|
t.Fatalf("migrate: %v", err)
|
|
}
|
|
|
|
now := time.Now()
|
|
if err := db.Create(&model.LingxianProviderConfig{
|
|
ID: 21,
|
|
SysOrigin: "LIKEI",
|
|
Profile: profileProd,
|
|
Active: true,
|
|
AppKey: "test-key",
|
|
TestUID: "test-uid",
|
|
TestToken: "test-token",
|
|
TestRoomID: "test-room",
|
|
CreateTime: now,
|
|
UpdateTime: now,
|
|
}).Error; err != nil {
|
|
t.Fatalf("seed provider: %v", err)
|
|
}
|
|
if err := db.Create(&model.LingxianGameCatalog{
|
|
ID: 22,
|
|
SysOrigin: "LIKEI",
|
|
Profile: profileProd,
|
|
InternalGameID: "1",
|
|
VendorGameID: "1",
|
|
Name: "Half Lingxian",
|
|
PreviewURL: "https://example.test/half.html",
|
|
DownloadURL: "https://example.test/full.html",
|
|
PackageVersion: "11",
|
|
Status: catalogEnabled,
|
|
CreateTime: now,
|
|
UpdateTime: now,
|
|
}).Error; err != nil {
|
|
t.Fatalf("seed catalog: %v", err)
|
|
}
|
|
if err := db.Create(&model.SysGameListConfig{
|
|
ID: 23,
|
|
SysOrigin: "LIKEI",
|
|
GameOrigin: vendorType,
|
|
GameID: "1",
|
|
Name: "Half Lingxian",
|
|
Category: roomCategory,
|
|
GameCode: "1",
|
|
Showcase: true,
|
|
Sort: 1,
|
|
FullScreen: false,
|
|
ClientOrigin: "COMMON",
|
|
GameMode: "[3]",
|
|
}).Error; err != nil {
|
|
t.Fatalf("seed config: %v", err)
|
|
}
|
|
orientation := 1
|
|
if err := db.Create(&model.SysGameListVendorExt{
|
|
ID: 24,
|
|
GameListConfigID: 23,
|
|
SysOrigin: "LIKEI",
|
|
Profile: profileProd,
|
|
VendorType: vendorType,
|
|
VendorGameID: "1",
|
|
LaunchMode: launchModeH5,
|
|
PackageVersion: "11",
|
|
PackageURL: "https://example.test/full.html",
|
|
PreviewURL: "https://example.test/half.html",
|
|
Orientation: &orientation,
|
|
SafeHeight: 640,
|
|
BridgeSchemaVersion: "1.0",
|
|
ExtraJSON: `{"gameType":"LINGXIAN"}`,
|
|
Enabled: true,
|
|
CreateTime: now,
|
|
UpdateTime: now,
|
|
}).Error; err != nil {
|
|
t.Fatalf("seed vendor ext: %v", err)
|
|
}
|
|
|
|
service := NewService(config.Config{HTTP: config.HTTPConfig{Timeout: time.Second}}, db, nil)
|
|
provider := NewAppProvider(service)
|
|
user := gameprovider.AuthUser{UserID: 1001, SysOrigin: "LIKEI", Token: "user-token"}
|
|
|
|
list, err := provider.ListRoomGames(ctx, user, "room-1", roomCategory)
|
|
if err != nil {
|
|
t.Fatalf("ListRoomGames: %v", err)
|
|
}
|
|
if len(list.Items) != 1 {
|
|
t.Fatalf("items = %d, want 1", len(list.Items))
|
|
}
|
|
item := list.Items[0]
|
|
if item.FullScreen {
|
|
t.Fatalf("fullScreen = true, want false")
|
|
}
|
|
if item.SafeHeight != 640 {
|
|
t.Fatalf("safeHeight = %d, want 640", item.SafeHeight)
|
|
}
|
|
if item.Orientation != 1 {
|
|
t.Fatalf("orientation = %d, want 1", item.Orientation)
|
|
}
|
|
if got := item.LaunchParams["screenMode"]; got != "half" {
|
|
t.Fatalf("screenMode = %v, want half", got)
|
|
}
|
|
|
|
launch, err := provider.LaunchGame(ctx, user, gameprovider.LaunchRequest{RoomID: "room-1", GameID: "1"}, "")
|
|
if err != nil {
|
|
t.Fatalf("LaunchGame: %v", err)
|
|
}
|
|
if !strings.HasPrefix(launch.Entry.EntryURL, "https://example.test/half.html?") {
|
|
t.Fatalf("entryUrl = %q, want half url with query", launch.Entry.EntryURL)
|
|
}
|
|
if strings.Contains(launch.Entry.EntryURL, "full.html") {
|
|
t.Fatalf("entryUrl = %q, should not use full url", launch.Entry.EntryURL)
|
|
}
|
|
if launch.Entry.SafeHeight != 640 {
|
|
t.Fatalf("launch safeHeight = %d, want 640", launch.Entry.SafeHeight)
|
|
}
|
|
parsed, err := url.Parse(launch.Entry.EntryURL)
|
|
if err != nil {
|
|
t.Fatalf("parse entry url: %v", err)
|
|
}
|
|
query := parsed.Query()
|
|
if got := query.Get("uid"); got != "test-uid" {
|
|
t.Fatalf("query uid = %q, want test-uid", got)
|
|
}
|
|
if got := query.Get("token"); got != "test-token" {
|
|
t.Fatalf("query token = %q, want test-token", got)
|
|
}
|
|
if got := query.Get("lang"); got != defaultLaunchLang {
|
|
t.Fatalf("query lang = %q, want %s", got, defaultLaunchLang)
|
|
}
|
|
if got := query.Get("roomid"); got != "test-room" {
|
|
t.Fatalf("query roomid = %q, want test-room", got)
|
|
}
|
|
if got := query.Get("roomId"); got != "test-room" {
|
|
t.Fatalf("query roomId = %q, want test-room", got)
|
|
}
|
|
if got := launch.LaunchConfig.(map[string]any)["roomid"]; got != "test-room" {
|
|
t.Fatalf("launchConfig.roomid = %v, want test-room", got)
|
|
}
|
|
if got := launch.LaunchConfig.(map[string]any)["lang"]; got != defaultLaunchLang {
|
|
t.Fatalf("launchConfig.lang = %v, want %s", got, defaultLaunchLang)
|
|
}
|
|
if got := launch.RoomState.RoomID; got != "room-1" {
|
|
t.Fatalf("roomState.roomId = %q, want real room room-1", got)
|
|
}
|
|
}
|