From dbeaa5ae5f8ab7786752455e83ea2030c8dabbf6 Mon Sep 17 00:00:00 2001 From: Jan Potoms <2109932+Janpot@users.noreply.github.com> Date: Wed, 12 Feb 2020 07:52:47 +0100 Subject: [PATCH 1/4] Add failing test --- .../pages/api/catch-all/users/[...slug].js | 3 ++ .../pages/api/catch-all/users/index.js | 1 + .../api-support/test/index.test.js | 33 +++++++++++++++++++ 3 files changed, 37 insertions(+) create mode 100644 test/integration/api-support/pages/api/catch-all/users/[...slug].js create mode 100644 test/integration/api-support/pages/api/catch-all/users/index.js diff --git a/test/integration/api-support/pages/api/catch-all/users/[...slug].js b/test/integration/api-support/pages/api/catch-all/users/[...slug].js new file mode 100644 index 0000000000000..19d7fdef8cd21 --- /dev/null +++ b/test/integration/api-support/pages/api/catch-all/users/[...slug].js @@ -0,0 +1,3 @@ +export default function(req, res) { + res.json(req.query) +} diff --git a/test/integration/api-support/pages/api/catch-all/users/index.js b/test/integration/api-support/pages/api/catch-all/users/index.js new file mode 100644 index 0000000000000..f716604618fbe --- /dev/null +++ b/test/integration/api-support/pages/api/catch-all/users/index.js @@ -0,0 +1 @@ +export { default } from './[...slug]' diff --git a/test/integration/api-support/test/index.test.js b/test/integration/api-support/test/index.test.js index c4e5c7d389b37..916e17fc70db3 100644 --- a/test/integration/api-support/test/index.test.js +++ b/test/integration/api-support/test/index.test.js @@ -322,6 +322,39 @@ function runTests(dev = false) { expect(data).toEqual({ post: 'post-1', id: '1' }) }) + it('should return data when catch-all', async () => { + const data = await fetchViaHTTP( + appPort, + '/api/catch-all/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/catch-all/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/catch-all/users', + null, + {} + ).then(res => res.ok && res.json()) + + expect(data).toEqual({}) + }) + if (dev) { it('should compile only server code in development', async () => { await fetchViaHTTP(appPort, '/') From aa6e63d7bd5b625afe8ad0419ce3c9b5e001a7ac Mon Sep 17 00:00:00 2001 From: Jan Potoms <2109932+Janpot@users.noreply.github.com> Date: Sun, 16 Feb 2020 13:31:15 +0100 Subject: [PATCH 2/4] This seems to solve it --- packages/next/next-server/server/next-server.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/packages/next/next-server/server/next-server.ts b/packages/next/next-server/server/next-server.ts index 58531b826d759..92a3698ee261b 100644 --- a/packages/next/next-server/server/next-server.ts +++ b/packages/next/next-server/server/next-server.ts @@ -555,7 +555,7 @@ export default class Server { const handled = await this.handleApiRequest( req as NextApiRequest, res as NextApiResponse, - pathname!, + pathname, query ) if (handled) { @@ -652,7 +652,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 } From ad7059ea5ca9dda2a35b861ad1ae56db9b50addb Mon Sep 17 00:00:00 2001 From: Jan Potoms <2109932+Janpot@users.noreply.github.com> Date: Sun, 16 Feb 2020 15:51:18 +0100 Subject: [PATCH 3/4] Isolate test case because it's interferring with the other routes --- .../pages/api}/users/[...slug].js | 0 .../pages/api}/users/index.js | 0 .../api-catch-all/test/index.test.js | 85 +++++++++++++++++++ .../api-support/test/index.test.js | 33 ------- 4 files changed, 85 insertions(+), 33 deletions(-) rename test/integration/{api-support/pages/api/catch-all => api-catch-all/pages/api}/users/[...slug].js (100%) rename test/integration/{api-support/pages/api/catch-all => api-catch-all/pages/api}/users/index.js (100%) create mode 100644 test/integration/api-catch-all/test/index.test.js diff --git a/test/integration/api-support/pages/api/catch-all/users/[...slug].js b/test/integration/api-catch-all/pages/api/users/[...slug].js similarity index 100% rename from test/integration/api-support/pages/api/catch-all/users/[...slug].js rename to test/integration/api-catch-all/pages/api/users/[...slug].js diff --git a/test/integration/api-support/pages/api/catch-all/users/index.js b/test/integration/api-catch-all/pages/api/users/index.js similarity index 100% rename from test/integration/api-support/pages/api/catch-all/users/index.js rename to test/integration/api-catch-all/pages/api/users/index.js diff --git a/test/integration/api-catch-all/test/index.test.js b/test/integration/api-catch-all/test/index.test.js new file mode 100644 index 0000000000000..ce5bc9260e53d --- /dev/null +++ b/test/integration/api-catch-all/test/index.test.js @@ -0,0 +1,85 @@ +/* eslint-env jest */ +/* global jasmine */ +import fs from 'fs-extra' +import { join } from 'path' +import { + killApp, + findPort, + launchApp, + fetchViaHTTP, + nextBuild, + nextStart, +} from 'next-test-utils' + +jasmine.DEFAULT_TIMEOUT_INTERVAL = 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() + }) +}) diff --git a/test/integration/api-support/test/index.test.js b/test/integration/api-support/test/index.test.js index 916e17fc70db3..c4e5c7d389b37 100644 --- a/test/integration/api-support/test/index.test.js +++ b/test/integration/api-support/test/index.test.js @@ -322,39 +322,6 @@ function runTests(dev = false) { expect(data).toEqual({ post: 'post-1', id: '1' }) }) - it('should return data when catch-all', async () => { - const data = await fetchViaHTTP( - appPort, - '/api/catch-all/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/catch-all/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/catch-all/users', - null, - {} - ).then(res => res.ok && res.json()) - - expect(data).toEqual({}) - }) - if (dev) { it('should compile only server code in development', async () => { await fetchViaHTTP(appPort, '/') From 2b0d9b5d67a7b7d138c3ea89d6b1a92c65f025f6 Mon Sep 17 00:00:00 2001 From: Joe Haddad Date: Mon, 18 May 2020 13:50:04 -0400 Subject: [PATCH 4/4] Apply suggestions from code review --- test/integration/api-catch-all/test/index.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/integration/api-catch-all/test/index.test.js b/test/integration/api-catch-all/test/index.test.js index ce5bc9260e53d..3aba767e10587 100644 --- a/test/integration/api-catch-all/test/index.test.js +++ b/test/integration/api-catch-all/test/index.test.js @@ -1,5 +1,4 @@ /* eslint-env jest */ -/* global jasmine */ import fs from 'fs-extra' import { join } from 'path' import { @@ -11,7 +10,8 @@ import { nextStart, } from 'next-test-utils' -jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000 * 60 * 2 +jest.setTimeout(1000 * 60 * 2) + const appDir = join(__dirname, '../') const nextConfig = join(appDir, 'next.config.js') let appPort