152 lines
5.3 KiB
TypeScript
152 lines
5.3 KiB
TypeScript
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 项。/)
|
||
})
|