const assert = require('node:assert/strict');
const fs = require('node:fs');
const path = require('node:path');
const test = require('node:test');
const AppPromotionPages = require('../public/js/app-promotion-pages.js');
const appPage = fs.readFileSync(path.resolve(__dirname, '../app.html'), 'utf8');
const promotionId = '2062179707935264769';
function promotionFixture(overrides) {
return Object.assign({
promotionId,
promotionKey: 'app-download',
promotionTitle: '下载移动端',
promotionDesc: '随时查看家谱内容',
coverOssId: '2062179707935264701',
targetUrl: 'https://example.com/download',
platform: 'all',
sortOrder: 10,
status: '0',
remark: 'internal-only'
}, overrides);
}
test('推广响应只保留 AppPromotionVo 的安全展示字段并保持长 ID 字符串', () => {
assert.deepEqual(AppPromotionPages.normalizePromotion(promotionFixture()), {
promotionId,
promotionTitle: '下载移动端',
promotionDesc: '随时查看家谱内容',
targetUrl: 'https://example.com/download'
});
assert.equal(AppPromotionPages.normalizePromotion(promotionFixture({
promotionId: Number.MAX_SAFE_INTEGER + 1
})), null);
});
test('推广响应拒绝停用记录和空标题', () => {
assert.equal(AppPromotionPages.normalizePromotion(promotionFixture({ status: '1' })), null);
assert.equal(AppPromotionPages.normalizePromotion(promotionFixture({ promotionTitle: ' ' })), null);
});
test('推广列表只接受直接数组且任一非法元素使整批失败', () => {
assert.equal(AppPromotionPages.normalizePromotionList([promotionFixture()]).length, 1);
assert.deepEqual(AppPromotionPages.normalizePromotionList([]), []);
assert.deepEqual(AppPromotionPages.normalizePromotionList({
rows: [promotionFixture()]
}), []);
assert.deepEqual(AppPromotionPages.normalizePromotionList([
promotionFixture(),
promotionFixture({ promotionId: '' })
]), []);
});
test('推广链接只允许绝对 HTTP 或 HTTPS 地址', () => {
assert.equal(
AppPromotionPages.normalizeTargetUrl(' https://example.com/download '),
'https://example.com/download'
);
assert.equal(AppPromotionPages.normalizeTargetUrl('http://example.com'), 'http://example.com/');
['javascript:alert(1)', 'data:text/html,test', '/download', 'download.html', ''].forEach((value) => {
assert.equal(AppPromotionPages.normalizeTargetUrl(value), '');
});
});
test('推广卡片转义响应并隐藏 OSS ID、后台键、排序、状态和备注', () => {
const html = AppPromotionPages.renderPromotionList([promotionFixture({
promotionTitle: '',
promotionDesc: '
',
coverOssId: 'secret-oss',
promotionKey: 'secret-key',
remark: 'secret-remark'
})]);
assert.match(html, /<script>/);
assert.match(html, /<img src=x>/);
assert.match(html, /target="_blank"/);
assert.match(html, /rel="noopener noreferrer"/);
assert.doesNotMatch(
html,
/