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 }) => (
{title}
), })) 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 }) => (
onChange(e.target.value)} data-testid="search-input-field" />
), })) 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( {component} ) } it('渲染页面标题和布局', () => { renderWithProviders() expect(screen.getByTestId('navbar')).toBeInTheDocument() expect(screen.getByText('搜索')).toBeInTheDocument() }) it('显示搜索输入框', () => { renderWithProviders() expect(screen.getByTestId('search-input')).toBeInTheDocument() expect(screen.getByPlaceholderText('搜索商品...')).toBeInTheDocument() }) it('显示搜索历史', async () => { renderWithProviders() 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() 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() await waitFor(() => { expect(screen.getByText('暂无搜索记录')).toBeInTheDocument() expect(screen.getByText('输入关键词搜索商品')).toBeInTheDocument() }) }) it('处理搜索提交', async () => { renderWithProviders() // 输入搜索关键词 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() 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() 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() await waitFor(() => { const clearButton = screen.getByText('清空') fireEvent.click(clearButton) // 验证清空搜索历史 expect(mockRemoveStorageSync).toHaveBeenCalledWith('search_history') }) }) it('处理搜索输入框清除', () => { renderWithProviders() // 输入搜索关键词 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() 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) }) }) })