package gamemanagement import ( "encoding/json" "net/http" "net/http/httptest" "strconv" "testing" gamev1 "hyapp.local/api/proto/game/v1" ) func TestFetchBaishunGameSyncPlanFetchesSignsAndFormatsCatalog(t *testing.T) { const appKey = "baishun-test-key" var receivedPath string server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { receivedPath = r.URL.Path var body map[string]any if err := json.NewDecoder(r.Body).Decode(&body); err != nil { t.Fatalf("decode request: %v", err) } nonce := stringFromJSONValue(body["signature_nonce"]) timestamp := stringFromJSONValue(body["timestamp"]) if got, want := body["signature"], baishunMD5(nonce+appKey+timestamp); got != want { t.Fatalf("signature = %v, want %s body=%+v", got, want, body) } if body["app_channel"] != "test-channel" || stringFromJSONValue(body["app_id"]) != "21397507" || stringFromJSONValue(body["game_list_type"]) != "1" { t.Fatalf("request body mismatch: %+v", body) } w.Header().Set("Content-Type", "application/json") _, _ = w.Write([]byte(`{"code":0,"message":"ok","data":[{"game_id":1006,"name":"Gold of Test","preview_url":"https://cdn.test/1006.png","download_url":"https://h5.test/1006/index.html","game_orientation":2,"safe_height":1024}]}`)) })) defer server.Close() plan, err := fetchBaishunGameSyncPlan(t.Context(), &gamev1.GamePlatform{ PlatformCode: "baishun", AdapterType: adapterBaishunV1, CallbackSecret: appKey, AdapterConfigJson: `{ "app_id": 21397507, "app_channel": "test-channel", "provider_api_base_url": ` + strconv.Quote(server.URL) + ` }`, }, syncGamesRequest{}) if err != nil { t.Fatalf("fetchBaishunGameSyncPlan failed: %v", err) } if receivedPath != "/v1/api/gamelist" { t.Fatalf("path = %q, want /v1/api/gamelist", receivedPath) } if len(plan.Games) != 1 { t.Fatalf("games len = %d, want 1", len(plan.Games)) } game := plan.Games[0] if game.GameID != "baishun_1006" || game.ProviderGameID != "1006" || game.GameName != "Gold of Test" { t.Fatalf("catalog identity mismatch: %+v", game) } if game.IconURL != "https://cdn.test/1006.png" || game.CoverURL != "https://cdn.test/1006.png" || game.Orientation != "landscape" || game.Status != "disabled" || game.LaunchMode != "full_screen" { t.Fatalf("catalog presentation mismatch: %+v", game) } if game.SafeHeight != 1024 { t.Fatalf("safeHeight = %d, want 1024", game.SafeHeight) } var merged struct { GameURLs map[string]string `json:"game_urls"` } if err := json.Unmarshal([]byte(mergeAdapterGameURLs(`{}`, selectedGameURLs(plan.GameURLs, plan.Games))), &merged); err != nil { t.Fatalf("decode merged config: %v", err) } if merged.GameURLs["1006"] != "https://h5.test/1006/index.html" { t.Fatalf("merged game url = %q", merged.GameURLs["1006"]) } } func TestFetchZeeOneGameSyncPlanReadsConfiguredGameURLs(t *testing.T) { plan, err := fetchProviderGameSyncPlan(t.Context(), &gamev1.GamePlatform{ PlatformCode: "zeeone", AdapterType: adapterZeeOneV1, AdapterConfigJson: `{ "game_urls": { "1028": "https://dx3kkv99b7clg.cloudfront.net/test/1028_starShinePrincess/index.html", "1021": "https://dx3kkv99b7clg.cloudfront.net/test/1021_gold_of_olympus/index.html" } }`, }, syncGamesRequest{}) if err != nil { t.Fatalf("fetchProviderGameSyncPlan failed: %v", err) } if len(plan.Games) != 2 { t.Fatalf("games len = %d, want 2", len(plan.Games)) } first := plan.Games[0] if first.GameID != "zeeone_1021" || first.ProviderGameID != "1021" || first.GameName != "Gold of Olympus" { t.Fatalf("first game mismatch: %+v", first) } second := plan.Games[1] if second.GameID != "zeeone_1028" || second.ProviderGameID != "1028" || second.GameName != "Star Shine Princess" { t.Fatalf("second game mismatch: %+v", second) } if plan.GameURLs["1021"] != "https://dx3kkv99b7clg.cloudfront.net/test/1021_gold_of_olympus/index.html" { t.Fatalf("game url mismatch: %+v", plan.GameURLs) } if first.Status != "disabled" || first.LaunchMode != "full_screen" || first.Orientation != "portrait" { t.Fatalf("default fields mismatch: %+v", first) } } func TestSelectProviderGamesKeepsOnlySelectedIDs(t *testing.T) { games := []catalogRequest{ {ProviderGameID: "1001", GameName: "one"}, {ProviderGameID: "1002", GameName: "two"}, } selected := selectProviderGames(games, []string{"1002"}) if len(selected) != 1 || selected[0].ProviderGameID != "1002" { t.Fatalf("selected games mismatch: %+v", selected) } } func TestMissingBaishunSyncFieldsNamesExactInputs(t *testing.T) { missing := missingBaishunSyncFields(0, "", "", "") want := []string{ "adapterConfigJson.app_id", "adapterConfigJson.app_channel", "回调密钥", "adapterConfigJson.game_list_url 或 provider_api_base_url", } if len(missing) != len(want) { t.Fatalf("missing len = %d, want %d: %+v", len(missing), len(want), missing) } for index := range want { if missing[index] != want[index] { t.Fatalf("missing[%d] = %q, want %q", index, missing[index], want[index]) } } }