123 lines
4.9 KiB
TypeScript
123 lines
4.9 KiB
TypeScript
import { render, screen, within } from '@testing-library/react'
|
||
import CoreMetricsDashboard from './CoreMetricsDashboard'
|
||
|
||
jest.mock('next-auth/react', () => ({
|
||
useSession: () => ({ data: { user: { name: '本地超级管理员' } } }),
|
||
signOut: jest.fn(),
|
||
}))
|
||
|
||
describe('CoreMetricsDashboard', () => {
|
||
beforeEach(() => {
|
||
global.fetch = jest.fn().mockImplementation(async (url: string) => ({
|
||
ok: true,
|
||
json: async () => url.includes('ongoing-projects')
|
||
? {
|
||
success: true,
|
||
data: {
|
||
total: 2338,
|
||
lastSyncedAt: '2026-08-14T02:00:00.000Z',
|
||
syncStatus: 'ready',
|
||
},
|
||
}
|
||
: url.includes('monthly-launches')
|
||
? {
|
||
success: true,
|
||
data: {
|
||
completed: 8,
|
||
ongoing: 5,
|
||
total: 13,
|
||
monthStart: '2026-07-31T16:00:00.000Z',
|
||
monthEnd: '2026-08-31T16:00:00.000Z',
|
||
lastSyncedAt: '2026-08-14T02:00:00.000Z',
|
||
syncStatus: 'ready',
|
||
},
|
||
}
|
||
: url.includes('on-time-delivery')
|
||
? {
|
||
success: true,
|
||
data: {
|
||
onTime: 12,
|
||
overtime: 1,
|
||
pending: 0,
|
||
total: 13,
|
||
rate: 92.3,
|
||
monthStart: '2026-07-31T16:00:00.000Z',
|
||
monthEnd: '2026-08-31T16:00:00.000Z',
|
||
lastSyncedAt: '2026-08-14T02:00:00.000Z',
|
||
syncStatus: 'ready',
|
||
},
|
||
}
|
||
: {
|
||
success: true,
|
||
data: {
|
||
totalUploads: 30,
|
||
totalApproved: 15,
|
||
firstPassApproved: 11,
|
||
rate: 73.3,
|
||
statusBreakdown: { approved: 11, revisionRequired: 7, pendingReview: 10, unknown: 2 },
|
||
readAt: '2026-08-14T02:00:00.000Z',
|
||
syncStatus: 'ready',
|
||
lastSyncedAt: '2026-08-14T02:00:00.000Z',
|
||
},
|
||
},
|
||
})) as jest.Mock
|
||
})
|
||
|
||
afterEach(() => {
|
||
jest.restoreAllMocks()
|
||
})
|
||
|
||
it('展示真实流程指标、首轮通过率与其余两项诚实的示例状态', async () => {
|
||
render(<CoreMetricsDashboard />)
|
||
|
||
expect(screen.getByRole('heading', { level: 1, name: '核心指标' })).toBeInTheDocument()
|
||
expect(screen.queryByRole('complementary', { name: '数据接入说明' })).not.toBeInTheDocument()
|
||
expect(await screen.findByText('73.3%')).toBeInTheDocument()
|
||
expect(screen.getByText('V1通过 11 / 已通过 15')).toBeInTheDocument()
|
||
expect(screen.getByText('作品过稿后台')).toBeInTheDocument()
|
||
expect(screen.getAllByText('每小时同步').length).toBeGreaterThan(0)
|
||
expect(screen.getAllByText('示例值')).toHaveLength(2)
|
||
|
||
for (const label of ['进行中项目', '本月上新', '按时交付', '首轮通过', '团队负荷', '风险']) {
|
||
expect(screen.getByRole('heading', { level: 3, name: label })).toBeInTheDocument()
|
||
}
|
||
|
||
for (const value of ['2338', '8/13', '92.3%', '73.3%', '87%', '4项']) {
|
||
expect(screen.getByText(value)).toBeInTheDocument()
|
||
}
|
||
|
||
expect(screen.getByText('本月已完结 8 · 当前进行中 5')).toBeInTheDocument()
|
||
|
||
expect(screen.getAllByText('公式待接入')).toHaveLength(2)
|
||
expect(screen.getAllByText('钉钉流程快照').length).toBeGreaterThan(0)
|
||
expect(screen.getByText('未超时 12 / 本月完结 13')).toBeInTheDocument()
|
||
expect(screen.getAllByText('查看明细')).toHaveLength(5)
|
||
expect(screen.getByText('查看所有作品明细')).toBeInTheDocument()
|
||
const onTimeDelivery = screen.getByRole('link', { name: '查看按时交付明细' })
|
||
expect(within(onTimeDelivery).getByLabelText('按时交付当前值92.3%,黄色区间90%–95%')).toHaveClass('text-[#a88a00]')
|
||
expect(within(onTimeDelivery).queryByText('黄色区间 · 90%–95%')).not.toBeInTheDocument()
|
||
expect(screen.getByRole('link', { name: '查看进行中项目明细' })).toHaveAttribute(
|
||
'href',
|
||
'/workspaces/dashboard/core-metrics/ongoing-projects',
|
||
)
|
||
expect(screen.getByRole('link', { name: '查看风险明细' })).toHaveAttribute(
|
||
'href',
|
||
'/workspaces/dashboard/core-metrics/risks',
|
||
)
|
||
expect(screen.getByRole('link', { name: '查看所有作品明细' })).toHaveAttribute(
|
||
'href',
|
||
'/workspaces/dashboard/core-metrics/first-pass-rate',
|
||
)
|
||
expect(screen.queryByRole('link', { name: /返回部门看板/ })).not.toBeInTheDocument()
|
||
})
|
||
|
||
it('数据接口失败时不保留虚构百分比', async () => {
|
||
global.fetch = jest.fn().mockResolvedValue({ ok: false, json: async () => ({ success: false }) }) as jest.Mock
|
||
render(<CoreMetricsDashboard />)
|
||
|
||
expect(await screen.findAllByText('读取失败')).toHaveLength(4)
|
||
expect(screen.queryByText('82.3%')).not.toBeInTheDocument()
|
||
expect(screen.getAllByText('数据未加载')).toHaveLength(4)
|
||
})
|
||
})
|