const assert = require('node:assert/strict');
const fs = require('node:fs');
const path = require('node:path');
const test = require('node:test');
const NotificationPages = require('../public/js/notification-pages.js');
function notificationFixture(overrides) {
return Object.assign({
notificationId: '2060000000000000001',
genealogyId: '2060000000000000002',
genealogyNo: 'G20260729001',
genealogyName: '叶氏家谱',
senderUserId: '2060000000000000003',
senderNickName: '叶子',
senderPhone: '19100000000',
noticeType: 'family_feed_comment',
noticeTitle: '新的评论',
noticeContent: '有人评论了家族动态',
bizType: 'family_feed_comment',
bizId: '2060000000000000004',
bizSummary: '家族圈评论',
publishTime: '2026-07-29 10:30:00',
readStatus: '0',
readTime: null,
status: '0',
remark: ''
}, overrides || {});
}
test('通知筛选只允许全部、未读和已读三种查询', () => {
assert.deepEqual(NotificationPages.buildNotificationQuery(''), {});
assert.deepEqual(NotificationPages.buildNotificationQuery('0'), { readStatus: '0' });
assert.deepEqual(NotificationPages.buildNotificationQuery('1'), { readStatus: '1' });
assert.deepEqual(NotificationPages.buildNotificationQuery('unsafe'), {});
});
test('通知列表只接受 PC 的非分页数组并规范完整 NotificationView', () => {
const record = notificationFixture();
assert.deepEqual(NotificationPages.normalizeNotifications([record]), [
NotificationPages.normalizeNotification(record)
]);
assert.deepEqual(NotificationPages.normalizeNotifications({ rows: [record] }), []);
assert.equal(NotificationPages.normalizeNotification({
...record,
notificationId: Number('2060000000000000001')
}), null);
assert.equal(NotificationPages.normalizeNotification({
...record,
readStatus: '2'
}), null);
});
test('通知可选业务 ID 接受 null 但拒绝不安全数字', () => {
assert.ok(NotificationPages.normalizeNotification(notificationFixture({
genealogyId: null,
senderUserId: null,
bizId: null
})));
assert.equal(NotificationPages.normalizeNotification(notificationFixture({
bizId: Number('2060000000000000004')
})), null);
});
test('未读数只接受非负安全整数', () => {
assert.equal(NotificationPages.getUnreadCount(3), 3);
assert.equal(NotificationPages.getUnreadCount('3'), 3);
assert.equal(NotificationPages.getUnreadCount(-1), 0);
assert.equal(NotificationPages.getUnreadCount(1.5), 0);
assert.equal(NotificationPages.getUnreadCount(Number.MAX_SAFE_INTEGER + 1), 0);
});
test('通知列表和详情转义正文且不暴露手机号或内部 ID', () => {
const record = NotificationPages.normalizeNotification(notificationFixture({
noticeTitle: '',
noticeContent: '
通知正文'
}));
const rowHtml = NotificationPages.renderNotificationRow(record);
const detailHtml = NotificationPages.renderNotificationDetail(record);
assert.doesNotMatch(rowHtml + detailHtml, /