import { fireEvent, render, screen, waitFor } from '@testing-library/react' import { describe, expect, it, vi } from 'vitest' import PostEditForm from '@/components/PostEditForm' import { buildPost, buildTag } from '@/test/factories' const postsApi = vi.hoisted (() => ({ updatePost: vi.fn (), })) const api = vi.hoisted (() => ({ isApiError: vi.fn (() => false), })) const toastApi = vi.hoisted (() => ({ toast: vi.fn (), })) vi.mock ('@/lib/posts', () => postsApi) vi.mock ('@/lib/api', () => api) vi.mock ('@/components/ui/use-toast', () => toastApi) vi.mock ('@/components/dialogues/DialogueProvider', () => ({ useDialogue: () => ({ choice: vi.fn (), }), })) describe ('PostEditForm', () => { it ('submits edited post fields with the current base version', async () => { const onSave = vi.fn () const post = buildPost ({ id: 8, versionNo: 4, title: 'old', tags: [ buildTag ({ name: 'general-tag', category: 'general' }), buildTag ({ id: 2, name: 'nico-tag', category: 'nico' }), ], parentPosts: [buildPost ({ id: 2, title: 'parent' })], }) postsApi.updatePost.mockResolvedValueOnce ({ ...post, versionNo: 5, title: 'new', tags: [buildTag ({ name: 'new-tag' })], }) render () const [title, parentIds] = screen.getAllByRole ('textbox') fireEvent.change (title, { target: { value: 'new' } }) fireEvent.change (parentIds, { target: { value: '3 4' } }) fireEvent.submit (screen.getByRole ('button', { name: '更新' }).closest ('form')!) await waitFor (() => { expect (postsApi.updatePost).toHaveBeenCalledWith ( expect.objectContaining ({ id: 8, title: 'new', parentPostIds: '3 4', tags: 'general-tag', }), { baseVersionNo: 4 }, ) }) expect (onSave).toHaveBeenCalledWith (expect.objectContaining ({ versionNo: 5 })) expect (toastApi.toast).toHaveBeenCalledWith ({ description: '更新しました.' }) }) })