import React from 'react' import { render, screen } from '@testing-library/react' import '@testing-library/jest-dom' import Statistics from '../../src/pages/Statistics/Statistics' // Mock Taro jest.mock('@tarojs/taro', () => ({ createCanvasContext: jest.fn(() => ({ draw: jest.fn(), stroke: jest.fn(), beginPath: jest.fn(), closePath: jest.fn(), moveTo: jest.fn(), lineTo: jest.fn(), arc: jest.fn(), setFillStyle: jest.fn(), setStrokeStyle: jest.fn(), setLineWidth: jest.fn(), fillText: jest.fn(), setTextAlign: jest.fn(), setTextBaseline: jest.fn(), fill: jest.fn(), translate: jest.fn(), rotate: jest.fn(), scale: jest.fn(), })), getSystemInfoSync: jest.fn(() => ({ pixelRatio: 2, windowWidth: 375, windowHeight: 667, })), ENV_TYPE: { WEAPP: 'WEAPP', SWAN: 'SWAN', ALIPAY: 'ALIPAY', TT: 'TT', QQ: 'QQ', JD: 'JD', }, getEnv: jest.fn(() => 'WEAPP'), })) // Mock React Query jest.mock('@tanstack/react-query', () => ({ useQuery: jest.fn(() => ({ data: null, isLoading: false, error: null, })), })) // Mock mini-charts components jest.mock('@d8d/mini-charts', () => ({ ColumnChart: ({ canvasId, width, height }: any) => (
{canvasId} ({width}x{height})
), PieChart: ({ canvasId, width, height, pieType }: any) => (
{canvasId} ({width}x{height}) {pieType}
), BarChart: ({ canvasId, width, height }: any) => (
{canvasId} ({width}x{height})
), })) // Mock layout components jest.mock('@d8d/yongren-shared-ui/components/YongrenTabBarLayout', () => ({ YongrenTabBarLayout: ({ children, activeKey }: any) => (
{children}
), })) jest.mock('@d8d/mini-shared-ui-components/components/navbar', () => ({ Navbar: ({ title }: any) =>
{title}
, })) // Mock API client jest.mock('../../src/api/enterpriseStatisticsClient', () => ({ enterpriseStatisticsClient: { 'disability-type-distribution': { $get: jest.fn(), }, 'gender-distribution': { $get: jest.fn(), }, 'age-distribution': { $get: jest.fn(), }, 'household-distribution': { $get: jest.fn(), }, 'job-status-distribution': { $get: jest.fn(), }, 'salary-distribution': { $get: jest.fn(), }, }, })) describe('Statistics Page', () => { beforeEach(() => { jest.clearAllMocks() }) it('应该正确渲染统计页面', () => { render() expect(screen.getByTestId('navbar')).toHaveTextContent('数据统计') }) it('应该显示统计卡片', () => { render() expect(screen.getByText('在职人数')).toBeInTheDocument() expect(screen.getByText('平均薪资')).toBeInTheDocument() expect(screen.getByText('在职率')).toBeInTheDocument() expect(screen.getByText('新增人数')).toBeInTheDocument() }) it('应该显示所有图表标题', () => { render() expect(screen.getByText('残疾类型分布')).toBeInTheDocument() expect(screen.getByText('性别分布')).toBeInTheDocument() expect(screen.getByText('年龄分布')).toBeInTheDocument() expect(screen.getByText('户籍省份分布')).toBeInTheDocument() expect(screen.getByText('在职状态统计')).toBeInTheDocument() expect(screen.getByText('薪资分布')).toBeInTheDocument() }) it('应该渲染残疾类型柱状图', () => { const { useQuery } = require('@tanstack/react-query') useQuery.mockImplementation(() => ({ data: { stats: [ { key: '肢体', value: 10, percentage: 35.7 }, { key: '听力', value: 8, percentage: 28.6 }, ], total: 28, }, isLoading: false, })) render() expect(screen.getByTestId('column-chart-disability-type-chart')).toBeInTheDocument() }) it('应该渲染性别分布柱状图', () => { const { useQuery } = require('@tanstack/react-query') useQuery.mockImplementation(() => ({ data: { stats: [ { key: '男', value: 15, percentage: 60 }, { key: '女', value: 10, percentage: 40 }, ], total: 25, }, isLoading: false, })) render() expect(screen.getByTestId('column-chart-gender-chart')).toBeInTheDocument() }) it('应该渲染年龄分布饼图', () => { const { useQuery } = require('@tanstack/react-query') useQuery.mockImplementation(() => ({ data: { stats: [ { key: '18-25岁', value: 5, percentage: 20 }, { key: '26-35岁', value: 10, percentage: 40 }, ], total: 25, }, isLoading: false, })) render() expect(screen.getByTestId('pie-chart-age-chart')).toBeInTheDocument() expect(screen.getByTestId('pie-chart-age-chart')).toHaveAttribute('data-pie-type', 'pie') }) it('应该渲染户籍省份横向柱状图', () => { const { useQuery } = require('@tanstack/react-query') useQuery.mockImplementation(() => ({ data: { stats: [ { key: '广东', value: 10, percentage: 40 }, { key: '湖南', value: 8, percentage: 32 }, ], total: 25, }, isLoading: false, })) render() expect(screen.getByTestId('bar-chart-household-chart')).toBeInTheDocument() }) it('应该渲染在职状态环形图', () => { const { useQuery } = require('@tanstack/react-query') useQuery.mockImplementation(() => ({ data: { stats: [ { key: '在职', value: 20, percentage: 80 }, { key: '离职', value: 5, percentage: 20 }, ], total: 25, }, isLoading: false, })) render() expect(screen.getByTestId('pie-chart-job-status-chart')).toBeInTheDocument() expect(screen.getByTestId('pie-chart-job-status-chart')).toHaveAttribute('data-pie-type', 'ring') }) it('应该渲染薪资分布横向柱状图', () => { const { useQuery } = require('@tanstack/react-query') useQuery.mockImplementation(() => ({ data: { stats: [ { key: '3000-4000', value: 5, percentage: 20 }, { key: '4000-5000', value: 10, percentage: 40 }, ], total: 25, }, isLoading: false, })) render() expect(screen.getByTestId('bar-chart-salary-chart')).toBeInTheDocument() }) it('应该显示加载状态', () => { const { useQuery } = require('@tanstack/react-query') useQuery.mockImplementation(() => ({ data: null, isLoading: true, })) render() expect(screen.getAllByText('加载中...')).toHaveLength(6) }) it('应该显示暂无数据状态', () => { const { useQuery } = require('@tanstack/react-query') useQuery.mockImplementation(() => ({ data: { stats: [], total: 0 }, isLoading: false, })) render() expect(screen.getAllByText('暂无数据')).toHaveLength(6) }) }) describe('数据转换函数', () => { it('convertToColumnData 应该正确转换数据', () => { const stats = [ { key: '类别A', value: 10 }, { key: '类别B', value: 20 }, ] const result = { categories: ['类别A', '类别B'], series: [{ name: '人数', data: [10, 20] }] } expect(result.categories).toEqual(['类别A', '类别B']) expect(result.series[0].data).toEqual([10, 20]) }) it('convertToPieData 应该正确转换数据', () => { const stats = [ { key: '类别A', value: 10 }, { key: '类别B', value: 20 }, ] const result = stats.map(item => ({ name: item.key, data: item.value || 0 })) expect(result).toEqual([ { name: '类别A', data: 10 }, { name: '类别B', data: 20 } ]) }) })