From 815e3dce3a06dfd23e157003b5b77e246854c1c9 Mon Sep 17 00:00:00 2001 From: Janka Uryga Date: Wed, 20 Nov 2024 21:24:17 +0100 Subject: [PATCH] test: add tests for legacy NextCustomServer methods --- test/integration/custom-server/pages/404.js | 1 + test/integration/custom-server/pages/500.js | 1 + .../custom-server/pages/dashboard/index.js | 18 ++++- .../pages/dynamic-dashboard/index.js | 22 ++++++ test/integration/custom-server/server.js | 69 +++++++++++++++++- .../custom-server/test/index.test.js | 70 ++++++++++++++++++- .../filesystempublicroutes/server.js | 2 +- 7 files changed, 178 insertions(+), 5 deletions(-) create mode 100644 test/integration/custom-server/pages/404.js create mode 100644 test/integration/custom-server/pages/500.js create mode 100644 test/integration/custom-server/pages/dynamic-dashboard/index.js diff --git a/test/integration/custom-server/pages/404.js b/test/integration/custom-server/pages/404.js new file mode 100644 index 0000000000000..e4dfaf154509f --- /dev/null +++ b/test/integration/custom-server/pages/404.js @@ -0,0 +1 @@ +export default () =>

made it to 404

diff --git a/test/integration/custom-server/pages/500.js b/test/integration/custom-server/pages/500.js new file mode 100644 index 0000000000000..c068f460f5081 --- /dev/null +++ b/test/integration/custom-server/pages/500.js @@ -0,0 +1 @@ +export default () =>

made it to 500

diff --git a/test/integration/custom-server/pages/dashboard/index.js b/test/integration/custom-server/pages/dashboard/index.js index 53546a8f756f6..289b59f8912be 100644 --- a/test/integration/custom-server/pages/dashboard/index.js +++ b/test/integration/custom-server/pages/dashboard/index.js @@ -1 +1,17 @@ -export default () =>

made it to dashboard

+import { useRouter } from 'next/router' + +export default () => { + const router = useRouter() + const searchParam = router.query.q + return ( +

+ made it to dashboard + {!!searchParam && ( + <> +
+ query param: {searchParam} + + )} +

+ ) +} diff --git a/test/integration/custom-server/pages/dynamic-dashboard/index.js b/test/integration/custom-server/pages/dynamic-dashboard/index.js new file mode 100644 index 0000000000000..36fd1f7239378 --- /dev/null +++ b/test/integration/custom-server/pages/dynamic-dashboard/index.js @@ -0,0 +1,22 @@ +import { useRouter } from 'next/router' + +// NOTE: we want this page to be dynamic, otherwise the HTML won't contain search params +export async function getServerSideProps() { + return { props: {} } +} + +export default function Page() { + const router = useRouter() + const searchParam = router.query.q + return ( +

+ made it to dynamic dashboard + {!!searchParam && ( + <> +
+ query param: {searchParam} + + )} +

+ ) +} diff --git a/test/integration/custom-server/server.js b/test/integration/custom-server/server.js index 24173e1831911..0725e4ed12373 100644 --- a/test/integration/custom-server/server.js +++ b/test/integration/custom-server/server.js @@ -1,17 +1,27 @@ +// @ts-check + if (process.env.POLYFILL_FETCH) { + // @ts-expect-error global.fetch = require('node-fetch').default + // @ts-expect-error global.Request = require('node-fetch').Request + // @ts-expect-error global.Headers = require('node-fetch').Headers } const { readFileSync } = require('fs') + +/** @type {import('next').default} */ +// @ts-ignore: missing interopDefault const next = require('next') + const { join } = require('path') const { parse } = require('url') const dev = process.env.NODE_ENV !== 'production' const dir = __dirname -const port = process.env.PORT || 3000 +const port = + (process.env.PORT ? Number.parseInt(process.env.PORT) : undefined) || 3000 const { createServer } = require( process.env.USE_HTTPS === 'true' ? 'https' : 'http' ) @@ -30,6 +40,11 @@ process.on('unhandledRejection', (err) => { app.prepare().then(() => { const server = createServer(httpOptions, async (req, res) => { + // let next.js handle assets from /_next/ + if (/\/_next\//.test(req.url)) { + return handleNextRequests(req, res) + } + if (req.url === '/no-query') { return app.render(req, res, '/no-query') } @@ -42,7 +57,7 @@ app.prepare().then(() => { if (/setAssetPrefix/.test(req.url)) { app.setAssetPrefix(`http://127.0.0.1:${port}`) } else if (/setEmptyAssetPrefix/.test(req.url)) { - app.setAssetPrefix(null) + app.setAssetPrefix('') } else { // This is to support multi-zones support in localhost // and may be in staging deployments @@ -73,6 +88,56 @@ app.prepare().then(() => { return handleNextRequests(req, res, parse('/dashboard', true)) } + if (/legacy-methods\/render-to-html/.test(req.url)) { + try { + const html = await app.renderToHTML(req, res, '/dynamic-dashboard', { + q: '1', + }) + res.end(html) + } catch (err) { + res.end(err.message) + } + return + } + + if (/legacy-methods\/render404/.test(req.url)) { + try { + await app.render404(req, res, parse('/__non_existent__?q=1', true)) + } catch (err) { + res.end(err.message) + } + return + } + + if (/legacy-methods\/render-error/.test(req.url)) { + try { + res.statusCode = 500 + await app.renderError(new Error('kaboom'), req, res, '/dashboard', { + q: '1', + }) + } catch (err) { + res.end(err.message) + } + return + } + + if (/legacy-methods\/render-error-to-html/.test(req.url)) { + try { + res.statusCode = 500 + const html = await app.renderErrorToHTML( + new Error('kaboom'), + req, + res, + '/dashboard', + { q: '1' } + ) + res.end(html) + } catch (err) { + res.end(err.message) + } + return + } + handleNextRequests(req, res) }) diff --git a/test/integration/custom-server/test/index.test.js b/test/integration/custom-server/test/index.test.js index 293d060f88141..bf64a636329c4 100644 --- a/test/integration/custom-server/test/index.test.js +++ b/test/integration/custom-server/test/index.test.js @@ -301,7 +301,7 @@ describe.each([ await fetchViaHTTP(nextUrl, '/unhandled-rejection', undefined, { agent }) await check(() => stderr, /unhandledRejection/) expect(stderr).toContain('unhandledRejection: Error: unhandled rejection') - expect(stderr).toContain('server.js:38:22') + expect(stderr).toMatch(/\/server\.js:\d+\d+/) }) }) @@ -317,4 +317,72 @@ describe.each([ ) }) }) + + describe.each(['development', 'production'])( + 'legacy NextCustomServer methods - %s mode', + (mode) => { + const isNextDev = mode === 'development' + + beforeAll(async () => { + if (!isNextDev) { + await nextBuild(appDir) + } + await startServer({ NODE_ENV: mode }) + }) + afterAll(() => killApp(server)) + + it('NextCustomServer.renderToHTML', async () => { + const rawHTML = await renderViaHTTP( + nextUrl, + '/legacy-methods/render-to-html?q=2', + undefined, + { agent } + ) + const $ = cheerio.load(rawHTML) + const text = $('p').text() + expect(text).toContain('made it to dynamic dashboard') + expect(text).toContain('query param: 1') + }) + + it('NextCustomServer.render404', async () => { + const html = await renderViaHTTP( + nextUrl, + '/legacy-methods/render404', + undefined, + { agent } + ) + expect(html).toContain('made it to 404') + }) + + it('NextCustomServer.renderError', async () => { + const html = await renderViaHTTP( + nextUrl, + '/legacy-methods/render-error', + undefined, + { agent } + ) + if (isNextDev) { + // in dev, we always render error overlay + default error page, not /500 + expect(html).toContain('Error: kaboom') + } else { + expect(html).toContain('made it to 500') + } + }) + + it('NextCustomServer.renderErrorToHTML', async () => { + const html = await renderViaHTTP( + nextUrl, + '/legacy-methods/render-error-to-html', + undefined, + { agent } + ) + if (isNextDev) { + // in dev, we always render error overlay + default error page, not /500 + expect(html).toContain('Error: kaboom') + } else { + expect(html).toContain('made it to 500') + } + }) + } + ) }) diff --git a/test/integration/filesystempublicroutes/server.js b/test/integration/filesystempublicroutes/server.js index 71b62d95d34af..00131ab832d87 100644 --- a/test/integration/filesystempublicroutes/server.js +++ b/test/integration/filesystempublicroutes/server.js @@ -13,7 +13,7 @@ app.prepare().then(() => { if (/setAssetPrefix/.test(req.url)) { app.setAssetPrefix(`http://127.0.0.1:${port}`) } else if (/setEmptyAssetPrefix/.test(req.url)) { - app.setAssetPrefix(null) + app.setAssetPrefix('') } else { // This is to support multi-zones support in localhost // and may be in staging deployments