yap-blog/tests/unit/html.test.ts
2026-07-02 21:32:33 -04:00

57 lines
2 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { sanitizeHtml } from "@/lib/html";
describe("sanitizeHtml (stored editor bodies)", () => {
it("strips <script> elements including their content", () => {
const html = sanitizeHtml('<p>Before</p><script>alert("pwned")</script><p>After</p>');
expect(html).not.toContain("<script");
expect(html).not.toContain("pwned");
expect(html).toContain("Before");
expect(html).toContain("After");
});
it("removes event-handler attributes", () => {
const html = sanitizeHtml('<img src="/uploads/x.png" onerror="alert(1)">');
expect(html).not.toContain("onerror");
expect(html).toContain('src="/uploads/x.png"');
});
it("removes javascript: URLs from links", () => {
const html = sanitizeHtml('<a href="javascript:alert(1)">click me</a>');
expect(html).not.toContain("javascript:");
expect(html).toContain("click me");
});
it("keeps the marks the editor produces, including underline", () => {
const html = sanitizeHtml("<p><u>under</u> <s>gone</s> <strong>bold</strong></p>");
expect(html).toContain("<u>under</u>");
expect(html).toContain("<s>gone</s>");
expect(html).toContain("<strong>bold</strong>");
});
it("keeps relative upload URLs and http(s) images", () => {
expect(sanitizeHtml('<img src="/uploads/a.png" alt="text">')).toContain(
'/uploads/a.png',
);
expect(sanitizeHtml('<img src="https://example.com/b.jpg">')).toContain(
"https://example.com/b.jpg",
);
});
it("keeps table structure", () => {
const html = sanitizeHtml(
"<table><tbody><tr><th>h</th></tr><tr><td>d</td></tr></tbody></table>",
);
expect(html).toContain("<table>");
expect(html).toContain("<th>h</th>");
expect(html).toContain("<td>d</td>");
});
it("drops iframes and style tags", () => {
const html = sanitizeHtml('<iframe src="https://evil.example"></iframe><style>*{}</style><p>ok</p>');
expect(html).not.toContain("iframe");
expect(html).not.toContain("<style");
expect(html).toContain("ok");
});
});