|
| 1 | +import { load } from 'cheerio' |
| 2 | +import { getLogger } from 'lambda-local' |
| 3 | +import { v4 } from 'uuid' |
| 4 | +import { beforeEach, expect, test, vi } from 'vitest' |
| 5 | +import { |
| 6 | + createFixture, |
| 7 | + invokeFunction, |
| 8 | + runPlugin, |
| 9 | + type FixtureTestContext, |
| 10 | +} from '../utils/fixture.js' |
| 11 | +import { generateRandomObjectID, getBlobEntries, startMockBlobStore } from '../utils/helpers.js' |
| 12 | + |
| 13 | +// Disable the verbose logging of the lambda-local runtime |
| 14 | +getLogger().level = 'alert' |
| 15 | + |
| 16 | +beforeEach<FixtureTestContext>(async (ctx) => { |
| 17 | + // set for each test a new deployID and siteID |
| 18 | + ctx.deployID = generateRandomObjectID() |
| 19 | + ctx.siteID = v4() |
| 20 | + vi.stubEnv('SITE_ID', ctx.siteID) |
| 21 | + vi.stubEnv('DEPLOY_ID', ctx.deployID) |
| 22 | + vi.stubEnv('NETLIFY_PURGE_API_TOKEN', 'fake-token') |
| 23 | + // hide debug logs in tests |
| 24 | + // vi.spyOn(console, 'debug').mockImplementation(() => {}) |
| 25 | + |
| 26 | + await startMockBlobStore(ctx) |
| 27 | +}) |
| 28 | + |
| 29 | +test<FixtureTestContext>('should revalidate a route by path', async (ctx) => { |
| 30 | + await createFixture('server-components', ctx) |
| 31 | + await runPlugin(ctx) |
| 32 | + |
| 33 | + expect(await ctx.blobStore.get('server/app/static-fetch/1')).not.toBeNull() |
| 34 | + expect(await ctx.blobStore.get('.netlfiy/cache/tags/_N_T_/static-fetch/[id]/page')).toBeNull() |
| 35 | + |
| 36 | + // test the function call |
| 37 | + const [post1, post1Route2] = await Promise.all([ |
| 38 | + invokeFunction(ctx, { url: '/static-fetch/1' }), |
| 39 | + invokeFunction(ctx, { url: '/static-fetch/2' }), |
| 40 | + ]) |
| 41 | + const post1Date = load(post1.body)('[data-testid="date-now"]').text() |
| 42 | + expect(post1.statusCode).toBe(200) |
| 43 | + expect(post1Route2.statusCode).toBe(200) |
| 44 | + expect(load(post1.body)('h1').text()).toBe('Hello, Statically fetched show 1') |
| 45 | + expect(post1.headers, 'a cache hit on the first invocation of a prerendered page').toEqual( |
| 46 | + expect.objectContaining({ |
| 47 | + 'x-nextjs-cache': 'HIT', |
| 48 | + 'netlify-cdn-cache-control': 's-maxage=31536000, stale-while-revalidate', |
| 49 | + }), |
| 50 | + ) |
| 51 | + expect(post1Route2.headers, 'a cache hit on the first invocation of a prerendered page').toEqual( |
| 52 | + expect.objectContaining({ |
| 53 | + 'x-nextjs-cache': 'HIT', |
| 54 | + 'netlify-cdn-cache-control': 's-maxage=31536000, stale-while-revalidate', |
| 55 | + }), |
| 56 | + ) |
| 57 | + |
| 58 | + const revalidate = await invokeFunction(ctx, { url: '/api/on-demand-revalidate/path' }) |
| 59 | + expect(revalidate.statusCode).toBe(200) |
| 60 | + expect(JSON.parse(revalidate.body)).toEqual({ revalidated: true, now: expect.any(String) }) |
| 61 | + // expect(calledPurge).toBe(1) |
| 62 | + // it does not wait for the cache.set so we have to manually wait here until the blob storage got populated |
| 63 | + await new Promise<void>((resolve) => setTimeout(resolve, 1000)) |
| 64 | + |
| 65 | + const entries = await getBlobEntries(ctx) |
| 66 | + expect(await ctx.blobStore.get('.netlfiy/cache/tags/_N_T_/static-fetch/[id]/page')).not.toBeNull() |
| 67 | + |
| 68 | + console.log(entries) |
| 69 | + const [post2, post2Route2] = await Promise.all([ |
| 70 | + invokeFunction(ctx, { url: '/static-fetch/1' }), |
| 71 | + invokeFunction(ctx, { url: '/static-fetch/2' }), |
| 72 | + ]) |
| 73 | + const post2Date = load(post2.body)('[data-testid="date-now"]').text() |
| 74 | + expect(post2.statusCode).toBe(200) |
| 75 | + expect(post2Route2.statusCode).toBe(200) |
| 76 | + expect(load(post2.body)('h1').text()).toBe('Hello, Statically fetched show 1') |
| 77 | + expect(post2.headers, 'a cache miss on the on demand revalidated path /1').toEqual( |
| 78 | + expect.objectContaining({ |
| 79 | + 'x-nextjs-cache': 'MISS', |
| 80 | + 'netlify-cdn-cache-control': 's-maxage=31536000, stale-while-revalidate', |
| 81 | + }), |
| 82 | + ) |
| 83 | + expect(post2Route2.headers, 'a cache miss on the on demand revalidated path /2').toEqual( |
| 84 | + expect.objectContaining({ |
| 85 | + 'x-nextjs-cache': 'MISS', |
| 86 | + 'netlify-cdn-cache-control': 's-maxage=31536000, stale-while-revalidate', |
| 87 | + }), |
| 88 | + ) |
| 89 | + expect(post2Date).not.toBe(post1Date) |
| 90 | +}) |
0 commit comments