const assert = require('node:assert/strict'); const fs = require('node:fs'); const path = require('node:path'); const test = require('node:test'); const GrowthPages = require('../public/js/growth-pages.js'); test('成长记录页只从 URL 读取安全的真实家谱和记录编号', () => { assert.equal( GrowthPages.getCurrentGenealogyId('?genealogyId=2060000000000000001&recordId=2060000000000000002'), '2060000000000000001' ); assert.equal( GrowthPages.getCurrentRecordId('?genealogyId=2060000000000000001&recordId=2060000000000000002'), '2060000000000000002' ); assert.equal(GrowthPages.getCurrentGenealogyId(''), ''); assert.equal(GrowthPages.getCurrentRecordId('?recordId=unsafe'), ''); }); test('成长记录写入只构造 YAML GrowthRecordBody 字段并转换后端日期格式', () => { assert.deepEqual( GrowthPages.buildGrowthRecordBody({ lineagePersonId: '2060000000000000003', recordType: ' 入学 ', recordTitle: ' 入学记录 ', recordContent: ' 顺利入学 ', recordDate: '2026-07-24', remindTime: '2026-07-24T09:30', mediaOssIds: '2060000000000000004,2060000000000000005', sortOrder: '3', status: '0', recordId: 'should-not-send', appUserId: 'should-not-send' }), { lineagePersonId: '2060000000000000003', recordType: '入学', recordTitle: '入学记录', recordContent: '顺利入学', recordDate: '2026-07-24', remindTime: '2026-07-24 09:30:00', mediaOssIds: '2060000000000000004,2060000000000000005', sortOrder: 3, status: '0' } ); }); test('成长记录校验标题、选择器 ID、附件、排序和可重读状态', () => { assert.equal(GrowthPages.validateGrowthRecordBody({ recordTitle: '' }), '请填写记录标题'); assert.equal( GrowthPages.validateGrowthRecordBody({ recordTitle: '记录', lineagePersonId: 'A-1' }), '请选择有效的世系人物' ); assert.equal( GrowthPages.validateGrowthRecordBody({ recordTitle: '记录', mediaOssIds: '101, 102' }), '附件上传结果无效' ); assert.equal( GrowthPages.validateGrowthRecordBody(GrowthPages.buildGrowthRecordBody({ recordTitle: '记录', sortOrder: '1.5' })), '排序值必须是安全整数' ); assert.equal( GrowthPages.validateGrowthRecordBody({ recordTitle: '记录', recordDate: '2026/07/24' }), '记录日期格式无效' ); assert.equal( GrowthPages.validateGrowthRecordBody({ recordTitle: '记录', remindTime: '2026-07-24T09:30:00+08:00' }), '提醒时间格式无效' ); assert.equal( GrowthPages.validateGrowthRecordBody({ recordTitle: '记录', status: '1' }), '当前 PC 无法重新读取停用记录,暂不开放停用' ); assert.equal( GrowthPages.validateGrowthRecordBody({ recordTitle: '记录', mediaOssIds: '101,102', sortOrder: 1, status: '0' }), '' ); }); test('成长记录写后重读必须返回同一条稳定记录', () => { const detail = { recordId: '2060000000000000001', genealogyId: '2060000000000000002', recordTitle: '入学记录', status: '0' }; assert.equal(GrowthPages.matchesSavedRecord(detail, '2060000000000000001'), true); assert.equal(GrowthPages.matchesSavedRecord(detail, '2060000000000000009'), false); assert.equal(GrowthPages.matchesSavedRecord({}, '2060000000000000001'), false); }); test('成长记录响应使用 PC GrowthRecordVo 并拒绝不安全长 ID', () => { assert.deepEqual(GrowthPages.normalizeGrowthRecord({ recordId: '2060000000000000001', genealogyId: '2060000000000000002', genealogyNo: 'G20260729001', genealogyName: '叶氏家谱', surname: '叶', appUserId: '2060000000000000003', appUserNickName: '叶子', appUserPhone: '19100000000', lineagePersonId: '2060000000000000004', lineagePersonNo: 'P001', lineagePersonName: '叶小明', recordType: '入学', recordTitle: '小学入学', recordContent: '

第一天上学

', recordDate: '2026-09-01 00:00:00', remindTime: '2027-09-01 08:30:00', mediaOssIds: '2060000000000000005,2060000000000000006', sortOrder: 1, status: '0', remark: '成长节点' }), { recordId: '2060000000000000001', genealogyId: '2060000000000000002', genealogyNo: 'G20260729001', genealogyName: '叶氏家谱', surname: '叶', appUserId: '2060000000000000003', appUserNickName: '叶子', appUserPhone: '19100000000', lineagePersonId: '2060000000000000004', lineagePersonNo: 'P001', lineagePersonName: '叶小明', recordType: '入学', recordTitle: '小学入学', recordContent: '

第一天上学

', recordDate: '2026-09-01 00:00:00', remindTime: '2027-09-01 08:30:00', mediaOssIds: '2060000000000000005,2060000000000000006', sortOrder: 1, status: '0', remark: '成长节点' }); assert.equal(GrowthPages.normalizeGrowthRecord({ recordId: Number('2060000000000000001'), genealogyId: '2', recordTitle: '标题', status: '0' }), null); }); test('成长记录渲染业务字段但不暴露手机号、OSS ID 或未转义正文', () => { const record = GrowthPages.normalizeGrowthRecord({ recordId: '1', genealogyId: '2', appUserId: '3', appUserNickName: '叶子', appUserPhone: '19100000000', lineagePersonId: '4', lineagePersonName: '叶小明', recordType: '入学', recordTitle: '', recordContent: '第一天上学', recordDate: '2026-09-01 00:00:00', mediaOssIds: '5,6', sortOrder: 1, status: '0' }); const html = GrowthPages.renderGrowthDetail(record); assert.doesNotMatch(html, /