| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 |
- import React from 'react'
- import { render, screen, fireEvent, waitFor } from '@testing-library/react'
- import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
- import SearchPage from '@/pages/search/index'
- // 导入Taro mock函数
- import {
- mockNavigateTo,
- mockGetStorageSync,
- mockSetStorageSync,
- mockRemoveStorageSync
- } from '~/__mocks__/taroMock'
- // Mock components
- jest.mock('@/components/ui/navbar', () => ({
- Navbar: ({ title, onClickLeft }: { title: string; onClickLeft: () => void }) => (
- <div data-testid="navbar">
- <span>{title}</span>
- <button onClick={onClickLeft}>返回</button>
- </div>
- ),
- }))
- jest.mock('@/components/tdesign/search', () => ({
- __esModule: true,
- default: ({
- placeholder,
- value,
- onChange,
- onSubmit,
- onClear,
- shape
- }: {
- placeholder: string
- value: string
- onChange: (value: string) => void
- onSubmit: () => void
- onClear: () => void
- shape: string
- }) => (
- <div data-testid="search-input">
- <input
- type="text"
- placeholder={placeholder}
- value={value}
- onChange={(e) => onChange(e.target.value)}
- data-testid="search-input-field"
- />
- <button onClick={onSubmit} data-testid="search-submit">搜索</button>
- <button onClick={onClear} data-testid="search-clear">清除</button>
- </div>
- ),
- }))
- describe('SearchPage', () => {
- let queryClient: QueryClient
- beforeEach(() => {
- queryClient = new QueryClient({
- defaultOptions: {
- queries: { retry: false },
- mutations: { retry: false },
- },
- })
- // Reset all mocks
- jest.clearAllMocks()
- // 设置默认的本地存储数据
- mockGetStorageSync.mockImplementation((key: string) => {
- if (key === 'search_history') {
- return ['手机', '耳机', '笔记本电脑']
- }
- return null
- })
- mockSetStorageSync.mockImplementation(() => {})
- mockRemoveStorageSync.mockImplementation(() => {})
- })
- const renderWithProviders = (component: React.ReactElement) => {
- return render(
- <QueryClientProvider client={queryClient}>
- {component}
- </QueryClientProvider>
- )
- }
- it('渲染页面标题和布局', () => {
- renderWithProviders(<SearchPage />)
- expect(screen.getByTestId('navbar')).toBeInTheDocument()
- expect(screen.getByText('搜索')).toBeInTheDocument()
- })
- it('显示搜索输入框', () => {
- renderWithProviders(<SearchPage />)
- expect(screen.getByTestId('search-input')).toBeInTheDocument()
- expect(screen.getByPlaceholderText('搜索商品...')).toBeInTheDocument()
- })
- it('显示搜索历史', async () => {
- renderWithProviders(<SearchPage />)
- await waitFor(() => {
- expect(screen.getByText('搜索历史')).toBeInTheDocument()
- expect(screen.getByText('手机')).toBeInTheDocument()
- expect(screen.getByText('耳机')).toBeInTheDocument()
- expect(screen.getByText('笔记本电脑')).toBeInTheDocument()
- expect(screen.getByText('清空')).toBeInTheDocument()
- })
- })
- it('显示热门搜索', async () => {
- renderWithProviders(<SearchPage />)
- await waitFor(() => {
- expect(screen.getByText('热门搜索')).toBeInTheDocument()
- expect(screen.getByText('手机')).toBeInTheDocument()
- expect(screen.getByText('笔记本电脑')).toBeInTheDocument()
- expect(screen.getByText('耳机')).toBeInTheDocument()
- expect(screen.getByText('智能手表')).toBeInTheDocument()
- })
- })
- it('显示空状态', async () => {
- // 模拟没有搜索历史和热门搜索的情况
- mockGetStorageSync.mockReturnValue([])
- renderWithProviders(<SearchPage />)
- await waitFor(() => {
- expect(screen.getByText('暂无搜索记录')).toBeInTheDocument()
- expect(screen.getByText('输入关键词搜索商品')).toBeInTheDocument()
- })
- })
- it('处理搜索提交', async () => {
- renderWithProviders(<SearchPage />)
- // 输入搜索关键词
- const searchInput = screen.getByTestId('search-input-field')
- fireEvent.change(searchInput, { target: { value: 'iPhone' } })
- // 提交搜索
- const searchButton = screen.getByTestId('search-submit')
- fireEvent.click(searchButton)
- await waitFor(() => {
- // 验证保存搜索历史
- expect(mockSetStorageSync).toHaveBeenCalledWith('search_history', ['iPhone', '手机', '耳机', '笔记本电脑'])
- // 验证跳转到搜索结果页面
- expect(mockNavigateTo).toHaveBeenCalledWith({
- url: '/pages/search-result/index?keyword=iPhone'
- })
- })
- })
- it('点击历史搜索项', async () => {
- renderWithProviders(<SearchPage />)
- await waitFor(() => {
- const historyItem = screen.getByText('手机')
- fireEvent.click(historyItem)
- // 验证保存搜索历史
- expect(mockSetStorageSync).toHaveBeenCalledWith('search_history', ['手机', '耳机', '笔记本电脑'])
- // 验证跳转到搜索结果页面
- expect(mockNavigateTo).toHaveBeenCalledWith({
- url: '/pages/search-result/index?keyword=手机'
- })
- })
- })
- it('点击热门搜索项', async () => {
- renderWithProviders(<SearchPage />)
- await waitFor(() => {
- const popularItem = screen.getByText('智能手表')
- fireEvent.click(popularItem)
- // 验证保存搜索历史
- expect(mockSetStorageSync).toHaveBeenCalledWith('search_history', ['智能手表', '手机', '耳机', '笔记本电脑'])
- // 验证跳转到搜索结果页面
- expect(mockNavigateTo).toHaveBeenCalledWith({
- url: '/pages/search-result/index?keyword=智能手表'
- })
- })
- })
- it('清空搜索历史', async () => {
- renderWithProviders(<SearchPage />)
- await waitFor(() => {
- const clearButton = screen.getByText('清空')
- fireEvent.click(clearButton)
- // 验证清空搜索历史
- expect(mockRemoveStorageSync).toHaveBeenCalledWith('search_history')
- })
- })
- it('处理搜索输入框清除', () => {
- renderWithProviders(<SearchPage />)
- // 输入搜索关键词
- const searchInput = screen.getByTestId('search-input-field')
- fireEvent.change(searchInput, { target: { value: 'iPhone' } })
- // 清除搜索输入
- const clearButton = screen.getByTestId('search-clear')
- fireEvent.click(clearButton)
- // 验证搜索输入被清空
- expect(searchInput).toHaveValue('')
- })
- it('验证样式类名应用', async () => {
- renderWithProviders(<SearchPage />)
- await waitFor(() => {
- const container = document.querySelector('.search-page')
- expect(container).toBeInTheDocument()
- const content = document.querySelector('.search-page-content')
- expect(content).toBeInTheDocument()
- const searchInputContainer = document.querySelector('.search-input-container')
- expect(searchInputContainer).toBeInTheDocument()
- const searchSections = document.querySelectorAll('.search-section')
- expect(searchSections.length).toBeGreaterThan(0)
- const searchItems = document.querySelectorAll('.search-item')
- expect(searchItems.length).toBeGreaterThan(0)
- })
- })
- })
|