Emdash source with visual editor image upload fix
Fixes: 1. media.ts: wrap placeholder generation in try-catch 2. toolbar.ts: check r.ok, display error message in popover
This commit is contained in:
150
packages/admin/tests/lib/locales.test.ts
Normal file
150
packages/admin/tests/lib/locales.test.ts
Normal file
@@ -0,0 +1,150 @@
|
||||
import { describe, expect, test } from "vitest";
|
||||
|
||||
import {
|
||||
DEFAULT_LOCALE,
|
||||
getLocaleDir,
|
||||
loadMessages,
|
||||
resolveLocale,
|
||||
SUPPORTED_LOCALES,
|
||||
} from "../../src/locales/index.js";
|
||||
|
||||
for (const { code } of SUPPORTED_LOCALES) {
|
||||
test(`loadMessages resolves catalog for supported locale "${code}"`, async () => {
|
||||
const messages = await loadMessages(code);
|
||||
expect(messages).toBeDefined();
|
||||
expect(typeof messages).toBe("object");
|
||||
expect(Object.keys(messages).length).toBeGreaterThan(0);
|
||||
});
|
||||
}
|
||||
|
||||
test("loadMessages falls back to English for unknown locale", async () => {
|
||||
const [fallback, english] = await Promise.all([loadMessages("xx"), loadMessages("en")]);
|
||||
expect(fallback).toEqual(english);
|
||||
});
|
||||
|
||||
// -- getLocaleDir ----------------------------------------------------------
|
||||
|
||||
describe("getLocaleDir", () => {
|
||||
test("returns 'rtl' for Arabic", () => {
|
||||
expect(getLocaleDir("ar")).toBe("rtl");
|
||||
});
|
||||
|
||||
test("returns 'ltr' for English", () => {
|
||||
expect(getLocaleDir("en")).toBe("ltr");
|
||||
});
|
||||
|
||||
test("returns 'ltr' for locales without explicit dir", () => {
|
||||
expect(getLocaleDir("de")).toBe("ltr");
|
||||
expect(getLocaleDir("fr")).toBe("ltr");
|
||||
expect(getLocaleDir("pt-BR")).toBe("ltr");
|
||||
});
|
||||
|
||||
test("returns 'ltr' for unknown locale", () => {
|
||||
expect(getLocaleDir("xx")).toBe("ltr");
|
||||
});
|
||||
});
|
||||
|
||||
// -- resolveLocale ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Build a Request with the given headers. Browser environments silently
|
||||
* strip the `cookie` header (forbidden header name) from Request/Headers,
|
||||
* so we override `.get()` to inject it for testing purposes.
|
||||
*/
|
||||
function makeRequest(headers: Record<string, string> = {}): Request {
|
||||
const { cookie, ...rest } = headers;
|
||||
const req = new Request("http://localhost/", { headers: rest });
|
||||
if (cookie) {
|
||||
const original = req.headers.get.bind(req.headers);
|
||||
req.headers.get = (name: string) => (name.toLowerCase() === "cookie" ? cookie : original(name));
|
||||
}
|
||||
return req;
|
||||
}
|
||||
|
||||
describe("resolveLocale", () => {
|
||||
test("returns DEFAULT_LOCALE when no cookie or accept-language", () => {
|
||||
expect(resolveLocale(makeRequest())).toBe(DEFAULT_LOCALE);
|
||||
});
|
||||
|
||||
// Cookie precedence
|
||||
test("returns locale from emdash-locale cookie", () => {
|
||||
expect(resolveLocale(makeRequest({ cookie: "emdash-locale=de" }))).toBe("de");
|
||||
});
|
||||
|
||||
test("ignores cookie with unsupported locale", () => {
|
||||
expect(resolveLocale(makeRequest({ cookie: "emdash-locale=xx" }))).toBe(DEFAULT_LOCALE);
|
||||
});
|
||||
|
||||
test("cookie takes precedence over accept-language", () => {
|
||||
expect(
|
||||
resolveLocale(
|
||||
makeRequest({
|
||||
cookie: "emdash-locale=de",
|
||||
"accept-language": "fr",
|
||||
}),
|
||||
),
|
||||
).toBe("de");
|
||||
});
|
||||
|
||||
// Accept-Language exact match
|
||||
test("matches exact accept-language tag", () => {
|
||||
expect(resolveLocale(makeRequest({ "accept-language": "de" }))).toBe("de");
|
||||
});
|
||||
|
||||
test("matches accept-language with region (pt-BR)", () => {
|
||||
expect(resolveLocale(makeRequest({ "accept-language": "pt-BR" }))).toBe("pt-BR");
|
||||
});
|
||||
|
||||
// Accept-Language case insensitivity (fix for Copilot review #4)
|
||||
test("matches accept-language case-insensitively (pt-br -> pt-BR)", () => {
|
||||
expect(resolveLocale(makeRequest({ "accept-language": "pt-br" }))).toBe("pt-BR");
|
||||
});
|
||||
|
||||
test("matches accept-language case-insensitively (ZH-CN -> zh-CN)", () => {
|
||||
expect(resolveLocale(makeRequest({ "accept-language": "ZH-CN" }))).toBe("zh-CN");
|
||||
});
|
||||
|
||||
test("matches accept-language case-insensitively (DE -> de)", () => {
|
||||
expect(resolveLocale(makeRequest({ "accept-language": "DE" }))).toBe("de");
|
||||
});
|
||||
|
||||
// Accept-Language base language fallback
|
||||
test("falls back to base language (pt-PT -> pt-BR)", () => {
|
||||
expect(resolveLocale(makeRequest({ "accept-language": "pt-PT" }))).toBe("pt-BR");
|
||||
});
|
||||
|
||||
test("matches exact accept-language tag with region (zh-TW)", () => {
|
||||
expect(resolveLocale(makeRequest({ "accept-language": "zh-TW" }))).toBe("zh-TW");
|
||||
});
|
||||
|
||||
test("matches Traditional Chinese script tag (zh-Hant -> zh-TW)", () => {
|
||||
expect(resolveLocale(makeRequest({ "accept-language": "zh-Hant" }))).toBe("zh-TW");
|
||||
});
|
||||
|
||||
test("matches Traditional Chinese script+region tag (zh-Hant-TW -> zh-TW)", () => {
|
||||
expect(resolveLocale(makeRequest({ "accept-language": "zh-Hant-TW" }))).toBe("zh-TW");
|
||||
});
|
||||
|
||||
test("matches Simplified Chinese script tag (zh-Hans -> zh-CN)", () => {
|
||||
expect(resolveLocale(makeRequest({ "accept-language": "zh-Hans" }))).toBe("zh-CN");
|
||||
});
|
||||
// Accept-Language with quality weights
|
||||
test("respects order in accept-language list", () => {
|
||||
expect(resolveLocale(makeRequest({ "accept-language": "fr;q=0.9, de;q=1.0" }))).toBe("fr");
|
||||
});
|
||||
|
||||
test("skips unsupported languages in accept-language list", () => {
|
||||
expect(resolveLocale(makeRequest({ "accept-language": "xx, yy, de" }))).toBe("de");
|
||||
});
|
||||
|
||||
// Malformed input
|
||||
test("handles empty accept-language gracefully", () => {
|
||||
expect(resolveLocale(makeRequest({ "accept-language": "" }))).toBe(DEFAULT_LOCALE);
|
||||
});
|
||||
|
||||
test("handles garbage accept-language gracefully", () => {
|
||||
expect(resolveLocale(makeRequest({ "accept-language": "not-a-real-locale-tag!!!" }))).toBe(
|
||||
DEFAULT_LOCALE,
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user