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', ) }) })