85 行
2.7 KiB
TypeScript
85 行
2.7 KiB
TypeScript
import { fireEvent, screen, waitFor } from '@testing-library/react'
|
|
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
|
|
import SettingPage from '@/pages/users/SettingPage'
|
|
import { buildUser } from '@/test/factories'
|
|
import { renderWithProviders } from '@/test/render'
|
|
|
|
const api = vi.hoisted (() => ({
|
|
apiPut: vi.fn (),
|
|
isApiError: vi.fn (),
|
|
}))
|
|
|
|
const toastApi = vi.hoisted (() => ({
|
|
toast: vi.fn (),
|
|
}))
|
|
|
|
vi.mock ('@/lib/api', () => api)
|
|
vi.mock ('@/components/ui/use-toast', () => toastApi)
|
|
vi.mock ('@/components/users/UserCodeDialogue', () => ({
|
|
default: () => null,
|
|
}))
|
|
vi.mock ('@/components/users/InheritDialogue', () => ({
|
|
default: () => null,
|
|
}))
|
|
|
|
describe ('SettingPage', () => {
|
|
beforeEach (() => {
|
|
vi.clearAllMocks ()
|
|
api.isApiError.mockReturnValue (false)
|
|
})
|
|
|
|
it ('shows loading when user is absent', () => {
|
|
renderWithProviders (<SettingPage user={null} setUser={vi.fn ()}/>)
|
|
|
|
expect (screen.getByText ('Loading...')).toBeInTheDocument ()
|
|
})
|
|
|
|
it ('updates the current user name', async () => {
|
|
const user = buildUser ({ id: 11, name: 'old' })
|
|
const setUser = vi.fn ()
|
|
api.apiPut.mockResolvedValueOnce ({ ...user, name: 'new' })
|
|
|
|
renderWithProviders (<SettingPage user={user} setUser={setUser}/>)
|
|
|
|
fireEvent.change (screen.getByRole ('textbox'), { target: { value: 'new' } })
|
|
fireEvent.click (screen.getByRole ('button', { name: '更新' }))
|
|
|
|
await waitFor (() => {
|
|
expect (api.apiPut).toHaveBeenCalledWith (
|
|
'/users/11',
|
|
expect.any (FormData),
|
|
{ headers: { 'Content-Type': 'multipart/form-data' } },
|
|
)
|
|
})
|
|
const formData = api.apiPut.mock.calls[0]?.[1] as FormData
|
|
expect (formData.get ('name')).toBe ('new')
|
|
expect (setUser).toHaveBeenCalled ()
|
|
expect (toastApi.toast).toHaveBeenCalledWith ({ title: '設定を更新しました.' })
|
|
})
|
|
|
|
it ('shows validation errors returned for the name field', async () => {
|
|
const user = buildUser ({ id: 11, name: 'old' })
|
|
api.isApiError.mockReturnValue (true)
|
|
api.apiPut.mockRejectedValueOnce ({
|
|
response: {
|
|
status: 422,
|
|
data: {
|
|
type: 'validation_error',
|
|
message: '入力内容を確認してください.',
|
|
errors: { name: ['名前は必須です.'] },
|
|
base_errors: [],
|
|
},
|
|
},
|
|
})
|
|
|
|
renderWithProviders (<SettingPage user={user} setUser={vi.fn ()}/>)
|
|
|
|
fireEvent.change (screen.getByRole ('textbox'), { target: { value: '' } })
|
|
fireEvent.click (screen.getByRole ('button', { name: '更新' }))
|
|
|
|
expect (await screen.findByText ('名前は必須です.')).toBeInTheDocument ()
|
|
expect (screen.getByRole ('textbox')).toHaveAttribute ('aria-invalid', 'true')
|
|
})
|
|
})
|