/ opencodehub / tests / unit / markdown.test.ts
Swadhin Biswas Feature/ai code reviewer (#73) · 8/2/2026
105a287
126 lines · 3.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import { renderMarkdown } from "@/lib/markdown";
import { describe, expect, it } from "vitest";

describe("renderMarkdown", () => {
  it("renders simple text", async () => {
    const html = await renderMarkdown("Hello world");
    expect(html).toContain("Hello world");
  });

  it("renders headings", async () => {
    const html = await renderMarkdown("# Title\n## Subtitle");
    expect(html).toContain("<h1");
    expect(html).toContain("Title");
    expect(html).toContain("<h2");
    expect(html).toContain("Subtitle");
  });

  it("renders bold and italic", async () => {
    const html = await renderMarkdown("**bold** and *italic*");
    expect(html).toContain("<strong>bold</strong>");
    expect(html).toContain("<em>italic</em>");
  });

  it("renders links", async () => {
    const html = await renderMarkdown("[OpenCodeHub](https://example.com)");
    expect(html).toContain("<a");
    expect(html).toContain("https://example.com");
  });

  it("renders code blocks", async () => {
    const html = await renderMarkdown("```js\nconst x = 1;\n```");
    expect(html).toContain("<code");
    expect(html).toContain("const");
    expect(html).toContain("x");
  });

  it("renders inline code", async () => {
    const html = await renderMarkdown("Use `npm install` to install");
    expect(html).toContain("<code");
    expect(html).toContain("npm install");
  });

  it("renders unordered lists", async () => {
    const html = await renderMarkdown("- Item 1\n- Item 2\n- Item 3");
    expect(html).toContain("<ul");
    expect(html).toContain("<li");
    expect(html).toContain("Item 1");
  });

  it("renders ordered lists", async () => {
    const html = await renderMarkdown("1. First\n2. Second");
    expect(html).toContain("<ol");
    expect(html).toContain("First");
  });

  it("renders GFM tables", async () => {
    const md = `
| Column A | Column B |
|----------|----------|
| Val 1    | Val 2    |
    `.trim();
    const html = await renderMarkdown(md);
    expect(html).toContain("<table");
    expect(html).toContain("Column A");
    expect(html).toContain("Val 1");
  });

  it("renders GFM task lists", async () => {
    const md = "- [x] Done\n- [ ] Todo";
    const html = await renderMarkdown(md);
    expect(html).toContain("Done");
    expect(html).toContain("Todo");
  });

  it("renders GFM strikethrough", async () => {
    const html = await renderMarkdown("~~deleted~~");
    expect(html).toContain("<del");
    expect(html).toContain("deleted");
  });

  it("sanitizes dangerous html", async () => {
    const html = await renderMarkdown('<script>alert("xss")</script>');
    expect(html).not.toContain("<script");
  });

  it("removes dangerous attributes", async () => {
    const html = await renderMarkdown('<img onerror="alert(1)" src="x">');
    expect(html).not.toContain("onerror");
  });

  it("handles empty string", async () => {
    const html = await renderMarkdown("");
    expect(typeof html).toBe("string");
  });

  it("handles whitespace-only content", async () => {
    const html = await renderMarkdown("   \n\n   ");
    expect(typeof html).toBe("string");
  });

  it("renders cross-repo issue references", async () => {
    const html = await renderMarkdown("See owner/repo#123 for details");
    // The remarkCrossRepoLinks plugin should convert owner/repo#123 to a link
    expect(html).toContain("owner/repo#123");
  });

  it("renders blockquotes", async () => {
    const html = await renderMarkdown("> This is a quote");
    expect(html).toContain("<blockquote");
    expect(html).toContain("This is a quote");
  });

  it("renders horizontal rules", async () => {
    const html = await renderMarkdown("---");
    expect(html).toContain("<hr");
  });

  it("renders images", async () => {
    const html = await renderMarkdown(
      "![alt text](https://example.com/img.png)",
    );
    expect(html).toContain("<img");
    expect(html).toContain("alt text");
  });
});