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

Commit 14ad854

Browse files
committed
add unit tests, minor updates
1 parent b5ee47b commit 14ad854

35 files changed

+354
-10
lines changed

packages/libs/lambda-at-edge/src/build.ts

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -708,18 +708,11 @@ class Builder {
708708
let prerenderManifestHTMLPageAssets: Promise<void>[] = [];
709709
let fallbackHTMLPageAssets: Promise<void>[] = [];
710710

711-
// Copy locale-specific prerendered files if defined, otherwise use empty which signifies no locale
712-
let locales: string[];
713-
if (routesManifest.i18n) {
714-
locales = routesManifest.i18n?.locales;
715-
locales.push("defaultLocale"); // special value to push default locale
716-
} else {
717-
locales = [""]; // no locales defined
718-
}
719-
711+
// Copy locale-specific prerendered files if defined, otherwise use empty which works for no locale
712+
const locales = routesManifest.i18n?.locales ?? [""];
720713
const defaultLocale = routesManifest.i18n?.defaultLocale;
721714

722-
for (let locale of locales) {
715+
for (const locale of locales) {
723716
prerenderManifestJSONPropFileAssets.concat(
724717
Object.keys(prerenderManifest.routes).map((key) => {
725718
const JSONFileName = key.endsWith("/")
Lines changed: 267 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,267 @@
1+
import { join } from "path";
2+
import fse from "fs-extra";
3+
import execa from "execa";
4+
import Builder, { ASSETS_DIR } from "../../src/build";
5+
import { DEFAULT_LAMBDA_CODE_DIR, API_LAMBDA_CODE_DIR } from "../../src/build";
6+
import { cleanupDir, removeNewLineChars } from "../test-utils";
7+
import { OriginRequestDefaultHandlerManifest } from "../../src/types";
8+
9+
jest.mock("execa");
10+
11+
describe("Builder Tests (with locales)", () => {
12+
let fseRemoveSpy: jest.SpyInstance;
13+
let fseEmptyDirSpy: jest.SpyInstance;
14+
let defaultBuildManifest: OriginRequestDefaultHandlerManifest;
15+
16+
const fixturePath = join(__dirname, "./simple-app-fixture-with-locales");
17+
const outputDir = join(fixturePath, ".test_sls_next_output");
18+
19+
beforeEach(async () => {
20+
const mockExeca = execa as jest.Mock;
21+
mockExeca.mockResolvedValueOnce();
22+
23+
fseRemoveSpy = jest.spyOn(fse, "remove").mockImplementation(() => {
24+
return;
25+
});
26+
fseEmptyDirSpy = jest.spyOn(fse, "emptyDir");
27+
28+
const builder = new Builder(fixturePath, outputDir);
29+
await builder.build();
30+
31+
defaultBuildManifest = await fse.readJSON(
32+
join(outputDir, `${DEFAULT_LAMBDA_CODE_DIR}/manifest.json`)
33+
);
34+
});
35+
36+
afterEach(() => {
37+
fseEmptyDirSpy.mockRestore();
38+
fseRemoveSpy.mockRestore();
39+
//return cleanupDir(outputDir);
40+
});
41+
42+
describe("Cleanup", () => {
43+
it(".next directory is emptied except for cache/ folder", () => {
44+
expect(fseRemoveSpy).toBeCalledWith(
45+
join(fixturePath, ".next/serverless")
46+
);
47+
expect(fseRemoveSpy).toBeCalledWith(
48+
join(fixturePath, ".next/prerender-manifest.json")
49+
);
50+
expect(fseRemoveSpy).not.toBeCalledWith(join(fixturePath, ".next/cache"));
51+
});
52+
53+
it("output directory is cleanup before building", () => {
54+
expect(fseEmptyDirSpy).toBeCalledWith(
55+
expect.stringContaining(join(".test_sls_next_output", "default-lambda"))
56+
);
57+
expect(fseEmptyDirSpy).toBeCalledWith(
58+
expect.stringContaining(join(".test_sls_next_output", "api-lambda"))
59+
);
60+
expect(fseEmptyDirSpy).toBeCalledWith(
61+
expect.stringContaining(join(".test_sls_next_output", "assets"))
62+
);
63+
});
64+
});
65+
66+
describe("Default Handler Manifest", () => {
67+
it("adds full manifest", () => {
68+
const {
69+
buildId,
70+
publicFiles,
71+
pages: {
72+
ssr: { dynamic, nonDynamic },
73+
html
74+
},
75+
trailingSlash
76+
} = defaultBuildManifest;
77+
78+
expect(removeNewLineChars(buildId)).toEqual("test-build-id");
79+
expect(dynamic).toEqual({
80+
"/:root": {
81+
file: "pages/[root].js",
82+
regex: expect.any(String)
83+
},
84+
"/customers/:customer": {
85+
file: "pages/customers/[customer].js",
86+
regex: expect.any(String)
87+
},
88+
"/customers/:customer/:post": {
89+
file: "pages/customers/[customer]/[post].js",
90+
regex: expect.any(String)
91+
},
92+
"/customers/:customer/profile": {
93+
file: "pages/customers/[customer]/profile.js",
94+
regex: expect.any(String)
95+
},
96+
"/customers/:catchAll*": {
97+
file: "pages/customers/[...catchAll].js",
98+
regex: expect.any(String)
99+
}
100+
});
101+
102+
expect(nonDynamic).toEqual({
103+
"/customers/new": "pages/customers/new.js",
104+
"/": "pages/index.js",
105+
"/_app": "pages/_app.js",
106+
"/_document": "pages/_document.js"
107+
});
108+
109+
expect(html).toEqual({
110+
nonDynamic: {
111+
"/404": "pages/404.html",
112+
"/terms": "pages/terms.html",
113+
"/about": "pages/about.html"
114+
},
115+
dynamic: {
116+
"/blog/:post": {
117+
file: "pages/blog/[post].html",
118+
regex: expect.any(String)
119+
}
120+
}
121+
});
122+
123+
expect(publicFiles).toEqual({
124+
"/favicon.ico": "favicon.ico",
125+
"/sub/image.png": "sub/image.png",
126+
"/sw.js": "sw.js"
127+
});
128+
129+
expect(trailingSlash).toBe(false);
130+
});
131+
});
132+
133+
describe("API Handler", () => {
134+
it("has empty API handler directory", async () => {
135+
expect.assertions(1);
136+
137+
const apiDir = await fse.readdir(
138+
join(outputDir, `${API_LAMBDA_CODE_DIR}`)
139+
);
140+
141+
expect(apiDir).toEqual([]);
142+
});
143+
});
144+
145+
describe("Default Handler", () => {
146+
it("copies build files", async () => {
147+
expect.assertions(7);
148+
149+
const files = await fse.readdir(
150+
join(outputDir, `${DEFAULT_LAMBDA_CODE_DIR}`)
151+
);
152+
const pages = await fse.readdir(
153+
join(outputDir, `${DEFAULT_LAMBDA_CODE_DIR}/pages`)
154+
);
155+
const customerPages = await fse.readdir(
156+
join(outputDir, `${DEFAULT_LAMBDA_CODE_DIR}/pages/customers`)
157+
);
158+
const apiDirExists = await fse.pathExists(
159+
join(outputDir, `${DEFAULT_LAMBDA_CODE_DIR}/pages/api`)
160+
);
161+
162+
expect(files).toEqual([
163+
"index.js",
164+
"manifest.json",
165+
"pages",
166+
"prerender-manifest.json",
167+
"routes-manifest.json"
168+
]);
169+
170+
// api pages should not be included in the default lambda
171+
expect(apiDirExists).toEqual(false);
172+
173+
// HTML Prerendered pages or JSON static props files
174+
// should not be included in the default lambda
175+
expect(pages).not.toContain(["blog.json", "index.json", "contact.json"]);
176+
expect(pages).not.toContain([
177+
"about.html",
178+
"terms.html",
179+
"contact.html",
180+
"index.html"
181+
]);
182+
183+
// JS files used only for prerendering at build time (contact.js, index.js) are not included since there are no API routes
184+
expect(pages).not.toContain(["contact.js", "index.js"]);
185+
186+
// Default lambda has locale directories "en", "nl" but they are empty for now
187+
expect(pages).toEqual(["_error.js", "blog.js", "customers", "en", "nl"]);
188+
expect(customerPages).toEqual(["[...catchAll].js", "[post].js"]);
189+
});
190+
});
191+
192+
describe("Assets", () => {
193+
it("copies locale-specific asset files", async () => {
194+
expect.assertions(11);
195+
// Root
196+
const nextDataFiles = await fse.readdir(
197+
join(outputDir, `${ASSETS_DIR}/_next/data/test-build-id`)
198+
);
199+
expect(nextDataFiles).toEqual(["contact.json", "en", "index.json", "nl"]);
200+
201+
// English
202+
const enNextDataFiles = await fse.readdir(
203+
join(outputDir, `${ASSETS_DIR}/_next/data/test-build-id/en`)
204+
);
205+
expect(enNextDataFiles).toEqual(["contact.json", "index.json"]);
206+
207+
const enIndexJson = await fse.readFile(
208+
join(outputDir, `${ASSETS_DIR}/_next/data/test-build-id/en/index.json`),
209+
"utf8"
210+
);
211+
expect(enIndexJson).toBe('"en"');
212+
213+
const enPageFiles = await fse.readdir(
214+
join(outputDir, `${ASSETS_DIR}/static-pages/test-build-id/en`)
215+
);
216+
expect(enPageFiles).toEqual(["contact.html", "index.html"]);
217+
218+
const enIndexHtml = await fse.readFile(
219+
join(
220+
outputDir,
221+
`${ASSETS_DIR}/static-pages/test-build-id/en/index.html`
222+
),
223+
"utf8"
224+
);
225+
expect(enIndexHtml).toBe("en");
226+
227+
// Dutch
228+
const nlNextDataFiles = await fse.readdir(
229+
join(outputDir, `${ASSETS_DIR}/_next/data/test-build-id/nl`)
230+
);
231+
expect(nlNextDataFiles).toEqual(["contact.json", "index.json"]);
232+
233+
const nlIndexJson = await fse.readFile(
234+
join(outputDir, `${ASSETS_DIR}/_next/data/test-build-id/nl/index.json`),
235+
"utf8"
236+
);
237+
expect(nlIndexJson).toBe('"nl"');
238+
239+
const nlPageFiles = await fse.readdir(
240+
join(outputDir, `${ASSETS_DIR}/static-pages/test-build-id/nl`)
241+
);
242+
expect(nlPageFiles).toEqual(["contact.html", "index.html"]);
243+
244+
const nlIndexHtml = await fse.readFile(
245+
join(
246+
outputDir,
247+
`${ASSETS_DIR}/static-pages/test-build-id/nl/index.html`
248+
),
249+
"utf8"
250+
);
251+
expect(nlIndexHtml).toBe("nl");
252+
253+
// Default locale: English
254+
const defaultIndexJson = await fse.readFile(
255+
join(outputDir, `${ASSETS_DIR}/_next/data/test-build-id/index.json`),
256+
"utf8"
257+
);
258+
expect(defaultIndexJson).toBe('"en"');
259+
260+
const defaultIndexHtml = await fse.readFile(
261+
join(outputDir, `${ASSETS_DIR}/static-pages/test-build-id/index.html`),
262+
"utf8"
263+
);
264+
expect(defaultIndexHtml).toBe("en");
265+
});
266+
});
267+
});
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
test-build-id
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Having a cache/ folder allows to test the cleanup of .next/ except for cache/ for faster builds
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"version": 1,
3+
"images": {
4+
"deviceSizes": [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
5+
"imageSizes": [16, 32, 48, 64, 96, 128, 256, 384],
6+
"domains": [],
7+
"path": "/_next/image",
8+
"loader": "default",
9+
"sizes": [
10+
640,
11+
750,
12+
828,
13+
1080,
14+
1200,
15+
1920,
16+
2048,
17+
3840,
18+
16,
19+
32,
20+
48,
21+
64,
22+
96,
23+
128,
24+
256,
25+
384
26+
]
27+
}
28+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"version": 2,
3+
"routes": {
4+
"/": {
5+
"initialRevalidateSeconds": false,
6+
"srcRoute": null,
7+
"dataRoute": "/_next/data/test-build-id/index.json"
8+
},
9+
"/contact": {
10+
"initialRevalidateSeconds": false,
11+
"srcRoute": null,
12+
"dataRoute": "/_next/data/test-build-id/contact.json"
13+
}
14+
}
15+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"version": 1,
3+
"pages404": true,
4+
"basePath": "",
5+
"redirects": [],
6+
"rewrites": [],
7+
"headers": [],
8+
"dynamicRoutes": [],
9+
"i18n": {
10+
"locales": ["en", "nl"],
11+
"defaultLocale": "en"
12+
}
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"/[root]": "pages/[root].js",
3+
"/customers/[customer]": "pages/customers/[customer].js",
4+
"/customers/[customer]/[post]": "pages/customers/[customer]/[post].js",
5+
"/customers/new": "pages/customers/new.js",
6+
"/customers/[customer]/profile": "pages/customers/[customer]/profile.js",
7+
"/customers/[...catchAll]": "pages/customers/[...catchAll].js",
8+
"/terms": "pages/terms.html",
9+
"/about": "pages/about.html",
10+
"/blog/[post]": "pages/blog/[post].html",
11+
"/": "pages/index.js",
12+
"/_app": "pages/_app.js",
13+
"/_document": "pages/_document.js",
14+
"/404": "pages/404.html"
15+
}

packages/libs/lambda-at-edge/tests/build/simple-app-fixture-with-locales/.next/serverless/pages/_error.js

Whitespace-only changes.

packages/libs/lambda-at-edge/tests/build/simple-app-fixture-with-locales/.next/serverless/pages/blog.js

Whitespace-only changes.

packages/libs/lambda-at-edge/tests/build/simple-app-fixture-with-locales/.next/serverless/pages/contact.js

Whitespace-only changes.

packages/libs/lambda-at-edge/tests/build/simple-app-fixture-with-locales/.next/serverless/pages/customers/[...catchAll].js

Whitespace-only changes.

packages/libs/lambda-at-edge/tests/build/simple-app-fixture-with-locales/.next/serverless/pages/customers/[post].js

Whitespace-only changes.

packages/libs/lambda-at-edge/tests/build/simple-app-fixture-with-locales/.next/serverless/pages/en/about.html

Whitespace-only changes.

packages/libs/lambda-at-edge/tests/build/simple-app-fixture-with-locales/.next/serverless/pages/en/blog.html

Whitespace-only changes.

packages/libs/lambda-at-edge/tests/build/simple-app-fixture-with-locales/.next/serverless/pages/en/blog.json

Whitespace-only changes.

packages/libs/lambda-at-edge/tests/build/simple-app-fixture-with-locales/.next/serverless/pages/en/contact.html

Whitespace-only changes.

packages/libs/lambda-at-edge/tests/build/simple-app-fixture-with-locales/.next/serverless/pages/en/contact.json

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
en
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"en"

packages/libs/lambda-at-edge/tests/build/simple-app-fixture-with-locales/.next/serverless/pages/en/terms.html

Whitespace-only changes.

packages/libs/lambda-at-edge/tests/build/simple-app-fixture-with-locales/.next/serverless/pages/index.js

Whitespace-only changes.

packages/libs/lambda-at-edge/tests/build/simple-app-fixture-with-locales/.next/serverless/pages/nl/about.html

Whitespace-only changes.

packages/libs/lambda-at-edge/tests/build/simple-app-fixture-with-locales/.next/serverless/pages/nl/blog.html

Whitespace-only changes.

packages/libs/lambda-at-edge/tests/build/simple-app-fixture-with-locales/.next/serverless/pages/nl/blog.json

Whitespace-only changes.

packages/libs/lambda-at-edge/tests/build/simple-app-fixture-with-locales/.next/serverless/pages/nl/contact.html

Whitespace-only changes.

packages/libs/lambda-at-edge/tests/build/simple-app-fixture-with-locales/.next/serverless/pages/nl/contact.json

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
nl
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"nl"

packages/libs/lambda-at-edge/tests/build/simple-app-fixture-with-locales/.next/serverless/pages/nl/terms.html

Whitespace-only changes.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module.exports = {
2+
target: "serverless",
3+
i18n: {
4+
locales: ["en", "nl"],
5+
defaultLocale: "en"
6+
}
7+
};

packages/libs/lambda-at-edge/tests/build/simple-app-fixture-with-locales/public/favicon.ico

Whitespace-only changes.

packages/libs/lambda-at-edge/tests/build/simple-app-fixture-with-locales/public/sub/image.png

Loading

packages/libs/lambda-at-edge/tests/build/simple-app-fixture-with-locales/public/sw.js

Whitespace-only changes.

packages/libs/lambda-at-edge/tests/build/simple-app-fixture-with-locales/static/donotdelete.txt

Whitespace-only changes.

0 commit comments

Comments
 (0)