import React from 'react' import { render, screen, fireEvent, waitFor } from '@testing-library/react' import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import HomePage from '../../src/pages/home/index' // Mock Taro 导航 const mockNavigateTo = jest.fn() jest.mock('@tarojs/taro', () => ({ navigateTo: mockNavigateTo })) // Mock AreaPicker 组件 jest.mock('../../src/components/AreaPicker', () => ({ AreaPicker: jest.fn(({ visible, onClose, onConfirm, value, title }) => { if (!visible) return null return (
{title}
) }) })) // Mock TabBarLayout 组件 jest.mock('@/layouts/tab-bar-layout', () => ({ TabBarLayout: jest.fn(({ children, activeKey, className }) => (
{children}
)) })) // 创建测试用的 QueryClient const createTestQueryClient = () => new QueryClient({ defaultOptions: { queries: { retry: false, }, }, }) // 包装组件 const Wrapper = ({ children }: { children: React.ReactNode }) => { const queryClient = createTestQueryClient() return ( {children} ) } describe('首页组合查询逻辑测试', () => { beforeEach(() => { jest.clearAllMocks() }) describe('组合查询映射逻辑', () => { test('应该正确映射大巴拼车组合查询参数', async () => { render( ) // 设置出发地和目的地 const startLocationButton = screen.getByText('出发地').closest('button') fireEvent.click(startLocationButton!) const confirmButton = screen.getByTestId('area-picker-confirm') fireEvent.click(confirmButton) const endLocationButton = screen.getByText('目的地').closest('button') fireEvent.click(endLocationButton!) fireEvent.click(confirmButton) // 等待状态更新 await waitFor(() => { expect(screen.getAllByText('北京市 北京市 朝阳区')).toHaveLength(2) }) // 默认选择大巴拼车,点击查询 const searchButton = screen.getByText('查询路线') fireEvent.click(searchButton) // 验证导航参数 expect(mockNavigateTo).toHaveBeenCalledWith({ url: expect.stringContaining('vehicleType=bus') }) expect(mockNavigateTo).toHaveBeenCalledWith({ url: expect.stringContaining('travelMode=carpool') }) }) test('应该正确映射商务车组合查询参数', async () => { render( ) // 设置出发地和目的地 const startLocationButton = screen.getByText('出发地').closest('button') fireEvent.click(startLocationButton!) const confirmButton = screen.getByTestId('area-picker-confirm') fireEvent.click(confirmButton) const endLocationButton = screen.getByText('目的地').closest('button') fireEvent.click(endLocationButton!) fireEvent.click(confirmButton) // 等待状态更新 await waitFor(() => { expect(screen.getAllByText('北京市 北京市 朝阳区')).toHaveLength(2) }) // 选择商务车 const businessOption = screen.getByText('商务车') fireEvent.click(businessOption) // 点击查询 const searchButton = screen.getByText('查询路线') fireEvent.click(searchButton) // 验证导航参数 - 商务车支持拼车和包车两种出行方式 expect(mockNavigateTo).toHaveBeenCalledWith({ url: expect.stringContaining('vehicleType=business') }) expect(mockNavigateTo).toHaveBeenCalledWith({ url: expect.stringContaining('travelMode=carpool,charter') }) }) test('应该正确映射包车组合查询参数', async () => { render( ) // 设置出发地和目的地 const startLocationButton = screen.getByText('出发地').closest('button') fireEvent.click(startLocationButton!) const confirmButton = screen.getByTestId('area-picker-confirm') fireEvent.click(confirmButton) const endLocationButton = screen.getByText('目的地').closest('button') fireEvent.click(endLocationButton!) fireEvent.click(confirmButton) // 等待状态更新 await waitFor(() => { expect(screen.getAllByText('北京市 北京市 朝阳区')).toHaveLength(2) }) // 选择包车 const charterOption = screen.getByText('包车') fireEvent.click(charterOption) // 点击查询 const searchButton = screen.getByText('查询路线') fireEvent.click(searchButton) // 验证导航参数 - 包车支持大巴和商务车两种车型 expect(mockNavigateTo).toHaveBeenCalledWith({ url: expect.stringContaining('vehicleType=bus,business') }) expect(mockNavigateTo).toHaveBeenCalledWith({ url: expect.stringContaining('travelMode=charter') }) }) test('应该正确显示组合查询选项', () => { render( ) // 验证三个组合查询选项都存在 expect(screen.getByText('大巴拼车')).toBeInTheDocument() expect(screen.getByText('商务车')).toBeInTheDocument() expect(screen.getByText('包车')).toBeInTheDocument() }) test('应该正确显示组合查询选项的选中状态', () => { render( ) // 默认选中大巴拼车 const busOption = screen.getByText('大巴拼车') expect(busOption.parentElement).toHaveClass('bg-gradient-to-r') expect(busOption.parentElement).toHaveClass('text-white') // 选择商务车 const businessOption = screen.getByText('商务车') fireEvent.click(businessOption) // 验证商务车被选中,大巴拼车取消选中 expect(businessOption.parentElement).toHaveClass('bg-gradient-to-r') expect(businessOption.parentElement).toHaveClass('text-white') expect(busOption.parentElement).not.toHaveClass('text-white') }) }) describe('组合查询参数传递', () => { test('应该正确传递完整的组合查询参数', async () => { render( ) // 设置出发地和目的地 const startLocationButton = screen.getByText('出发地').closest('button') fireEvent.click(startLocationButton!) const confirmButton = screen.getByTestId('area-picker-confirm') fireEvent.click(confirmButton) const endLocationButton = screen.getByText('目的地').closest('button') fireEvent.click(endLocationButton!) fireEvent.click(confirmButton) // 等待状态更新 await waitFor(() => { expect(screen.getAllByText('北京市 北京市 朝阳区')).toHaveLength(2) }) // 选择包车 const charterOption = screen.getByText('包车') fireEvent.click(charterOption) // 点击查询 const searchButton = screen.getByText('查询路线') fireEvent.click(searchButton) // 验证完整的导航参数 const navigateCall = mockNavigateTo.mock.calls[0][0] const url = navigateCall.url expect(url).toContain('startAreaIds=[1,11,101]') expect(url).toContain('endAreaIds=[1,11,101]') expect(url).toContain('date=') expect(url).toContain('vehicleType=bus,business') expect(url).toContain('travelMode=charter') }) test('应该正确传递商务车多值出行方式参数', async () => { render( ) // 设置出发地和目的地 const startLocationButton = screen.getByText('出发地').closest('button') fireEvent.click(startLocationButton!) const confirmButton = screen.getByTestId('area-picker-confirm') fireEvent.click(confirmButton) const endLocationButton = screen.getByText('目的地').closest('button') fireEvent.click(endLocationButton!) fireEvent.click(confirmButton) // 等待状态更新 await waitFor(() => { expect(screen.getAllByText('北京市 北京市 朝阳区')).toHaveLength(2) }) // 选择商务车 const businessOption = screen.getByText('商务车') fireEvent.click(businessOption) // 点击查询 const searchButton = screen.getByText('查询路线') fireEvent.click(searchButton) // 验证商务车支持多值出行方式参数 const navigateCall = mockNavigateTo.mock.calls[0][0] const url = navigateCall.url expect(url).toContain('vehicleType=business') expect(url).toContain('travelMode=carpool,charter') }) test('应该正确传递包车多值车型参数', async () => { render( ) // 设置出发地和目的地 const startLocationButton = screen.getByText('出发地').closest('button') fireEvent.click(startLocationButton!) const confirmButton = screen.getByTestId('area-picker-confirm') fireEvent.click(confirmButton) const endLocationButton = screen.getByText('目的地').closest('button') fireEvent.click(endLocationButton!) fireEvent.click(confirmButton) // 等待状态更新 await waitFor(() => { expect(screen.getAllByText('北京市 北京市 朝阳区')).toHaveLength(2) }) // 选择包车 const charterOption = screen.getByText('包车') fireEvent.click(charterOption) // 点击查询 const searchButton = screen.getByText('查询路线') fireEvent.click(searchButton) // 验证包车支持多值车型参数 const navigateCall = mockNavigateTo.mock.calls[0][0] const url = navigateCall.url expect(url).toContain('vehicleType=bus,business') expect(url).toContain('travelMode=charter') }) }) describe('组合查询样式验证', () => { test('应该为不同组合查询选项应用正确的样式', () => { render( ) const busOption = screen.getByText('大巴拼车') const businessOption = screen.getByText('商务车') const charterOption = screen.getByText('包车') // 默认选中大巴拼车 expect(busOption.parentElement).toHaveClass('bg-gradient-to-r') expect(busOption.parentElement).toHaveClass('text-white') // 选择商务车 fireEvent.click(businessOption) expect(businessOption.parentElement).toHaveClass('bg-gradient-to-r') expect(businessOption.parentElement).toHaveClass('text-white') // 选择包车 fireEvent.click(charterOption) expect(charterOption.parentElement).toHaveClass('bg-gradient-to-r') expect(charterOption.parentElement).toHaveClass('text-white') }) test('应该正确切换组合查询选项的选中状态', () => { render( ) const busOption = screen.getByText('大巴拼车') const businessOption = screen.getByText('商务车') const charterOption = screen.getByText('包车') // 初始状态:大巴拼车选中 expect(busOption.parentElement).toHaveClass('text-white') expect(businessOption.parentElement).not.toHaveClass('text-white') expect(charterOption.parentElement).not.toHaveClass('text-white') // 选择商务车 fireEvent.click(businessOption) expect(busOption.parentElement).not.toHaveClass('text-white') expect(businessOption.parentElement).toHaveClass('text-white') expect(charterOption.parentElement).not.toHaveClass('text-white') // 选择包车 fireEvent.click(charterOption) expect(busOption.parentElement).not.toHaveClass('text-white') expect(businessOption.parentElement).not.toHaveClass('text-white') expect(charterOption.parentElement).toHaveClass('text-white') }) }) describe('组合查询边界情况', () => { test('应该正确处理默认组合查询参数', () => { render( ) // 验证默认参数 const busOption = screen.getByText('大巴拼车') expect(busOption.parentElement).toHaveClass('text-white') // 验证默认参数设置 expect(mockNavigateTo).not.toHaveBeenCalled() }) test('应该正确处理组合查询参数变化', async () => { render( ) // 设置出发地和目的地 const startLocationButton = screen.getByText('出发地').closest('button') fireEvent.click(startLocationButton!) const confirmButton = screen.getByTestId('area-picker-confirm') fireEvent.click(confirmButton) const endLocationButton = screen.getByText('目的地').closest('button') fireEvent.click(endLocationButton!) fireEvent.click(confirmButton) // 等待状态更新 await waitFor(() => { expect(screen.getAllByText('北京市 北京市 朝阳区')).toHaveLength(2) }) // 测试从大巴拼车切换到商务车 const busOption = screen.getByText('大巴拼车') const businessOption = screen.getByText('商务车') // 初始选择大巴拼车 expect(busOption.parentElement).toHaveClass('text-white') // 切换到商务车 fireEvent.click(businessOption) expect(businessOption.parentElement).toHaveClass('text-white') expect(busOption.parentElement).not.toHaveClass('text-white') // 点击查询 const searchButton = screen.getByText('查询路线') fireEvent.click(searchButton) // 验证商务车参数 const navigateCall = mockNavigateTo.mock.calls[0][0] const url = navigateCall.url expect(url).toContain('vehicleType=business') expect(url).toContain('travelMode=carpool,charter') expect(url).not.toContain('vehicleType=bus') expect(url).not.toContain('travelMode=carpool') }) }) })