132 lines
5.3 KiB
Go
132 lines
5.3 KiB
Go
package http
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
gamev1 "hyapp.local/api/proto/game/v1"
|
|
"hyapp/services/gateway-service/internal/auth"
|
|
"hyapp/services/gateway-service/internal/transport/http/httpkit"
|
|
)
|
|
|
|
func TestListGamesUsesAuthenticatedUserRegionAndReturnsEnvelope(t *testing.T) {
|
|
gameClient := &fakeGatewayGameClient{listResp: &gamev1.ListGamesResponse{
|
|
Games: []*gamev1.AppGame{{
|
|
GameId: "demo_rocket_001",
|
|
PlatformCode: "demo",
|
|
NameKey: "game.demo_rocket_001.name",
|
|
Name: "Rocket",
|
|
LaunchMode: "h5_popup",
|
|
Orientation: "portrait",
|
|
Enabled: true,
|
|
}},
|
|
ServerTimeMs: 1700000000000,
|
|
}}
|
|
handler := NewHandlerWithClients(&fakeRoomClient{}, nil, nil, &fakeUserProfileClient{regionID: 1001})
|
|
handler.SetGameClient(gameClient)
|
|
router := handler.Routes(auth.NewVerifier("secret"))
|
|
request := httptest.NewRequest(http.MethodGet, "/api/v1/games?scene=voice_room&room_id=room-1", nil)
|
|
request.Header.Set("Authorization", "Bearer "+signGatewayToken(t, "secret", 42))
|
|
request.Header.Set("X-App-Language", "en")
|
|
recorder := httptest.NewRecorder()
|
|
|
|
router.ServeHTTP(recorder, request)
|
|
|
|
if recorder.Code != http.StatusOK {
|
|
t.Fatalf("status mismatch: got %d body=%s", recorder.Code, recorder.Body.String())
|
|
}
|
|
if gameClient.lastList.GetUserId() != 42 || gameClient.lastList.GetRegionId() != 1001 || gameClient.lastList.GetScene() != "voice_room" || gameClient.lastList.GetRoomId() != "room-1" {
|
|
t.Fatalf("ListGames request mismatch: %+v", gameClient.lastList)
|
|
}
|
|
var envelope httpkit.ResponseEnvelope
|
|
if err := json.NewDecoder(recorder.Body).Decode(&envelope); err != nil {
|
|
t.Fatalf("decode response failed: %v", err)
|
|
}
|
|
data := envelope.Data.(map[string]any)
|
|
games := data["games"].([]any)
|
|
first := games[0].(map[string]any)
|
|
if first["platform_code"] != "demo" || first["game_id"] != "demo_rocket_001" {
|
|
t.Fatalf("game response mismatch: %+v", first)
|
|
}
|
|
}
|
|
|
|
func TestLaunchGameForwardsDisplayUserID(t *testing.T) {
|
|
gameClient := &fakeGatewayGameClient{launchResp: &gamev1.LaunchGameResponse{
|
|
SessionId: "game_sess_1",
|
|
LaunchUrl: "https://provider.example/h5?session_token=token",
|
|
ExpiresAtMs: 1700000900000,
|
|
Orientation: "portrait",
|
|
}}
|
|
handler := NewHandlerWithClients(&fakeRoomClient{}, nil, nil, &fakeUserProfileClient{})
|
|
handler.SetGameClient(gameClient)
|
|
router := handler.Routes(auth.NewVerifier("secret"))
|
|
request := httptest.NewRequest(http.MethodPost, "/api/v1/games/demo_rocket_001/launch", bytes.NewReader([]byte(`{"scene":"voice_room","room_id":"room-1"}`)))
|
|
request.Header.Set("Authorization", "Bearer "+signGatewayToken(t, "secret", 42))
|
|
recorder := httptest.NewRecorder()
|
|
|
|
router.ServeHTTP(recorder, request)
|
|
|
|
if recorder.Code != http.StatusOK {
|
|
t.Fatalf("status mismatch: got %d body=%s", recorder.Code, recorder.Body.String())
|
|
}
|
|
if gameClient.lastLaunch.GetGameId() != "demo_rocket_001" || gameClient.lastLaunch.GetDisplayUserId() != "100001" || gameClient.lastLaunch.GetRoomId() != "room-1" {
|
|
t.Fatalf("LaunchGame request mismatch: %+v", gameClient.lastLaunch)
|
|
}
|
|
}
|
|
|
|
func TestGameCallbackIsRawPublicResponse(t *testing.T) {
|
|
gameClient := &fakeGatewayGameClient{callbackResp: &gamev1.CallbackResponse{RawBody: []byte(`{"code":0}`), ContentType: "application/json"}}
|
|
handler := NewHandlerWithClients(&fakeRoomClient{}, nil, nil, &fakeUserProfileClient{})
|
|
handler.SetGameClient(gameClient)
|
|
router := handler.Routes(auth.NewVerifier("secret"))
|
|
request := httptest.NewRequest(http.MethodPost, "/api/v1/game-callbacks/demo/change_coin?nonce=1", bytes.NewReader([]byte(`{"provider_order_id":"p1"}`)))
|
|
request.Header.Set("X-App-Code", "lalu")
|
|
recorder := httptest.NewRecorder()
|
|
|
|
router.ServeHTTP(recorder, request)
|
|
|
|
if recorder.Code != http.StatusOK || recorder.Body.String() != `{"code":0}` {
|
|
t.Fatalf("callback response must not use app envelope: status=%d body=%s", recorder.Code, recorder.Body.String())
|
|
}
|
|
if gameClient.lastCallback.GetPlatformCode() != "demo" || gameClient.lastCallback.GetOperation() != "change_coin" || string(gameClient.lastCallback.GetRawBody()) != `{"provider_order_id":"p1"}` || gameClient.lastCallback.GetQuery()["nonce"] != "1" {
|
|
t.Fatalf("callback request mismatch: %+v", gameClient.lastCallback)
|
|
}
|
|
}
|
|
|
|
type fakeGatewayGameClient struct {
|
|
listResp *gamev1.ListGamesResponse
|
|
launchResp *gamev1.LaunchGameResponse
|
|
callbackResp *gamev1.CallbackResponse
|
|
lastList *gamev1.ListGamesRequest
|
|
lastLaunch *gamev1.LaunchGameRequest
|
|
lastCallback *gamev1.CallbackRequest
|
|
}
|
|
|
|
func (f *fakeGatewayGameClient) ListGames(_ context.Context, req *gamev1.ListGamesRequest) (*gamev1.ListGamesResponse, error) {
|
|
f.lastList = req
|
|
if f.listResp != nil {
|
|
return f.listResp, nil
|
|
}
|
|
return &gamev1.ListGamesResponse{}, nil
|
|
}
|
|
|
|
func (f *fakeGatewayGameClient) LaunchGame(_ context.Context, req *gamev1.LaunchGameRequest) (*gamev1.LaunchGameResponse, error) {
|
|
f.lastLaunch = req
|
|
if f.launchResp != nil {
|
|
return f.launchResp, nil
|
|
}
|
|
return &gamev1.LaunchGameResponse{}, nil
|
|
}
|
|
|
|
func (f *fakeGatewayGameClient) HandleCallback(_ context.Context, req *gamev1.CallbackRequest) (*gamev1.CallbackResponse, error) {
|
|
f.lastCallback = req
|
|
if f.callbackResp != nil {
|
|
return f.callbackResp, nil
|
|
}
|
|
return &gamev1.CallbackResponse{RawBody: []byte(`{"code":0}`), ContentType: "application/json"}, nil
|
|
}
|