GuDingZiChan/backend/src/services/__tests__/hrSyncService.test.ts

152 lines
5.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 项。/)
})