From 3e47e5a8424d9e84f9bc102cb0b7205845b28263 Mon Sep 17 00:00:00 2001 From: ShafinNigamana Date: Fri, 12 Jun 2026 01:25:02 +0530 Subject: [PATCH] \test(cacheControl): add empty-fallback test and robust options parameter handling" --- utils/cacheControl.empty-fallback.test.ts | 59 +++++++++++++++++++++++ utils/cacheControl.ts | 9 ++-- 2 files changed, 62 insertions(+), 6 deletions(-) create mode 100644 utils/cacheControl.empty-fallback.test.ts diff --git a/utils/cacheControl.empty-fallback.test.ts b/utils/cacheControl.empty-fallback.test.ts new file mode 100644 index 000000000..b8d763102 --- /dev/null +++ b/utils/cacheControl.empty-fallback.test.ts @@ -0,0 +1,59 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { describe, expect, it } from 'vitest'; +import { buildCacheControlHeader } from './cacheControl'; + +describe('buildCacheControlHeader - Edge Cases & Empty/Missing Inputs Verification', () => { + it('1. falls back to default cache control when options object is completely omitted', () => { + // Calling the function with no arguments should fallback gracefully without throwing + expect(buildCacheControlHeader()).toBe('s-maxage=3600, stale-while-revalidate=86400'); + }); + + it('2. falls back to default cache control when options is an empty object', () => { + expect(buildCacheControlHeader({})).toBe('s-maxage=3600, stale-while-revalidate=86400'); + }); + + it('3. falls back to default cache control when options object is null', () => { + // Casting to any to test JavaScript-level null input resilience + expect(buildCacheControlHeader(null as any)).toBe( + 's-maxage=3600, stale-while-revalidate=86400' + ); + }); + + it('4. falls back to default cache control when options contain only undefined or null values', () => { + expect( + buildCacheControlHeader({ + bypass: undefined, + secondsToMidnight: undefined, + isHistoricalYear: undefined, + }) + ).toBe('s-maxage=3600, stale-while-revalidate=86400'); + + expect( + buildCacheControlHeader({ + bypass: null as any, + secondsToMidnight: null as any, + isHistoricalYear: null as any, + }) + ).toBe('s-maxage=3600, stale-while-revalidate=86400'); + }); + + it('5. prioritizes bypass=true even if other options are invalid/null/undefined', () => { + expect( + buildCacheControlHeader({ + bypass: true, + secondsToMidnight: null as any, + isHistoricalYear: undefined, + }) + ).toBe('no-cache, no-store, must-revalidate'); + }); + + it('6. prioritizes isHistoricalYear=true when bypass is falsy and secondsToMidnight is null/undefined', () => { + expect( + buildCacheControlHeader({ + bypass: false, + secondsToMidnight: undefined, + isHistoricalYear: true, + }) + ).toBe('public, s-maxage=31536000, immutable'); + }); +}); diff --git a/utils/cacheControl.ts b/utils/cacheControl.ts index 2972cb658..05d95ce2f 100644 --- a/utils/cacheControl.ts +++ b/utils/cacheControl.ts @@ -4,11 +4,8 @@ interface CacheControlOptions { isHistoricalYear?: boolean; } -export function buildCacheControlHeader({ - bypass, - secondsToMidnight, - isHistoricalYear, -}: CacheControlOptions): string { +export function buildCacheControlHeader(options: CacheControlOptions = {}): string { + const { bypass, secondsToMidnight, isHistoricalYear } = options || {}; if (bypass) { return 'no-cache, no-store, must-revalidate'; } @@ -17,7 +14,7 @@ export function buildCacheControlHeader({ return 'public, s-maxage=31536000, immutable'; } - if (secondsToMidnight !== undefined) { + if (secondsToMidnight !== undefined && secondsToMidnight !== null) { return `public, s-maxage=${secondsToMidnight}, stale-while-revalidate=86400`; }