rsnext/test/e2e/edge-pages-support/index.test.ts

176 lines
5.3 KiB
TypeScript
Raw Normal View History

import { createNext, FileRef } from 'e2e-utils'
import { NextInstance } from 'test/lib/next-modes/base'
import { fetchViaHTTP, normalizeRegEx, renderViaHTTP } from 'next-test-utils'
import cheerio from 'cheerio'
import { join } from 'path'
import escapeStringRegexp from 'escape-string-regexp'
Fix outputting un-necessary trace files for edge functions (#43304) <!-- Thanks for opening a PR! Your contribution is much appreciated. To make sure your PR is handled as smoothly as possible we request that you follow the checklist sections below. Choose the right checklist for the change that you're making: --> ## Bug - [x] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] [e2e](https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs) tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm build && pnpm lint` - [ ] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md) fixes #39275 and related issues like #39858 and hopefully #41395 (can't test because `pnpm next-with-deps build ./dev-app` keeps crashing on `Collecting page data...` - `useContext` seems to be null, and even without the changes it still crashes). This works by checking if the file is an edge function in Next.js's Webpack plugin `TraceEntryPointsPlugin`, if true then output the nft file to the output path, if not move up a folder like previously. I tried changing Webpack config's output.path from `path: !dev && isNodeServer ? path.join(outputPath, 'chunks') : outputPath` to `path: !dev && (isNodeServer || isEdgeServer) ? path.join(outputPath, 'chunks') : outputPath`, but it just causes the build script to crash because files like middleware-manifest.json are output to outputPath/chunks instead of the expected outputPath. So I find this to be the better solution. Co-authored-by: JJ Kasper <jj@jjsweb.site>
2022-11-24 03:56:11 +01:00
import fs from 'fs-extra'
describe('edge-render-getserversideprops', () => {
let next: NextInstance
beforeAll(async () => {
next = await createNext({
files: new FileRef(join(__dirname, 'app')),
dependencies: {},
})
})
afterAll(() => next.destroy())
Fix outputting un-necessary trace files for edge functions (#43304) <!-- Thanks for opening a PR! Your contribution is much appreciated. To make sure your PR is handled as smoothly as possible we request that you follow the checklist sections below. Choose the right checklist for the change that you're making: --> ## Bug - [x] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] [e2e](https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs) tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm build && pnpm lint` - [ ] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md) fixes #39275 and related issues like #39858 and hopefully #41395 (can't test because `pnpm next-with-deps build ./dev-app` keeps crashing on `Collecting page data...` - `useContext` seems to be null, and even without the changes it still crashes). This works by checking if the file is an edge function in Next.js's Webpack plugin `TraceEntryPointsPlugin`, if true then output the nft file to the output path, if not move up a folder like previously. I tried changing Webpack config's output.path from `path: !dev && isNodeServer ? path.join(outputPath, 'chunks') : outputPath` to `path: !dev && (isNodeServer || isEdgeServer) ? path.join(outputPath, 'chunks') : outputPath`, but it just causes the build script to crash because files like middleware-manifest.json are output to outputPath/chunks instead of the expected outputPath. So I find this to be the better solution. Co-authored-by: JJ Kasper <jj@jjsweb.site>
2022-11-24 03:56:11 +01:00
if ((global as any).isNextStart) {
it('should not output trace files for edge routes', async () => {
expect(await fs.pathExists(join(next.testDir, '.next/pages'))).toBe(false)
expect(
await fs.pathExists(join(next.testDir, '.next/server/pages/[id].js'))
).toBe(true)
expect(
await fs.pathExists(
join(next.testDir, '.next/server/pages/[id].js.nft.json')
)
).toBe(false)
expect(
await fs.pathExists(join(next.testDir, '.next/server/pages/index.js'))
).toBe(true)
expect(
await fs.pathExists(
join(next.testDir, '.next/server/pages/index.js.nft.json')
)
).toBe(false)
})
}
it('should have correct query for pages/api', async () => {
const res = await fetchViaHTTP(next.url, '/api/hello', { a: 'b' })
expect(res.status).toBe(200)
expect(await res.json()).toEqual({
hello: 'world',
query: {
a: 'b',
},
})
})
it('should have correct query for pages/api dynamic', async () => {
const res = await fetchViaHTTP(next.url, '/api/id-1', { a: 'b' })
expect(res.status).toBe(200)
expect(await res.json()).toEqual({
hello: 'again',
query: {
a: 'b',
id: 'id-1',
},
})
})
it('should have correct query/params on index', async () => {
const html = await renderViaHTTP(next.url, '/')
const $ = cheerio.load(html)
expect($('#page').text()).toBe('/index')
const props = JSON.parse($('#props').text())
expect(props.query).toEqual({})
expect(props.params).toBe(null)
expect(props.url).toBe('/')
})
it('should have correct query/params on /[id]', async () => {
const html = await renderViaHTTP(next.url, '/123', { hello: 'world' })
const $ = cheerio.load(html)
expect($('#page').text()).toBe('/[id]')
const props = JSON.parse($('#props').text())
expect(props.query).toEqual({ id: '123', hello: 'world' })
expect(props.params).toEqual({ id: '123' })
expect(props.url).toBe('/123?hello=world')
})
it('should have correct query/params on rewrite', async () => {
const html = await renderViaHTTP(next.url, '/rewrite-me', {
hello: 'world',
})
const $ = cheerio.load(html)
expect($('#page').text()).toBe('/index')
const props = JSON.parse($('#props').text())
expect(props.query).toEqual({ hello: 'world' })
expect(props.params).toEqual(null)
expect(props.url).toBe('/rewrite-me?hello=world')
})
it('should have correct query/params on dynamic rewrite', async () => {
const html = await renderViaHTTP(next.url, '/rewrite-me-dynamic', {
hello: 'world',
})
const $ = cheerio.load(html)
expect($('#page').text()).toBe('/[id]')
const props = JSON.parse($('#props').text())
expect(props.query).toEqual({ id: 'first', hello: 'world' })
expect(props.params).toEqual({ id: 'first' })
expect(props.url).toBe('/rewrite-me-dynamic?hello=world')
})
it('should respond to _next/data for index correctly', async () => {
const res = await fetchViaHTTP(
next.url,
`/_next/data/${next.buildId}/index.json`,
undefined,
{
headers: {
'x-nextjs-data': '1',
},
}
)
expect(res.status).toBe(200)
const { pageProps: props } = await res.json()
expect(props.query).toEqual({})
expect(props.params).toBe(null)
})
it('should respond to _next/data for [id] correctly', async () => {
const res = await fetchViaHTTP(
next.url,
`/_next/data/${next.buildId}/321.json`,
{ hello: 'world' },
{
headers: {
'x-nextjs-data': '1',
},
}
)
expect(res.status).toBe(200)
const { pageProps: props } = await res.json()
expect(props.query).toEqual({ id: '321', hello: 'world' })
expect(props.params).toEqual({ id: '321' })
})
if ((global as any).isNextStart) {
it('should have data routes in routes-manifest', async () => {
const manifest = JSON.parse(
await next.readFile('.next/routes-manifest.json')
)
for (const route of manifest.dataRoutes) {
route.dataRouteRegex = normalizeRegEx(route.dataRouteRegex)
}
expect(manifest.dataRoutes).toEqual([
{
dataRouteRegex: normalizeRegEx(
`^/_next/data/${escapeStringRegexp(next.buildId)}/index.json$`
),
page: '/',
},
{
dataRouteRegex: normalizeRegEx(
`^/_next/data/${escapeStringRegexp(next.buildId)}/([^/]+?)\\.json$`
),
namedDataRouteRegex: `^/_next/data/${escapeStringRegexp(
next.buildId
)}/(?<nxtPid>[^/]+?)\\.json$`,
page: '/[id]',
routeKeys: {
nxtPid: 'nxtPid',
},
},
])
})
}
})