Skip to content

Commit fe4b84f

Browse files
committed
test(cloud-function): cover canonicals-aware locale redirects
1 parent efd4ce8 commit fe4b84f

2 files changed

Lines changed: 161 additions & 0 deletions

File tree

cloud-function/src/app.test.js

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,4 +190,162 @@ describe("mdnHandler", () => {
190190
strictEqual(res.statusCode, 200);
191191
});
192192
});
193+
194+
describe("missing locale (canonical-aware fallback)", () => {
195+
it("redirects /about to /en-US/about (issue #279)", async () => {
196+
const req = createRequest({
197+
method: "GET",
198+
url: "/about",
199+
hostname: "localhost",
200+
headers: { host: "localhost" },
201+
});
202+
const res = createResponse();
203+
mdnHandler(req, res);
204+
205+
strictEqual(res.statusCode, 302);
206+
strictEqual(res._getRedirectUrl(), "/en-US/about");
207+
});
208+
209+
it("redirects /community to /en-US/community", async () => {
210+
const req = createRequest({
211+
method: "GET",
212+
url: "/community",
213+
hostname: "localhost",
214+
headers: { host: "localhost" },
215+
});
216+
const res = createResponse();
217+
mdnHandler(req, res);
218+
219+
strictEqual(res.statusCode, 302);
220+
strictEqual(res._getRedirectUrl(), "/en-US/community");
221+
});
222+
223+
it("redirects /advertising to /en-US/advertising", async () => {
224+
const req = createRequest({
225+
method: "GET",
226+
url: "/advertising",
227+
hostname: "localhost",
228+
headers: { host: "localhost" },
229+
});
230+
const res = createResponse();
231+
mdnHandler(req, res);
232+
233+
strictEqual(res.statusCode, 302);
234+
strictEqual(res._getRedirectUrl(), "/en-US/advertising");
235+
});
236+
237+
it("preserves query string when inserting locale", async () => {
238+
const req = createRequest({
239+
method: "GET",
240+
url: "/about?foo=bar",
241+
hostname: "localhost",
242+
headers: { host: "localhost" },
243+
});
244+
const res = createResponse();
245+
mdnHandler(req, res);
246+
247+
strictEqual(res.statusCode, 302);
248+
strictEqual(res._getRedirectUrl(), "/en-US/about?foo=bar");
249+
});
250+
251+
it("uses Accept-Language to pick best locale when multiple are available", async () => {
252+
const req = createRequest({
253+
method: "GET",
254+
url: "/docs/Web",
255+
hostname: "localhost",
256+
headers: { host: "localhost", "accept-language": "fr" },
257+
});
258+
const res = createResponse();
259+
mdnHandler(req, res);
260+
261+
strictEqual(res.statusCode, 302);
262+
strictEqual(res._getRedirectUrl(), "/fr/docs/Web");
263+
});
264+
265+
it("falls back to en-US when preferredlocale has no translation", async () => {
266+
const req = createRequest({
267+
method: "GET",
268+
url: "/about",
269+
hostname: "localhost",
270+
headers: { host: "localhost" },
271+
cookies: { preferredlocale: "de" },
272+
});
273+
const res = createResponse();
274+
mdnHandler(req, res);
275+
276+
strictEqual(res.statusCode, 302);
277+
strictEqual(res._getRedirectUrl(), "/en-US/about");
278+
});
279+
});
280+
281+
describe("locale fallback to en-US", () => {
282+
it("redirects /de/about to /en-US/about when de translation is missing", async () => {
283+
const req = createRequest({
284+
method: "GET",
285+
url: "/de/about",
286+
hostname: "localhost",
287+
headers: { host: "localhost" },
288+
});
289+
const res = createResponse();
290+
mdnHandler(req, res);
291+
292+
strictEqual(res.statusCode, 302);
293+
strictEqual(res._getRedirectUrl(), "/en-US/about");
294+
});
295+
296+
it("does not fall back from en-US to itself for missing pages", async () => {
297+
const req = createRequest({
298+
method: "GET",
299+
url: "/en-US/non-existent-page",
300+
hostname: "localhost",
301+
headers: { host: "localhost" },
302+
});
303+
const res = createResponse();
304+
mdnHandler(req, res);
305+
306+
strictEqual(res.statusCode, 200);
307+
});
308+
309+
it("does not redirect when neither current locale nor en-US has the page", async () => {
310+
const req = createRequest({
311+
method: "GET",
312+
url: "/de/non-existent-page",
313+
hostname: "localhost",
314+
headers: { host: "localhost" },
315+
});
316+
const res = createResponse();
317+
mdnHandler(req, res);
318+
319+
strictEqual(res.statusCode, 200);
320+
});
321+
});
322+
323+
describe("unsupported locale recovery", () => {
324+
it("redirects /xy/about to /en-US/about (treats xy as bogus locale)", async () => {
325+
const req = createRequest({
326+
method: "GET",
327+
url: "/xy/about",
328+
hostname: "localhost",
329+
headers: { host: "localhost" },
330+
});
331+
const res = createResponse();
332+
mdnHandler(req, res);
333+
334+
strictEqual(res.statusCode, 302);
335+
strictEqual(res._getRedirectUrl(), "/en-US/about");
336+
});
337+
338+
it("does not redirect /xy/non-existent (no canonical match in either form)", async () => {
339+
const req = createRequest({
340+
method: "GET",
341+
url: "/xy/non-existent",
342+
hostname: "localhost",
343+
headers: { host: "localhost" },
344+
});
345+
const res = createResponse();
346+
mdnHandler(req, res);
347+
348+
strictEqual(res.statusCode, 200);
349+
});
350+
});
193351
});

cloud-function/src/fixtures/canonicals.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
{
22
"/en-us": "/en-US/",
3+
"/en-us/about": "/en-US/about",
4+
"/en-us/advertising": "/en-US/advertising",
35
"/en-us/blog": "/en-US/blog/",
6+
"/en-us/community": "/en-US/community",
47
"/en-us/docs/web": "/en-US/docs/Web",
58
"/en-us/docs/web/api": "/en-US/docs/Web/API",
69
"/fr": "/fr/",

0 commit comments

Comments
 (0)