Files
mangabaka-seeder/test/html.test.ts
T
Lucas WintherandClaude Opus 5.5 baa3476b73 fix(server): inert proxy responses, API-call header, image-only uploads; origin check by host
From the final review: proxied archived HTML could run on our origin and read a
remembered token; /api/upload accepted any Wayback URL and GIF-prefixed bytes; the
origin check broke behind a TLS proxy; one unreadable snapshot could fail a run.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-15 01:49:52 +02:00

30 lines
1.4 KiB
TypeScript

import { expect, test } from "bun:test";
import { decodeEntities, findTags, metaContent, parseAttributes, textOf } from "../src/core/html";
test("decodes named and numeric entities", () => {
expect(decodeEntities("a &amp; b &lt;c&gt; &quot;d&quot; &#39;e&#x27; &apos;f&apos; &bogus;")).toBe(`a & b <c> "d" 'e' 'f' &bogus;`);
});
test("parses attributes in any order and quoting style", () => {
expect(parseAttributes(`<meta content="x&amp;y" property=og:image data-a='1' hidden>`))
.toEqual({ content: "x&y", property: "og:image", "data-a": "1", hidden: "" });
expect(parseAttributes(`<div class="detail_bg" style="background:url('https://a/b.jpg') repeat-x">`).style)
.toBe("background:url('https://a/b.jpg') repeat-x");
});
test("finds tags and meta content by property or name", () => {
const html = `<head><meta name="twitter:image" content="t.jpg"/><META property="og:image" content="o.jpg"></head>`;
expect(findTags(html, "meta")).toHaveLength(2);
expect(metaContent(html, "og:image")).toBe("o.jpg");
expect(metaContent(html, "twitter:image")).toBe("t.jpg");
expect(metaContent(html, "og:title")).toBeUndefined();
});
test("textOf strips tags and collapses whitespace", () => {
expect(textOf("<span>Tower</span>\n of &amp; God ")).toBe("Tower of & God");
});
test("an out-of-range numeric entity is left as written instead of throwing", () => {
expect(decodeEntities("a &#99999999; b &#x110000; c")).toBe("a &#99999999; b &#x110000; c");
});