41 lines
2.3 KiB
JavaScript
41 lines
2.3 KiB
JavaScript
import test from 'node:test'
|
||
import assert from 'node:assert/strict'
|
||
import { renderMarkdown } from '../src/lib/markdown.ts'
|
||
|
||
test('renders the reported Chinese bold text without showing formatting markers', () => {
|
||
const source = '**昵称:会变成美少女 小红书号:49575364531**(IP 广东;13 关注 / 1.4 万粉丝 / 29.6 万获赞与收藏,标签“潮流博主”)。'
|
||
const html = renderMarkdown(source)
|
||
assert.match(html, /<strong>昵称:会变成美少女 小红书号:49575364531<\/strong>(IP 广东/)
|
||
assert(!html.includes('**'))
|
||
})
|
||
|
||
test('renders lists, headings, quotes, code, tables and line breaks', () => {
|
||
const html = renderMarkdown('# 方案\n\n1. **确认预算**\n2. 使用 `app_id`\n\n> 等待确认\n\n```js\nconst value = "<script>"\n```\n\n| 项目 | 数量 |\n| --- | --- |\n| 盒子 | 500 |\n\n第一行\n第二行')
|
||
for (const tag of ['<h1>', '<ol>', '<strong>', '<blockquote>', '<code>', '<pre>', '<table>', '<br>']) assert(html.includes(tag), `missing ${tag}`)
|
||
assert(html.includes('<div class="markdown-table">'))
|
||
assert.match(html, /<script>/)
|
||
})
|
||
|
||
test('streams incomplete markdown without losing source text and formats it once complete', () => {
|
||
assert.match(renderMarkdown('**确认'), /\*\*确认/)
|
||
assert.match(renderMarkdown('**确认预算**'), /<strong>确认预算<\/strong>/)
|
||
assert.match(renderMarkdown('```txt\n未结束代码'), /<pre><code class="language-txt">未结束代码/)
|
||
})
|
||
|
||
test('escapes raw HTML and refuses executable or local link schemes', () => {
|
||
const html = renderMarkdown('<script>alert(1)</script>\n<img src=x onerror=alert(1)>\n\n[危险](javascript:alert(1)) [文件](file:///C:/secret) [数据](data:text/html,test)')
|
||
assert(!/<script|<img|<iframe/i.test(html))
|
||
assert(!/<a\b/.test(html))
|
||
assert.match(html, /<script>/)
|
||
assert.match(html, /<img/)
|
||
})
|
||
|
||
test('external links and image links cannot navigate the chat or load remote images', () => {
|
||
const html = renderMarkdown('[参考](https://example.com/?x=1&y=2 "说明")\n\n')
|
||
assert.equal((html.match(/target="_blank"/g) || []).length, 2)
|
||
assert.equal((html.match(/rel="noopener noreferrer"/g) || []).length, 2)
|
||
assert(!html.includes('<img'))
|
||
assert.match(html, /href="https:\/\/example.com\/image.png"/)
|
||
assert.match(html, /x=1&y=2/)
|
||
})
|