import assert from 'node:assert/strict'; import { admissionNoticeCode, resolveDocumentVerificationSecret, safeCodeEqual, scoreReportCode } from '../src/security/document-verification.mjs'; const secret = 'test-document-verification-secret-32-characters'; const exam = { id: 'exam_1' }; const registration = { id: 'registration_1', userId: 'candidate_1' }; const results = [ { subjectId: 'math', score: 118, publishedAt: '2026-07-20T08:00:00.000Z' }, { subjectId: 'chinese', score: 112, publishedAt: '2026-07-20T08:00:00.000Z' } ]; const scoreCode = scoreReportCode(secret, registration, exam, results); const reorderedCode = scoreReportCode(secret, registration, exam, [...results].reverse()); const changedScoreCode = scoreReportCode(secret, registration, exam, [{ ...results[0], score: 119 }, results[1]]); assert.match(scoreCode, /^SR-[A-F0-9]{24}$/); assert.equal(scoreCode, reorderedCode, '科目返回顺序不应改变同一成绩单的防伪码'); assert.notEqual(scoreCode, changedScoreCode, '成绩变化必须使旧防伪码失效'); assert.equal(safeCodeEqual(scoreCode, scoreCode.toLowerCase()), true); assert.equal(safeCodeEqual(scoreCode, `${scoreCode}0`), false); const placement = { id: 'placement_1', userId: 'candidate_1', schoolId: 'school_1', payload: { categoryCode: 'general', noticeNumber: 'AD01-EX-2026-000001' }, updatedAt: '2026-07-21T08:00:00.000Z' }; const noticeCode = admissionNoticeCode(secret, placement, exam); const movedSchoolCode = admissionNoticeCode(secret, { ...placement, schoolId: 'school_2' }, exam); const changedNumberCode = admissionNoticeCode(secret, { ...placement, payload: { ...placement.payload, noticeNumber: 'AD01-EX-2026-000002' } }, exam); assert.match(noticeCode, /^AN-[A-F0-9]{24}$/); assert.notEqual(noticeCode, movedSchoolCode, '录取学校变化必须使旧通知书防伪码失效'); assert.notEqual(noticeCode, changedNumberCode, '录取通知书编号变化必须使旧防伪码失效'); assert.throws( () => resolveDocumentVerificationSecret({ NODE_ENV: 'production', DOCUMENT_VERIFICATION_SECRET: 'too-short' }), /至少 32 个字符/, '生产环境不得静默使用弱密钥或开发回退值' ); assert.equal( resolveDocumentVerificationSecret({ NODE_ENV: 'production', DOCUMENT_VERIFICATION_SECRET: secret }), secret ); console.log('✓ 文书防伪码稳定性、篡改失效与安全比较测试通过');