100 lines
4.0 KiB
TypeScript
100 lines
4.0 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',
|
||
},
|
||
}
|
||
: {
|
||
success: true,
|
||
data: {
|
||
totalUploads: 30,
|
||
firstPassApproved: 11,
|
||
rate: 36.7,
|
||
statusBreakdown: { approved: 11, revisionRequired: 7, pendingReview: 10, unknown: 2 },
|
||
readAt: '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('36.7%')).toBeInTheDocument()
|
||
expect(screen.getByText('V1通过 11 / 全部 30')).toBeInTheDocument()
|
||
expect(screen.getByText('实时读取')).toBeInTheDocument()
|
||
expect(screen.getAllByText('每小时同步').length).toBeGreaterThan(0)
|
||
expect(screen.getAllByText('示例值')).toHaveLength(3)
|
||
|
||
for (const label of ['进行中项目', '本月上新', '按时交付', '首轮通过', '团队负荷', '风险']) {
|
||
expect(screen.getByRole('heading', { level: 3, name: label })).toBeInTheDocument()
|
||
}
|
||
|
||
for (const value of ['2338', '8/13', '94.6%', '36.7%', '87%', '4项']) {
|
||
expect(screen.getByText(value)).toBeInTheDocument()
|
||
}
|
||
|
||
expect(screen.getByText('已完成 8 · 进行中 5')).toBeInTheDocument()
|
||
|
||
expect(screen.getAllByText('公式待接入')).toHaveLength(3)
|
||
expect(screen.getAllByText('钉钉流程快照').length).toBeGreaterThan(0)
|
||
expect(screen.getByText('口径已定义')).toBeInTheDocument()
|
||
expect(screen.getAllByText('查看明细')).toHaveLength(6)
|
||
const onTimeDelivery = screen.getByRole('link', { name: '查看按时交付明细' })
|
||
expect(within(onTimeDelivery).getByLabelText('按时交付示例值94.6%,黄色区间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.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(3)
|
||
expect(screen.queryByText('82.3%')).not.toBeInTheDocument()
|
||
expect(screen.getAllByText('数据未加载')).toHaveLength(3)
|
||
})
|
||
})
|