Skip to content

Commit dc87bbd

Browse files
authored
chore(nextjs): Add tests covering the new middleware matcher (clerk#3741)
1 parent a86525d commit dc87bbd

1 file changed

Lines changed: 87 additions & 0 deletions

File tree

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import { pathToRegexp } from 'path-to-regexp';
2+
3+
const createMatcher = (config: { matcher: string[] }) => (path: string) => {
4+
return config.matcher.some(matcher => {
5+
return pathToRegexp(matcher).test(path);
6+
});
7+
};
8+
9+
describe('nextjs matcher', () => {
10+
/**
11+
* 🚨🚨🚨🚨
12+
* This is the matcher we document for clerkMiddleware + authMiddleware.
13+
* Any change made to the matcher here needs to be reflected in the documentation, the dashboard
14+
* and vice versa.
15+
* 🚨🚨🚨🚨
16+
*/
17+
const config = {
18+
matcher: [
19+
// Skip Next.js internals and all static files, unless found in search params
20+
'/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)',
21+
// Always run for API routes
22+
'/(api|trpc)(.*)',
23+
],
24+
};
25+
26+
const match = createMatcher(config);
27+
28+
it.each([
29+
// Skip nextjs internals
30+
'/_next', //
31+
'/_next/',
32+
'/_next/static/',
33+
'/_next/static',
34+
'/_next/images',
35+
'/favicon.ico',
36+
// Skip android manifest file
37+
'/site.webmanifest',
38+
// Skip normal files
39+
'/file.js',
40+
'/img.jpeg',
41+
'/img.jpg',
42+
'/img.png',
43+
'/img.jpg?param=1',
44+
// We can't cover this case without extremely complex regex
45+
// '/img.jpg?param=img.jpg',
46+
])('skips the middleware for "%s"', async path => {
47+
expect(match(path)).toBe(false);
48+
});
49+
50+
it.each([
51+
// Always protect /api and /trpc
52+
'/api/', //
53+
'/api',
54+
'/api/endpoint',
55+
'/api/endpoint.json',
56+
'/trpc',
57+
'/trpc/',
58+
'/trpc/endpoint',
59+
'/trpc/endpoint.json',
60+
'/trpc/endpoint.action',
61+
// Paths with file extensions are not files without `.`
62+
'/somethingjpg',
63+
// Always protect jsons
64+
'/file.json',
65+
'/file.json/',
66+
'/a/b.json',
67+
// Sanity checks for paths
68+
'/',
69+
'/path',
70+
'/path/',
71+
'/nested/path',
72+
'/nested/path/multiple/levels',
73+
// Paths with slugs containing `.` are not files
74+
'/slug-123',
75+
'/sl.ug-123',
76+
'/sl.ug',
77+
'/clerk.com',
78+
// Paths containing search params are not files, even if they contain a file extension
79+
'/download?filename=1.jpg',
80+
'/download/?filename=1.jpg',
81+
'/download?test=1&filename=1.jpg',
82+
'/download?filename=1.jpg&test=1',
83+
'/download?filename=1.png&test=1',
84+
])('triggers the middleware for "%s"', path => {
85+
expect(match(path)).toBe(true);
86+
});
87+
});

0 commit comments

Comments
 (0)