|
- import { fireEvent, screen, waitFor } from '@testing-library/react'
- import { beforeEach, describe, expect, it, vi } from 'vitest'
-
- import PostSearchPage from '@/pages/posts/PostSearchPage'
- import { buildPost, buildTag } from '@/test/factories'
- import { renderWithProviders } from '@/test/render'
-
- const postsApi = vi.hoisted (() => ({
- fetchPosts: vi.fn (),
- }))
-
- const api = vi.hoisted (() => ({
- apiGet: vi.fn (),
- }))
-
- vi.mock ('@/lib/posts', () => postsApi)
- vi.mock ('@/lib/api', () => api)
-
- describe ('PostSearchPage', () => {
- beforeEach (() => {
- vi.clearAllMocks ()
- api.apiGet.mockResolvedValue ([])
- })
-
- it ('loads posts from URL search filters', async () => {
- postsApi.fetchPosts.mockResolvedValueOnce ({
- posts: [buildPost ({ id: 4, title: '検索対象', tags: [buildTag ({ name: '虹夏' })] })],
- count: 1,
- })
-
- renderWithProviders (
- <PostSearchPage/>,
- { route: '/posts/search?title=%E6%A4%9C%E7%B4%A2&tags=x&match=any&page=2' },
- )
-
- await waitFor (() => {
- expect (postsApi.fetchPosts).toHaveBeenCalledWith (
- expect.objectContaining ({
- title: '検索',
- tags: 'x',
- match: 'any',
- page: 2,
- }),
- )
- })
- expect ((await screen.findAllByRole ('link', { name: '検索対象' }))[0]).toHaveAttribute (
- 'href',
- '/posts/4',
- )
- })
-
- it ('submits form state into a new search', async () => {
- postsApi.fetchPosts.mockResolvedValue ({ posts: [], count: 0 })
-
- renderWithProviders (<PostSearchPage/>, { route: '/posts/search' })
-
- const textboxes = screen.getAllByRole ('textbox')
- fireEvent.change (textboxes[0], { target: { value: 'title' } })
- fireEvent.change (textboxes[1], { target: { value: 'https://example.com' } })
- fireEvent.change (textboxes[2], { target: { value: 'tag' } })
- fireEvent.click (screen.getByRole ('radio', { name: 'OR' }))
- fireEvent.click (screen.getByRole ('button', { name: '検索' }))
-
- await waitFor (() => {
- expect (postsApi.fetchPosts).toHaveBeenLastCalledWith (
- expect.objectContaining ({
- title: 'title',
- url: 'https://example.com',
- tags: 'tag',
- match: 'any',
- page: 1,
- }),
- )
- })
- })
-
- it ('shows the no-result message', async () => {
- postsApi.fetchPosts.mockResolvedValueOnce ({ posts: [], count: 0 })
-
- renderWithProviders (<PostSearchPage/>, { route: '/posts/search' })
-
- expect (await screen.findByText ('結果ないよ(笑)')).toBeInTheDocument ()
- })
- })
|