From 33724484c308084078d045e7edcddc99df6efda2 Mon Sep 17 00:00:00 2001 From: Angel Mendez Date: Thu, 3 Aug 2023 16:02:54 -0600 Subject: [PATCH 1/4] refactor: move and rename file --- .../dev/dev-forms-and-redirects.test.cjs} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename tests/integration/{500.command.dev.test.cjs => commands/dev/dev-forms-and-redirects.test.cjs} (98%) diff --git a/tests/integration/500.command.dev.test.cjs b/tests/integration/commands/dev/dev-forms-and-redirects.test.cjs similarity index 98% rename from tests/integration/500.command.dev.test.cjs rename to tests/integration/commands/dev/dev-forms-and-redirects.test.cjs index 5b00ab04ab6..86091b9f5da 100644 --- a/tests/integration/500.command.dev.test.cjs +++ b/tests/integration/commands/dev/dev-forms-and-redirects.test.cjs @@ -8,9 +8,9 @@ const { isCI } = require('ci-info') const FormData = require('form-data') const getPort = require('get-port') -const { withDevServer } = require('./utils/dev-server.cjs') -const got = require('./utils/got.cjs') -const { withSiteBuilder } = require('./utils/site-builder.cjs') +const { withDevServer } = require('../../utils/dev-server.cjs') +const got = require('../../utils/got.cjs') +const { withSiteBuilder } = require('../../utils/site-builder.cjs') const test = isCI ? avaTest.serial.bind(avaTest) : avaTest From 209471fdc662140e022b6394c6e7b3d310231975 Mon Sep 17 00:00:00 2001 From: Angel Mendez Date: Thu, 3 Aug 2023 16:11:35 -0600 Subject: [PATCH 2/4] refactor: convert test file to esm - convert file to esm - adjust file accordingly --- ...t.cjs => dev-forms-and-redirects.test.mjs} | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) rename tests/integration/commands/dev/{dev-forms-and-redirects.test.cjs => dev-forms-and-redirects.test.mjs} (97%) diff --git a/tests/integration/commands/dev/dev-forms-and-redirects.test.cjs b/tests/integration/commands/dev/dev-forms-and-redirects.test.mjs similarity index 97% rename from tests/integration/commands/dev/dev-forms-and-redirects.test.cjs rename to tests/integration/commands/dev/dev-forms-and-redirects.test.mjs index 86091b9f5da..1b150269ac3 100644 --- a/tests/integration/commands/dev/dev-forms-and-redirects.test.cjs +++ b/tests/integration/commands/dev/dev-forms-and-redirects.test.mjs @@ -1,16 +1,16 @@ // Handlers are meant to be async outside tests -const { promises: fs } = require('fs') -const path = require('path') +import fs from 'fs/promises' +import path from 'path' // eslint-disable-next-line ava/use-test -const avaTest = require('ava') -const { isCI } = require('ci-info') -const FormData = require('form-data') -const getPort = require('get-port') - -const { withDevServer } = require('../../utils/dev-server.cjs') -const got = require('../../utils/got.cjs') -const { withSiteBuilder } = require('../../utils/site-builder.cjs') +import avaTest from 'ava' +import { isCI } from 'ci-info' +import FormData from 'form-data' +import getPort from 'get-port' + +import { withDevServer } from '../../utils/dev-server.cjs' +import got from '../../utils/got.cjs' +import { withSiteBuilder } from '../../utils/site-builder.cjs' const test = isCI ? avaTest.serial.bind(avaTest) : avaTest From 62c57efd9710406cc15e7ff06467c1af928fdb53 Mon Sep 17 00:00:00 2001 From: Angel Mendez Date: Thu, 3 Aug 2023 17:16:53 -0600 Subject: [PATCH 3/4] refactor: replace ava with vitest - replace ava with vitest - adjust tests accordingly - run test concurrently --- .../dev/dev-forms-and-redirects.test.mjs | 714 +++++++++--------- 1 file changed, 356 insertions(+), 358 deletions(-) diff --git a/tests/integration/commands/dev/dev-forms-and-redirects.test.mjs b/tests/integration/commands/dev/dev-forms-and-redirects.test.mjs index 1b150269ac3..a74d2cf4ff2 100644 --- a/tests/integration/commands/dev/dev-forms-and-redirects.test.mjs +++ b/tests/integration/commands/dev/dev-forms-and-redirects.test.mjs @@ -2,382 +2,379 @@ import fs from 'fs/promises' import path from 'path' -// eslint-disable-next-line ava/use-test -import avaTest from 'ava' -import { isCI } from 'ci-info' import FormData from 'form-data' import getPort from 'get-port' +import { describe, test } from 'vitest' import { withDevServer } from '../../utils/dev-server.cjs' import got from '../../utils/got.cjs' import { withSiteBuilder } from '../../utils/site-builder.cjs' -const test = isCI ? avaTest.serial.bind(avaTest) : avaTest - -test('should return 404 when redirecting to a non existing function', async (t) => { - await withSiteBuilder('site-with-missing-function', async (builder) => { - builder.withNetlifyToml({ - config: { - functions: { directory: 'functions' }, - redirects: [{ from: '/api/*', to: '/.netlify/functions/:splat', status: 200 }], - }, - }) - - await builder.buildAsync() - - await withDevServer({ cwd: builder.directory }, async (server) => { - const response = await got - .post(`${server.url}/api/none`, { - body: 'nothing', - }) - .catch((error) => error.response) - - t.is(response.statusCode, 404) - }) - }) -}) - -test('should parse function query parameters using simple parsing', async (t) => { - await withSiteBuilder('site-with-multi-part-function', async (builder) => { - builder - .withNetlifyToml({ +describe.concurrent('commands/dev-forms-and-redirects', () => { + test('should return 404 when redirecting to a non existing function', async (t) => { + await withSiteBuilder('site-with-missing-function', async (builder) => { + builder.withNetlifyToml({ config: { functions: { directory: 'functions' }, + redirects: [{ from: '/api/*', to: '/.netlify/functions/:splat', status: 200 }], }, }) - .withFunction({ - path: 'echo.js', - handler: async (event) => ({ - statusCode: 200, - body: JSON.stringify(event), - }), - }) - await builder.buildAsync() + await builder.buildAsync() - await withDevServer({ cwd: builder.directory }, async (server) => { - const response1 = await got(`${server.url}/.netlify/functions/echo?category[SOMETHING][]=something`).json() - const response2 = await got(`${server.url}/.netlify/functions/echo?category=one&category=two`).json() + await withDevServer({ cwd: builder.directory }, async (server) => { + const response = await got + .post(`${server.url}/api/none`, { + body: 'nothing', + }) + .catch((error) => error.response) - t.deepEqual(response1.queryStringParameters, { 'category[SOMETHING][]': 'something' }) - t.deepEqual(response2.queryStringParameters, { category: 'one, two' }) + t.expect(response.statusCode).toBe(404) + }) }) }) -}) -test('should handle form submission', async (t) => { - await withSiteBuilder('site-with-form', async (builder) => { - builder - .withContentFile({ - path: 'index.html', - content: '

⊂◉‿◉つ

', - }) - .withNetlifyToml({ - config: { - functions: { directory: 'functions' }, - }, - }) - .withFunction({ - path: 'submission-created.js', - handler: async (event) => ({ - statusCode: 200, - body: JSON.stringify(event), - }), - }) + test('should parse function query parameters using simple parsing', async (t) => { + await withSiteBuilder('site-with-multi-part-function', async (builder) => { + builder + .withNetlifyToml({ + config: { + functions: { directory: 'functions' }, + }, + }) + .withFunction({ + path: 'echo.js', + handler: async (event) => ({ + statusCode: 200, + body: JSON.stringify(event), + }), + }) - await builder.buildAsync() + await builder.buildAsync() - await withDevServer({ cwd: builder.directory }, async (server) => { - const form = new FormData() - form.append('some', 'thing') - const response = await got - .post(`${server.url}/?ding=dong`, { - body: form, - }) - .json() + await withDevServer({ cwd: builder.directory }, async (server) => { + const response1 = await got(`${server.url}/.netlify/functions/echo?category[SOMETHING][]=something`).json() + const response2 = await got(`${server.url}/.netlify/functions/echo?category=one&category=two`).json() - const body = JSON.parse(response.body) - const expectedBody = { - payload: { - created_at: body.payload.created_at, - data: { - ip: '::ffff:127.0.0.1', - some: 'thing', - user_agent: 'got (https://github.com/sindresorhus/got)', - }, - human_fields: { - Some: 'thing', - }, - ordered_human_fields: [ - { - name: 'some', - title: 'Some', - value: 'thing', - }, - ], - site_url: '', - }, - } - - t.is(response.headers.host, `${server.host}:${server.port}`) - t.is(response.headers['content-length'], JSON.stringify(expectedBody).length.toString()) - t.is(response.headers['content-type'], 'application/json') - t.is(response.httpMethod, 'POST') - t.is(response.isBase64Encoded, false) - t.is(response.path, '/') - t.deepEqual(response.queryStringParameters, { ding: 'dong' }) - t.deepEqual(body, expectedBody) + t.expect(response1.queryStringParameters).toStrictEqual({ 'category[SOMETHING][]': 'something' }) + t.expect(response2.queryStringParameters).toStrictEqual({ category: 'one, two' }) + }) }) }) -}) -test('should handle form submission with a background function', async (t) => { - await withSiteBuilder('site-with-form-background-function', async (builder) => { - await builder - .withContentFile({ - path: 'index.html', - content: '

⊂◉‿◉つ

', - }) - .withNetlifyToml({ - config: { - functions: { directory: 'functions' }, - }, - }) - .withFunction({ - path: 'submission-created-background.js', - handler: async (event) => ({ - statusCode: 200, - body: JSON.stringify(event), - }), - }) - .buildAsync() + test('should handle form submission', async (t) => { + await withSiteBuilder('site-with-form', async (builder) => { + builder + .withContentFile({ + path: 'index.html', + content: '

⊂◉‿◉つ

', + }) + .withNetlifyToml({ + config: { + functions: { directory: 'functions' }, + }, + }) + .withFunction({ + path: 'submission-created.js', + handler: async (event) => ({ + statusCode: 200, + body: JSON.stringify(event), + }), + }) + + await builder.buildAsync() + + await withDevServer({ cwd: builder.directory }, async (server) => { + const form = new FormData() + form.append('some', 'thing') + const response = await got + .post(`${server.url}/?ding=dong`, { + body: form, + }) + .json() + + const body = JSON.parse(response.body) + const expectedBody = { + payload: { + created_at: body.payload.created_at, + data: { + ip: '::ffff:127.0.0.1', + some: 'thing', + user_agent: 'got (https://github.com/sindresorhus/got)', + }, + human_fields: { + Some: 'thing', + }, + ordered_human_fields: [ + { + name: 'some', + title: 'Some', + value: 'thing', + }, + ], + site_url: '', + }, + } - await withDevServer({ cwd: builder.directory }, async (server) => { - const form = new FormData() - form.append('some', 'thing') - const response = await got.post(`${server.url}/?ding=dong`, { - body: form, + t.expect(response.headers.host).toEqual(`${server.host}:${server.port}`) + t.expect(response.headers['content-length']).toEqual(JSON.stringify(expectedBody).length.toString()) + t.expect(response.headers['content-type']).toEqual('application/json') + t.expect(response.httpMethod).toEqual('POST') + t.expect(response.isBase64Encoded).toBe(false) + t.expect(response.path).toEqual('/') + t.expect(response.queryStringParameters).toStrictEqual({ ding: 'dong' }) + t.expect(body).toStrictEqual(expectedBody) }) - t.is(response.statusCode, 202) - t.is(response.body, '') }) }) -}) -test('should not handle form submission when content type is `text/plain`', async (t) => { - await withSiteBuilder('site-with-form-text-plain', async (builder) => { - builder - .withContentFile({ - path: 'index.html', - content: '

⊂◉‿◉つ

', - }) - .withNetlifyToml({ - config: { - functions: { directory: 'functions' }, - }, - }) - .withFunction({ - path: 'submission-created.js', - handler: async (event) => ({ - statusCode: 200, - body: JSON.stringify(event), - }), - }) + test('should handle form submission with a background function', async (t) => { + await withSiteBuilder('site-with-form-background-function', async (builder) => { + await builder + .withContentFile({ + path: 'index.html', + content: '

⊂◉‿◉つ

', + }) + .withNetlifyToml({ + config: { + functions: { directory: 'functions' }, + }, + }) + .withFunction({ + path: 'submission-created-background.js', + handler: async (event) => ({ + statusCode: 200, + body: JSON.stringify(event), + }), + }) + .buildAsync() - await builder.buildAsync() + await withDevServer({ cwd: builder.directory }, async (server) => { + const form = new FormData() + form.append('some', 'thing') + const response = await got.post(`${server.url}/?ding=dong`, { + body: form, + }) + t.expect(response.statusCode).toBe(202) + t.expect(response.body).toEqual('') + }) + }) + }) - await withDevServer({ cwd: builder.directory }, async (server) => { - const response = await got - .post(`${server.url}/?ding=dong`, { - body: 'Something', - headers: { - 'content-type': 'text/plain', + test('should not handle form submission when content type is `text/plain`', async (t) => { + await withSiteBuilder('site-with-form-text-plain', async (builder) => { + builder + .withContentFile({ + path: 'index.html', + content: '

⊂◉‿◉つ

', + }) + .withNetlifyToml({ + config: { + functions: { directory: 'functions' }, }, }) - .catch((error) => error.response) - t.is(response.statusCode, 405) - t.is(response.body, 'Method Not Allowed') + .withFunction({ + path: 'submission-created.js', + handler: async (event) => ({ + statusCode: 200, + body: JSON.stringify(event), + }), + }) + + await builder.buildAsync() + + await withDevServer({ cwd: builder.directory }, async (server) => { + const response = await got + .post(`${server.url}/?ding=dong`, { + body: 'Something', + headers: { + 'content-type': 'text/plain', + }, + }) + .catch((error) => error.response) + t.expect(response.statusCode).toBe(405) + t.expect(response.body).toEqual('Method Not Allowed') + }) }) }) -}) -test('should return existing local file even when rewrite matches when force=false', async (t) => { - await withSiteBuilder('site-with-shadowing-force-false', async (builder) => { - builder - .withContentFile({ - path: 'foo.html', - content: '

foo', - }) - .withContentFile({ - path: path.join('not-foo', 'index.html'), - content: '

not-foo', - }) - .withNetlifyToml({ - config: { - redirects: [{ from: '/foo', to: '/not-foo', status: 200, force: false }], - }, - }) + test('should return existing local file even when rewrite matches when force=false', async (t) => { + await withSiteBuilder('site-with-shadowing-force-false', async (builder) => { + builder + .withContentFile({ + path: 'foo.html', + content: '

foo', + }) + .withContentFile({ + path: path.join('not-foo', 'index.html'), + content: '

not-foo', + }) + .withNetlifyToml({ + config: { + redirects: [{ from: '/foo', to: '/not-foo', status: 200, force: false }], + }, + }) - await builder.buildAsync() + await builder.buildAsync() - await withDevServer({ cwd: builder.directory }, async (server) => { - const response = await got(`${server.url}/foo?ping=pong`).text() - t.is(response, '

foo') + await withDevServer({ cwd: builder.directory }, async (server) => { + const response = await got(`${server.url}/foo?ping=pong`).text() + t.expect(response).toEqual('

foo') + }) }) }) -}) -test('should return existing local file even when redirect matches when force=false', async (t) => { - await withSiteBuilder('site-with-shadowing-force-false', async (builder) => { - builder - .withContentFile({ - path: 'foo.html', - content: '

foo', - }) - .withContentFile({ - path: path.join('not-foo', 'index.html'), - content: '

not-foo', - }) - .withNetlifyToml({ - config: { - redirects: [{ from: '/foo', to: '/not-foo', status: 301, force: false }], - }, - }) + test('should return existing local file even when redirect matches when force=false', async (t) => { + await withSiteBuilder('site-with-shadowing-force-false', async (builder) => { + builder + .withContentFile({ + path: 'foo.html', + content: '

foo', + }) + .withContentFile({ + path: path.join('not-foo', 'index.html'), + content: '

not-foo', + }) + .withNetlifyToml({ + config: { + redirects: [{ from: '/foo', to: '/not-foo', status: 301, force: false }], + }, + }) - await builder.buildAsync() + await builder.buildAsync() - await withDevServer({ cwd: builder.directory }, async (server) => { - const response = await got(`${server.url}/foo?ping=pong`).text() - t.is(response, '

foo') + await withDevServer({ cwd: builder.directory }, async (server) => { + const response = await got(`${server.url}/foo?ping=pong`).text() + t.expect(response).toEqual('

foo') + }) }) }) -}) -test('should ignore existing local file when redirect matches and force=true', async (t) => { - await withSiteBuilder('site-with-shadowing-force-true', async (builder) => { - builder - .withContentFile({ - path: 'foo.html', - content: '

foo', - }) - .withContentFile({ - path: path.join('not-foo', 'index.html'), - content: '

not-foo', - }) - .withNetlifyToml({ - config: { - redirects: [{ from: '/foo', to: '/not-foo', status: 301, force: true }], - }, - }) + test('should ignore existing local file when redirect matches and force=true', async (t) => { + await withSiteBuilder('site-with-shadowing-force-true', async (builder) => { + builder + .withContentFile({ + path: 'foo.html', + content: '

foo', + }) + .withContentFile({ + path: path.join('not-foo', 'index.html'), + content: '

not-foo', + }) + .withNetlifyToml({ + config: { + redirects: [{ from: '/foo', to: '/not-foo', status: 301, force: true }], + }, + }) - await builder.buildAsync() + await builder.buildAsync() - await withDevServer({ cwd: builder.directory }, async (server) => { - const response = await got(`${server.url}/foo`, { followRedirect: false }) - t.is(response.headers.location, `/not-foo`) + await withDevServer({ cwd: builder.directory }, async (server) => { + const response = await got(`${server.url}/foo`, { followRedirect: false }) + t.expect(response.headers.location).toEqual(`/not-foo`) - const body = await got(`${server.url}/foo`).text() - t.is(body, '

not-foo') + const body = await got(`${server.url}/foo`).text() + t.expect(body).toEqual('

not-foo') + }) }) }) -}) -test('should use existing file when rule contains file extension and force=false', async (t) => { - await withSiteBuilder('site-with-shadowing-file-extension-force-false', async (builder) => { - builder - .withContentFile({ - path: 'foo.html', - content: '

foo', - }) - .withContentFile({ - path: path.join('not-foo', 'index.html'), - content: '

not-foo', - }) - .withNetlifyToml({ - config: { - redirects: [{ from: '/foo.html', to: '/not-foo', status: 301, force: false }], - }, - }) + test('should use existing file when rule contains file extension and force=false', async (t) => { + await withSiteBuilder('site-with-shadowing-file-extension-force-false', async (builder) => { + builder + .withContentFile({ + path: 'foo.html', + content: '

foo', + }) + .withContentFile({ + path: path.join('not-foo', 'index.html'), + content: '

not-foo', + }) + .withNetlifyToml({ + config: { + redirects: [{ from: '/foo.html', to: '/not-foo', status: 301, force: false }], + }, + }) - await builder.buildAsync() + await builder.buildAsync() - await withDevServer({ cwd: builder.directory }, async (server) => { - const response = await got(`${server.url}/foo.html`, { followRedirect: false }) - t.is(response.headers.location, undefined) - t.is(response.body, '

foo') + await withDevServer({ cwd: builder.directory }, async (server) => { + const response = await got(`${server.url}/foo.html`, { followRedirect: false }) + t.expect(response.headers.location).toBe(undefined) + t.expect(response.body).toEqual('

foo') + }) }) }) -}) -test('should redirect when rule contains file extension and force=true', async (t) => { - await withSiteBuilder('site-with-shadowing-file-extension-force-true', async (builder) => { - builder - .withContentFile({ - path: 'foo.html', - content: '

foo', - }) - .withContentFile({ - path: path.join('not-foo', 'index.html'), - content: '

not-foo', - }) - .withNetlifyToml({ - config: { - redirects: [{ from: '/foo.html', to: '/not-foo', status: 301, force: true }], - }, - }) + test('should redirect when rule contains file extension and force=true', async (t) => { + await withSiteBuilder('site-with-shadowing-file-extension-force-true', async (builder) => { + builder + .withContentFile({ + path: 'foo.html', + content: '

foo', + }) + .withContentFile({ + path: path.join('not-foo', 'index.html'), + content: '

not-foo', + }) + .withNetlifyToml({ + config: { + redirects: [{ from: '/foo.html', to: '/not-foo', status: 301, force: true }], + }, + }) - await builder.buildAsync() + await builder.buildAsync() - await withDevServer({ cwd: builder.directory }, async (server) => { - const response = await got(`${server.url}/foo.html`, { followRedirect: false }) - t.is(response.headers.location, `/not-foo`) + await withDevServer({ cwd: builder.directory }, async (server) => { + const response = await got(`${server.url}/foo.html`, { followRedirect: false }) + t.expect(response.headers.location).toEqual(`/not-foo`) - const body = await got(`${server.url}/foo.html`).text() - t.is(body, '

not-foo') + const body = await got(`${server.url}/foo.html`).text() + t.expect(body).toEqual('

not-foo') + }) }) }) -}) -test('should redirect from sub directory to root directory', async (t) => { - await withSiteBuilder('site-with-shadowing-sub-to-root', async (builder) => { - builder - .withContentFile({ - path: 'foo.html', - content: '

foo', - }) - .withContentFile({ - path: path.join('not-foo', 'index.html'), - content: '

not-foo', - }) - .withNetlifyToml({ - config: { - redirects: [{ from: '/not-foo', to: '/foo', status: 200, force: true }], - }, - }) + test('should redirect from sub directory to root directory', async (t) => { + await withSiteBuilder('site-with-shadowing-sub-to-root', async (builder) => { + builder + .withContentFile({ + path: 'foo.html', + content: '

foo', + }) + .withContentFile({ + path: path.join('not-foo', 'index.html'), + content: '

not-foo', + }) + .withNetlifyToml({ + config: { + redirects: [{ from: '/not-foo', to: '/foo', status: 200, force: true }], + }, + }) - await builder.buildAsync() + await builder.buildAsync() - await withDevServer({ cwd: builder.directory }, async (server) => { - const response1 = await got(`${server.url}/not-foo`).text() - const response2 = await got(`${server.url}/not-foo/`).text() + await withDevServer({ cwd: builder.directory }, async (server) => { + const response1 = await got(`${server.url}/not-foo`).text() + const response2 = await got(`${server.url}/not-foo/`).text() - // TODO: check why this doesn't redirect - const response3 = await got(`${server.url}/not-foo/index.html`).text() + // TODO: check why this doesn't redirect + const response3 = await got(`${server.url}/not-foo/index.html`).text() - t.is(response1, '

foo') - t.is(response2, '

foo') - t.is(response3, '

not-foo') + t.expect(response1).toEqual('

foo') + t.expect(response2).toEqual('

foo') + t.expect(response3).toEqual('

not-foo') + }) }) }) -}) -test('Runs build plugins with the `onPreDev` event', async (t) => { - const userServerPort = await getPort() - const pluginManifest = 'name: local-plugin' + test('Runs build plugins with the `onPreDev` event', async (t) => { + const userServerPort = await getPort() + const pluginManifest = 'name: local-plugin' - // This test plugin starts an HTTP server that we'll hit when the dev server - // is ready, asserting that plugins in dev mode can have long-running jobs. - const pluginSource = ` + // This test plugin starts an HTTP server that we'll hit when the dev server + // is ready, asserting that plugins in dev mode can have long-running jobs. + const pluginSource = ` const http = require("http"); module.exports = { @@ -395,40 +392,40 @@ test('Runs build plugins with the `onPreDev` event', async (t) => { }; ` - const { temporaryDirectory } = await import('tempy') - const pluginDirectory = await temporaryDirectory() + const { temporaryDirectory } = await import('tempy') + const pluginDirectory = await temporaryDirectory() - await fs.writeFile(path.join(pluginDirectory, 'manifest.yml'), pluginManifest) - await fs.writeFile(path.join(pluginDirectory, 'index.js'), pluginSource) + await fs.writeFile(path.join(pluginDirectory, 'manifest.yml'), pluginManifest) + await fs.writeFile(path.join(pluginDirectory, 'index.js'), pluginSource) - await withSiteBuilder('site-with-custom-server-in-plugin', async (builder) => { - builder - .withNetlifyToml({ - config: { - plugins: [{ package: path.relative(builder.directory, pluginDirectory) }], - }, - }) - .withContentFile({ - path: 'foo.html', - content: '

foo', - }) + await withSiteBuilder('site-with-custom-server-in-plugin', async (builder) => { + builder + .withNetlifyToml({ + config: { + plugins: [{ package: path.relative(builder.directory, pluginDirectory) }], + }, + }) + .withContentFile({ + path: 'foo.html', + content: '

foo', + }) - await builder.buildAsync() + await builder.buildAsync() - await withDevServer({ cwd: builder.directory }, async (server) => { - t.is(await got(`${server.url}/foo`).text(), '

foo') - t.is(await got(`http://localhost:${userServerPort}`).text(), 'Hello world') + await withDevServer({ cwd: builder.directory }, async (server) => { + t.expect(await got(`${server.url}/foo`).text()).toEqual('

foo') + t.expect(await got(`http://localhost:${userServerPort}`).text()).toEqual('Hello world') + }) }) }) -}) -test('Handles errors from the `onPreDev` event', async (t) => { - const userServerPort = await getPort() - const pluginManifest = 'name: local-plugin' + test('Handles errors from the `onPreDev` event', async (t) => { + const userServerPort = await getPort() + const pluginManifest = 'name: local-plugin' - // This test plugin starts an HTTP server that we'll hit when the dev server - // is ready, asserting that plugins in dev mode can have long-running jobs. - const pluginSource = ` + // This test plugin starts an HTTP server that we'll hit when the dev server + // is ready, asserting that plugins in dev mode can have long-running jobs. + const pluginSource = ` const http = require("http"); module.exports = { @@ -442,35 +439,36 @@ test('Handles errors from the `onPreDev` event', async (t) => { }; ` - const { temporaryDirectory } = await import('tempy') - const pluginDirectory = await temporaryDirectory() + const { temporaryDirectory } = await import('tempy') + const pluginDirectory = await temporaryDirectory() - await fs.writeFile(path.join(pluginDirectory, 'manifest.yml'), pluginManifest) - await fs.writeFile(path.join(pluginDirectory, 'index.js'), pluginSource) + await fs.writeFile(path.join(pluginDirectory, 'manifest.yml'), pluginManifest) + await fs.writeFile(path.join(pluginDirectory, 'index.js'), pluginSource) - await withSiteBuilder('site-with-custom-server-in-plugin', async (builder) => { - builder - .withNetlifyToml({ - config: { - plugins: [{ package: path.relative(builder.directory, pluginDirectory) }], - }, - }) - .withContentFile({ - path: 'foo.html', - content: '

foo', - }) + await withSiteBuilder('site-with-custom-server-in-plugin', async (builder) => { + builder + .withNetlifyToml({ + config: { + plugins: [{ package: path.relative(builder.directory, pluginDirectory) }], + }, + }) + .withContentFile({ + path: 'foo.html', + content: '

foo', + }) - await builder.buildAsync() + await builder.buildAsync() - await t.throwsAsync(() => - withDevServer( - { cwd: builder.directory }, - async (server) => { - t.is(await got(`${server.url}/foo`).text(), '

foo') - t.is(await got(`http://localhost:${userServerPort}`).text(), 'Hello world') - }, - { message: /Error: Something went wrong/ }, - ), - ) + t.expect(() => + withDevServer( + { cwd: builder.directory }, + async (server) => { + await t.expect(await got(`${server.url}/foo`).text()).toEqual('

foo') + await t.expect(await got(`http://localhost:${userServerPort}`).text()).toEqual('Hello world') + }, + { message: /Error: Something went wrong/ }, + ), + ).rejects.toThrowError() + }) }) }) From 29f0458a373fcd934346e314b10b9dda9bf6a7b4 Mon Sep 17 00:00:00 2001 From: Angel Mendez Date: Fri, 4 Aug 2023 12:15:25 -0600 Subject: [PATCH 4/4] refactor: replace got with node-fetch --- .../dev/dev-forms-and-redirects.test.mjs | 107 ++++++++++-------- 1 file changed, 60 insertions(+), 47 deletions(-) diff --git a/tests/integration/commands/dev/dev-forms-and-redirects.test.mjs b/tests/integration/commands/dev/dev-forms-and-redirects.test.mjs index a74d2cf4ff2..31b681ed576 100644 --- a/tests/integration/commands/dev/dev-forms-and-redirects.test.mjs +++ b/tests/integration/commands/dev/dev-forms-and-redirects.test.mjs @@ -4,10 +4,10 @@ import path from 'path' import FormData from 'form-data' import getPort from 'get-port' +import fetch from 'node-fetch' import { describe, test } from 'vitest' import { withDevServer } from '../../utils/dev-server.cjs' -import got from '../../utils/got.cjs' import { withSiteBuilder } from '../../utils/site-builder.cjs' describe.concurrent('commands/dev-forms-and-redirects', () => { @@ -23,13 +23,12 @@ describe.concurrent('commands/dev-forms-and-redirects', () => { await builder.buildAsync() await withDevServer({ cwd: builder.directory }, async (server) => { - const response = await got - .post(`${server.url}/api/none`, { - body: 'nothing', - }) - .catch((error) => error.response) + const response = await fetch(`${server.url}/api/none`, { + method: 'POST', + body: 'nothing', + }) - t.expect(response.statusCode).toBe(404) + t.expect(response.status).toBe(404) }) }) }) @@ -53,8 +52,10 @@ describe.concurrent('commands/dev-forms-and-redirects', () => { await builder.buildAsync() await withDevServer({ cwd: builder.directory }, async (server) => { - const response1 = await got(`${server.url}/.netlify/functions/echo?category[SOMETHING][]=something`).json() - const response2 = await got(`${server.url}/.netlify/functions/echo?category=one&category=two`).json() + const [response1, response2] = await Promise.all([ + fetch(`${server.url}/.netlify/functions/echo?category[SOMETHING][]=something`).then((res) => res.json()), + fetch(`${server.url}/.netlify/functions/echo?category=one&category=two`).then((res) => res.json()), + ]) t.expect(response1.queryStringParameters).toStrictEqual({ 'category[SOMETHING][]': 'something' }) t.expect(response2.queryStringParameters).toStrictEqual({ category: 'one, two' }) @@ -87,11 +88,10 @@ describe.concurrent('commands/dev-forms-and-redirects', () => { await withDevServer({ cwd: builder.directory }, async (server) => { const form = new FormData() form.append('some', 'thing') - const response = await got - .post(`${server.url}/?ding=dong`, { - body: form, - }) - .json() + const response = await fetch(`${server.url}/?ding=dong`, { + method: 'POST', + body: form, + }).then((res) => res.json()) const body = JSON.parse(response.body) const expectedBody = { @@ -100,7 +100,7 @@ describe.concurrent('commands/dev-forms-and-redirects', () => { data: { ip: '::ffff:127.0.0.1', some: 'thing', - user_agent: 'got (https://github.com/sindresorhus/got)', + user_agent: 'node-fetch/1.0 (+https://github.com/bitinn/node-fetch)', }, human_fields: { Some: 'thing', @@ -152,11 +152,12 @@ describe.concurrent('commands/dev-forms-and-redirects', () => { await withDevServer({ cwd: builder.directory }, async (server) => { const form = new FormData() form.append('some', 'thing') - const response = await got.post(`${server.url}/?ding=dong`, { + const response = await fetch(`${server.url}/?ding=dong`, { + method: 'POST', body: form, }) - t.expect(response.statusCode).toBe(202) - t.expect(response.body).toEqual('') + t.expect(response.status).toBe(202) + t.expect(await response.text()).toEqual('') }) }) }) @@ -184,16 +185,15 @@ describe.concurrent('commands/dev-forms-and-redirects', () => { await builder.buildAsync() await withDevServer({ cwd: builder.directory }, async (server) => { - const response = await got - .post(`${server.url}/?ding=dong`, { - body: 'Something', - headers: { - 'content-type': 'text/plain', - }, - }) - .catch((error) => error.response) - t.expect(response.statusCode).toBe(405) - t.expect(response.body).toEqual('Method Not Allowed') + const response = await fetch(`${server.url}/?ding=dong`, { + method: 'POST', + body: 'Something', + headers: { + 'content-type': 'text/plain', + }, + }) + t.expect(response.status).toBe(405) + t.expect(await response.text()).toEqual('Method Not Allowed') }) }) }) @@ -218,7 +218,7 @@ describe.concurrent('commands/dev-forms-and-redirects', () => { await builder.buildAsync() await withDevServer({ cwd: builder.directory }, async (server) => { - const response = await got(`${server.url}/foo?ping=pong`).text() + const response = await fetch(`${server.url}/foo?ping=pong`).then((res) => res.text()) t.expect(response).toEqual('

foo') }) }) @@ -244,7 +244,7 @@ describe.concurrent('commands/dev-forms-and-redirects', () => { await builder.buildAsync() await withDevServer({ cwd: builder.directory }, async (server) => { - const response = await got(`${server.url}/foo?ping=pong`).text() + const response = await fetch(`${server.url}/foo?ping=pong`).then((res) => res.text()) t.expect(response).toEqual('

foo') }) }) @@ -270,10 +270,12 @@ describe.concurrent('commands/dev-forms-and-redirects', () => { await builder.buildAsync() await withDevServer({ cwd: builder.directory }, async (server) => { - const response = await got(`${server.url}/foo`, { followRedirect: false }) - t.expect(response.headers.location).toEqual(`/not-foo`) + const [response, body] = await Promise.all([ + fetch(`${server.url}/foo`, { redirect: 'manual' }), + fetch(`${server.url}/foo`).then((res) => res.text()), + ]) - const body = await got(`${server.url}/foo`).text() + t.expect(response.headers.get('location')).toEqual(`${server.url}/not-foo`) t.expect(body).toEqual('

not-foo') }) }) @@ -299,9 +301,9 @@ describe.concurrent('commands/dev-forms-and-redirects', () => { await builder.buildAsync() await withDevServer({ cwd: builder.directory }, async (server) => { - const response = await got(`${server.url}/foo.html`, { followRedirect: false }) + const response = await fetch(`${server.url}/foo.html`, { follow: 0 }) t.expect(response.headers.location).toBe(undefined) - t.expect(response.body).toEqual('

foo') + t.expect(await response.text()).toEqual('

foo') }) }) }) @@ -326,10 +328,12 @@ describe.concurrent('commands/dev-forms-and-redirects', () => { await builder.buildAsync() await withDevServer({ cwd: builder.directory }, async (server) => { - const response = await got(`${server.url}/foo.html`, { followRedirect: false }) - t.expect(response.headers.location).toEqual(`/not-foo`) + const [response, body] = await Promise.all([ + fetch(`${server.url}/foo.html`, { redirect: 'manual' }), + fetch(`${server.url}/foo.html`).then((res) => res.text()), + ]) - const body = await got(`${server.url}/foo.html`).text() + t.expect(response.headers.get('location')).toEqual(`${server.url}/not-foo`) t.expect(body).toEqual('

not-foo') }) }) @@ -355,11 +359,12 @@ describe.concurrent('commands/dev-forms-and-redirects', () => { await builder.buildAsync() await withDevServer({ cwd: builder.directory }, async (server) => { - const response1 = await got(`${server.url}/not-foo`).text() - const response2 = await got(`${server.url}/not-foo/`).text() - - // TODO: check why this doesn't redirect - const response3 = await got(`${server.url}/not-foo/index.html`).text() + const [response1, response2, response3] = await Promise.all([ + fetch(`${server.url}/not-foo`).then((res) => res.text()), + fetch(`${server.url}/not-foo/`).then((res) => res.text()), + // TODO: check why this doesn't redirect + fetch(`${server.url}/not-foo/index.html`).then((res) => res.text()), + ]) t.expect(response1).toEqual('

foo') t.expect(response2).toEqual('

foo') @@ -413,8 +418,12 @@ describe.concurrent('commands/dev-forms-and-redirects', () => { await builder.buildAsync() await withDevServer({ cwd: builder.directory }, async (server) => { - t.expect(await got(`${server.url}/foo`).text()).toEqual('

foo') - t.expect(await got(`http://localhost:${userServerPort}`).text()).toEqual('Hello world') + const [response1, response2] = await Promise.all([ + fetch(`${server.url}/foo`).then((res) => res.text()), + fetch(`http://localhost:${userServerPort}`).then((res) => res.text()), + ]) + t.expect(response1).toEqual('

foo') + t.expect(response2).toEqual('Hello world') }) }) }) @@ -463,8 +472,12 @@ describe.concurrent('commands/dev-forms-and-redirects', () => { withDevServer( { cwd: builder.directory }, async (server) => { - await t.expect(await got(`${server.url}/foo`).text()).toEqual('

foo') - await t.expect(await got(`http://localhost:${userServerPort}`).text()).toEqual('Hello world') + const [response1, response2] = await Promise.all([ + fetch(`${server.url}/foo`).then((res) => res.text()), + fetch(`http://localhost:${userServerPort}`).then((res) => res.text()), + ]) + await t.expect(response1).toEqual('

foo') + await t.expect(response2).toEqual('Hello world') }, { message: /Error: Something went wrong/ }, ),