import React from 'react'
import { render, screen, waitFor } from '@testing-library/react'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import ScheduleListPage from '../../src/pages/schedule-list/ScheduleListPage'
// Mock Taro API
jest.mock('@tarojs/taro', () => ({
useRouter: jest.fn(() => ({
params: {
startAreaIds: JSON.stringify([1, 2]),
endAreaIds: JSON.stringify([3, 4]),
date: '2025-10-31',
vehicleType: 'bus',
travelMode: 'carpool',
activityId: '1',
routeType: 'departure'
}
})),
navigateTo: jest.fn(),
navigateBack: jest.fn()
}))
// Mock API client
jest.mock('../../src/api', () => ({
routeClient: {
search: {
$get: jest.fn(() => Promise.resolve({
status: 200,
json: () => Promise.resolve({
data: {
routes: [
{
id: 1,
name: '测试路线',
description: null,
startLocationId: 1,
endLocationId: 2,
startLocation: {
id: 1,
name: '起点',
provinceId: 1,
cityId: 1,
districtId: 1,
address: '起点地址'
},
endLocation: {
id: 2,
name: '终点',
provinceId: 2,
cityId: 2,
districtId: 2,
address: '终点地址'
},
pickupPoint: '上车点',
dropoffPoint: '下车点',
departureTime: '2025-10-31T08:00:00Z',
vehicleType: 'bus',
travelMode: 'carpool',
price: 100,
seatCount: 40,
availableSeats: 20,
activityId: 1,
activity: {
id: 1,
name: '测试活动',
description: null,
venueLocationId: 3,
venueLocation: {
id: 3,
name: '活动场地',
provinceId: 3,
cityId: 3,
districtId: 3,
address: '活动场地地址'
},
startDate: '2025-10-31',
endDate: '2025-11-01'
},
routeType: 'departure',
isDisabled: 0,
isDeleted: 0,
createdAt: '2025-10-31T00:00:00Z',
updatedAt: '2025-10-31T00:00:00Z'
}
],
activities: [
{
id: 1,
name: '测试活动',
description: null,
venueLocationId: 3,
venueLocation: {
id: 3,
name: '活动场地',
provinceId: 3,
cityId: 3,
districtId: 3,
address: '活动场地地址'
},
startDate: '2025-10-31',
endDate: '2025-11-01'
}
]
}
})
}))
}
}
}))
// Mock date-fns
jest.mock('date-fns', () => ({
format: jest.fn(() => '08:00'),
zhCN: {}
}))
// Mock components
jest.mock('../../src/components/ui/navbar', () => ({
Navbar: ({ title, onClickLeft }: { title: string; onClickLeft: () => void }) => (
),
NavbarPresets: {
primary: {}
}
}))
const createTestQueryClient = () => new QueryClient({
defaultOptions: {
queries: { retry: false },
},
})
const Wrapper = ({ children }: { children: React.ReactNode }) => (
{children}
)
describe('ScheduleListPage', () => {
beforeEach(() => {
jest.clearAllMocks()
})
test('应该正确渲染班次页面', async () => {
render(
)
// 等待数据加载
await waitFor(() => {
expect(screen.getByText('选择班次')).toBeInTheDocument()
})
// 验证页面标题
expect(screen.getByText('选择班次')).toBeInTheDocument()
// 验证活动名称显示
expect(screen.getByText('测试活动')).toBeInTheDocument()
// 验证路线信息显示
expect(screen.getByText('起点 → 终点')).toBeInTheDocument()
expect(screen.getByText('去程')).toBeInTheDocument()
// 验证班次列表显示
expect(screen.getByText('可选班次')).toBeInTheDocument()
expect(screen.getByText('(1个班次)')).toBeInTheDocument()
// 验证班次详情显示
expect(screen.getByText('08:00')).toBeInTheDocument()
expect(screen.getByText('¥100/人')).toBeInTheDocument()
expect(screen.getByText('大巴拼车')).toBeInTheDocument()
expect(screen.getByText('拼车')).toBeInTheDocument()
expect(screen.getByText('上车点')).toBeInTheDocument()
expect(screen.getByText('下车点')).toBeInTheDocument()
expect(screen.getByText('剩余20/40座')).toBeInTheDocument()
expect(screen.getByText('空调')).toBeInTheDocument()
expect(screen.getByText('免费WiFi')).toBeInTheDocument()
// 验证预订按钮
expect(screen.getByText('立即购票')).toBeInTheDocument()
})
test('应该隐藏日期选择功能', async () => {
render(
)
// 等待数据加载
await waitFor(() => {
expect(screen.getByText('选择班次')).toBeInTheDocument()
})
// 验证日期选择UI组件已隐藏
// 不应该显示"选择出发日期"文本
const dateSelectionText = screen.queryByText('选择出发日期')
expect(dateSelectionText).not.toBeInTheDocument()
// 不应该显示日期选项
const dateOptions = screen.queryByText('2025-10-31')
expect(dateOptions).not.toBeInTheDocument()
})
test('应该显示加载状态', () => {
// Mock loading state
const mockApi = require('../../src/api')
mockApi.routeClient.search.$get.mockImplementationOnce(
() => new Promise(() => {}) // Never resolves to simulate loading
)
render(
)
expect(screen.getByText('加载中...')).toBeInTheDocument()
})
test('应该显示无班次状态', async () => {
// Mock empty data
const mockApi = require('../../src/api')
mockApi.routeClient.search.$get.mockResolvedValueOnce({
status: 200,
json: () => Promise.resolve({
data: {
routes: [],
activities: []
}
})
})
render(
)
await waitFor(() => {
expect(screen.getByText('暂无班次')).toBeInTheDocument()
})
expect(screen.getByText('请选择其他日期查看')).toBeInTheDocument()
})
})