import { fireEvent, screen, waitFor } from '@testing-library/react' import { Route, Routes } from 'react-router-dom' import { beforeEach, describe, expect, it, vi } from 'vitest' import DeerjikistDetailPage from '@/pages/deerjikists/DeerjikistDetailPage' import { buildTag } from '@/test/factories' import { renderWithProviders } from '@/test/render' const tagsApi = vi.hoisted (() => ({ fetchDeerjikistsByTag: vi.fn (), })) const api = vi.hoisted (() => ({ apiPut: vi.fn (), isApiError: vi.fn (), })) const toastApi = vi.hoisted (() => ({ toast: vi.fn (), })) vi.mock ('@/lib/tags', () => tagsApi) vi.mock ('@/lib/api', () => api) vi.mock ('@/components/ui/use-toast', () => toastApi) const renderPage = () => renderWithProviders ( }/> , { route: '/tags/7/deerjikists' }, ) describe ('DeerjikistDetailPage', () => { beforeEach (() => { vi.clearAllMocks () api.isApiError.mockReturnValue (false) }) it ('shows indexed validation errors returned for deerjikist rows', async () => { tagsApi.fetchDeerjikistsByTag.mockResolvedValueOnce ({ tag: buildTag ({ id: 7, name: 'deerjika', category: 'deerjikist' }), deerjikists: [{ platform: null, code: 'abc' }], }) api.isApiError.mockReturnValue (true) api.apiPut.mockRejectedValueOnce ({ response: { status: 422, data: { type: 'validation_error', message: '入力内容を確認してください.', errors: { 'deerjikists.0.platform': ['プラットフォームを入力してください.'] }, base_errors: [], }, }, }) renderPage () await screen.findByDisplayValue ('abc') fireEvent.submit (screen.getByRole ('button', { name: '更新' }).closest ('form')!) await waitFor (() => { expect (api.apiPut).toHaveBeenCalledWith ( '/tags/7/deerjikists', [{ platform: null, code: 'abc' }], ) }) expect (await screen.findByText ('プラットフォームを入力してください.')).toBeInTheDocument () expect (screen.getByRole ('combobox')).toHaveAttribute ('aria-invalid', 'true') }) })