gongxiangp2/lib/__tests__/performance-survey-templates.test.ts

80 lines
3.2 KiB
TypeScript

import {
DEFAULT_PERFORMANCE_SURVEY_TEMPLATES,
calculateAggregateScore,
calculateResponseScores,
} from '@/lib/performance-survey-templates'
describe('performance survey templates', () => {
test('course share template uses the legacy 100-point and 30% weighted scoring rule', () => {
const template = DEFAULT_PERFORMANCE_SURVEY_TEMPLATES.find((item) => item.code === 'course_share')!
const scores = Object.fromEntries(template.questions.map((question) => [question.id, 20]))
const result = calculateResponseScores(template, scores)
expect(template.questions).toHaveLength(5)
expect(template.maxTotal).toBe(100)
expect(template.weight).toBe(0.3)
expect(template.itemName).toBe('课程')
expect(template.respondentNameFallback).toBe('匿名学员')
expect(template.belowBand).toBe('满意度不足 77%,此项考核为 0')
expect(result.totalScore).toBe(100)
expect(result.kpiScore).toBe(120)
expect(result.weightedScore).toBe(36)
})
test('person-period templates use the legacy 120-point and 20% weighted scoring rule', () => {
const template = DEFAULT_PERFORMANCE_SURVEY_TEMPLATES.find((item) => item.code === 'cross_department')!
const scores = Object.fromEntries(template.questions.map((question) => [question.id, 20]))
const result = calculateResponseScores(template, scores)
expect(template.questions).toHaveLength(6)
expect(template.maxTotal).toBe(120)
expect(template.weight).toBe(0.2)
expect(result.totalScore).toBe(120)
expect(result.kpiScore).toBe(120)
expect(result.weightedScore).toBe(24)
})
test('aggregate scoring drops one highest and one lowest response when there are at least three', () => {
const template = DEFAULT_PERFORMANCE_SURVEY_TEMPLATES.find((item) => item.code === 'cross_department')!
const result = calculateAggregateScore(
[
{
totalScore: 60,
createdAt: '2026-07-04T00:00:00.000Z',
scores: Object.fromEntries(template.questions.map((question) => [question.id, 10])),
respondentName: '最低分',
},
{
totalScore: 100,
createdAt: '2026-07-04T00:01:00.000Z',
scores: Object.fromEntries(template.questions.map((question) => [question.id, question.id === 'requirementClarity' ? 18 : 16])),
respondentName: '有效分',
},
{
totalScore: 120,
createdAt: '2026-07-04T00:02:00.000Z',
scores: Object.fromEntries(template.questions.map((question) => [question.id, 20])),
respondentName: '最高分',
},
],
template.scoreBands,
template.weight,
template,
)
expect(result.droppedHighestLowest).toBe(true)
expect(result.effectiveCount).toBe(1)
expect(result.rawAverage).toBe(93.33)
expect(result.trimNote).toBe('已剔除 1 个最高总分和 1 个最低总分')
expect(result.removedHigh?.respondentName).toBe('最高分')
expect(result.removedLow?.respondentName).toBe('最低分')
expect(result.dimensionAverages.requirementClarity).toBe(18)
expect(result.achievementScore).toBe(100)
expect(result.kpiScore).toBe(100)
expect(result.weightedScore).toBe(20)
})
})