diff --git a/ui/src/lib/ads.test.ts b/ui/src/lib/ads.test.ts index 79f9ece..4e5d739 100644 --- a/ui/src/lib/ads.test.ts +++ b/ui/src/lib/ads.test.ts @@ -108,6 +108,20 @@ describe('maybeShowInterstitial (client-mirrored gate)', () => { expect(mocks.vkShowInterstitial).toHaveBeenCalledTimes(1); // only the hint ad fired }); + it('a hint-pushed ad restarts the vs_ai gap, so the next plain move is not over-served', async () => { + // The scenario the owner flagged: a vs_ai ad, then 20 min later a hinted move pushes an ad on + // its short gap, then a plain move 10 min after that must NOT fire — the shared timer restarted + // the 30-min vs_ai gap at the hint ad, so 10 min is not enough (it fires only 30 min after it). + const vsAi = { vsAi: true, online: true }; + expect(await maybeShowInterstitial(ADS, 'move', vsAi)).toBe(true); // t0 + vi.setSystemTime(BASE + 20 * 60_000); // +20 min: a hint pushes an ad on its 1-min gap + expect(await maybeShowInterstitial(ADS, 'hint', vsAi)).toBe(true); + vi.setSystemTime(BASE + 30 * 60_000); // +10 min after the hint ad + expect(await maybeShowInterstitial(ADS, 'move', vsAi)).toBe(false); + vi.setSystemTime(BASE + 50 * 60_000); // +30 min after the hint ad + expect(await maybeShowInterstitial(ADS, 'move', vsAi)).toBe(true); + }); + it('uses the longer vs_ai cooldown for a vs_ai move', async () => { expect(await maybeShowInterstitial(ADS, 'move', { vsAi: true, online: true })).toBe(true); vi.setSystemTime(BASE + 1_799_000); // +1799s < the 1800s vs_ai cooldown