From cacef68313d6636d089d652625452a885751ab38 Mon Sep 17 00:00:00 2001 From: imjlk Date: Mon, 20 Jul 2026 10:39:29 +0900 Subject: [PATCH] fix(ait): fail closed on missing Game Center support --- .../ait-host-game-center-support.md | 7 ++++ adapters/ait/src/host.test.ts | 36 +++++++++++++++++++ adapters/ait/src/host.ts | 6 +++- 3 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 .sampo/changesets/ait-host-game-center-support.md diff --git a/.sampo/changesets/ait-host-game-center-support.md b/.sampo/changesets/ait-host-game-center-support.md new file mode 100644 index 00000000..d612f1e2 --- /dev/null +++ b/.sampo/changesets/ait-host-game-center-support.md @@ -0,0 +1,7 @@ +--- +npm/@mpgd/adapter-ait: patch (Fixed) +--- + +Treat a missing Apps in Toss operational-environment support constant as an unsupported Game +Center capability instead of failing wrapper startup. Leaderboard submission and opening remain +disabled until the host can verify the minimum native version. diff --git a/adapters/ait/src/host.test.ts b/adapters/ait/src/host.test.ts index 4e119989..d9679223 100644 --- a/adapters/ait/src/host.test.ts +++ b/adapters/ait/src/host.test.ts @@ -810,6 +810,42 @@ describe('AIT production host bridge', () => { expect(showCount).toBe(1); }); + it('treats a missing Game Center environment constant as unsupported', async () => { + const diagnostic = vi.spyOn(console, 'debug').mockImplementation(() => {}); + const submitScore = vi.fn(async () => ({ statusCode: 'SUCCESS' as const })); + const openLeaderboard = vi.fn(async () => {}); + + try { + const bridge = createAitHostBridge({ + dependencies: createDependencies({ + isMinVersionSupported: () => { + throw new Error('getOperationalEnvironment is not a constant handler'); + }, + submitGameCenterLeaderBoardScore: submitScore, + openGameCenterLeaderboard: openLeaderboard, + }), + }); + + await expect(request(bridge, 'runtime.getCapabilities', {})).resolves.toMatchObject({ + nativeLeaderboard: false, + }); + await expect(request(bridge, 'leaderboard.submitScore', { score: 42 })).resolves.toEqual({ + submitted: false, + }); + await expect(request(bridge, 'leaderboard.open', {})).resolves.toEqual({}); + expect(submitScore).not.toHaveBeenCalled(); + expect(openLeaderboard).not.toHaveBeenCalled(); + expect(diagnostic).toHaveBeenCalledWith( + 'AIT capability support check failed; disabling the feature.', + expect.objectContaining({ + message: 'getOperationalEnvironment is not a constant handler', + }), + ); + } finally { + diagnostic.mockRestore(); + } + }); + it('delegates supported Game Center score submission and opening', async () => { const submittedScores: string[] = []; let openCount = 0; diff --git a/adapters/ait/src/host.ts b/adapters/ait/src/host.ts index 64d1f8e8..68098543 100644 --- a/adapters/ait/src/host.ts +++ b/adapters/ait/src/host.ts @@ -922,7 +922,11 @@ function toAitDeepLink(input: string, appName: string): string | undefined { } function isGameCenterSupported(dependencies: AitHostDependencies): boolean { - return dependencies.isMinVersionSupported({ android: '5.221.0', ios: '5.221.0' }); + return isCapabilitySupported(() => + dependencies.isMinVersionSupported({ + android: '5.221.0', + ios: '5.221.0', + })); } function areFullScreenAdsSupported(dependencies: AitHostDependencies): boolean {