import { useCallback, useEffect } from 'react' import { fireEvent, render, screen, waitFor } from '@testing-library/react' import { describe, expect, it, vi } from 'vitest' import DialogueProvider from '@/components/dialogues/DialogueProvider' import useDialogue from '@/lib/dialogues/useDialogue' import type { DialogueFormControls } from '@/lib/dialogues/useDialogue' const FormBody = ( { controls, onSelect }: { controls: DialogueFormControls onSelect: () => Promise | boolean }, ) => { useEffect (() => { controls.setActions ([{ label: '左操作', placement: 'start', onSelect }, { label: '保存', onSelect: () => true }]) }, [controls, onSelect]) return
長いフォーム本文
} const NestedConfirmFormBody = ({ controls }: { controls: DialogueFormControls }) => { const reset = useCallback (async () => { await controls.confirm ({ title: '変更をリセットしますか?', confirmText: 'リセット' }) return false }, [controls]) return } describe ('DialogueProvider', () => { it ('keeps ordinary dialogues in FIFO order', async () => { const Launcher = () => { const dialogue = useDialogue () return ( ) } render () fireEvent.click (screen.getByRole ('button', { name: '開く' })) expect (screen.getByText ('一件目')).toBeInTheDocument () expect (screen.queryByText ('二件目')).not.toBeInTheDocument () fireEvent.click (screen.getByRole ('button', { name: '確定' })) expect (await screen.findByText ('二件目')).toBeInTheDocument () }) it ('keeps a large form open when an action returns false', async () => { const action = vi.fn ().mockResolvedValue (false) const Launcher = () => { const dialogue = useDialogue () return ( ) } render () fireEvent.click (screen.getByRole ('button', { name: '開く' })) const dialogue = screen.getByRole ('dialog') expect (dialogue).toHaveClass ('max-h-[calc(100dvh-1rem)]', 'flex-col', 'max-w-3xl') await waitFor (() => expect (screen.getByRole ('button', { name: '左操作' })) .toBeInTheDocument ()) expect (screen.getByRole ('button', { name: '左操作' })).toHaveClass ( 'w-full', 'md:w-auto') fireEvent.click (screen.getByRole ('button', { name: '左操作' })) await waitFor (() => expect (action).toHaveBeenCalledTimes (1)) expect (screen.getByText ('投稿を編輯')).toBeInTheDocument () }) it ('opens a nested confirmation over a form and returns to the same form', async () => { const Launcher = () => { const dialogue = useDialogue () return ( ) } render () fireEvent.click (screen.getByRole ('button', { name: '開く' })) const action = await screen.findByRole ('button', { name: '左操作' }) fireEvent.click (action) expect (await screen.findByText ('変更をリセットしますか?')).toBeInTheDocument () fireEvent.click (screen.getByRole ('button', { name: 'リセット' })) await waitFor (() => { expect (screen.queryByText ('変更をリセットしますか?')).not.toBeInTheDocument () }) expect (screen.getByText ('投稿を編輯')).toBeInTheDocument () }) })