Files
homarr/packages/translation/src/middleware.spec.ts
T

95 lines
3.5 KiB
TypeScript

import { NextRequest } from "next/server";
import { describe, expect, it } from "vitest";
import { createI18nMiddleware } from "./middleware";
const createRewrittenRequest = (response: Response) => {
const destination = response.headers.get("x-middleware-rewrite");
const overriddenHeaderNames = response.headers.get("x-middleware-override-headers")?.split(",") ?? [];
const headers = new Headers();
for (const name of overriddenHeaderNames) {
const value = response.headers.get(`x-middleware-request-${name}`);
if (value !== null) {
headers.set(name, value);
}
}
if (destination === null) {
throw new Error("Expected middleware to rewrite the request");
}
return new NextRequest(destination, { headers });
};
describe("createI18nMiddleware", () => {
it("canonicalizes a prefixed path when the locale header is supplied externally", () => {
const middleware = createI18nMiddleware("en");
const request = new NextRequest("http://localhost/en/auth/login", {
headers: {
cookie: "homarr.locale=fr",
"x-next-intl-locale": "en",
},
});
const response = middleware(request);
expect(response.headers.get("x-middleware-next")).toBeNull();
expect(response.headers.get("location")).toBe("http://localhost/auth/login");
expect(response.headers.get("set-cookie")).toContain("homarr.locale=en");
});
it("continues a valid internal locale handoff across middleware instances", () => {
const firstPassMiddleware = createI18nMiddleware("en");
const publicRequest = new NextRequest("http://localhost/auth/login");
const rewriteResponse = firstPassMiddleware(publicRequest);
expect(rewriteResponse.headers.get("x-middleware-rewrite")).toBe("http://localhost/en/auth/login");
const localizedRequest = createRewrittenRequest(rewriteResponse);
const secondPassMiddleware = createI18nMiddleware("en");
const handoffResponse = secondPassMiddleware(localizedRequest);
expect(handoffResponse.headers.get("x-middleware-next")).toBe("1");
expect(handoffResponse.headers.get("location")).toBeNull();
expect(handoffResponse.headers.get("x-middleware-override-headers")).toBe("x-next-intl-locale");
});
it.each([
{
name: "unsupported locale",
pathname: "/en/auth/login",
locale: "xx",
},
{
name: "locale that does not match the path",
pathname: "/fr/auth/login",
locale: "en",
},
])("does not continue an internal handoff with a $name", ({ pathname, locale }) => {
const middleware = createI18nMiddleware("en");
const rewriteResponse = middleware(new NextRequest("http://localhost/auth/login"));
const rewrittenRequest = createRewrittenRequest(rewriteResponse);
rewrittenRequest.headers.set("x-next-intl-locale", locale);
const request = new NextRequest(`http://localhost${pathname}`, {
headers: rewrittenRequest.headers,
});
const response = middleware(request);
expect(response.headers.get("x-middleware-next")).toBeNull();
expect(response.headers.get("location")).toBe("http://localhost/auth/login");
});
it("canonicalizes a directly requested prefixed path and synchronizes its locale", () => {
const middleware = createI18nMiddleware("en");
const request = new NextRequest("http://localhost/fr/auth/login");
const response = middleware(request);
expect(response.headers.get("x-middleware-next")).toBeNull();
expect(response.headers.get("location")).toBe("http://localhost/auth/login");
expect(response.headers.get("set-cookie")).toContain("homarr.locale=fr");
});
});