const assert = require('node:assert/strict'); const fs = require('node:fs'); const path = require('node:path'); const test = require('node:test'); const RelativePages = require('../public/js/relative-pages.js'); test('亲友记录页只从 URL 读取安全的真实家谱和记录编号', () => { assert.equal( RelativePages.getCurrentGenealogyId('?genealogyId=2060000000000000001&relativeId=2060000000000000002'), '2060000000000000001' ); assert.equal( RelativePages.getCurrentRelativeId('?genealogyId=2060000000000000001&relativeId=2060000000000000002'), '2060000000000000002' ); assert.equal(RelativePages.getCurrentGenealogyId(''), ''); assert.equal(RelativePages.getCurrentRelativeId('?relativeId=unsafe'), ''); }); test('亲友记录写入只构造 YAML RelativeRecordBody 并转换后端时间格式', () => { assert.deepEqual(RelativePages.buildRelativeRecordBody({ relativeName: ' 王叔 ', relationName: ' 长辈 ', eventName: ' 寿宴 ', eventTime: '2026-07-24T09:30', giftAmount: '500.5', recordContent: ' 出席 ', mediaOssIds: '2060000000000000003,2060000000000000004', sortOrder: '3', status: '0', relativeId: 'should-not-send', appUserId: 'should-not-send' }), { relativeName: '王叔', relationName: '长辈', eventName: '寿宴', eventTime: '2026-07-24 09:30:00', giftAmount: 500.5, recordContent: '出席', mediaOssIds: '2060000000000000003,2060000000000000004', sortOrder: 3, status: '0' }); }); test('亲友记录校验姓名、金额、时间、附件、排序和可重读状态', () => { assert.equal(RelativePages.validateRelativeRecordBody({ relativeName: '' }), '请填写亲友姓名'); assert.equal( RelativePages.validateRelativeRecordBody(RelativePages.buildRelativeRecordBody({ relativeName: '王叔', giftAmount: '一百' })), '礼金金额必须是有限数字' ); assert.equal( RelativePages.validateRelativeRecordBody(RelativePages.buildRelativeRecordBody({ relativeName: '王叔', giftAmount: '9007199254740993.01' })), '礼金金额超出浏览器可安全提交的精度' ); assert.equal( RelativePages.validateRelativeRecordBody(RelativePages.buildRelativeRecordBody({ relativeName: '王叔', giftAmount: '500.50' })), '' ); assert.equal( RelativePages.validateRelativeRecordBody({ relativeName: '王叔', eventTime: '2026-07-24T09:30:00+08:00' }), '事件时间格式无效' ); assert.equal( RelativePages.validateRelativeRecordBody({ relativeName: '王叔', eventTime: '2026-99-24 09:30:00' }), '事件时间格式无效' ); assert.equal( RelativePages.validateRelativeRecordBody({ relativeName: '王叔', mediaOssIds: '101, 102' }), '附件上传结果无效' ); assert.equal( RelativePages.validateRelativeRecordBody(RelativePages.buildRelativeRecordBody({ relativeName: '王叔', sortOrder: '1.5' })), '排序值必须是安全整数' ); assert.equal( RelativePages.validateRelativeRecordBody({ relativeName: '王叔', status: '1' }), '当前 PC 无法重新读取停用记录,暂不开放停用' ); assert.equal( RelativePages.validateRelativeRecordBody({ relativeName: '王叔', giftAmount: -500.25, status: '0' }), '' ); }); test('亲友记录响应使用 PC RelativeRecordVo 并保留 BigDecimal 字符串', () => { assert.deepEqual(RelativePages.normalizeRelativeRecord({ relativeId: '2060000000000000001', genealogyId: '2060000000000000002', genealogyNo: 'G20260729001', genealogyName: '叶氏家谱', surname: '叶', appUserId: '2060000000000000003', appUserNickName: '叶子', appUserPhone: '19100000000', relativeName: '王叔', relationName: '长辈', eventName: '寿宴', eventTime: '2026-07-24 09:30:00', giftAmount: '500.50', recordContent: '出席', mediaOssIds: '2060000000000000004', sortOrder: 1, status: '0', remark: '往来记录' }), { relativeId: '2060000000000000001', genealogyId: '2060000000000000002', genealogyNo: 'G20260729001', genealogyName: '叶氏家谱', surname: '叶', appUserId: '2060000000000000003', appUserNickName: '叶子', appUserPhone: '19100000000', relativeName: '王叔', relationName: '长辈', eventName: '寿宴', eventTime: '2026-07-24 09:30:00', giftAmount: '500.50', recordContent: '出席', mediaOssIds: '2060000000000000004', sortOrder: 1, status: '0', remark: '往来记录' }); assert.equal(RelativePages.normalizeRelativeRecord({ relativeId: Number('2060000000000000001'), genealogyId: '2', relativeName: '王叔', status: '0' }), null); }); test('亲友记录渲染业务字段但不暴露手机号、OSS ID 或未转义内容', () => { const record = RelativePages.normalizeRelativeRecord({ relativeId: '1', genealogyId: '2', appUserId: '3', appUserNickName: '叶子', appUserPhone: '19100000000', relativeName: '', relationName: '长辈', eventName: '寿宴', eventTime: '2026-07-24 09:30:00', giftAmount: '500.50', recordContent: '出席', mediaOssIds: '4,5', sortOrder: 1, status: '0' }); const html = RelativePages.renderRelativeDetail(record); assert.doesNotMatch(html, /