42 lines
1.5 KiB
TypeScript
42 lines
1.5 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { renderMarkdown } from "@/lib/markdown";
|
|
|
|
describe("renderMarkdown", () => {
|
|
it("renders basic markdown", () => {
|
|
const html = renderMarkdown("Some **bold** and *italic* text.");
|
|
expect(html).toContain("<strong>bold</strong>");
|
|
expect(html).toContain("<em>italic</em>");
|
|
});
|
|
|
|
it("renders GFM tables and fenced code", () => {
|
|
const html = renderMarkdown("| a | b |\n| - | - |\n| 1 | 2 |\n\n```\ncode\n```");
|
|
expect(html).toContain("<table>");
|
|
expect(html).toContain("<pre>");
|
|
});
|
|
|
|
it("strips <script> elements including their content", () => {
|
|
const html = renderMarkdown('Before\n\n<script>alert("pwned")</script>\n\nAfter');
|
|
expect(html).not.toContain("<script");
|
|
expect(html).not.toContain("pwned");
|
|
expect(html).toContain("Before");
|
|
expect(html).toContain("After");
|
|
});
|
|
|
|
it("removes event-handler attributes from allowed elements", () => {
|
|
const html = renderMarkdown('<img src="https://example.com/x.png" onerror="alert(1)">');
|
|
expect(html).not.toContain("onerror");
|
|
expect(html).not.toContain("alert(1)");
|
|
});
|
|
|
|
it("removes javascript: URLs from links", () => {
|
|
const html = renderMarkdown("[click me](javascript:alert(1))");
|
|
expect(html).not.toContain("javascript:");
|
|
expect(html).toContain("click me");
|
|
});
|
|
|
|
it("keeps safe inline HTML like <kbd>", () => {
|
|
const html = renderMarkdown("Press <kbd>Tab</kbd> to move.");
|
|
expect(html).toContain("<kbd>Tab</kbd>");
|
|
});
|
|
});
|