const assert = require('node:assert/strict'); const fs = require('node:fs'); const path = require('node:path'); const test = require('node:test'); const JoinReviewPages = require('../public/js/join-review-pages.js'); const genealogyId = '2062179707935264769'; const applyId = '2062179707935264770'; function read(relativePath) { return fs.readFileSync(path.resolve(__dirname, '..', relativePath), 'utf8'); } test('审核页只从当前家谱上下文读取稳定字符串 ID', () => { assert.equal(JoinReviewPages.getCurrentGenealogyId('?genealogyId=' + genealogyId), genealogyId); assert.equal(JoinReviewPages.getCurrentGenealogyId('?genealogyId=unsafe'), ''); assert.equal(JoinReviewPages.getCurrentGenealogyId('?genealogyId=1e21'), ''); }); test('审核请求只构造 status 和可选审核说明', () => { assert.deepEqual(JoinReviewPages.buildJoinAuditBody({ status: '2', auditRemark: ' 资料不一致 ', applyId: 'must-drop', genealogyId: 'must-drop' }), { status: '2', auditRemark: '资料不一致' }); assert.deepEqual(JoinReviewPages.buildJoinAuditBody({ status: '1', auditRemark: ' ' }), { status: '1' }); assert.equal(JoinReviewPages.validateJoinAuditBody({ status: '1' }), ''); assert.equal(JoinReviewPages.validateJoinAuditBody({ status: '2', auditRemark: '因'.repeat(500) }), ''); assert.match(JoinReviewPages.validateJoinAuditBody({ status: '0' }), /审核状态/); assert.match(JoinReviewPages.validateJoinAuditBody({ status: '2', auditRemark: '因'.repeat(501) }), /500/); }); test('待审核列表隐藏内部 ID 和账号手机号,只有管理者可见操作', () => { const data = [{ applyId, genealogyId, genealogyName: '叶氏家谱', applicantName: '<叶子>', phone: '19181970173', relationDesc: '族亲', applyReason: '申请加入', status: '0', appUserId: 'secret-user', appUserPhone: 'secret-account-phone', inviterUserId: 'secret-inviter', auditUserId: 'secret-auditor' }]; const managerHtml = JoinReviewPages.renderPendingJoinApplies(data, true); const memberHtml = JoinReviewPages.renderPendingJoinApplies(data, false); assert.match(managerHtml, /<叶子>/); assert.match(managerHtml, /19181970173/); assert.match(managerHtml, new RegExp('data-join-audit-id="' + applyId + '"')); assert.match(managerHtml, /data-join-audit-status="1"/); assert.match(managerHtml, /data-join-audit-status="2"/); assert.doesNotMatch(memberHtml, /data-join-audit-id|data-join-audit-status/); assert.doesNotMatch(managerHtml, /secret-user|secret-account-phone|secret-inviter|secret-auditor/); }); test('审核页开放真实 PC 管理行为且不允许手填业务 ID', () => { const page = read('profile-join-review.html'); const script = read('public/js/join-review-pages.js'); assert.doesNotMatch(page, /data-feature-status="pending"|pending-pages\.js/); assert.match(page, /data-join-review-page/); assert.match(page, /data-join-apply-list="pending"/); assert.match(page, /data-join-review-refresh/); assert.match(page, /public\/js\/join-review-pages\.js/); assert.doesNotMatch(page, /name="(?:genealogyId|applyId|appUserId|inviterUserId|auditUserId)"/); assert.match(script, /await api\.genealogyDetail\(/); assert.match(script, /detail\.canManage === true/); assert.match(script, /await api\.auditGenealogyJoinApply\(/); assert.match(script, /await api\.pendingGenealogyJoinApplies\(/); assert.match(script, /审核后申请仍在待审核列表/); });