Files
EIS-dotnet/tests/document-verification.test.mjs
T
2026-07-22 18:22:52 +08:00

45 lines
2.3 KiB
JavaScript

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('✓ 文书防伪码稳定性、篡改失效与安全比较测试通过');