From 4f5f563776703ab9ce38941227d87a655775af07 Mon Sep 17 00:00:00 2001 From: pieh Date: Mon, 14 Oct 2024 13:29:34 +0200 Subject: [PATCH 1/2] fix: drop empty directives to not produce invalid header values --- src/run/headers.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/run/headers.ts b/src/run/headers.ts index 411edf0052..9af7f26832 100644 --- a/src/run/headers.ts +++ b/src/run/headers.ts @@ -54,7 +54,10 @@ const generateNetlifyVaryValues = ({ } const getHeaderValueArray = (header: string): string[] => { - return header.split(',').map((value) => value.trim()) + return header + .split(',') + .map((value) => value.trim()) + .filter(Boolean) } const omitHeaderValues = (header: string, values: string[]): string => { From 93dd2b610827fde7c45ddc95b7f51579fb975b54 Mon Sep 17 00:00:00 2001 From: pieh Date: Mon, 14 Oct 2024 13:42:06 +0200 Subject: [PATCH 2/2] test: adjust tests for next@15.0.0-canary.187 --- tests/e2e/on-demand-app.test.ts | 17 +++-- tests/e2e/page-router.test.ts | 80 +++++++++++++++++------ tests/e2e/simple-app.test.ts | 4 +- tests/e2e/turborepo.test.ts | 17 +++-- tests/integration/cache-handler.test.ts | 9 ++- tests/integration/fetch-handler.test.ts | 9 ++- tests/integration/revalidate-path.test.ts | 17 +++-- tests/integration/revalidate-tags.test.ts | 17 +++-- tests/integration/simple-app.test.ts | 22 ++++--- 9 files changed, 143 insertions(+), 49 deletions(-) diff --git a/tests/e2e/on-demand-app.test.ts b/tests/e2e/on-demand-app.test.ts index a87d9cc265..cd26eb8a19 100644 --- a/tests/e2e/on-demand-app.test.ts +++ b/tests/e2e/on-demand-app.test.ts @@ -1,5 +1,6 @@ import { expect } from '@playwright/test' import { test } from '../utils/playwright-helpers.js' +import { nextVersionSatisfies } from '../utils/next-version-helpers.mjs' test.describe('app router on-demand revalidation', () => { for (const { label, prerendered, pagePath, revalidateApiPath, expectedH1Content } of [ @@ -90,7 +91,9 @@ test.describe('app router on-demand revalidation', () => { expect(response1?.status()).toBe(200) expect(headers1['x-nextjs-cache']).toBeUndefined() expect(headers1['netlify-cdn-cache-control']).toBe( - 's-maxage=31536000, stale-while-revalidate=31536000, durable', + nextVersionSatisfies('>=15.0.0-canary.187') + ? 's-maxage=31536000, durable' + : 's-maxage=31536000, stale-while-revalidate=31536000, durable', ) const date1 = await page.textContent('[data-testid="date-now"]') @@ -118,7 +121,9 @@ test.describe('app router on-demand revalidation', () => { expect(headers2['cache-status']).toMatch(/"Next.js"; hit/m) } expect(headers2['netlify-cdn-cache-control']).toBe( - 's-maxage=31536000, stale-while-revalidate=31536000, durable', + nextVersionSatisfies('>=15.0.0-canary.187') + ? 's-maxage=31536000, durable' + : 's-maxage=31536000, stale-while-revalidate=31536000, durable', ) // the page is cached @@ -148,7 +153,9 @@ test.describe('app router on-demand revalidation', () => { expect(response3?.status()).toBe(200) expect(headers3?.['x-nextjs-cache']).toBeUndefined() expect(headers3['netlify-cdn-cache-control']).toBe( - 's-maxage=31536000, stale-while-revalidate=31536000, durable', + nextVersionSatisfies('>=15.0.0-canary.187') + ? 's-maxage=31536000, durable' + : 's-maxage=31536000, stale-while-revalidate=31536000, durable', ) // the page has now an updated date @@ -175,7 +182,9 @@ test.describe('app router on-demand revalidation', () => { expect(headers4['cache-status']).toMatch(/"Next.js"; hit/m) } expect(headers4['netlify-cdn-cache-control']).toBe( - 's-maxage=31536000, stale-while-revalidate=31536000, durable', + nextVersionSatisfies('>=15.0.0-canary.187') + ? 's-maxage=31536000, durable' + : 's-maxage=31536000, stale-while-revalidate=31536000, durable', ) // the page is cached diff --git a/tests/e2e/page-router.test.ts b/tests/e2e/page-router.test.ts index 2124ba53c7..6c4f2ac0d2 100644 --- a/tests/e2e/page-router.test.ts +++ b/tests/e2e/page-router.test.ts @@ -128,7 +128,9 @@ test.describe('Simple Page Router (no basePath, no i18n)', () => { expect(headers1['x-nextjs-cache']).toBeUndefined() expect(headers1['netlify-cache-tag']).toBe(`_n_t_${encodeURI(pagePath).toLowerCase()}`) expect(headers1['netlify-cdn-cache-control']).toBe( - 's-maxage=31536000, stale-while-revalidate=31536000, durable', + nextVersionSatisfies('>=15.0.0-canary.187') + ? 's-maxage=31536000, durable' + : 's-maxage=31536000, stale-while-revalidate=31536000, durable', ) const date1 = await page.textContent('[data-testid="date-now"]') @@ -156,7 +158,9 @@ test.describe('Simple Page Router (no basePath, no i18n)', () => { expect(headers1Json['x-nextjs-cache']).toBeUndefined() expect(headers1Json['netlify-cache-tag']).toBe(`_n_t_${encodeURI(pagePath).toLowerCase()}`) expect(headers1Json['netlify-cdn-cache-control']).toBe( - 's-maxage=31536000, stale-while-revalidate=31536000, durable', + nextVersionSatisfies('>=15.0.0-canary.187') + ? 's-maxage=31536000, durable' + : 's-maxage=31536000, stale-while-revalidate=31536000, durable', ) const data1 = (await response1Json?.json()) || {} expect(data1?.pageProps?.time).toBe(date1) @@ -181,7 +185,9 @@ test.describe('Simple Page Router (no basePath, no i18n)', () => { expect(headers2['cache-status']).toMatch(/"Next.js"; hit/m) } expect(headers2['netlify-cdn-cache-control']).toBe( - 's-maxage=31536000, stale-while-revalidate=31536000, durable', + nextVersionSatisfies('>=15.0.0-canary.187') + ? 's-maxage=31536000, durable' + : 's-maxage=31536000, stale-while-revalidate=31536000, durable', ) // the page is cached @@ -212,7 +218,9 @@ test.describe('Simple Page Router (no basePath, no i18n)', () => { expect(headers2Json['cache-status']).toMatch(/"Next.js"; hit/m) } expect(headers2Json['netlify-cdn-cache-control']).toBe( - 's-maxage=31536000, stale-while-revalidate=31536000, durable', + nextVersionSatisfies('>=15.0.0-canary.187') + ? 's-maxage=31536000, durable' + : 's-maxage=31536000, stale-while-revalidate=31536000, durable', ) const data2 = (await response2Json?.json()) || {} @@ -267,7 +275,9 @@ test.describe('Simple Page Router (no basePath, no i18n)', () => { expect(response3Json?.status()).toBe(200) expect(headers3Json['x-nextjs-cache']).toBeUndefined() expect(headers3Json['netlify-cdn-cache-control']).toBe( - 's-maxage=31536000, stale-while-revalidate=31536000, durable', + nextVersionSatisfies('>=15.0.0-canary.187') + ? 's-maxage=31536000, durable' + : 's-maxage=31536000, stale-while-revalidate=31536000, durable', ) const data3 = (await response3Json?.json()) || {} @@ -382,7 +392,9 @@ test.describe('Simple Page Router (no basePath, no i18n)', () => { expect(await page.textContent('h1')).toBe('404') expect(headers['netlify-cdn-cache-control']).toBe( - 's-maxage=31536000, stale-while-revalidate=31536000, durable', + nextVersionSatisfies('>=15.0.0-canary.187') + ? 's-maxage=31536000, durable' + : 's-maxage=31536000, stale-while-revalidate=31536000, durable', ) expect(headers['cache-control']).toBe('public,max-age=0,must-revalidate') }) @@ -532,7 +544,9 @@ test.describe('Page Router with basePath and i18n', () => { `_n_t_/en${encodeURI(pagePath).toLowerCase()}`, ) expect(headers1ImplicitLocale['netlify-cdn-cache-control']).toBe( - 's-maxage=31536000, stale-while-revalidate=31536000, durable', + nextVersionSatisfies('>=15.0.0-canary.187') + ? 's-maxage=31536000, durable' + : 's-maxage=31536000, stale-while-revalidate=31536000, durable', ) const date1ImplicitLocale = await page.textContent('[data-testid="date-now"]') @@ -560,7 +574,9 @@ test.describe('Page Router with basePath and i18n', () => { `_n_t_/en${encodeURI(pagePath).toLowerCase()}`, ) expect(headers1ExplicitLocale['netlify-cdn-cache-control']).toBe( - 's-maxage=31536000, stale-while-revalidate=31536000, durable', + nextVersionSatisfies('>=15.0.0-canary.187') + ? 's-maxage=31536000, durable' + : 's-maxage=31536000, stale-while-revalidate=31536000, durable', ) const date1ExplicitLocale = await page.textContent('[data-testid="date-now"]') @@ -594,7 +610,9 @@ test.describe('Page Router with basePath and i18n', () => { `_n_t_/en${encodeURI(pagePath).toLowerCase()}`, ) expect(headers1Json['netlify-cdn-cache-control']).toBe( - 's-maxage=31536000, stale-while-revalidate=31536000, durable', + nextVersionSatisfies('>=15.0.0-canary.187') + ? 's-maxage=31536000, durable' + : 's-maxage=31536000, stale-while-revalidate=31536000, durable', ) const data1 = (await response1Json?.json()) || {} expect(data1?.pageProps?.time).toBe(date1ImplicitLocale) @@ -622,7 +640,9 @@ test.describe('Page Router with basePath and i18n', () => { expect(headers2ImplicitLocale['cache-status']).toMatch(/"Next.js"; hit/m) } expect(headers2ImplicitLocale['netlify-cdn-cache-control']).toBe( - 's-maxage=31536000, stale-while-revalidate=31536000, durable', + nextVersionSatisfies('>=15.0.0-canary.187') + ? 's-maxage=31536000, durable' + : 's-maxage=31536000, stale-while-revalidate=31536000, durable', ) // the page is cached @@ -652,7 +672,9 @@ test.describe('Page Router with basePath and i18n', () => { expect(headers2ExplicitLocale['cache-status']).toMatch(/"Next.js"; hit/m) } expect(headers2ExplicitLocale['netlify-cdn-cache-control']).toBe( - 's-maxage=31536000, stale-while-revalidate=31536000, durable', + nextVersionSatisfies('>=15.0.0-canary.187') + ? 's-maxage=31536000, durable' + : 's-maxage=31536000, stale-while-revalidate=31536000, durable', ) // the page is cached @@ -683,7 +705,9 @@ test.describe('Page Router with basePath and i18n', () => { expect(headers2Json['cache-status']).toMatch(/"Next.js"; hit/m) } expect(headers2Json['netlify-cdn-cache-control']).toBe( - 's-maxage=31536000, stale-while-revalidate=31536000, durable', + nextVersionSatisfies('>=15.0.0-canary.187') + ? 's-maxage=31536000, durable' + : 's-maxage=31536000, stale-while-revalidate=31536000, durable', ) const data2 = (await response2Json?.json()) || {} @@ -777,7 +801,9 @@ test.describe('Page Router with basePath and i18n', () => { expect(headers3Json['cache-status']).toMatch(/"Next.js"; hit/m) } expect(headers3Json['netlify-cdn-cache-control']).toBe( - 's-maxage=31536000, stale-while-revalidate=31536000, durable', + nextVersionSatisfies('>=15.0.0-canary.187') + ? 's-maxage=31536000, durable' + : 's-maxage=31536000, stale-while-revalidate=31536000, durable', ) const data3 = (await response3Json?.json()) || {} @@ -866,7 +892,9 @@ test.describe('Page Router with basePath and i18n', () => { expect(response4Json?.status()).toBe(200) expect(headers4Json['x-nextjs-cache']).toBeUndefined() expect(headers4Json['netlify-cdn-cache-control']).toBe( - 's-maxage=31536000, stale-while-revalidate=31536000, durable', + nextVersionSatisfies('>=15.0.0-canary.187') + ? 's-maxage=31536000, durable' + : 's-maxage=31536000, stale-while-revalidate=31536000, durable', ) const data4 = (await response4Json?.json()) || {} @@ -912,7 +940,9 @@ test.describe('Page Router with basePath and i18n', () => { expect(headers1['x-nextjs-cache']).toBeUndefined() expect(headers1['netlify-cache-tag']).toBe(`_n_t_/de${encodeURI(pagePath).toLowerCase()}`) expect(headers1['netlify-cdn-cache-control']).toBe( - 's-maxage=31536000, stale-while-revalidate=31536000, durable', + nextVersionSatisfies('>=15.0.0-canary.187') + ? 's-maxage=31536000, durable' + : 's-maxage=31536000, stale-while-revalidate=31536000, durable', ) const date1 = await page.textContent('[data-testid="date-now"]') @@ -943,7 +973,9 @@ test.describe('Page Router with basePath and i18n', () => { `_n_t_/de${encodeURI(pagePath).toLowerCase()}`, ) expect(headers1Json['netlify-cdn-cache-control']).toBe( - 's-maxage=31536000, stale-while-revalidate=31536000, durable', + nextVersionSatisfies('>=15.0.0-canary.187') + ? 's-maxage=31536000, durable' + : 's-maxage=31536000, stale-while-revalidate=31536000, durable', ) const data1 = (await response1Json?.json()) || {} expect(data1?.pageProps?.time).toBe(date1) @@ -971,7 +1003,9 @@ test.describe('Page Router with basePath and i18n', () => { expect(headers2['cache-status']).toMatch(/"Next.js"; hit/m) } expect(headers2['netlify-cdn-cache-control']).toBe( - 's-maxage=31536000, stale-while-revalidate=31536000, durable', + nextVersionSatisfies('>=15.0.0-canary.187') + ? 's-maxage=31536000, durable' + : 's-maxage=31536000, stale-while-revalidate=31536000, durable', ) // the page is cached @@ -1003,7 +1037,9 @@ test.describe('Page Router with basePath and i18n', () => { expect(headers2Json['cache-status']).toMatch(/"Next.js"; hit/m) } expect(headers2Json['netlify-cdn-cache-control']).toBe( - 's-maxage=31536000, stale-while-revalidate=31536000, durable', + nextVersionSatisfies('>=15.0.0-canary.187') + ? 's-maxage=31536000, durable' + : 's-maxage=31536000, stale-while-revalidate=31536000, durable', ) const data2 = (await response2Json?.json()) || {} @@ -1070,7 +1106,9 @@ test.describe('Page Router with basePath and i18n', () => { expect(headers3Json['cache-status']).toMatch(/"Next.js"; hit/m) } expect(headers3Json['netlify-cdn-cache-control']).toBe( - 's-maxage=31536000, stale-while-revalidate=31536000, durable', + nextVersionSatisfies('>=15.0.0-canary.187') + ? 's-maxage=31536000, durable' + : 's-maxage=31536000, stale-while-revalidate=31536000, durable', ) const data3 = (await response3Json?.json()) || {} @@ -1114,7 +1152,9 @@ test.describe('Page Router with basePath and i18n', () => { expect(await page.textContent('h1')).toBe('404') expect(headers['netlify-cdn-cache-control']).toBe( - 's-maxage=31536000, stale-while-revalidate=31536000, durable', + nextVersionSatisfies('>=15.0.0-canary.187') + ? 's-maxage=31536000, durable' + : 's-maxage=31536000, stale-while-revalidate=31536000, durable', ) expect(headers['cache-control']).toBe('public,max-age=0,must-revalidate') }) diff --git a/tests/e2e/simple-app.test.ts b/tests/e2e/simple-app.test.ts index 98058eb3af..15f1f585fe 100644 --- a/tests/e2e/simple-app.test.ts +++ b/tests/e2e/simple-app.test.ts @@ -247,7 +247,9 @@ test('requesting a non existing page route that needs to be fetched from the blo expect(await page.textContent('h1')).toBe('404 Not Found') expect(headers['netlify-cdn-cache-control']).toBe( - 's-maxage=31536000, stale-while-revalidate=31536000, durable', + nextVersionSatisfies('>=15.0.0-canary.187') + ? 's-maxage=31536000, durable' + : 's-maxage=31536000, stale-while-revalidate=31536000, durable', ) expect(headers['cache-control']).toBe('public,max-age=0,must-revalidate') }) diff --git a/tests/e2e/turborepo.test.ts b/tests/e2e/turborepo.test.ts index 9afecccd9d..604cfabc19 100644 --- a/tests/e2e/turborepo.test.ts +++ b/tests/e2e/turborepo.test.ts @@ -1,5 +1,6 @@ import { expect } from '@playwright/test' import { test } from '../utils/playwright-helpers.js' +import { nextVersionSatisfies } from '../utils/next-version-helpers.mjs' // those tests have different fixtures and can run in parallel test.describe.configure({ mode: 'parallel' }) @@ -35,7 +36,9 @@ test.describe('[PNPM] Package manager', () => { expect(response1?.status()).toBe(200) expect(headers1['x-nextjs-cache']).toBeUndefined() expect(headers1['netlify-cdn-cache-control']).toBe( - 's-maxage=31536000, stale-while-revalidate=31536000, durable', + nextVersionSatisfies('>=15.0.0-canary.187') + ? 's-maxage=31536000, durable' + : 's-maxage=31536000, stale-while-revalidate=31536000, durable', ) const date1 = await page.textContent('[data-testid="date-now"]') @@ -65,7 +68,9 @@ test.describe('[PNPM] Package manager', () => { expect(headers2['cache-status']).toMatch(/"Next.js"; hit/m) } expect(headers2['netlify-cdn-cache-control']).toBe( - 's-maxage=31536000, stale-while-revalidate=31536000, durable', + nextVersionSatisfies('>=15.0.0-canary.187') + ? 's-maxage=31536000, durable' + : 's-maxage=31536000, stale-while-revalidate=31536000, durable', ) // the page is cached @@ -139,7 +144,9 @@ test.describe('[NPM] Package manager', () => { expect(response1?.status()).toBe(200) expect(headers1['x-nextjs-cache']).toBeUndefined() expect(headers1['netlify-cdn-cache-control']).toBe( - 's-maxage=31536000, stale-while-revalidate=31536000, durable', + nextVersionSatisfies('>=15.0.0-canary.187') + ? 's-maxage=31536000, durable' + : 's-maxage=31536000, stale-while-revalidate=31536000, durable', ) const date1 = await page.textContent('[data-testid="date-now"]') @@ -169,7 +176,9 @@ test.describe('[NPM] Package manager', () => { expect(headers2['cache-status']).toMatch(/"Next.js"; hit/m) } expect(headers2['netlify-cdn-cache-control']).toBe( - 's-maxage=31536000, stale-while-revalidate=31536000, durable', + nextVersionSatisfies('>=15.0.0-canary.187') + ? 's-maxage=31536000, durable' + : 's-maxage=31536000, stale-while-revalidate=31536000, durable', ) // the page is cached diff --git a/tests/integration/cache-handler.test.ts b/tests/integration/cache-handler.test.ts index 42397a34ff..6610ae73b8 100644 --- a/tests/integration/cache-handler.test.ts +++ b/tests/integration/cache-handler.test.ts @@ -17,6 +17,7 @@ import { getBlobEntries, startMockBlobStore, } from '../utils/helpers.js' +import { nextVersionSatisfies } from '../utils/next-version-helpers.mjs' // Disable the verbose logging of the lambda-local runtime getLogger().level = 'alert' @@ -89,7 +90,9 @@ describe('page router', () => { ).toEqual( expect.objectContaining({ 'cache-status': '"Next.js"; hit', - 'netlify-cdn-cache-control': 's-maxage=5, stale-while-revalidate=31536000, durable', + 'netlify-cdn-cache-control': nextVersionSatisfies('>=15.0.0-canary.187') + ? `s-maxage=5, stale-while-revalidate=${31536000 - 5}, durable` + : 's-maxage=5, stale-while-revalidate=31536000, durable', }), ) expect( @@ -240,7 +243,9 @@ describe('app router', () => { // It will be hit instead of stale expect.objectContaining({ 'cache-status': '"Next.js"; hit', - 'netlify-cdn-cache-control': 's-maxage=31536000, stale-while-revalidate=31536000, durable', + 'netlify-cdn-cache-control': nextVersionSatisfies('>=15.0.0-canary.187') + ? 's-maxage=31536000, durable' + : 's-maxage=31536000, stale-while-revalidate=31536000, durable', }), ) expect( diff --git a/tests/integration/fetch-handler.test.ts b/tests/integration/fetch-handler.test.ts index 398f8355fe..b525dfd16e 100644 --- a/tests/integration/fetch-handler.test.ts +++ b/tests/integration/fetch-handler.test.ts @@ -7,6 +7,7 @@ import { afterAll, beforeAll, beforeEach, expect, test, vi } from 'vitest' import { type FixtureTestContext } from '../utils/contexts.js' import { createFixture, invokeFunction, runPlugin, runPluginStep } from '../utils/fixture.js' import { generateRandomObjectID, startMockBlobStore } from '../utils/helpers.js' +import { nextVersionSatisfies } from '../utils/next-version-helpers.mjs' // Disable the verbose logging of the lambda-local runtime getLogger().level = 'alert' @@ -229,7 +230,9 @@ test('if the fetch call is cached correctly (cached page res ).toEqual( expect.objectContaining({ 'cache-status': '"Next.js"; hit', - 'netlify-cdn-cache-control': 's-maxage=5, stale-while-revalidate=31536000, durable', + 'netlify-cdn-cache-control': nextVersionSatisfies('>=15.0.0-canary.187') + ? `s-maxage=5, stale-while-revalidate=${31536000 - 5}, durable` + : 's-maxage=5, stale-while-revalidate=31536000, durable', }), ) @@ -295,7 +298,9 @@ test('if the fetch call is cached correctly (cached page res ).toEqual( expect.objectContaining({ 'cache-status': '"Next.js"; hit', - 'netlify-cdn-cache-control': 's-maxage=5, stale-while-revalidate=31536000, durable', + 'netlify-cdn-cache-control': nextVersionSatisfies('>=15.0.0-canary.187') + ? `s-maxage=5, stale-while-revalidate=${31536000 - 5}, durable` + : 's-maxage=5, stale-while-revalidate=31536000, durable', }), ) }) diff --git a/tests/integration/revalidate-path.test.ts b/tests/integration/revalidate-path.test.ts index 342872e1e3..f326eea0b6 100644 --- a/tests/integration/revalidate-path.test.ts +++ b/tests/integration/revalidate-path.test.ts @@ -10,6 +10,7 @@ import { getBlobServerGets, startMockBlobStore, } from '../utils/helpers.js' +import { nextVersionSatisfies } from '../utils/next-version-helpers.mjs' function isTagManifest(key: string) { return key.startsWith('_N_T_') @@ -67,7 +68,9 @@ test('should revalidate a route by path', async (ctx) => { expect(post1.headers, 'a cache hit on the first invocation of a prerendered page').toEqual( expect.objectContaining({ 'cache-status': expect.stringMatching(/"Next.js"; hit/), - 'netlify-cdn-cache-control': 's-maxage=31536000, stale-while-revalidate=31536000, durable', + 'netlify-cdn-cache-control': nextVersionSatisfies('>=15.0.0-canary.187') + ? 's-maxage=31536000, durable' + : 's-maxage=31536000, stale-while-revalidate=31536000, durable', }), ) @@ -82,7 +85,9 @@ test('should revalidate a route by path', async (ctx) => { expect(post1Route2.headers, 'a cache hit on the first invocation of a prerendered page').toEqual( expect.objectContaining({ 'cache-status': expect.stringMatching(/"Next.js"; hit/), - 'netlify-cdn-cache-control': 's-maxage=31536000, stale-while-revalidate=31536000, durable', + 'netlify-cdn-cache-control': nextVersionSatisfies('>=15.0.0-canary.187') + ? 's-maxage=31536000, durable' + : 's-maxage=31536000, stale-while-revalidate=31536000, durable', }), ) @@ -110,7 +115,9 @@ test('should revalidate a route by path', async (ctx) => { expect(post2.headers, 'a cache miss on the on demand revalidated path /1').toEqual( expect.objectContaining({ 'cache-status': '"Next.js"; fwd=miss', - 'netlify-cdn-cache-control': 's-maxage=31536000, stale-while-revalidate=31536000, durable', + 'netlify-cdn-cache-control': nextVersionSatisfies('>=15.0.0-canary.187') + ? 's-maxage=31536000, durable' + : 's-maxage=31536000, stale-while-revalidate=31536000, durable', }), ) expect(post2Date).not.toBe(post1Date) @@ -127,7 +134,9 @@ test('should revalidate a route by path', async (ctx) => { expect(post2Route2.headers, 'a cache miss on the on demand revalidated path /2').toEqual( expect.objectContaining({ 'cache-status': '"Next.js"; fwd=miss', - 'netlify-cdn-cache-control': 's-maxage=31536000, stale-while-revalidate=31536000, durable', + 'netlify-cdn-cache-control': nextVersionSatisfies('>=15.0.0-canary.187') + ? 's-maxage=31536000, durable' + : 's-maxage=31536000, stale-while-revalidate=31536000, durable', }), ) diff --git a/tests/integration/revalidate-tags.test.ts b/tests/integration/revalidate-tags.test.ts index 9b48c23956..c93f45a980 100644 --- a/tests/integration/revalidate-tags.test.ts +++ b/tests/integration/revalidate-tags.test.ts @@ -10,6 +10,7 @@ import { getBlobServerGets, startMockBlobStore, } from '../utils/helpers.js' +import { nextVersionSatisfies } from '../utils/next-version-helpers.mjs' function isTagManifest(key: string) { return key.startsWith('_N_T_') @@ -67,7 +68,9 @@ test('should revalidate a route by tag', async (ctx) => { expect(post1.headers, 'a cache hit on the first invocation of a prerendered page').toEqual( expect.objectContaining({ 'cache-status': expect.stringMatching(/"Next.js"; hit/), - 'netlify-cdn-cache-control': 's-maxage=31536000, stale-while-revalidate=31536000, durable', + 'netlify-cdn-cache-control': nextVersionSatisfies('>=15.0.0-canary.187') + ? 's-maxage=31536000, durable' + : 's-maxage=31536000, stale-while-revalidate=31536000, durable', }), ) @@ -94,7 +97,9 @@ test('should revalidate a route by tag', async (ctx) => { expect(post2.headers, 'a cache miss on the on demand revalidated page').toEqual( expect.objectContaining({ 'cache-status': '"Next.js"; fwd=miss', - 'netlify-cdn-cache-control': 's-maxage=31536000, stale-while-revalidate=31536000, durable', + 'netlify-cdn-cache-control': nextVersionSatisfies('>=15.0.0-canary.187') + ? 's-maxage=31536000, durable' + : 's-maxage=31536000, stale-while-revalidate=31536000, durable', }), ) expect(post2Date).not.toBe(post1Date) @@ -117,7 +122,9 @@ test('should revalidate a route by tag', async (ctx) => { expect(post3.headers, 'a cache hit on the revalidated and regenerated page').toEqual( expect.objectContaining({ 'cache-status': expect.stringMatching(/"Next.js"; hit/), - 'netlify-cdn-cache-control': 's-maxage=31536000, stale-while-revalidate=31536000, durable', + 'netlify-cdn-cache-control': nextVersionSatisfies('>=15.0.0-canary.187') + ? 's-maxage=31536000, durable' + : 's-maxage=31536000, stale-while-revalidate=31536000, durable', }), ) expect(post3Date).toBe(post2Date) @@ -146,7 +153,9 @@ test('should revalidate a route by tag', async (ctx) => { expect(post4.headers, 'a cache miss on the on demand revalidated page').toEqual( expect.objectContaining({ 'cache-status': '"Next.js"; fwd=miss', - 'netlify-cdn-cache-control': 's-maxage=31536000, stale-while-revalidate=31536000, durable', + 'netlify-cdn-cache-control': nextVersionSatisfies('>=15.0.0-canary.187') + ? 's-maxage=31536000, durable' + : 's-maxage=31536000, stale-while-revalidate=31536000, durable', }), ) expect(post4Date).not.toBe(post3Date) diff --git a/tests/integration/simple-app.test.ts b/tests/integration/simple-app.test.ts index 3b17f7130c..5cd82431c4 100644 --- a/tests/integration/simple-app.test.ts +++ b/tests/integration/simple-app.test.ts @@ -21,6 +21,7 @@ import { getBlobEntries, startMockBlobStore, } from '../utils/helpers.js' +import { nextVersionSatisfies } from '../utils/next-version-helpers.mjs' const mockedCp = cp as Mock< Parameters<(typeof import('node:fs/promises'))['cp']>, @@ -149,14 +150,19 @@ test('index should be normalized within the cacheHandler and expect(index.headers?.['netlify-cache-tag']).toBe('_N_T_/layout,_N_T_/page,_N_T_/') }) -test('stale-while-revalidate headers should be normalized to include delta-seconds', async (ctx) => { - await createFixture('simple', ctx) - await runPlugin(ctx) - const index = await invokeFunction(ctx, { url: '/' }) - expect(index.headers?.['netlify-cdn-cache-control']).toContain( - 'stale-while-revalidate=31536000, durable', - ) -}) +// with 15.0.0-canary.187 and later Next.js no longer produce `stale-while-revalidate` directive +// for permanently cached response +test.skipIf(nextVersionSatisfies('>=15.0.0-canary.187'))( + 'stale-while-revalidate headers should be normalized to include delta-seconds', + async (ctx) => { + await createFixture('simple', ctx) + await runPlugin(ctx) + const index = await invokeFunction(ctx, { url: '/' }) + expect(index.headers?.['netlify-cdn-cache-control']).toContain( + 'stale-while-revalidate=31536000, durable', + ) + }, +) test('handlers receive correct site domain', async (ctx) => { await createFixture('simple', ctx)