Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure catch-all routes 404 for index route #10502

Merged
merged 12 commits into from
May 19, 2020
13 changes: 11 additions & 2 deletions packages/next/next-server/server/next-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -604,7 +604,7 @@ export default class Server {
const handled = await this.handleApiRequest(
req as NextApiRequest,
res as NextApiResponse,
pathname!,
pathname,
query
)
if (handled) {
Expand Down Expand Up @@ -701,7 +701,16 @@ export default class Server {
// or else it won't be in the manifest yet
await this.ensureApiPage(page)

const builtPagePath = await this.getPagePath(page)
let builtPagePath
try {
builtPagePath = await this.getPagePath(page)
} catch (err) {
if (err.code === 'ENOENT') {
return false
}
throw err
}

const pageModule = require(builtPagePath)
query = { ...query, ...params }

Expand Down
3 changes: 3 additions & 0 deletions test/integration/api-catch-all/pages/api/users/[...slug].js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function(req, res) {
res.json(req.query)
}
1 change: 1 addition & 0 deletions test/integration/api-catch-all/pages/api/users/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './[...slug]'
85 changes: 85 additions & 0 deletions test/integration/api-catch-all/test/index.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/* eslint-env jest */
import fs from 'fs-extra'
import { join } from 'path'
import {
killApp,
findPort,
launchApp,
fetchViaHTTP,
nextBuild,
nextStart,
} from 'next-test-utils'

jest.setTimeout(1000 * 60 * 2)

const appDir = join(__dirname, '../')
const nextConfig = join(appDir, 'next.config.js')
let appPort
let app

function runTests() {
it('should return data when catch-all', async () => {
const data = await fetchViaHTTP(appPort, '/api/users/1', null, {}).then(
res => res.ok && res.json()
)

expect(data).toEqual({ slug: ['1'] })
})

it('should 404 when catch-all with index and trailing slash', async () => {
const data = await fetchViaHTTP(appPort, '/api/users/', null, {}).then(
res => res.status
)

expect(data).toEqual(404)
})

it('should return data when catch-all with index and no trailing slash', async () => {
const data = await fetchViaHTTP(appPort, '/api/users', null, {}).then(
res => res.ok && res.json()
)

expect(data).toEqual({})
})
}

describe('API routes', () => {
describe('dev support', () => {
beforeAll(async () => {
appPort = await findPort()
app = await launchApp(appDir, appPort)
})
afterAll(() => killApp(app))

runTests()
})

describe('Server support', () => {
beforeAll(async () => {
await nextBuild(appDir)
appPort = await findPort()
app = await nextStart(appDir, appPort)
})
afterAll(() => killApp(app))

runTests()
})

describe('Serverless support', () => {
beforeAll(async () => {
await fs.writeFile(
nextConfig,
`module.exports = { target: 'serverless' }`
)
await nextBuild(appDir)
appPort = await findPort()
app = await nextStart(appDir, appPort)
})
afterAll(async () => {
await killApp(app)
await fs.remove(nextConfig)
})

runTests()
})
})