[Testing] Export utilities to help test middleware and next.config.js routing (#70731)
This PR adds some testing utilities for testing `middleware` and
`next.config.js`. The goal is to make it easy for anyone to add tests
that assert the behavior of routing, such as how
`next.config.js#redirects`, `next.config.js#rewrites`, and `middleware`
interact, or what paths are matched by middleware. This is useful to
catch routing issues before the code ever reaches production.
This code is exported in a new `next/server/testing` export to keep it
separate from the rest of the `next/server` code.
This testing code is marked as `unstable_` since it is not reusing all
of the same code that the actual routing in `next dev` and `next start`
is using. It is an approximation to make unit testing easier.
# Middleware
A new `unstable_doesMiddlewareMatch` function was added to assert when
middleware will be run for a path.
```js
import { unstable_doesMiddlewareMatch } from 'next/server/testing'
expect(
unstable_doesMiddlewareMatch({
config,
nextConfig,
url: '/test',
})
).toEqual(false)
```
Helpers were also created to test for whether the response was a
redirect or rewrite.
# Next.config.js
A new `unstable_getResponseFromNextConfig` function was added to run
`headers`, `redirects`, and `rewrites` functions from `next.config.js`,
calling them in the order that they would actually be executed in.
```js
import { getRedirectUrl, unstable_getResponseFromNextConfig } from 'next/server/testing'
const response = await unstable_getResponseFromNextConfig({
url: 'https://nextjs.org/test',
nextConfig: {
async redirects() {
return [{ source: '/test', destination: '/test2', permanent: false }]
},
},
})
expect(response.status).toEqual(307)
expect(getRedirectUrl(response)).toEqual('https://nextjs.org/test2')
```
---------
Co-authored-by: Zack Tanner <1939140+ztanner@users.noreply.github.com>
Co-authored-by: JJ Kasper <jj@jjsweb.site>