ScheduleListPage.test.tsx 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. import React from 'react'
  2. import { render, screen, waitFor } from '@testing-library/react'
  3. import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
  4. import ScheduleListPage from '../../src/pages/schedule-list/ScheduleListPage'
  5. // Mock Taro API
  6. jest.mock('@tarojs/taro', () => ({
  7. useRouter: jest.fn(() => ({
  8. params: {
  9. startAreaIds: JSON.stringify([1, 2]),
  10. endAreaIds: JSON.stringify([3, 4]),
  11. date: '2025-10-31',
  12. vehicleType: 'bus',
  13. travelMode: 'carpool',
  14. activityId: '1',
  15. routeType: 'departure'
  16. }
  17. })),
  18. navigateTo: jest.fn(),
  19. navigateBack: jest.fn()
  20. }))
  21. // Mock API client
  22. jest.mock('../../src/api', () => ({
  23. routeClient: {
  24. search: {
  25. $get: jest.fn(() => Promise.resolve({
  26. status: 200,
  27. json: () => Promise.resolve({
  28. data: {
  29. routes: [
  30. {
  31. id: 1,
  32. name: '测试路线',
  33. description: null,
  34. startLocationId: 1,
  35. endLocationId: 2,
  36. startLocation: {
  37. id: 1,
  38. name: '起点',
  39. provinceId: 1,
  40. cityId: 1,
  41. districtId: 1,
  42. address: '起点地址'
  43. },
  44. endLocation: {
  45. id: 2,
  46. name: '终点',
  47. provinceId: 2,
  48. cityId: 2,
  49. districtId: 2,
  50. address: '终点地址'
  51. },
  52. pickupPoint: '上车点',
  53. dropoffPoint: '下车点',
  54. departureTime: '2025-10-31T08:00:00Z',
  55. vehicleType: 'bus',
  56. travelMode: 'carpool',
  57. price: 100,
  58. seatCount: 40,
  59. availableSeats: 20,
  60. activityId: 1,
  61. activity: {
  62. id: 1,
  63. name: '测试活动',
  64. description: null,
  65. venueLocationId: 3,
  66. venueLocation: {
  67. id: 3,
  68. name: '活动场地',
  69. provinceId: 3,
  70. cityId: 3,
  71. districtId: 3,
  72. address: '活动场地地址'
  73. },
  74. startDate: '2025-10-31',
  75. endDate: '2025-11-01'
  76. },
  77. routeType: 'departure',
  78. isDisabled: 0,
  79. isDeleted: 0,
  80. createdAt: '2025-10-31T00:00:00Z',
  81. updatedAt: '2025-10-31T00:00:00Z'
  82. }
  83. ],
  84. activities: [
  85. {
  86. id: 1,
  87. name: '测试活动',
  88. description: null,
  89. venueLocationId: 3,
  90. venueLocation: {
  91. id: 3,
  92. name: '活动场地',
  93. provinceId: 3,
  94. cityId: 3,
  95. districtId: 3,
  96. address: '活动场地地址'
  97. },
  98. startDate: '2025-10-31',
  99. endDate: '2025-11-01'
  100. }
  101. ]
  102. }
  103. })
  104. }))
  105. }
  106. }
  107. }))
  108. // Mock date-fns
  109. jest.mock('date-fns', () => ({
  110. format: jest.fn(() => '08:00'),
  111. zhCN: {}
  112. }))
  113. // Mock components
  114. jest.mock('../../src/components/ui/navbar', () => ({
  115. Navbar: ({ title, onClickLeft }: { title: string; onClickLeft: () => void }) => (
  116. <div data-testid="navbar">
  117. <div>{title}</div>
  118. <button onClick={onClickLeft}>返回</button>
  119. </div>
  120. ),
  121. NavbarPresets: {
  122. primary: {}
  123. }
  124. }))
  125. const createTestQueryClient = () => new QueryClient({
  126. defaultOptions: {
  127. queries: { retry: false },
  128. },
  129. })
  130. const Wrapper = ({ children }: { children: React.ReactNode }) => (
  131. <QueryClientProvider client={createTestQueryClient()}>
  132. {children}
  133. </QueryClientProvider>
  134. )
  135. describe('ScheduleListPage', () => {
  136. beforeEach(() => {
  137. jest.clearAllMocks()
  138. })
  139. test('应该正确渲染班次页面', async () => {
  140. render(
  141. <Wrapper>
  142. <ScheduleListPage />
  143. </Wrapper>
  144. )
  145. // 等待数据加载
  146. await waitFor(() => {
  147. expect(screen.getByText('选择班次')).toBeInTheDocument()
  148. })
  149. // 验证页面标题
  150. expect(screen.getByText('选择班次')).toBeInTheDocument()
  151. // 验证活动名称显示
  152. expect(screen.getByText('测试活动')).toBeInTheDocument()
  153. // 验证路线信息显示
  154. expect(screen.getByText('起点 → 终点')).toBeInTheDocument()
  155. expect(screen.getByText('去程')).toBeInTheDocument()
  156. // 验证班次列表显示
  157. expect(screen.getByText('可选班次')).toBeInTheDocument()
  158. expect(screen.getByText('(1个班次)')).toBeInTheDocument()
  159. // 验证班次详情显示
  160. expect(screen.getByText('08:00')).toBeInTheDocument()
  161. expect(screen.getByText('¥100/人')).toBeInTheDocument()
  162. expect(screen.getByText('大巴拼车')).toBeInTheDocument()
  163. expect(screen.getByText('拼车')).toBeInTheDocument()
  164. expect(screen.getByText('上车点')).toBeInTheDocument()
  165. expect(screen.getByText('下车点')).toBeInTheDocument()
  166. expect(screen.getByText('剩余20/40座')).toBeInTheDocument()
  167. expect(screen.getByText('空调')).toBeInTheDocument()
  168. expect(screen.getByText('免费WiFi')).toBeInTheDocument()
  169. // 验证预订按钮
  170. expect(screen.getByText('立即购票')).toBeInTheDocument()
  171. })
  172. test('应该隐藏日期选择功能', async () => {
  173. render(
  174. <Wrapper>
  175. <ScheduleListPage />
  176. </Wrapper>
  177. )
  178. // 等待数据加载
  179. await waitFor(() => {
  180. expect(screen.getByText('选择班次')).toBeInTheDocument()
  181. })
  182. // 验证日期选择UI组件已隐藏
  183. // 不应该显示"选择出发日期"文本
  184. const dateSelectionText = screen.queryByText('选择出发日期')
  185. expect(dateSelectionText).not.toBeInTheDocument()
  186. // 不应该显示日期选项
  187. const dateOptions = screen.queryByText('2025-10-31')
  188. expect(dateOptions).not.toBeInTheDocument()
  189. })
  190. test('应该显示加载状态', () => {
  191. // Mock loading state
  192. const mockApi = require('../../src/api')
  193. mockApi.routeClient.search.$get.mockImplementationOnce(
  194. () => new Promise(() => {}) // Never resolves to simulate loading
  195. )
  196. render(
  197. <Wrapper>
  198. <ScheduleListPage />
  199. </Wrapper>
  200. )
  201. expect(screen.getByText('加载中...')).toBeInTheDocument()
  202. })
  203. test('应该显示无班次状态', async () => {
  204. // Mock empty data
  205. const mockApi = require('../../src/api')
  206. mockApi.routeClient.search.$get.mockResolvedValueOnce({
  207. status: 200,
  208. json: () => Promise.resolve({
  209. data: {
  210. routes: [],
  211. activities: []
  212. }
  213. })
  214. })
  215. render(
  216. <Wrapper>
  217. <ScheduleListPage />
  218. </Wrapper>
  219. )
  220. await waitFor(() => {
  221. expect(screen.getByText('暂无班次')).toBeInTheDocument()
  222. })
  223. expect(screen.getByText('请选择其他日期查看')).toBeInTheDocument()
  224. })
  225. })