const assert = require('node:assert/strict');
const fs = require('node:fs');
const path = require('node:path');
const test = require('node:test');
const HelpPages = require('../public/js/help-pages.js');
const helpId = '2062179707935264769';
function read(relativePath) {
return fs.readFileSync(path.resolve(__dirname, '..', relativePath), 'utf8');
}
function helpFixture(overrides) {
return Object.assign({
helpId,
helpCategory: '账号与安全',
helpTitle: '如何修改登录密码?',
helpContent: '进入账号安全页,完成验证后修改密码。',
coverOssId: '2062179707935264701',
sortOrder: 10,
viewCount: 12,
status: '0',
remark: 'internal-only'
}, overrides);
}
test('帮助文章只保留 HelpArticleVo 的安全展示字段并保持长 ID 字符串', () => {
assert.deepEqual(HelpPages.normalizeHelpArticle(helpFixture()), {
helpId,
helpCategory: '账号与安全',
helpTitle: '如何修改登录密码?',
helpContent: '进入账号安全页,完成验证后修改密码。',
viewCount: '12'
});
assert.equal(HelpPages.normalizeHelpArticle(helpFixture({
helpId: Number.MAX_SAFE_INTEGER + 1
})), null);
assert.equal(HelpPages.normalizeHelpArticle(helpFixture({
viewCount: '9007199254740993123'
})).viewCount, '9007199254740993123');
});
test('帮助文章拒绝停用、空标题、空正文和非法浏览量', () => {
assert.equal(HelpPages.normalizeHelpArticle(helpFixture({ status: '1' })), null);
assert.equal(HelpPages.normalizeHelpArticle(helpFixture({ helpTitle: ' ' })), null);
assert.equal(HelpPages.normalizeHelpArticle(helpFixture({ helpContent: '' })), null);
assert.equal(HelpPages.normalizeHelpArticle(helpFixture({ viewCount: -1 })), null);
assert.equal(HelpPages.normalizeHelpArticle(helpFixture({ viewCount: '1.5' })), null);
});
test('帮助文章列表只接受直接数组且任一非法元素使整批失败', () => {
assert.equal(HelpPages.normalizeHelpArticleList([helpFixture()]).length, 1);
assert.deepEqual(HelpPages.normalizeHelpArticleList([]), []);
assert.deepEqual(HelpPages.normalizeHelpArticleList({
rows: [helpFixture()]
}), []);
assert.deepEqual(HelpPages.normalizeHelpArticleList([
helpFixture(),
helpFixture({ helpId: '' })
]), []);
});
test('帮助文章列表和详情转义响应且不暴露 OSS ID、排序、状态和备注', () => {
const article = helpFixture({
helpTitle: '',
helpContent: '
\n第二行',
helpCategory: '分类',
coverOssId: 'secret-oss',
remark: 'secret-remark'
});
const listHtml = HelpPages.renderHelpArticleList([article]);
const detailHtml = HelpPages.renderHelpArticleDetail(article);
assert.match(listHtml, /<script>/);
assert.match(detailHtml, /<img src=x onerror=alert\(1\)>
第二行/);
assert.doesNotMatch(listHtml + detailHtml, /