index.test.js 4.54 KB
/**
 * 搜索页面测试套件
 * @description 测试搜索功能的各种场景,包括输入、状态切换等
 * @date 2026-02-13
 */

import { describe, it, expect, beforeEach, vi } from 'vitest'
import { mount } from '@vue/test-utils'
import { createPinia, setActivePinia } from 'pinia'
import Taro from '@tarojs/taro'
import SearchPage from './index.vue'
import { searchAPI } from '@/api/search'

vi.mock('@tarojs/taro', () => ({
  default: {
    showToast: vi.fn(),
    showModal: vi.fn(),
    getCurrentPages: vi.fn(() => [])
  },
  useDidShow: vi.fn(),
  usePullDownRefresh: vi.fn(),
  stopPullDownRefresh: vi.fn()
}))

vi.mock('@/hooks/useGo', () => ({
  useGo: () => vi.fn()
}))

vi.mock('@/api/search', () => ({
  searchAPI: vi.fn()
}))

const create_wrapper = () => {
  const pinia = createPinia()
  setActivePinia(pinia)
  return mount(SearchPage, {
    global: {
      plugins: [pinia],
      components: {
        NavHeader: { template: '<div />' },
        IconFont: { template: '<div />' },
        SearchBar: { template: '<input />' }
      }
    }
  })
}

describe('搜索页面测试', () => {
  beforeEach(() => {
    searchAPI.mockReset()
    Taro.showToast.mockReset()
  })

  it('初始化状态正确', () => {
    const wrapper = create_wrapper()
    expect(wrapper.vm.activeTab).toBe('')
    expect(wrapper.vm.hasSearched).toBe(false)
    expect(wrapper.vm.currentList.length).toBe(0)
    expect(wrapper.vm.currentTotal).toBe(0)
    expect(wrapper.vm.shouldEnableScrollLoad).toBe(false)
    expect(wrapper.vm.tabsData.length).toBe(2)
    expect(wrapper.vm.tabsData[0].id).toBe('product')
    expect(wrapper.vm.tabsData[1].id).toBe('file')
  })

  it('空关键词时提示并保持未搜索状态', async () => {
    const wrapper = create_wrapper()
    wrapper.vm.searchKeyword = ''
    await wrapper.vm.handleSearch()

    expect(Taro.showToast).toHaveBeenCalledTimes(1)
    expect(wrapper.vm.hasSearched).toBe(false)
    expect(wrapper.vm.activeTab).toBe('')
  })

  it('搜索成功后默认选中产品并展示列表', async () => {
    const wrapper = create_wrapper()
    searchAPI.mockResolvedValueOnce({
      code: 1,
      msg: 'ok',
      data: {
        products: {
          list: [{ id: 1, product_name: '保险A', tags: [] }],
          total: 1
        },
        files: {
          list: [{ id: 10, name: '培训资料', value: 'url', size: '1MB', extension: 'pdf', is_favorite: 1 }],
          total: 1
        }
      }
    })

    wrapper.vm.searchKeyword = '保险'
    await wrapper.vm.handleSearch()

    expect(wrapper.vm.hasSearched).toBe(true)
    expect(wrapper.vm.activeTab).toBe('product')
    expect(wrapper.vm.currentList.length).toBe(1)
    expect(wrapper.vm.currentTotal).toBe(1)
    expect(wrapper.vm.hasMore).toBe(false)
  })

  it('切换 tab 时按当前关键词重新搜索', async () => {
    const wrapper = create_wrapper()
    searchAPI.mockResolvedValueOnce({
      code: 1,
      msg: 'ok',
      data: {
        products: {
          list: [{ id: 1, product_name: '保险A', tags: [] }],
          total: 1
        },
        files: {
          list: [],
          total: 0
        }
      }
    })

    wrapper.vm.searchKeyword = '保险'
    await wrapper.vm.handleSearch()

    searchAPI.mockResolvedValueOnce({
      code: 1,
      msg: 'ok',
      data: {
        products: {
          list: [],
          total: 0
        },
        files: {
          list: [{ id: 10, name: '培训资料', value: 'url', size: '1MB', extension: 'pdf', is_favorite: 0 }],
          total: 1
        }
      }
    })

    await wrapper.vm.onTabClick('file')

    expect(wrapper.vm.activeTab).toBe('file')
    expect(wrapper.vm.currentList.length).toBe(1)
    expect(searchAPI).toHaveBeenCalledWith({ keyword: '保险', page: 0, limit: 20, type: 'file' })
  })

  it('清空搜索后重置状态', async () => {
    const wrapper = create_wrapper()
    searchAPI.mockResolvedValueOnce({
      code: 1,
      msg: 'ok',
      data: {
        products: {
          list: [{ id: 1, product_name: '保险A', tags: [] }],
          total: 1
        },
        files: {
          list: [],
          total: 0
        }
      }
    })

    wrapper.vm.searchKeyword = '保险'
    await wrapper.vm.handleSearch()

    wrapper.vm.clearSearch()

    expect(wrapper.vm.hasSearched).toBe(false)
    expect(wrapper.vm.activeTab).toBe('')
    expect(wrapper.vm.currentList.length).toBe(0)
  })

  it('未搜索或无关键词时不触发加载更多', async () => {
    const wrapper = create_wrapper()
    await wrapper.vm.handleLoadMore(1)
    expect(searchAPI).not.toHaveBeenCalled()
  })
})