Skip to content

Commit

Permalink
test: fix tests to work with new implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
wyattjoh committed Apr 25, 2024
1 parent ce02b1b commit 0f3670c
Show file tree
Hide file tree
Showing 8 changed files with 179 additions and 134 deletions.
33 changes: 21 additions & 12 deletions packages/next/src/server/lib/patch-fetch.ts
Expand Up @@ -694,14 +694,18 @@ function createPatchedFetcher(
// If enabled, we should bail out of static generation.
trackDynamicFetch(staticGenerationStore, dynamicUsageReason)

// PPR is not enabled, or React postpone is not available, we
// should set the revalidate to 0.
staticGenerationStore.revalidate = 0

const err = new DynamicServerError(dynamicUsageReason)
staticGenerationStore.dynamicUsageErr = err
staticGenerationStore.dynamicUsageDescription = dynamicUsageReason
throw err
// If partial prerendering is not enabled, then we should throw an
// error to indicate that this fetch is dynamic.
if (!staticGenerationStore.prerenderState) {
// PPR is not enabled, or React postpone is not available, we
// should set the revalidate to 0.
staticGenerationStore.revalidate = 0

const err = new DynamicServerError(dynamicUsageReason)
staticGenerationStore.dynamicUsageErr = err
staticGenerationStore.dynamicUsageDescription = dynamicUsageReason
throw err
}
}

const hasNextConfig = 'next' in init
Expand All @@ -726,10 +730,15 @@ function createPatchedFetcher(
// If enabled, we should bail out of static generation.
trackDynamicFetch(staticGenerationStore, dynamicUsageReason)

const err = new DynamicServerError(dynamicUsageReason)
staticGenerationStore.dynamicUsageErr = err
staticGenerationStore.dynamicUsageDescription = dynamicUsageReason
throw err
// If partial prerendering is not enabled, then we should throw an
// error to indicate that this fetch is dynamic.
if (!staticGenerationStore.prerenderState) {
const err = new DynamicServerError(dynamicUsageReason)
staticGenerationStore.dynamicUsageErr = err
staticGenerationStore.dynamicUsageDescription =
dynamicUsageReason
throw err
}
}

if (!staticGenerationStore.forceStatic || next.revalidate !== 0) {
Expand Down
73 changes: 0 additions & 73 deletions test/e2e/app-dir/app-static/app-static.test.ts
Expand Up @@ -3213,79 +3213,6 @@ describe('app-dir static/dynamic handling', () => {
})

describe('unstable_cache', () => {
if (isNextStart) {
describe('fetch', () => {
let server: http.Server | null = null
afterEach(async () => {
if (!server) return

await server.close()
server = null
})

it('should not cache inner fetch calls', async () => {
let generations: string[] = []
server = http.createServer(async (key, res) => {
const random = Math.floor(Math.random() * 100).toString()
generations.push(random)
res.end(random)
})
const port = await findPort()
server.listen(port)
const address = `http://localhost:${port}/`

const first = await next
.fetch('/unstable-cache/fetch', {
headers: {
'X-Test-Data-Server': address,
},
})
.then((res) => res.json())

expect(generations).toHaveLength(1)
expect(first).toEqual(
expect.objectContaining({
data: generations[0],
})
)

const second = await next
.fetch('/unstable-cache/fetch', {
headers: {
'X-Test-Data-Server': address,
},
})
.then((res) => res.json())

expect(generations).toHaveLength(1)
expect(first).toEqual(second)

// Revalidate the cache for the unstable_cache, but explicitly not
// the inner fetch call. We expect it to not cache either.
await next.fetch('/unstable-cache/fetch?tag=unstable-cache-fetch', {
method: 'DELETE',
})

const third = await next
.fetch('/unstable-cache/fetch', {
headers: {
'X-Test-Data-Server': address,
},
})
.then((res) => res.json())

expect(generations).toHaveLength(2)
expect(generations[1]).not.toEqual(generations[0])
expect(third).toEqual(
expect.objectContaining({
data: generations[1],
})
)
expect(third).not.toEqual(first)
})
})
}

it('should retrieve the same value on second request', async () => {
const res = await next.fetch('/unstable-cache/dynamic')
const html = await res.text()
Expand Down
49 changes: 0 additions & 49 deletions test/e2e/app-dir/app-static/app/unstable-cache/fetch/route.ts

This file was deleted.

7 changes: 7 additions & 0 deletions test/e2e/app-dir/ppr-unstable-cache/app/layout.jsx
@@ -0,0 +1,7 @@
export default function Layout({ children }) {
return (
<html>
<body>{children}</body>
</html>
)
}
37 changes: 37 additions & 0 deletions test/e2e/app-dir/ppr-unstable-cache/app/page.jsx
@@ -0,0 +1,37 @@
import { unstable_cache } from 'next/cache'

const getData = unstable_cache(
async () => {
const noStore = await fetch(
process.env.TEST_DATA_SERVER + '?cache=no-store',
{ method: 'GET', cache: 'no-store' }
).then((res) => res.text())

const forceCache = await fetch(
process.env.TEST_DATA_SERVER + '?cache=force-cache',
{ method: 'GET', cache: 'force-cache' }
).then((res) => res.text())

return JSON.stringify(
{
random: Math.floor(Math.random() * 1000).toString(),
data: {
forceCache,
noStore,
},
},
null,
2
)
},
undefined,
{
tags: ['unstable-cache-fetch'],
}
)

export default async function Page() {
const data = await getData()

return <pre id="data">{data}</pre>
}
@@ -0,0 +1,6 @@
import { revalidateTag } from 'next/cache'

export const POST = async () => {
revalidateTag('unstable-cache-fetch')
return new Response('OK', { status: 200 })
}
5 changes: 5 additions & 0 deletions test/e2e/app-dir/ppr-unstable-cache/next.config.js
@@ -0,0 +1,5 @@
module.exports = {
experimental: {
ppr: true,
},
}
103 changes: 103 additions & 0 deletions test/e2e/app-dir/ppr-unstable-cache/ppr-unstable-cache.test.ts
@@ -0,0 +1,103 @@
import { NextInstance, createNext, isNextDeploy, isNextDev } from 'e2e-utils'
import { findPort } from 'next-test-utils'
import http from 'node:http'

describe('ppr-unstable-cache', () => {
if (isNextDeploy) {
it.skip('should not run in deploy mode', () => {})
return
}

if (isNextDev) {
it.skip('should not run in dev mode', () => {})
return
}

let next: NextInstance | null = null
let server: http.Server | null = null
afterEach(async () => {
if (next) {
await next.destroy()
next = null
}

if (server) {
await server.close()
server = null
}
})

it('should not cache inner fetch calls', async () => {
let generations: string[] = []
server = http.createServer(async (req, res) => {
try {
if (!req.url) throw new Error('No URL')

const cache = new URL(req.url, 'http://n').searchParams.get('cache')
if (!cache) throw new Error('No cache key')

const random = Math.floor(Math.random() * 1000).toString()
const data = cache + ':' + random
generations.push(data)
res.end(data)
} catch (err) {
res.statusCode = 500
res.end(err.message)
}
})
const port = await findPort()
server.listen(port)

next = await createNext({
files: __dirname,
env: { TEST_DATA_SERVER: `http://localhost:${port}/` },
})

expect(generations).toHaveLength(3)

const first = await next
.render$('/')
.then(($) => JSON.parse($('#data').text()))

expect(generations).toHaveLength(3)

expect(first.data.forceCache).toBeOneOf(generations)
expect(first.data.noStore).toBeOneOf(generations)

// Try a few more times, we should always get the same result.
for (let i = 0; i < 3; i++) {
const again = await next
.render$('/')
.then(($) => JSON.parse($('#data').text()))

expect(generations).toHaveLength(3)
expect(first).toEqual(again)
}

// Revalidate the tag associated with the `unstable_cache` call.
const revalidate = await next.fetch('/revalidate-tag', { method: 'POST' })
expect(revalidate.status).toBe(200)
await revalidate.text()

const revalidated = await next
.render$('/')
.then(($) => JSON.parse($('#data').text()))

// Expect that the `cache: no-store` value has been updated, but not
// the `cache: force-cache` value.
expect(generations).toHaveLength(5)

// We know now that the generations have been updated, so let's try to
// validate the value. We don't need to do this within the retry.
expect(revalidated.random).not.toEqual(first.random)
expect(revalidated.data.forceCache).toBeOneOf(generations.slice(0, 3))
expect(revalidated.data.noStore).toBeOneOf(generations.slice(3))
expect(revalidated).not.toEqual(first)

// Ensure that the `force-cache` value has not been updated, and only called
// once.
expect(generations.filter((g) => g.startsWith('force-cache'))).toHaveLength(
1
)
})
})

0 comments on commit 0f3670c

Please sign in to comment.