diff --git a/common/src/util/__tests__/lazy-response-ads.test.ts b/common/src/util/__tests__/lazy-response-ads.test.ts new file mode 100644 index 0000000000..1b8e499f90 --- /dev/null +++ b/common/src/util/__tests__/lazy-response-ads.test.ts @@ -0,0 +1,47 @@ +import { describe, expect, it } from 'bun:test' + +import { responseAdDisplayCount } from '../lazy-response-ads' + +describe('responseAdDisplayCount', () => { + it('returns eligibleCount when poolSize is at or above the max', () => { + expect( + responseAdDisplayCount({ eligibleCount: 5, poolSize: 100 }), + ).toBe(5) + }) + + it('clamps to poolSize when poolSize is below the max', () => { + expect(responseAdDisplayCount({ eligibleCount: 10, poolSize: 3 })).toBe(3) + }) + + it('returns 0 when eligibleCount is NaN', () => { + expect(responseAdDisplayCount({ eligibleCount: NaN, poolSize: 10 })).toBe(0) + }) + + it('returns 0 when poolSize is NaN', () => { + expect(responseAdDisplayCount({ eligibleCount: 5, poolSize: NaN })).toBe(0) + }) + + it('returns 0 when eligibleCount is Infinity', () => { + expect( + responseAdDisplayCount({ eligibleCount: Infinity, poolSize: 10 }), + ).toBe(0) + }) + + it('returns 0 when poolSize is Infinity', () => { + expect( + responseAdDisplayCount({ eligibleCount: 5, poolSize: Infinity }), + ).toBe(0) + }) + + it('returns 0 when both inputs are negative', () => { + expect( + responseAdDisplayCount({ eligibleCount: -5, poolSize: -10 }), + ).toBe(0) + }) + + it('floors fractional inputs', () => { + expect( + responseAdDisplayCount({ eligibleCount: 5.7, poolSize: 3.2 }), + ).toBe(3) + }) +}) diff --git a/common/src/util/lazy-response-ads.ts b/common/src/util/lazy-response-ads.ts index 1b491a44d8..2214f85dea 100644 --- a/common/src/util/lazy-response-ads.ts +++ b/common/src/util/lazy-response-ads.ts @@ -16,8 +16,10 @@ export function responseAdDisplayCount(params: { eligibleCount: number poolSize: number }): number { - const eligibleCount = Math.max(0, Math.floor(params.eligibleCount)) - const poolSize = Math.max(0, Math.floor(params.poolSize)) + const safeEligibleCount = Number.isFinite(params.eligibleCount) ? params.eligibleCount : 0 + const safePoolSize = Number.isFinite(params.poolSize) ? params.poolSize : 0 + const eligibleCount = Math.max(0, Math.floor(safeEligibleCount)) + const poolSize = Math.max(0, Math.floor(safePoolSize)) return poolSize >= MAX_RESPONSE_AD_POOL_SIZE ? eligibleCount : Math.min(eligibleCount, poolSize)