fix(ads): share one interstitial cooldown timer across kinds
CI / changes (pull_request) Successful in 1s
CI / unit (pull_request) Successful in 10s
CI / integration (pull_request) Successful in 25s
CI / ui (pull_request) Successful in 1m10s
CI / conformance (pull_request) Successful in 10s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m53s
CI / changes (pull_request) Successful in 1s
CI / unit (pull_request) Successful in 10s
CI / integration (pull_request) Successful in 25s
CI / ui (pull_request) Successful in 1m10s
CI / conformance (pull_request) Successful in 10s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m53s
Cooldowns were tracked per kind ({move,hint}), so a hint ad and a move ad
did not see each other: after a hinted move's ad the move timer was still
zero, and the next plain move fired an ad immediately — two ads within a
minute, under the cooldown. Track a single shared last-shown time; the kind
only selects the required gap (hint 1m, move 5m, vs_ai 30m) measured from the
last interstitial of any kind. A hint can still fire on its shorter gap
(D30's "independent" hint cooldown), but never stacks a second ad within a
cooldown.
Tests: a hint uses the shorter shared gap; a move does not stack onto a
just-shown hint ad.
This commit is contained in:
+16
-6
@@ -79,7 +79,7 @@ describe('maybeShowInterstitial (client-mirrored gate)', () => {
|
||||
expect(mocks.showToast).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('respects the per-kind cooldown: a second move within the window is gated', async () => {
|
||||
it('respects the cooldown: a second move within the window is gated', async () => {
|
||||
expect(await maybeShowInterstitial(ADS, 'move', ONLINE)).toBe(true);
|
||||
vi.setSystemTime(BASE + 299_000); // +299s < the 300s global cooldown
|
||||
expect(await maybeShowInterstitial(ADS, 'move', ONLINE)).toBe(false);
|
||||
@@ -88,16 +88,26 @@ describe('maybeShowInterstitial (client-mirrored gate)', () => {
|
||||
expect(mocks.vkShowInterstitial).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
it('tracks move and hint cooldowns independently', async () => {
|
||||
it('shares one timer across kinds: a hint uses the shorter gap from the last ad', async () => {
|
||||
// A move ad, then a hint: the hint is held until its own (shorter) 60s gap from THAT ad has
|
||||
// elapsed — not fired at once (a per-kind timer used to let it fire immediately).
|
||||
expect(await maybeShowInterstitial(ADS, 'move', ONLINE)).toBe(true);
|
||||
// A hint right after a move still fires — a separate kind key with its own 60s cooldown.
|
||||
expect(await maybeShowInterstitial(ADS, 'hint', ONLINE)).toBe(true);
|
||||
vi.setSystemTime(BASE + 59_000); // +59s < the 60s hint cooldown
|
||||
vi.setSystemTime(BASE + 59_000);
|
||||
expect(await maybeShowInterstitial(ADS, 'hint', ONLINE)).toBe(false);
|
||||
vi.setSystemTime(BASE + 60_000);
|
||||
vi.setSystemTime(BASE + 60_000); // the hint's 60s gap from the last ad has elapsed
|
||||
expect(await maybeShowInterstitial(ADS, 'hint', ONLINE)).toBe(true);
|
||||
});
|
||||
|
||||
it('does not stack a move ad onto a just-shown hint ad (the reported bug)', async () => {
|
||||
// A vs_ai hint-move fires the hint ad; a plain vs_ai move 30s later must NOT fire — the shared
|
||||
// timer holds it for the vs_ai gap. Separate per-kind timers let it fire at once (the bug).
|
||||
const vsAi = { vsAi: true, online: true };
|
||||
expect(await maybeShowInterstitial(ADS, 'hint', vsAi)).toBe(true);
|
||||
vi.setSystemTime(BASE + 30_000); // 30s later, far under the 1800s vs_ai gap
|
||||
expect(await maybeShowInterstitial(ADS, 'move', vsAi)).toBe(false);
|
||||
expect(mocks.vkShowInterstitial).toHaveBeenCalledTimes(1); // only the hint ad fired
|
||||
});
|
||||
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user