import { changeField } from '@/test-utils/select'
import { fireEvent, render, screen } from '@testing-library/react'
import type { OnTimeDeliveryWorkflowItem } from '@/lib/ding-workflow-sync'
import OnTimeDeliveryInsightsView from './OnTimeDeliveryInsights'
const mockPush = jest.fn()
jest.mock('next/navigation', () => ({
usePathname: () => '/workspaces/dashboard/core-metrics/on-time-delivery',
useRouter: () => ({ push: mockPush }),
}))
const ART_PROCESS_CODE = 'PROC-3571C915-0506-4490-A91A-8AA7EA33F838'
const CONTENT_PROCESS_CODE = 'PROC-AE9FF3E1-A442-4E6A-85CF-0F2B86409673'
function buildItem(
id: string,
processCode: string,
assessmentStatus: 'on_time' | 'overtime' | 'pending',
options: { reviewFinishedAt?: string; assessmentFinishedAt?: string | null } = {},
): OnTimeDeliveryWorkflowItem {
const isContent = processCode === CONTENT_PROCESS_CODE
return {
id,
businessId: `BIZ-${id}`,
title: isContent ? `内容流程-${id}` : `美术流程-${id}`,
status: 'COMPLETED',
originatorUserId: `user-${id}`,
originatorDeptName: '品牌中心',
sourceCreatedAt: '2026-08-01T00:00:00.000Z',
sourceUpdatedAt: '2026-08-03T00:00:00.000Z',
activeTaskCount: 0,
taskCount: 2,
schemeFieldCount: 3,
latestTaskStatus: 'COMPLETED',
processCode,
projectType: isContent ? '内容视频和图片拍摄' : '美术设计流程',
brand: '亿家达',
requesterName: '测试需求人',
requesterDepartment: '品牌中心',
initiatorName: '测试发起人',
initiatorDepartment: '运营中心A',
formFields: {
platform: null,
brand: null,
category: null,
spu: null,
demandType: null,
standardOutputDeadline: null,
sourceType: null,
taskType: null,
installVideo: null,
quantity: null,
cameraQuantity: null,
planningTaskStats: null,
graphicTaskStats: null,
imageTaskStats: null,
},
assignmentNodeLabel: isContent ? '内容主管分配任务' : '品牌策划主管分配任务',
assignmentStartedAt: '2026-08-01T00:00:00.000Z',
reviewNodeLabel: isContent ? '编导审核' : '品牌策划主管审核',
reviewFinishedAt: options.reviewFinishedAt || '2026-08-03T00:00:00.000Z',
activeTasks: [],
result: 'AGREE',
sourceFinishedAt: '2026-08-03T00:00:00.000Z',
assessment: {
status: assessmentStatus,
standardDuration: 3,
durationUnit: isContent ? 'hour' : 'day',
actualDuration: assessmentStatus === 'pending' ? null : 2,
startedAt: '2026-08-01T00:00:00.000Z',
finishedAt: options.assessmentFinishedAt === undefined
? '2026-08-03T00:00:00.000Z'
: options.assessmentFinishedAt,
startNodeLabel: isContent ? '内容主管分配任务' : '品牌策划主管分配任务',
endNodeLabel: isContent ? '编导审核' : '品牌策划主管审核',
},
}
}
describe('OnTimeDeliveryInsightsView', () => {
beforeEach(() => mockPush.mockClear())
it('按全部、美术和内容流程切换公式、数量与明细', () => {
render(
,
)
expect(screen.getByText('当前口径:2 ÷ 3 = 66.7% · 超时 1')).toBeInTheDocument()
expect(screen.getByRole('tab', { name: '筛选全部流程,共3条' })).toHaveAttribute('aria-selected', 'true')
fireEvent.click(screen.getByRole('tab', { name: '筛选内容视频流程,共1条' }))
expect(screen.getByText('当前口径:1 ÷ 1 = 100% · 超时 0')).toBeInTheDocument()
expect(screen.getByRole('tab', { name: '筛选内容视频流程,共1条' })).toHaveClass('bg-[#e7f3ff]')
expect(screen.getByText('内容流程-content-on-time')).toBeInTheDocument()
expect(screen.queryByText('美术流程-art-on-time')).not.toBeInTheDocument()
fireEvent.click(screen.getByRole('tab', { name: '筛选美术设计流程,共2条' }))
expect(screen.getByText('当前口径:1 ÷ 2 = 50% · 超时 1')).toBeInTheDocument()
expect(screen.getByText('美术流程-art-overtime')).toBeInTheDocument()
expect(screen.queryByText('内容流程-content-on-time')).not.toBeInTheDocument()
})
it('排除待计算流程,并只纳入本月审核节点完成的已判定流程', () => {
render(
,
)
expect(screen.getByText('当前口径:1 ÷ 2 = 50% · 超时 1')).toBeInTheDocument()
expect(screen.getByRole('tab', { name: '筛选全部流程,共2条' })).toBeInTheDocument()
expect(screen.queryByText('内容流程-pending')).not.toBeInTheDocument()
expect(screen.queryByText('内容流程-reviewed-last-month')).not.toBeInTheDocument()
expect(screen.queryByText('内容流程-missing-review-time')).not.toBeInTheDocument()
})
it('按月份筛选并更新按时交付明细期间', () => {
render(
,
)
expect(screen.getByRole('form', { name: '按时交付日期筛选' })).toBeInTheDocument()
changeField(screen.getByRole('combobox', { name: '选择统计月份' }), {
target: { value: '2026-07' },
})
expect(mockPush).toHaveBeenCalledWith(
'/workspaces/dashboard/core-metrics/on-time-delivery?month=2026-07',
)
})
})