import React from 'react'
import { render, fireEvent, waitFor } from '@testing-library/react'
import { ActivitySelectPage } from '../../src/pages/select-activity/ActivitySelectPage'
// Mock Taro路由和导航
jest.mock('@tarojs/taro', () => ({
useRouter: jest.fn(() => ({
params: {
startLocationId: '1',
endLocationId: '2',
date: '2025-10-18',
vehicleType: 'bus'
}
})),
navigateTo: jest.fn()
}))
// Mock API调用
jest.mock('../../src/api', () => ({
routeClient: {
search: {
$get: jest.fn().mockResolvedValue({
status: 200,
json: jest.fn().mockResolvedValue([
{
id: 1,
startLocation: { name: '北京市' },
endLocation: { name: '上海市' },
activities: [
{
id: 101,
name: '上海音乐节',
venueLocation: {
name: '上海大舞台',
province: '上海市',
city: '上海市',
district: '徐汇区',
address: '上海市徐汇区漕溪北路1111号'
},
startDate: '2025-10-20T19:00:00Z',
endDate: '2025-10-20T22:00:00Z',
imageUrl: 'https://example.com/concert.jpg'
}
],
routeType: 'departure'
},
{
id: 2,
startLocation: { name: '北京市' },
endLocation: { name: '上海市' },
activities: [
{
id: 102,
name: '北京艺术展',
venueLocation: {
name: '北京美术馆',
province: '北京市',
city: '北京市',
district: '东城区',
address: '北京市东城区美术馆后街'
},
startDate: '2025-10-19T10:00:00Z',
endDate: '2025-10-19T18:00:00Z',
imageUrl: 'https://example.com/exhibition.jpg'
}
],
routeType: 'return'
}
])
})
}
}
}))
describe('ActivitySelectPage', () => {
beforeEach(() => {
jest.clearAllMocks()
})
it('应该正确渲染页面头部信息', async () => {
const { getByText } = render()
await waitFor(() => {
expect(getByText('北京市 → 上海市')).toBeTruthy()
expect(getByText('2025-10-18')).toBeTruthy()
expect(getByText('选择观看活动')).toBeTruthy()
})
})
it('应该加载并显示活动列表', async () => {
const { getByText } = render()
await waitFor(() => {
expect(getByText('去程活动')).toBeTruthy()
expect(getByText('返程活动')).toBeTruthy()
expect(getByText('上海音乐节')).toBeTruthy()
expect(getByText('北京艺术展')).toBeTruthy()
})
})
it('应该正确显示活动信息', async () => {
const { getByText } = render()
await waitFor(() => {
// 验证去程活动信息
expect(getByText('上海音乐节')).toBeTruthy()
expect(getByText('徐汇区 · 上海市 · 上海市')).toBeTruthy()
expect(getByText('到达:上海市')).toBeTruthy()
// 验证返程活动信息
expect(getByText('北京艺术展')).toBeTruthy()
expect(getByText('东城区 · 北京市 · 北京市')).toBeTruthy()
expect(getByText('出发:北京市')).toBeTruthy()
})
})
it('应该处理活动选择并导航', async () => {
const mockNavigateTo = require('@tarojs/taro').navigateTo
const { getByText } = render()
await waitFor(() => {
expect(getByText('上海音乐节')).toBeTruthy()
})
const activityItem = getByText('上海音乐节')
fireEvent.click(activityItem)
expect(mockNavigateTo).toHaveBeenCalledWith({
url: '/pages/schedule-list/ScheduleListPage?startLocationId=1&endLocationId=2&date=2025-10-18&vehicleType=bus&activityId=101&routeType=departure'
})
})
it('应该处理空活动列表', async () => {
// Mock 空数据
const routeClient = require('../../src/api').routeClient
routeClient.search.$get.mockResolvedValueOnce({
status: 200,
json: jest.fn().mockResolvedValue([])
})
const { getByText } = render()
await waitFor(() => {
expect(getByText('暂无相关活动')).toBeTruthy()
expect(getByText('北京市和上海市当前都没有热门活动')).toBeTruthy()
})
})
it('应该处理加载状态', () => {
// Mock 延迟加载
const routeClient = require('../../src/api').routeClient
routeClient.search.$get.mockImplementationOnce(
() => new Promise(resolve => setTimeout(resolve, 100))
)
const { getByText } = render()
expect(getByText('加载中...')).toBeTruthy()
})
it('应该正确格式化日期', async () => {
const { getByText } = render()
await waitFor(() => {
// 验证日期格式化
expect(getByText('2025/10/20')).toBeTruthy()
expect(getByText('2025/10/19')).toBeTruthy()
})
})
it('应该显示活动地址信息', async () => {
const { getByText } = render()
await waitFor(() => {
expect(getByText('上海市徐汇区漕溪北路1111号')).toBeTruthy()
expect(getByText('北京市东城区美术馆后街')).toBeTruthy()
})
})
it('应该处理路由参数缺失的情况', () => {
// Mock 缺失参数
const useRouter = require('@tarojs/taro').useRouter
useRouter.mockReturnValueOnce({
params: {}
})
const { getByText } = render()
// 验证页面仍然渲染,但可能显示错误或空状态
expect(getByText('选择观看活动')).toBeTruthy()
})
it('应该去重活动列表', async () => {
// Mock 包含重复活动的数据
const routeClient = require('../../src/api').routeClient
routeClient.search.$get.mockResolvedValueOnce({
status: 200,
json: jest.fn().mockResolvedValue([
{
id: 1,
startLocation: { name: '北京市' },
endLocation: { name: '上海市' },
activities: [
{
id: 101,
name: '上海音乐节',
venueLocation: { name: '上海大舞台' },
startDate: '2025-10-20T19:00:00Z',
endDate: '2025-10-20T22:00:00Z'
}
],
routeType: 'departure'
},
{
id: 2,
startLocation: { name: '北京市' },
endLocation: { name: '上海市' },
activities: [
{
id: 101,
name: '上海音乐节',
venueLocation: { name: '上海大舞台' },
startDate: '2025-10-20T19:00:00Z',
endDate: '2025-10-20T22:00:00Z'
}
],
routeType: 'departure'
}
])
})
const { getAllByText } = render()
await waitFor(() => {
// 验证重复活动只显示一次
const activityItems = getAllByText('上海音乐节')
expect(activityItems.length).toBe(1)
})
})
})