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]>
30 lines
1.4 KiB
TypeScript
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 & b <c> "d" 'e' 'f' &bogus;")).toBe(`a & b <c> "d" 'e' 'f' &bogus;`);
|
|
});
|
|
|
|
test("parses attributes in any order and quoting style", () => {
|
|
expect(parseAttributes(`<meta content="x&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 & God ")).toBe("Tower of & God");
|
|
});
|
|
|
|
test("an out-of-range numeric entity is left as written instead of throwing", () => {
|
|
expect(decodeEntities("a � b � c")).toBe("a � b � c");
|
|
});
|