Skip to content

Commit

Permalink
add tests for body reading methods
Browse files Browse the repository at this point in the history
  • Loading branch information
Kikobeats committed Oct 26, 2022
1 parent bba571a commit 0ca6375
Show file tree
Hide file tree
Showing 9 changed files with 199 additions and 7 deletions.
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -55,6 +55,7 @@
"@babel/preset-flow": "7.14.5",
"@babel/preset-react": "7.14.5",
"@edge-runtime/jest-environment": "1.1.0",
"@edge-runtime/primitives": "1.1.0",
"@fullhuman/postcss-purgecss": "1.3.0",
"@mdx-js/loader": "0.18.0",
"@next/bundle-analyzer": "workspace:*",
Expand Down
4 changes: 2 additions & 2 deletions packages/next/compiled/undici/index.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/next/package.json
Expand Up @@ -276,7 +276,7 @@
"timers-browserify": "2.0.12",
"tty-browserify": "0.0.1",
"ua-parser-js": "0.7.28",
"undici": "5.10.0",
"undici": "5.11.0",
"unistore": "3.4.1",
"util": "0.12.4",
"uuid": "8.3.2",
Expand Down
30 changes: 26 additions & 4 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions test/e2e/edge-can-read-request-body/app/.gitignore
@@ -0,0 +1 @@
.vercel
49 changes: 49 additions & 0 deletions test/e2e/edge-can-read-request-body/app/middleware.js
@@ -0,0 +1,49 @@
// @ts-check

import { NextResponse } from 'next/server'

/**
* @param {NextRequest} req
*/
export default async function middleware(req) {
const res = NextResponse.next()
res.headers.set('x-incoming-content-type', req.headers.get('content-type'))

const handler =
bodyHandlers[req.nextUrl.searchParams.get('middleware-handler')]
const headers = await handler?.(req)
for (const [key, value] of headers ?? []) {
res.headers.set(key, value)
}

return res
}

/**
* @typedef {import('next/server').NextRequest} NextRequest
* @typedef {(req: NextRequest) => Promise<[string, string][]>} Handler
* @type {Record<string, Handler>}
*/
const bodyHandlers = {
json: async (req) => {
const json = await req.json()
return [
['x-req-type', 'json'],
['x-serialized', JSON.stringify(json)],
]
},
text: async (req) => {
const text = await req.text()
return [
['x-req-type', 'text'],
['x-serialized', text],
]
},
formData: async (req) => {
const formData = await req.formData()
return [
['x-req-type', 'formData'],
['x-serialized', JSON.stringify(Object.fromEntries(formData))],
]
},
}
7 changes: 7 additions & 0 deletions test/e2e/edge-can-read-request-body/app/package.json
@@ -0,0 +1,7 @@
{
"dependencies": {
"next": "canary",
"react": "latest",
"react-dom": "latest"
}
}
3 changes: 3 additions & 0 deletions test/e2e/edge-can-read-request-body/app/pages/api/nothing.js
@@ -0,0 +1,3 @@
export default (_req, res) => {
res.send('ok')
}
109 changes: 109 additions & 0 deletions test/e2e/edge-can-read-request-body/index.test.ts
@@ -0,0 +1,109 @@
import { createNext, FileRef } from 'e2e-utils'
import { NextInstance } from 'test/lib/next-modes/base'
import { renderViaHTTP } from 'next-test-utils'
import { FormData, fetch } from '@edge-runtime/primitives'
import path from 'path'

async function serialize(response: Response) {
return {
text: await response.text(),
headers: Object.fromEntries(response.headers),
status: response.status,
}
}

describe('Edge can read request body', () => {
let next: NextInstance

beforeAll(async () => {
next = await createNext({
files: new FileRef(path.resolve(__dirname, './app')),
dependencies: {},
})
})
afterAll(() => next.destroy())

it('renders the static page', async () => {
const html = await renderViaHTTP(next.url, '/api/nothing')
expect(html).toContain('ok')
})

describe('middleware', () => {
it('reads a JSON body', async () => {
const response = await fetch(
`${next.url}/api/nothing?middleware-handler=json`,
{
method: 'POST',
body: JSON.stringify({ hello: 'world' }),
}
)
expect(await serialize(response)).toMatchObject({
text: expect.stringContaining('ok'),
status: 200,
headers: {
'x-req-type': 'json',
'x-serialized': '{"hello":"world"}',
},
})
})

it('reads a text body', async () => {
const response = await fetch(
`${next.url}/api/nothing?middleware-handler=text`,
{
method: 'POST',
body: JSON.stringify({ hello: 'world' }),
}
)
expect(await serialize(response)).toMatchObject({
text: expect.stringContaining('ok'),
status: 200,
headers: {
'x-req-type': 'text',
'x-serialized': '{"hello":"world"}',
},
})
})

it('reads an URL encoded form data', async () => {
const response = await fetch(
`${next.url}/api/nothing?middleware-handler=formData`,
{
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams({ hello: 'world' }).toString(),
}
)
expect(await serialize(response)).toMatchObject({
text: expect.stringContaining('ok'),
status: 200,
headers: {
'x-req-type': 'formData',
'x-serialized': '{"hello":"world"}',
},
})
})

it('reads a multipart form data', async () => {
const formData = new FormData()
formData.set('hello', 'world')
const response = await fetch(
`${next.url}/api/nothing?middleware-handler=formData`,
{
method: 'POST',
body: formData,
}
)
expect(await serialize(response)).toMatchObject({
text: expect.stringContaining('ok'),
status: 200,
headers: {
'x-req-type': 'formData',
'x-serialized': '{"hello":"world"}',
},
})
})
})
})

0 comments on commit 0ca6375

Please sign in to comment.