Files
Exam-Information-System/tests/document-verification.test.mjs
biss 3e1bced990 全站大数据台账补齐跨页搜索、筛选和分页,包括投档监督、报到审批、成绩复议、公开录取名单等。
后台重构为一级业务域,并将招生录取拆为 5 个二级菜单。
修复成绩等级排名遮挡科目。
成绩单、录取通知书均支持带防伪码和二维码的 PDF 下载。
录取通知书移除“录取专用章”,支持学校自定义模板。
通知书编号采用“学校代码 + 考试代码 + 学校独立流水号”。
完成招生学校报到台账:Y/N/P 状态、暂存、Excel 导入导出、二维码扫描确认。
完成报到提交、计划完成率、补录决定、超级管理员审批和自动公开闭环。
自动公告现已进入公开首页、考生通知及招生学校工作台。
验证结果:
完整 npm test 全部通过。
浏览器端三个角色工作台验收通过。
Excel 模板已实际导出并渲染验证。
两类 PDF 已实际生成、转图检查,二维码、编号和无印章版式正常。
2026-07-22 09:50: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('✓ 文书防伪码稳定性、篡改失效与安全比较测试通过');