Skip to content

Instantly share code, notes, and snippets.

@gabsprates
Created June 1, 2022 14:49
Show Gist options
  • Save gabsprates/5682ecbf43157e26a0197b97cd512ce8 to your computer and use it in GitHub Desktop.
Save gabsprates/5682ecbf43157e26a0197b97cd512ce8 to your computer and use it in GitHub Desktop.
A helper I built to test Next.js' Middleware functions

Using the helper:

const middlewareDeps = buildMiddlewareDependencies({
  route: '/path/to/[slug]',
  params: { slug: 'acme' },
  cookies: { access_token: 'api_will_deal_with_it' },
});

const response = await middleware(middlewareDeps.request, middlewareDeps.event);

// example
expect(response.status).toEqual(200);
import { NextFetchEvent, NextRequest } from 'next/server';
interface BuildMiddlewareDependenciesOptions {
cookies?: Record<string, string>;
params?: Record<string, string>;
route: string;
}
type BuildMiddlewareDependencies = (
options: BuildMiddlewareDependenciesOptions
) => {
url: URL;
event: NextFetchEvent;
request: NextRequest;
};
/** thanks to @jaredgorski
we didn't implemented support to catch all routes,
such as `[...slug]`, because we didn't need that
*/
const hydrateNextRouteWithQuery = (
route: string,
query: BaseRouterQuery = {}
): string => {
return Object.keys(query).reduce((routeStr, param) => {
return routeStr.replace(`[${param}]`, query[param] as string);
}, route);
};
const buildUrl = ({
params = {},
route,
}: Pick<BuildMiddlewareDependenciesOptions, 'params' | 'route'>): URL => {
const hydratedRoute = hydrateNextRouteWithQuery(route, params);
const url = new URL('https://domain.fake' + hydratedRoute);
Object.entries(params).forEach(([key, value]) => {
url.searchParams.set(key, value);
});
return url;
};
const buildHeaders = ({
cookies = {},
}: Pick<BuildMiddlewareDependenciesOptions, 'cookies'>) => {
const stringifiedCookies = Object.entries(cookies)
.map(([key, value]) => `${key}=${value}`)
.join(';');
const headers = new Headers();
headers.set('cookie', stringifiedCookies);
return headers;
};
export const buildMiddlewareDependencies: BuildMiddlewareDependencies = ({
cookies = {},
params = {},
route,
}) => {
const url = buildUrl({ params, route });
const headers = buildHeaders({ cookies });
const request = new NextRequest(url.href, {
page: { name: route, params },
headers,
});
const event = new NextFetchEvent({ request, page: url.pathname });
return {
event,
request,
url,
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment