// @vitest-environment jsdom
import { describe, it, expect } from "vitest";
import { createDefaultSanitizer, resolveSanitizer } from "./sanitize";
describe("createDefaultSanitizer", () => {
const sanitize = createDefaultSanitizer();
it("strips ")).toBe("
Hello
");
});
it("strips onerror event handlers from img tags", () => {
const result = sanitize('
');
expect(result).not.toContain("onerror");
expect(result).toContain("
{
const result = sanitize('click');
expect(result).not.toContain("javascript:");
});
it("strips onclick handlers", () => {
const result = sanitize('click
');
expect(result).not.toContain("onclick");
});
it("allows safe markdown output: headings", () => {
expect(sanitize("Title
")).toBe("Title
");
expect(sanitize("Subtitle
")).toBe("Subtitle
");
});
it("allows safe markdown output: paragraphs and formatting", () => {
expect(sanitize("bold and italic
"))
.toBe("bold and italic
");
});
it("allows safe markdown output: lists", () => {
const html = "";
expect(sanitize(html)).toBe(html);
});
it("allows safe markdown output: code blocks", () => {
const html = 'const x = 1;
';
expect(sanitize(html)).toBe(html);
});
it("allows safe markdown output: tables", () => {
const html = "";
expect(sanitize(html)).toBe(html);
});
it("allows safe links with href", () => {
const html = 'link';
expect(sanitize(html)).toBe(html);
});
it("allows safe images with https src", () => {
const html = '
';
expect(sanitize(html)).toBe(html);
});
it("allows data:image/ URIs (non-SVG)", () => {
const html = '
';
expect(sanitize(html)).toBe(html);
});
it("blocks data:image/svg+xml URIs", () => {
const result = sanitize('
');
expect(result).not.toContain("data:image/svg+xml");
});
it("blocks mixed-case data: URI scheme bypass", () => {
const result = sanitize('
');
expect(result).not.toContain("Data:image/svg+xml");
const result2 = sanitize('
');
expect(result2).not.toContain("DATA:image/svg+xml");
});
it("preserves widget-specific data attributes", () => {
const html = '';
expect(sanitize(html)).toBe(html);
});
it("preserves data-persona-component-directive", () => {
const html = '';
expect(sanitize(html)).toBe(html);
});
});
describe("resolveSanitizer", () => {
it("returns default sanitizer for undefined", () => {
const fn = resolveSanitizer(undefined);
expect(fn).toBeTypeOf("function");
expect(fn!("")).toBe("");
});
it("returns default sanitizer for true", () => {
const fn = resolveSanitizer(true);
expect(fn).toBeTypeOf("function");
expect(fn!("")).toBe("");
});
it("returns null for false (disabled)", () => {
expect(resolveSanitizer(false)).toBeNull();
});
it("returns the custom function as-is", () => {
const custom = (html: string) => html.toUpperCase();
const fn = resolveSanitizer(custom);
expect(fn).toBe(custom);
expect(fn!("hello")).toBe("HELLO");
});
});