Files
yaak-mountain-loop/packages/common-lib/decodeBodyText.test.ts
T
2026-11-04 21:21:05 -07:00

46 lines
2.3 KiB
TypeScript

import { describe, expect, test } from "vitest";
import { contentTypeCharset, decodeBodyText, strictUtf8Text } from "./decodeBodyText";
const latin1 = (text: string) => Uint8Array.from(text, (c) => c.charCodeAt(0));
// "こんにちは、世界" in Shift_JIS
const shiftJis = new Uint8Array([
0x82, 0xb1, 0x82, 0xf1, 0x82, 0xc9, 0x82, 0xbf, 0x82, 0xcd, 0x81, 0x41, 0x90, 0xa2, 0x8a, 0x45,
]);
const french = "Accès refusé : vous n'avez pas l'autorisation d'accéder à cette page.";
describe("decodeBodyText", () => {
test("decodes in the charset the content type names", () => {
const body = latin1(french);
expect(decodeBodyText(body, "text/html; charset=iso-8859-1")).toBe(french);
expect(decodeBodyText(body, 'text/plain; CHARSET="ISO-8859-1"')).toBe(french);
expect(decodeBodyText(shiftJis, "text/plain; charset=Shift_JIS")).toBe("こんにちは、世界");
});
test("reads an unlabeled body that isn't UTF-8 as windows-1252", () => {
expect(decodeBodyText(latin1(french), "text/html")).toBe(french);
expect(decodeBodyText(latin1(french), null)).toBe(french);
expect(decodeBodyText(new Uint8Array([0x93, 0x68, 0x69, 0x94]), null)).toBe("“hi”");
});
test("reads UTF-8 as UTF-8, labeled or not", () => {
const utf8 = new TextEncoder().encode(`{"city":"Zürich","greeting":"こんにちは"}`);
const text = `{"city":"Zürich","greeting":"こんにちは"}`;
expect(decodeBodyText(utf8, null)).toBe(text);
expect(decodeBodyText(utf8, "application/json")).toBe(text);
expect(decodeBodyText(utf8, "application/json; charset=utf-8")).toBe(text);
// A body labeled UTF-8 stays UTF-8, with what isn't replaced, as before
expect(decodeBodyText(new Uint8Array([0x61, 0xff]), "text/plain; charset=utf-8")).toBe("a�");
});
test("treats a charset TextDecoder doesn't know as no charset", () => {
expect(contentTypeCharset("text/plain; charset=not-a-charset")).toBeNull();
expect(decodeBodyText(latin1(french), "text/plain; charset=not-a-charset")).toBe(french);
});
test("keeps a truncated UTF-8 body UTF-8 when it ends partway through a character", () => {
const cut = new TextEncoder().encode("abc€").subarray(0, 5);
expect(strictUtf8Text(cut)).toBeNull();
expect(decodeBodyText(cut, null, { truncated: true })).toBe("abc");
});
});