// Task 5 失败测试(先于实现):WordPress 正文 HTML 白名单清洗 + SanitizeDiff[] 差异收集。 // 方案取舍(实现侧 JSDoc 为准):清洗本体交 sanitize-html;差异经 onOpenTag 观察钩子 // 按文档序收集(每次调用独立数组,纯函数)。 import { createReadStream } from 'node:fs' import { fileURLToPath } from 'node:url' import { describe, expect, it } from 'vitest' import sanitizeHtml, { type IOptions } from 'sanitize-html' import { parseWxrStream } from '../src/parse/wxr-stream.js' import { deriveMirrorView, SANITIZE_CONFIG, sanitizeBodyHtml, type SanitizeDiff, } from '../src/sanitize/html.js' const FIXTURE = fileURLToPath(new URL('../../../tests/fixtures/wxr/mini.xml', import.meta.url)) /** mini.xml post 101 的 content:encoded 原文(item-to-row 测试同款锚点) */ const MINI_101_BODY = '
Body with link and 
ok
') // script 内文随 nonTextTags 语义一并丢弃 expect(result.diffs).toStrictEqual([{ type: 'removed-tag', tag: 'script', excerpt: 't2
'
const result = sanitizeBodyHtml(dirty)
expect(result.html).toBe('t1
t2fb
')
expect(result.diffs).toStrictEqual([
{ type: 'removed-attr', tag: 'p', attr: 'onclick', excerpt: 'onclick="a()"' },
{ type: 'removed-tag', tag: 'script', excerpt: ''
const first = sanitizeBodyHtml(dirty)
const second = sanitizeBodyHtml(dirty)
expect(second).toStrictEqual(first)
expect(first.diffs).toHaveLength(4) // div.onclick / a.href / script / iframe
})
it('大小写归一:z')
expect(result.html).toBe('z')
expect(result.diffs).toStrictEqual([
{ type: 'removed-tag', tag: 'script', excerpt: ''],
['实体编码协议(: 解码后判定)', 'x'],
['控制字符走私(java\\u0001script:)', 'x'],
['NULL 字节走私(java\\u0000script:)', 'x'],
['URL 注释走私(javascript:)', 'x'],
['未加引号属性', 'x'],
['重复属性(解析器首值胜出)', 'd'],
['混合大小写标签与属性', 'y'],
['iframe + 事件属性混合', ''],
['多重违例混合', 't1
t2
'],
['data: 逗号内嵌 srcset(部分重写)', '
'],
['不可解析 srcset(,,,,,,)', '
'],
['深嵌套 30 层 + 内层违例', `deep
${'