Explorar el Código

✅ test(schedule): 添加班次列表页面测试

- 模拟Taro API、API客户端和组件
- 测试页面渲染、数据加载和UI显示
- 验证加载状态和无班次状态显示
- 验证日期选择功能隐藏逻辑
yourname hace 3 meses
padre
commit
2a18a90976
Se han modificado 1 ficheros con 251 adiciones y 0 borrados
  1. 251 0
      mini/tests/pages/ScheduleListPage.test.tsx

+ 251 - 0
mini/tests/pages/ScheduleListPage.test.tsx

@@ -0,0 +1,251 @@
+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 }) => (
+    <div data-testid="navbar">
+      <div>{title}</div>
+      <button onClick={onClickLeft}>返回</button>
+    </div>
+  ),
+  NavbarPresets: {
+    primary: {}
+  }
+}))
+
+const createTestQueryClient = () => new QueryClient({
+  defaultOptions: {
+    queries: { retry: false },
+  },
+})
+
+const Wrapper = ({ children }: { children: React.ReactNode }) => (
+  <QueryClientProvider client={createTestQueryClient()}>
+    {children}
+  </QueryClientProvider>
+)
+
+describe('ScheduleListPage', () => {
+  beforeEach(() => {
+    jest.clearAllMocks()
+  })
+
+  test('应该正确渲染班次页面', async () => {
+    render(
+      <Wrapper>
+        <ScheduleListPage />
+      </Wrapper>
+    )
+
+    // 等待数据加载
+    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(
+      <Wrapper>
+        <ScheduleListPage />
+      </Wrapper>
+    )
+
+    // 等待数据加载
+    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(
+      <Wrapper>
+        <ScheduleListPage />
+      </Wrapper>
+    )
+
+    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(
+      <Wrapper>
+        <ScheduleListPage />
+      </Wrapper>
+    )
+
+    await waitFor(() => {
+      expect(screen.getByText('暂无班次')).toBeInTheDocument()
+    })
+
+    expect(screen.getByText('请选择其他日期查看')).toBeInTheDocument()
+  })
+})