Skip to content
This repository was archived by the owner on Jan 28, 2025. It is now read-only.

Commit 92236d4

Browse files
authored
refactor(core, lambda-at-edge): refactor handler tests into core (#1310)
1 parent 821a033 commit 92236d4

38 files changed

+3840
-7105
lines changed

packages/libs/core/src/types.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,12 @@ export type RedirectData = {
3030
statusCode: number;
3131
source: string;
3232
destination: string;
33-
regex: string;
3433
internal?: boolean;
3534
};
3635

3736
export type RewriteData = {
3837
source: string;
3938
destination: string;
40-
regex: string;
4139
};
4240

4341
export type DynamicRoute = {
@@ -110,7 +108,6 @@ export type PageManifest = Manifest & {
110108
export type HeaderData = {
111109
source: string;
112110
headers: Header[];
113-
regex: string;
114111
};
115112

116113
export type DomainData = {
Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
import { PrerenderManifest } from "next/dist/build";
2+
import {
3+
ApiManifest,
4+
Event,
5+
handleApi,
6+
prepareBuildManifests,
7+
RoutesManifest
8+
} from "../../src";
9+
10+
const event = (url: string, headers?: { [key: string]: string }): Event => {
11+
return {
12+
req: {
13+
headers: headers ?? {},
14+
url
15+
} as any,
16+
res: {
17+
end: jest.fn(),
18+
setHeader: jest.fn()
19+
} as any,
20+
responsePromise: new Promise(() => ({}))
21+
};
22+
};
23+
24+
describe("Api handler", () => {
25+
let pagesManifest: { [key: string]: string };
26+
let manifest: ApiManifest;
27+
let routesManifest: RoutesManifest;
28+
let getPage: any;
29+
30+
beforeAll(async () => {
31+
const prerenderManifest: PrerenderManifest = {
32+
version: 3,
33+
notFoundRoutes: [],
34+
routes: {},
35+
dynamicRoutes: {},
36+
preview: {
37+
previewModeId: "test-id",
38+
previewModeEncryptionKey: "test-key",
39+
previewModeSigningKey: "test-sig-key"
40+
}
41+
};
42+
routesManifest = {
43+
basePath: "",
44+
headers: [
45+
{
46+
source: "/api/static",
47+
headers: [
48+
{
49+
key: "X-Test-Header",
50+
value: "value"
51+
}
52+
]
53+
}
54+
],
55+
redirects: [
56+
{
57+
source: "/api/redirect-simple",
58+
destination: "/api/static",
59+
statusCode: 307
60+
},
61+
{
62+
source: "/redirect/:dynamic",
63+
destination: "/api/dynamic/:dynamic",
64+
statusCode: 308
65+
},
66+
{
67+
source: "/api/redirect-query",
68+
destination: "/api/static?foo=bar",
69+
statusCode: 307
70+
}
71+
],
72+
rewrites: [
73+
{
74+
source: "/rewrite",
75+
destination: "/api/static"
76+
},
77+
{
78+
source: "/rewrite-not-found",
79+
destination: "/api/not/found"
80+
},
81+
{
82+
source: "/rewrite/:slug",
83+
destination: "/api/dynamic/:slug"
84+
},
85+
{
86+
source: "/rewrite-query/:slug",
87+
destination: "/api/static"
88+
},
89+
{
90+
source: "/rewrite-external",
91+
destination: "https://ext.example.com"
92+
}
93+
]
94+
};
95+
pagesManifest = {
96+
"/": "pages/index.html",
97+
"/404": "pages/404.html",
98+
"/500": "pages/500.html",
99+
"/api": "pages/api/index.js",
100+
"/api/static": "pages/api/static.js",
101+
"/api/dynamic/[id]": "pages/api/dynamic/[id].js"
102+
};
103+
const buildId = "test-build-id";
104+
const publicFiles = ["favicon.ico", "name with spaces.txt"];
105+
const manifests = await prepareBuildManifests(
106+
{
107+
buildId,
108+
domainRedirects: { "www.example.com": "https://example.com" }
109+
},
110+
{},
111+
routesManifest,
112+
pagesManifest,
113+
prerenderManifest,
114+
publicFiles
115+
);
116+
manifest = manifests.apiManifest;
117+
});
118+
119+
beforeEach(() => {
120+
jest.spyOn(console, "error").mockReturnValueOnce();
121+
getPage = jest.fn();
122+
getPage.mockReturnValueOnce({ default: jest.fn() });
123+
});
124+
125+
describe("Api pages", () => {
126+
it.each`
127+
uri | page
128+
${"/api"} | ${"pages/api/index.js"}
129+
${"/api/static"} | ${"pages/api/static.js"}
130+
${"/api/dynamic/1"} | ${"pages/api/dynamic/[id].js"}
131+
${"/rewrite"} | ${"pages/api/static.js"}
132+
${"/rewrite/2"} | ${"pages/api/dynamic/[id].js"}
133+
${"/rewrite-query/3"} | ${"pages/api/static.js"}
134+
`("Routes api request $uri to page $page", async ({ uri, page }) => {
135+
const route = await handleApi(
136+
event(uri),
137+
manifest,
138+
routesManifest,
139+
getPage
140+
);
141+
142+
expect(route).toBeFalsy();
143+
expect(getPage).toHaveBeenCalledWith(page);
144+
});
145+
146+
it.each`
147+
uri
148+
${"/api/notfound"}
149+
${"/api/dynamic/not/found"}
150+
${"/rewrite-not-found"}
151+
`("Returns 404 for $uri", async ({ uri }) => {
152+
const e = event(uri);
153+
const route = await handleApi(e, manifest, routesManifest, getPage);
154+
155+
expect(route).toBeFalsy();
156+
expect(e.res.statusCode).toEqual(404);
157+
});
158+
});
159+
160+
describe("Headers", () => {
161+
it.each`
162+
uri
163+
${"/api/static"}
164+
`("Sets headers for $uri", async ({ uri }) => {
165+
const e = event(uri);
166+
167+
await handleApi(e, manifest, routesManifest, getPage);
168+
169+
expect(e.res.setHeader).toHaveBeenCalledWith("X-Test-Header", "value");
170+
});
171+
});
172+
173+
describe("Redirects", () => {
174+
it.each`
175+
uri | code | destination
176+
${"/api/redirect-simple"} | ${307} | ${"/api/static"}
177+
${"/redirect/test"} | ${308} | ${"/api/dynamic/test"}
178+
${"/api/redirect-query?key=val"} | ${307} | ${"/api/static?key=val&foo=bar"}
179+
`(
180+
"Redirects $uri to $destination with code $code",
181+
async ({ code, destination, uri }) => {
182+
const e = event(uri);
183+
const route = await handleApi(e, manifest, routesManifest, getPage);
184+
185+
expect(route).toBeFalsy();
186+
expect(e.res.statusCode).toEqual(code);
187+
expect(e.res.setHeader).toHaveBeenCalledWith("Location", destination);
188+
expect(e.res.end).toHaveBeenCalled();
189+
}
190+
);
191+
192+
it.each`
193+
uri | code | destination
194+
${"/api"} | ${308} | ${"https://example.com/api"}
195+
${"/api/static"} | ${308} | ${"https://example.com/api/static"}
196+
${"/api?query"} | ${308} | ${"https://example.com/api?query"}
197+
`(
198+
"Redirects www.example.com$uri to $destination with code $code",
199+
async ({ code, destination, uri }) => {
200+
const e = event(uri, { Host: "www.example.com" });
201+
const route = await handleApi(e, manifest, routesManifest, getPage);
202+
203+
expect(route).toBeFalsy();
204+
expect(e.res.statusCode).toEqual(code);
205+
expect(e.res.setHeader).toHaveBeenCalledWith("Location", destination);
206+
expect(e.res.end).toHaveBeenCalled();
207+
}
208+
);
209+
});
210+
211+
describe("External rewrite", () => {
212+
it.each`
213+
uri | path
214+
${"/rewrite-external"} | ${"https://ext.example.com"}
215+
`("Returns external rewrite from $uri to $path", async ({ path, uri }) => {
216+
const e = event(uri);
217+
const route = await handleApi(e, manifest, routesManifest, getPage);
218+
219+
expect(route).toBeTruthy();
220+
if (route) {
221+
expect(route.isExternal).toBeTruthy();
222+
expect((route as any).path).toEqual(path);
223+
}
224+
});
225+
});
226+
});

0 commit comments

Comments
 (0)