diff options
author | 2022-07-22 15:22:31 -0400 | |
---|---|---|
committer | 2022-07-22 15:22:31 -0400 | |
commit | 4ca6a0933d92dd559327dd46a28712d918caebf7 (patch) | |
tree | 27ca6be8c801b815961bb54264cf9dec1eb38a93 /packages/integrations/node/test | |
parent | 9aecf7c7c7211f34236d8dde624ca388310d3727 (diff) | |
download | astro-4ca6a0933d92dd559327dd46a28712d918caebf7.tar.gz astro-4ca6a0933d92dd559327dd46a28712d918caebf7.tar.zst astro-4ca6a0933d92dd559327dd46a28712d918caebf7.zip |
Fixes Node adapter receiving a request body (#4023)
* Fixes Node adapter receiving a request body
* Updated lockfile
Diffstat (limited to 'packages/integrations/node/test')
4 files changed, 111 insertions, 0 deletions
diff --git a/packages/integrations/node/test/api-route.test.js b/packages/integrations/node/test/api-route.test.js new file mode 100644 index 000000000..963e0463a --- /dev/null +++ b/packages/integrations/node/test/api-route.test.js @@ -0,0 +1,37 @@ +import nodejs from '../dist/index.js'; +import { loadFixture, createRequestAndResponse, toPromise } from './test-utils.js'; +import { expect } from 'chai'; + + +describe('API routes', () => { + /** @type {import('./test-utils').Fixture} */ + let fixture; + + before(async () => { + fixture = await loadFixture({ + root: './fixtures/api-route/', + experimental: { + ssr: true, + }, + adapter: nodejs(), + }); + await fixture.build(); + }); + + it('Can get the request body', async () => { + const { handler } = await import('./fixtures/api-route/dist/server/entry.mjs'); + + let { req, res, done } = createRequestAndResponse({ + method: 'POST', + url: '/recipes' + }); + + handler(req, res); + req.send(JSON.stringify({ id: 2 })); + + let [ buffer ] = await done; + let json = JSON.parse(buffer.toString('utf-8')); + expect(json.length).to.equal(1); + expect(json[0].name).to.equal('Broccoli Soup'); + }); +}); diff --git a/packages/integrations/node/test/fixtures/api-route/package.json b/packages/integrations/node/test/fixtures/api-route/package.json new file mode 100644 index 000000000..c4d9bdd2b --- /dev/null +++ b/packages/integrations/node/test/fixtures/api-route/package.json @@ -0,0 +1,9 @@ +{ + "name": "@test/nodejs-api-route", + "version": "0.0.0", + "private": true, + "dependencies": { + "astro": "workspace:*", + "@astrojs/node": "workspace:*" + } +} diff --git a/packages/integrations/node/test/fixtures/api-route/src/pages/recipes.js b/packages/integrations/node/test/fixtures/api-route/src/pages/recipes.js new file mode 100644 index 000000000..edbd15a0e --- /dev/null +++ b/packages/integrations/node/test/fixtures/api-route/src/pages/recipes.js @@ -0,0 +1,24 @@ + +export async function post({ request }) { + let body = await request.json(); + const recipes = [ + { + id: 1, + name: 'Potato Soup' + }, + { + id: 2, + name: 'Broccoli Soup' + } + ]; + + let out = recipes.filter(r => { + return r.id === body.id; + }); + + return new Response(JSON.stringify(out), { + headers: { + 'Content-Type': 'application/json' + } + }); +} diff --git a/packages/integrations/node/test/test-utils.js b/packages/integrations/node/test/test-utils.js new file mode 100644 index 000000000..4bd42d557 --- /dev/null +++ b/packages/integrations/node/test/test-utils.js @@ -0,0 +1,41 @@ +import { loadFixture as baseLoadFixture } from '../../../astro/test/test-utils.js'; +import httpMocks from 'node-mocks-http'; +import { EventEmitter } from 'events'; + +/** + * @typedef {import('../../../astro/test/test-utils').Fixture} Fixture + */ + +export function loadFixture(inlineConfig) { + if (!inlineConfig || !inlineConfig.root) + throw new Error("Must provide { root: './fixtures/...' }"); + + // resolve the relative root (i.e. "./fixtures/tailwindcss") to a full filepath + // without this, the main `loadFixture` helper will resolve relative to `packages/astro/test` + return baseLoadFixture({ + ...inlineConfig, + root: new URL(inlineConfig.root, import.meta.url).toString(), + }); +} + +export function createRequestAndResponse(reqOptions) { + let req = httpMocks.createRequest(reqOptions); + + let res = httpMocks.createResponse({ + eventEmitter: EventEmitter, + req + }); + + let done = toPromise(res); + + return { req, res, done }; +} + +export function toPromise(res) { + return new Promise(resolve => { + res.on('end', () => { + let chunks = res._getChunks(); + resolve(chunks); + }); + }); +} |