OrderList.test.tsx 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. import React from 'react'
  2. import { render, screen, fireEvent, waitFor } from '@testing-library/react'
  3. import '@testing-library/jest-dom'
  4. // 测试是否可以导入共享的测试工具
  5. // 使用本地测试工具
  6. import { setupTestEnv, renderTaroComponent } from './__helpers__/local-test-utils'
  7. import OrderList from '../src/pages/OrderList/OrderList'
  8. import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
  9. // 测试设置共享测试环境
  10. setupTestEnv()
  11. // 创建测试用的QueryClient
  12. const createTestQueryClient = () => new QueryClient({
  13. defaultOptions: {
  14. queries: {
  15. retry: false,
  16. },
  17. },
  18. })
  19. // 测试包装器组件
  20. const TestWrapper = ({ children }: { children: React.ReactNode }) => {
  21. const queryClient = createTestQueryClient()
  22. return (
  23. <QueryClientProvider client={queryClient}>
  24. {children}
  25. </QueryClientProvider>
  26. )
  27. }
  28. // 包装的render函数
  29. const renderWithQueryClient = (component: React.ReactElement) => {
  30. return render(<TestWrapper>{component}</TestWrapper>)
  31. }
  32. // Mock Taro组件
  33. jest.mock('@tarojs/components', () => ({
  34. View: ({ children, className, ...props }: any) => (
  35. <div className={className} {...props}>{children}</div>
  36. ),
  37. Text: ({ children, className, ...props }: any) => (
  38. <span className={className} {...props}>{children}</span>
  39. ),
  40. ScrollView: ({ children, className, scrollY, ...props }: any) => (
  41. <div className={className} data-scroll-y={scrollY} {...props}>{children}</div>
  42. ),
  43. Input: ({ className, placeholder, value, onInput, ...props }: any) => (
  44. <input
  45. className={className}
  46. placeholder={placeholder}
  47. value={value}
  48. onChange={(e) => onInput?.({ detail: { value: e.target.value } })}
  49. {...props}
  50. />
  51. ),
  52. Button: ({ children, className, onClick, ...props }: any) => (
  53. <button className={className} onClick={onClick} {...props}>
  54. {children}
  55. </button>
  56. ),
  57. }))
  58. // Mock UI组件
  59. jest.mock('@d8d/yongren-shared-ui/components/YongrenTabBarLayout', () => ({
  60. YongrenTabBarLayout: ({ children, activeKey }: any) => (
  61. <div data-testid="yongren-tab-bar-layout" data-active-key={activeKey}>
  62. {children}
  63. </div>
  64. ),
  65. }))
  66. jest.mock('@d8d/mini-shared-ui-components/components/navbar', () => ({
  67. Navbar: ({ title, leftIcon, leftText, onClickLeft }: any) => (
  68. <div data-testid="navbar" data-title={title} data-left-icon={leftIcon} data-left-text={leftText}>
  69. <button onClick={onClickLeft}>Navbar Left</button>
  70. </div>
  71. ),
  72. }))
  73. // Mock RPC客户端
  74. jest.mock('@d8d/mini-shared-ui-components/utils/rpc/rpc-client', () => ({
  75. rpcClient: jest.fn(() => ({
  76. 'company-orders': {
  77. $get: jest.fn(() => Promise.resolve({
  78. ok: true,
  79. json: () => Promise.resolve({
  80. data: [
  81. {
  82. id: 1,
  83. orderNumber: 'ORDER-2023-11',
  84. orderName: '阿里巴巴2023-11',
  85. createTime: '2023-11-01T09:00:00Z',
  86. orderStatus: 'in_progress',
  87. expectedPersonCount: 10,
  88. actualPersonCount: 8,
  89. expectedStartDate: '2023-11-01',
  90. expectedEndDate: '2024-01-01',
  91. talentName: '张三',
  92. position: '前端开发'
  93. },
  94. {
  95. id: 2,
  96. orderNumber: 'ORDER-2023-08',
  97. orderName: '腾讯科技2023-08',
  98. createTime: '2023-08-15T10:30:00Z',
  99. orderStatus: 'completed',
  100. expectedPersonCount: 5,
  101. actualPersonCount: 5,
  102. expectedStartDate: '2023-08-15',
  103. expectedEndDate: '2023-12-15',
  104. talentName: '李四',
  105. position: '后端开发'
  106. },
  107. {
  108. id: 3,
  109. orderNumber: 'ORDER-2023-12',
  110. orderName: '字节跳动2023-12',
  111. createTime: '2023-12-01T14:20:00Z',
  112. orderStatus: 'in_progress',
  113. expectedPersonCount: 15,
  114. actualPersonCount: 12,
  115. expectedStartDate: '2023-12-01',
  116. expectedEndDate: '2024-03-01',
  117. talentName: '王五',
  118. position: '产品经理'
  119. }
  120. ],
  121. meta: { page: 1, pageSize: 20, total: 3, totalPages: 1 }
  122. })
  123. }))
  124. }
  125. }))
  126. }))
  127. describe('OrderList 组件测试', () => {
  128. test('渲染订单列表页面', async () => {
  129. renderWithQueryClient(<OrderList />)
  130. // 验证Navbar存在(立即渲染)
  131. expect(screen.getByTestId('navbar')).toBeInTheDocument()
  132. expect(screen.getByTestId('navbar')).toHaveAttribute('data-title', '订单列表')
  133. // 验证筛选标签(立即渲染)
  134. expect(screen.getAllByText('全部订单').length).toBeGreaterThan(0)
  135. expect(screen.getAllByText('进行中').length).toBeGreaterThan(0)
  136. expect(screen.getAllByText('已完成').length).toBeGreaterThan(0)
  137. expect(screen.getAllByText('已取消').length).toBeGreaterThan(0)
  138. // 验证搜索框(立即渲染)
  139. expect(screen.getByPlaceholderText('按订单号、人才姓名搜索')).toBeInTheDocument()
  140. // 等待数据加载并验证订单卡片
  141. await waitFor(() => {
  142. expect(screen.getByText('阿里巴巴2023-11')).toBeInTheDocument()
  143. })
  144. // 验证其他订单卡片和统计卡片(数据已加载)
  145. expect(screen.getByText('腾讯科技2023-08')).toBeInTheDocument()
  146. expect(screen.getByText('字节跳动2023-12')).toBeInTheDocument()
  147. expect(screen.getAllByText('本月打卡').length).toBeGreaterThan(0)
  148. expect(screen.getAllByText('工资视频').length).toBeGreaterThan(0)
  149. expect(screen.getAllByText('个税视频').length).toBeGreaterThan(0)
  150. })
  151. test('状态筛选功能', () => {
  152. renderWithQueryClient(<OrderList />)
  153. // 初始状态为"全部订单"
  154. const allOrdersTab = screen.getByText('全部订单')
  155. expect(allOrdersTab).toHaveClass('bg-blue-100')
  156. // 点击"进行中"筛选 - 使用更具体的选择器
  157. const filterTabs = screen.getAllByText('进行中')
  158. const inProgressTab = filterTabs[0] // 第一个是筛选标签
  159. fireEvent.click(inProgressTab)
  160. // 验证样式变化(通过类名检查)
  161. expect(inProgressTab).toHaveClass('bg-green-100')
  162. })
  163. test('搜索功能', () => {
  164. renderWithQueryClient(<OrderList />)
  165. const searchInput = screen.getByPlaceholderText('按订单号、人才姓名搜索')
  166. const searchButton = screen.getByText('搜索')
  167. // 输入搜索关键词
  168. fireEvent.change(searchInput, { target: { value: '阿里巴巴' } })
  169. expect(searchInput).toHaveValue('阿里巴巴')
  170. // 点击搜索按钮(主要验证没有错误)
  171. fireEvent.click(searchButton)
  172. })
  173. test('查看详情按钮点击', async () => {
  174. renderWithQueryClient(<OrderList />)
  175. // 等待数据加载
  176. await waitFor(() => {
  177. expect(screen.getByText('阿里巴巴2023-11')).toBeInTheDocument()
  178. })
  179. // 获取查看详情按钮
  180. const viewDetailButtons = screen.getAllByText('查看详情')
  181. expect(viewDetailButtons.length).toBeGreaterThan(0)
  182. // 点击第一个查看详情按钮
  183. fireEvent.click(viewDetailButtons[0])
  184. })
  185. // 分页控件已移除,改为无限滚动分页
  186. // 不再需要分页控件渲染测试
  187. })