Files
railwaysystem/build_ui/tests/unit/attendanceSigninEntry.spec.mjs
T

159 lines
6.6 KiB
JavaScript

import assert from 'node:assert';
import {
formatAttendanceTag,
formatEnrollmentStatusTag,
isEnrollmentEligibleForSignIn,
computeRosterActionEligibility,
resolveSignInFeedback
} from '../../src/views/train/checkin/attendancePolicy.js';
console.log('=== Testing Real Production Attendance Policy Helper ===');
// 1. 考勤状态语义映射:未签到 (NO_CHECKIN) 必须严格与缺勤 (0) 区分
{
const tagNull = formatAttendanceTag(null);
assert.strictEqual(tagNull.text, '未签到');
assert.strictEqual(tagNull.type, 'info');
const tagUndefined = formatAttendanceTag(undefined);
assert.strictEqual(tagUndefined.text, '未签到');
assert.strictEqual(tagUndefined.type, 'info');
const tagAbsent = formatAttendanceTag(0);
assert.strictEqual(tagAbsent.text, '缺勤');
assert.strictEqual(tagAbsent.type, 'danger');
// 严格区分未签到与缺勤事实
assert.notStrictEqual(tagNull.text, tagAbsent.text);
assert.notStrictEqual(tagNull.type, tagAbsent.type);
console.log('✔ PASS: Production formatAttendanceTag distinguishes NO_CHECKIN from ABSENT (0)');
}
// 2. 学员参训状态展示标签
{
assert.strictEqual(formatEnrollmentStatusTag(0).text, '待报到');
assert.strictEqual(formatEnrollmentStatusTag(1).text, '已报到');
assert.strictEqual(formatEnrollmentStatusTag(2).text, '请假');
assert.strictEqual(formatEnrollmentStatusTag(3).text, '放弃');
assert.strictEqual(formatEnrollmentStatusTag(4).text, '已完成');
console.log('✔ PASS: Production formatEnrollmentStatusTag maps all lifecycle statuses correctly');
}
// 3. 参训生命周期首次签到资格规则断言
{
assert.strictEqual(isEnrollmentEligibleForSignIn(0), false, 'status=0 待报到严禁签到');
assert.strictEqual(isEnrollmentEligibleForSignIn(1), true, 'status=1 已报到在训允许签到');
assert.strictEqual(isEnrollmentEligibleForSignIn(2), true, 'status=2 请假学员当前 Preview Default 允许签到');
assert.strictEqual(isEnrollmentEligibleForSignIn(3), false, 'status=3 放弃学员严禁签到');
assert.strictEqual(isEnrollmentEligibleForSignIn(4), false, 'status=4 已完成学员严禁签到');
assert.strictEqual(isEnrollmentEligibleForSignIn(null), false, 'null 状态 fail closed');
assert.strictEqual(isEnrollmentEligibleForSignIn(undefined), false, 'undefined 状态 fail closed');
assert.strictEqual(isEnrollmentEligibleForSignIn(99), false, '未知状态 fail closed');
console.log('✔ PASS: Production isEnrollmentEligibleForSignIn strictly enforces lifecycle guard');
}
// 4. 生产环境操作按钮可用性 (computeRosterActionEligibility) 覆盖
{
// A. status=0 待报到 + 无打卡记录 -> 签到按钮不存在
const row0 = {
enrollmentId: 100,
enrollmentStatus: 0,
checkinId: null,
attendanceStatus: null,
signInTime: null,
signOutTime: null,
canSignIn: false
};
const act0 = computeRosterActionEligibility(row0);
assert.strictEqual(act0.canSignIn, false, 'status=0 待报到学员签到按钮必须不存在');
assert.strictEqual(act0.canSignOut, false);
assert.strictEqual(act0.canAdjust, false);
// B. status=1 已报到 + NO_CHECKIN -> 签到按钮存在
const row1 = {
enrollmentId: 101,
enrollmentStatus: 1,
checkinId: null,
attendanceStatus: null,
signInTime: null,
signOutTime: null,
canSignIn: true
};
const act1 = computeRosterActionEligibility(row1);
assert.strictEqual(act1.canSignIn, true, 'status=1 已报到学员未签到时签到按钮必须存在');
assert.strictEqual(act1.canSignOut, false);
assert.strictEqual(act1.canAdjust, false);
// C. status=2 请假 + NO_CHECKIN -> 签到按钮存在 (Preview Default)
const row2 = {
enrollmentId: 102,
enrollmentStatus: 2,
checkinId: null,
attendanceStatus: null,
signInTime: null,
signOutTime: null,
canSignIn: true
};
const act2 = computeRosterActionEligibility(row2);
assert.strictEqual(act2.canSignIn, true, 'status=2 请假学员未签到时签到按钮必须存在 (Preview Default)');
assert.strictEqual(act2.canSignOut, false);
assert.strictEqual(act2.canAdjust, false);
// D. status=4 已完成 + NO_CHECKIN -> 签到按钮不存在
const row4 = {
enrollmentId: 104,
enrollmentStatus: 4,
checkinId: null,
attendanceStatus: null,
signInTime: null,
signOutTime: null,
canSignIn: false
};
const act4 = computeRosterActionEligibility(row4);
assert.strictEqual(act4.canSignIn, false, 'status=4 已完成学员签到按钮必须不存在');
assert.strictEqual(act4.canSignOut, false);
assert.strictEqual(act4.canAdjust, false);
// E. 已有合法签到记录 (无论 status 为何) -> 签到按钮禁止重复存在
const rowSignedIn = {
enrollmentId: 101,
enrollmentStatus: 1,
checkinId: 8888,
attendanceStatus: 1,
signInTime: '2026-09-22 08:30:00',
signOutTime: null,
canSignIn: false,
canSignOut: true,
canAdjust: true
};
const actSigned = computeRosterActionEligibility(rowSignedIn);
assert.strictEqual(actSigned.canSignIn, false, '已签到学员绝对不能再次显示签到按钮');
assert.strictEqual(actSigned.canSignOut, true, '已签到未签退学员激活签退');
assert.strictEqual(actSigned.canAdjust, true, '已有打卡记录激活调整');
console.log('✔ PASS: Production computeRosterActionEligibility covers all status button visibility');
}
// 5. 后端生命周期报错反馈解析真实性 (resolveSignInFeedback)
{
const errWaiting = { code: 40085, msg: '学员尚未完成开班报到,禁止录入课次考勤' };
const fbWaiting = resolveSignInFeedback(errWaiting, '张三');
assert.strictEqual(fbWaiting.isSuccess, false);
assert.strictEqual(fbWaiting.message.includes('学员尚未完成开班报到'), true);
assert.strictEqual(fbWaiting.message.includes('成功'), false);
const errCompleted = { code: 40087, msg: '学员参训档案已结训完成,禁止录入课次考勤' };
const fbCompleted = resolveSignInFeedback(errCompleted, '李四');
assert.strictEqual(fbCompleted.isSuccess, false);
assert.strictEqual(fbCompleted.message.includes('学员参训档案已结训完成'), true);
assert.strictEqual(fbCompleted.message.includes('成功'), false);
const errAbandoned = { code: 40086, msg: '学员参训状态已放弃,禁止录入课次考勤' };
const fbAbandoned = resolveSignInFeedback(errAbandoned, '王五');
assert.strictEqual(fbAbandoned.isSuccess, false);
assert.strictEqual(fbAbandoned.message.includes('学员参训状态已放弃'), true);
console.log('✔ PASS: Production resolveSignInFeedback faithfully reports errors without false success');
}
console.log('ALL PRODUCTION ATTENDANCE POLICY TESTS PASSED!');