import test from 'node:test' import assert from 'node:assert/strict' import { buildHrSyncPreviewLine, buildHrSyncDingTalkContent, formatBorrowedAssetSummary, resolveHrSyncPersonDisplayName, resolveSourcePersonStatus, shouldNotifyHrSync, shouldUseSourceDepartmentBinding } from '../hrSyncHelpers' test('resolvePersonStatus 默认应将状态值 2 视为 active,仅将状态值 5 视为 inactive', () => { const previous = process.env.HR_SYNC_INACTIVE_STATUS_VALUES delete process.env.HR_SYNC_INACTIVE_STATUS_VALUES try { assert.equal(resolveSourcePersonStatus('2'), 'active') assert.equal(resolveSourcePersonStatus('5'), 'inactive') assert.equal(resolveSourcePersonStatus('3'), 'active') } finally { if (previous === undefined) { delete process.env.HR_SYNC_INACTIVE_STATUS_VALUES } else { process.env.HR_SYNC_INACTIVE_STATUS_VALUES = previous } } }) test('resolvePersonStatus 在显式配置状态值 2 为停用时仍应尊重配置', () => { const previous = process.env.HR_SYNC_INACTIVE_STATUS_VALUES process.env.HR_SYNC_INACTIVE_STATUS_VALUES = '2,5' try { assert.equal(resolveSourcePersonStatus('2'), 'inactive') assert.equal(resolveSourcePersonStatus('5'), 'inactive') assert.equal(resolveSourcePersonStatus('3'), 'active') } finally { if (previous === undefined) { delete process.env.HR_SYNC_INACTIVE_STATUS_VALUES } else { process.env.HR_SYNC_INACTIVE_STATUS_VALUES = previous } } }) test('shouldUseSourceDepartmentBinding 默认应允许状态值 2 和 3 保留源部门', () => { const previous = process.env.HR_SYNC_INACTIVE_STATUS_VALUES delete process.env.HR_SYNC_INACTIVE_STATUS_VALUES try { assert.equal(shouldUseSourceDepartmentBinding('2'), true) assert.equal(shouldUseSourceDepartmentBinding('3'), true) assert.equal(shouldUseSourceDepartmentBinding('5'), false) } finally { if (previous === undefined) { delete process.env.HR_SYNC_INACTIVE_STATUS_VALUES } else { process.env.HR_SYNC_INACTIVE_STATUS_VALUES = previous } } }) test('resolvePersonStatus 在状态文案包含离职语义时应返回 inactive', () => { const previousKeywords = process.env.HR_SYNC_INACTIVE_STATUS_KEYWORDS process.env.HR_SYNC_INACTIVE_STATUS_KEYWORDS = '离职,停用,inactive' try { assert.equal(resolveSourcePersonStatus('离职'), 'inactive') assert.equal(resolveSourcePersonStatus('已停用'), 'inactive') assert.equal(resolveSourcePersonStatus('Inactive'), 'inactive') assert.equal(resolveSourcePersonStatus('在职'), 'active') } finally { process.env.HR_SYNC_INACTIVE_STATUS_KEYWORDS = previousKeywords } }) test('formatBorrowedAssetSummary 会按“编码 / 名称”输出并在超出数量时补充总数', () => { const summary = formatBorrowedAssetSummary([ { equipmentCode: 'JS-PC-1001', equipmentName: '主机' }, { equipmentCode: 'JS-MON-2001', equipmentName: '显示器' }, { equipmentCode: 'JS-KB-3001', equipmentName: '键盘' }, { equipmentCode: 'JS-MS-4001', equipmentName: '鼠标' } ]) assert.equal(summary, 'JS-PC-1001 / 主机、JS-MON-2001 / 显示器、JS-KB-3001 / 键盘 等 4 项') }) test('resolveHrSyncPersonDisplayName 会优先返回花名', () => { assert.equal( resolveHrSyncPersonDisplayName({ nickname: '三藏', realName: '张亮' }), '三藏' ) assert.equal( resolveHrSyncPersonDisplayName({ nickname: '', realName: '张亮' }), '张亮' ) }) test('buildHrSyncPreviewLine 会优先使用结构化资产生成预览行', () => { const line = buildHrSyncPreviewLine({ changeType: 'person_deactivated', title: '人员离职/停用:三藏', detail: '该人员已不在本次同步名单中,请行政确认是否还存在资产交接或借还处理。', afterSnapshot: { assets: [ { equipmentCode: 'JS-PC-1001', equipmentName: '主机' }, { equipmentCode: 'JS-MON-2001', equipmentName: '显示器' } ] } }) assert.equal(line, '人员离职/停用:三藏(名下资产:JS-PC-1001 / 主机、JS-MON-2001 / 显示器)') }) test('buildHrSyncPreviewLine 在没有结构化资产时仍兼容旧的详情文本', () => { const line = buildHrSyncPreviewLine({ changeType: 'person_position_changed', title: '岗位变动:悟空', detail: '岗位已从“摄影师”调整为“导演”。 名下资产:JS-PC-2001 / 主机。' }) assert.equal(line, '岗位变动:悟空(名下资产:JS-PC-2001 / 主机)') }) test('花名册同步无变化只保存日志,有变化或失败才通知管理员', () => { assert.equal(shouldNotifyHrSync('success', 0), false) assert.equal(shouldNotifyHrSync('success', 2), true) assert.equal(shouldNotifyHrSync('failed', 0), true) }) test('花名册钉钉汇总按时间、结果和待处理内容排版', () => { const content = buildHrSyncDingTalkContent({ status: 'success', occurredAt: new Date('2026-07-16T02:00:00.000Z'), changesCount: 3, summary: '新增人员 2 项,部门变化 1 项。' }) assert.match(content, /\*\*同步时间:\*\* 2026年7月16日 10:00/) assert.match(content, /\*\*执行结果:\*\* 发现 3 项变化,需要管理员核对/) assert.match(content, /\*\*待处理内容:\*\* 新增人员 2 项,部门变化 1 项。/) })