750aa40e8e
Reviewed-on: #355 Co-authored-by: miteruzo <miteruzo@naver.com> Co-committed-by: miteruzo <miteruzo@naver.com>
73 行
2.4 KiB
TypeScript
73 行
2.4 KiB
TypeScript
import { fireEvent, screen, waitFor } from '@testing-library/react'
|
|
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
|
|
import MaterialNewPage from '@/pages/materials/MaterialNewPage'
|
|
import { renderWithProviders } from '@/test/render'
|
|
|
|
const api = vi.hoisted (() => ({
|
|
apiGet: vi.fn (),
|
|
apiPost: vi.fn (),
|
|
isApiError: vi.fn (),
|
|
}))
|
|
|
|
const toastApi = vi.hoisted (() => ({
|
|
toast: vi.fn (),
|
|
}))
|
|
|
|
vi.mock ('@/lib/api', () => api)
|
|
vi.mock ('@/components/ui/use-toast', () => toastApi)
|
|
|
|
describe ('MaterialNewPage', () => {
|
|
beforeEach (() => {
|
|
vi.clearAllMocks ()
|
|
api.apiGet.mockResolvedValue ([])
|
|
api.isApiError.mockReturnValue (false)
|
|
})
|
|
|
|
it ('initializes tag from query and submits form data', async () => {
|
|
api.apiPost.mockResolvedValueOnce ({})
|
|
|
|
renderWithProviders (<MaterialNewPage/>, { route: '/materials/new?tag=%E8%99%B9%E5%A4%8F' })
|
|
|
|
expect (screen.getAllByRole ('textbox')[0]).toHaveValue ('虹夏')
|
|
fireEvent.change (screen.getAllByRole ('textbox')[1], {
|
|
target: { value: 'https://example.com/ref' },
|
|
})
|
|
fireEvent.click (screen.getByRole ('button', { name: '追加' }))
|
|
|
|
await waitFor (() => {
|
|
expect (api.apiPost).toHaveBeenCalledWith ('/materials', expect.any (FormData))
|
|
})
|
|
const formData = api.apiPost.mock.calls[0]?.[1] as FormData
|
|
expect (formData.get ('tag')).toBe ('虹夏')
|
|
expect (formData.get ('url')).toBe ('https://example.com/ref')
|
|
expect (toastApi.toast).toHaveBeenCalledWith ({ title: '送信成功!' })
|
|
})
|
|
|
|
it ('shows validation errors for file and url fields', async () => {
|
|
api.isApiError.mockReturnValue (true)
|
|
api.apiPost.mockRejectedValueOnce ({
|
|
response: {
|
|
status: 422,
|
|
data: {
|
|
type: 'validation_error',
|
|
message: '入力内容を確認してください.',
|
|
errors: {
|
|
file: ['ファイルまたは URL は必須です.'],
|
|
url: ['ファイルまたは URL は必須です.'],
|
|
},
|
|
base_errors: [],
|
|
},
|
|
},
|
|
})
|
|
|
|
renderWithProviders (<MaterialNewPage/>)
|
|
|
|
fireEvent.change (screen.getAllByRole ('textbox')[0], { target: { value: '虹夏' } })
|
|
fireEvent.click (screen.getByRole ('button', { name: '追加' }))
|
|
|
|
expect (await screen.findAllByText ('ファイルまたは URL は必須です.')).toHaveLength (2)
|
|
expect (screen.getAllByRole ('textbox')[1]).toHaveAttribute ('aria-invalid', 'true')
|
|
})
|
|
})
|