gongxiangp2/lib/__tests__/performance-survey-dashboard-export.test.ts
2026-08-06 14:28:26 +08:00

131 lines
4.7 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 ExcelJS from 'exceljs'
import {
buildPerformanceSurveyDashboardWorkbook,
buildPerformanceSurveyExportTable,
choosePerformanceSurveyExportDestination,
sanitizePerformanceSurveyExportFileName,
savePerformanceSurveyDashboardWorkbook,
type PerformanceSurveyDashboardExportData,
} from '@/lib/performance-survey-dashboard-export'
const exportData: PerformanceSurveyDashboardExportData = {
month: '2026-07',
filters: { positionGroupCode: 'brand_creative_manager' },
selectedPositionGroup: { code: 'brand_creative_manager', name: '品牌创意主管' },
positionGroups: [{ code: 'brand_creative_manager', name: '品牌创意主管' }],
templates: [
{ code: 'visual_review', name: '品牌调性视觉评分', maxTotal: 120 },
{ code: 'coordination', name: '跨部门协同', maxTotal: 120 },
{ code: 'cooperation', name: '工作配合度', maxTotal: 120 },
],
public: {
rows: [
{
month: '2026-07',
employee: {
displayName: '伯言',
jobNumber: 'JS15040602',
departmentName: '品牌创意A部',
positionLevel: 'M2',
},
cells: {
visual_review: { score: null, surveyCount: 1, positionGroupCode: 'brand_creative_manager' },
coordination: { score: 114.5, surveyCount: 1, positionGroupCode: 'brand_creative_manager' },
cooperation: { score: 98, surveyCount: 1, positionGroupCode: 'brand_creative_manager' },
},
},
],
},
}
describe('performance survey dashboard xlsx export', () => {
test('keeps numeric scores numeric and marks pending assessments clearly', () => {
const table = buildPerformanceSurveyExportTable(exportData)
expect(table.headers).toEqual([
'序号',
'岗位',
'考核月份',
'姓名',
'工号',
'组织',
'职级',
'品牌调性视觉评分(满分120)',
'跨部门协同(满分120)',
'工作配合度(满分120)',
])
expect(table.rows[0]).toEqual([
1,
'品牌创意主管',
'2026-07',
'伯言',
'JS15040602',
'品牌创意A部',
'M2',
'待评分',
114.5,
98,
])
})
test('creates a WPS-compatible workbook with title, filters and score rows', async () => {
const workbook = await buildPerformanceSurveyDashboardWorkbook(exportData)
const buffer = await workbook.xlsx.writeBuffer()
const reloaded = new ExcelJS.Workbook()
await reloaded.xlsx.load(buffer)
const worksheet = reloaded.worksheets[0]
expect(worksheet.name).toBe('2026-07_品牌创意主管')
expect(worksheet.getCell('A1').value).toBe('2026-07 · 品牌创意主管考核调研得分')
expect(worksheet.getCell('A5').value).toBe(1)
expect(worksheet.getCell('H5').value).toBe('待评分')
expect(worksheet.getCell('I5').value).toBe(114.5)
expect(worksheet.autoFilter).toBe('A4:J4')
})
test('sanitizes file-system reserved characters', () => {
expect(sanitizePerformanceSurveyExportFileName('考核:品牌/设计*主管'))
.toBe('考核_品牌_设计_主管.xlsx')
})
test('keeps the browser context when opening the native save picker', async () => {
const handle = { createWritable: jest.fn() }
const picker = jest.fn(function (this: unknown) {
expect(this).toBe(window)
return Promise.resolve(handle)
})
Object.defineProperty(window, 'showSaveFilePicker', {
configurable: true,
value: picker,
})
await expect(choosePerformanceSurveyExportDestination('考核调研.xlsx'))
.resolves.toEqual({ kind: 'file-system', handle })
expect(picker).toHaveBeenCalledWith(expect.objectContaining({
suggestedName: '考核调研.xlsx',
}))
delete (window as typeof window & { showSaveFilePicker?: unknown }).showSaveFilePicker
})
test('uses a native blob download when the save picker is unavailable', async () => {
const createObjectURL = jest.fn(() => 'blob:performance-survey-export')
const revokeObjectURL = jest.fn()
Object.defineProperty(URL, 'createObjectURL', { configurable: true, value: createObjectURL })
Object.defineProperty(URL, 'revokeObjectURL', { configurable: true, value: revokeObjectURL })
const click = jest.spyOn(HTMLAnchorElement.prototype, 'click').mockImplementation(() => {})
await savePerformanceSurveyDashboardWorkbook(
exportData,
'考核调研_品牌创意主管_2026-07.xlsx',
{ kind: 'download' },
)
expect(createObjectURL).toHaveBeenCalledWith(expect.any(Blob))
expect(click).toHaveBeenCalledTimes(1)
await new Promise((resolve) => window.setTimeout(resolve, 0))
expect(revokeObjectURL).toHaveBeenCalledWith('blob:performance-survey-export')
click.mockRestore()
})
})