このコミットが含まれているのは:
@@ -1,28 +1,25 @@
|
||||
import { fireEvent, screen } from '@testing-library/react'
|
||||
import { Route, Routes } from 'react-router-dom'
|
||||
import { render, screen } from '@testing-library/react'
|
||||
import { HelmetProvider } from 'react-helmet-async'
|
||||
import { MemoryRouter, Route, Routes } from 'react-router-dom'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import { savePostImportSession } from '@/lib/postImportSession'
|
||||
import PostImportResultPage from '@/pages/posts/PostImportResultPage'
|
||||
import PageTitle from '@/components/common/PageTitle'
|
||||
import { buildUser } from '@/test/factories'
|
||||
import { buildPostImportRow } from '@/test/postImportFactories'
|
||||
import { renderWithProviders } from '@/test/render'
|
||||
|
||||
const api = vi.hoisted (() => ({ apiPost: vi.fn () }))
|
||||
const toastApi = vi.hoisted (() => ({ toast: vi.fn () }))
|
||||
const toastApi = vi.hoisted (() => ({
|
||||
toast: vi.fn (),
|
||||
}))
|
||||
|
||||
const dialogue = vi.hoisted (() => ({
|
||||
form: vi.fn (() => Promise.resolve ()),
|
||||
}))
|
||||
|
||||
vi.mock ('@/lib/api', () => api)
|
||||
vi.mock ('@/components/ui/use-toast', () => toastApi)
|
||||
|
||||
const renderPage = () => renderWithProviders (
|
||||
<Routes>
|
||||
<Route
|
||||
path="/posts/import/:sessionId/result"
|
||||
element={<PostImportResultPage user={buildUser ()}/>}/>
|
||||
<Route path="/posts/import/:sessionId/review" element={<PageTitle>review route</PageTitle>}/>
|
||||
</Routes>,
|
||||
{ route: '/posts/import/session/result' })
|
||||
vi.mock ('@/lib/dialogues/useDialogue', () => ({
|
||||
default: () => dialogue,
|
||||
}))
|
||||
|
||||
describe ('PostImportResultPage', () => {
|
||||
beforeEach (() => {
|
||||
@@ -30,71 +27,44 @@ describe ('PostImportResultPage', () => {
|
||||
vi.clearAllMocks ()
|
||||
})
|
||||
|
||||
it ('shows exclusive result counts, post links, and failed-row actions', async () => {
|
||||
const rows = [
|
||||
buildPostImportRow ({ sourceRow: 1, importStatus: 'created', createdPostId: 11 }),
|
||||
buildPostImportRow ({ sourceRow: 2, importStatus: 'skipped',
|
||||
skipReason: 'existing', existingPostId: 22 }),
|
||||
buildPostImportRow ({ sourceRow: 3, importStatus: 'failed',
|
||||
importErrors: { base: ['登録中に失敗しました.'] } })]
|
||||
savePostImportSession ('session', { source: '', rows, repairMode: 'all' })
|
||||
it ('shows edit and retry only for recoverable failures and shows warnings', () => {
|
||||
savePostImportSession ('result-session', {
|
||||
source: '',
|
||||
repairMode: 'failed',
|
||||
rows: [
|
||||
buildPostImportRow ({
|
||||
sourceRow: 1,
|
||||
attributes: { title: 'recoverable row' },
|
||||
importStatus: 'failed',
|
||||
recoverable: true,
|
||||
importErrors: { base: ['recoverable failed'] } }),
|
||||
buildPostImportRow ({
|
||||
sourceRow: 2,
|
||||
attributes: { title: 'hard failed row' },
|
||||
importStatus: 'failed',
|
||||
importErrors: { base: ['hard failed'] } }),
|
||||
buildPostImportRow ({
|
||||
sourceRow: 3,
|
||||
attributes: { title: 'created row' },
|
||||
importStatus: 'created',
|
||||
createdPostId: 3,
|
||||
fieldWarnings: {
|
||||
thumbnailBase: ['サムネール画像を取得できませんでした.'] } })] })
|
||||
|
||||
renderPage ()
|
||||
render (
|
||||
<HelmetProvider>
|
||||
<MemoryRouter initialEntries={['/posts/import/result-session/result']}>
|
||||
<Routes>
|
||||
<Route
|
||||
path="/posts/import/:sessionId/result"
|
||||
element={<PostImportResultPage user={buildUser ()}/>}/>
|
||||
</Routes>
|
||||
</MemoryRouter>
|
||||
</HelmetProvider>)
|
||||
|
||||
expect (await screen.findByText (
|
||||
/登録成功\s*1件.*スキップ\s*1件.*失敗\s*1件/)).toBeInTheDocument ()
|
||||
expect (screen.getAllByRole ('link', { name: '投稿を開く' })
|
||||
.map (_1 => _1.getAttribute ('href'))).toEqual (['/posts/11', '/posts/22'])
|
||||
expect (screen.getByText ('登録中に失敗しました.')).toBeInTheDocument ()
|
||||
expect (screen.getByRole ('button', { name: '編輯' })).toBeInTheDocument ()
|
||||
expect (screen.getByRole ('button', { name: '再試行' })).toBeInTheDocument ()
|
||||
})
|
||||
|
||||
it ('keeps the result route and opens the dialogue on retry validation error', async () => {
|
||||
const failed = buildPostImportRow ({
|
||||
importStatus: 'failed',
|
||||
importErrors: { base: ['old error'] } })
|
||||
const invalid = buildPostImportRow ({
|
||||
importStatus: 'pending',
|
||||
status: 'error',
|
||||
validationErrors: { title: ['タイトルを確認してください.'] } })
|
||||
savePostImportSession ('session', {
|
||||
source: failed.url,
|
||||
rows: [failed],
|
||||
repairMode: 'all' })
|
||||
api.apiPost.mockResolvedValue ({ rows: [invalid] })
|
||||
|
||||
renderPage ()
|
||||
fireEvent.click (await screen.findByRole ('button', { name: '再試行' }))
|
||||
|
||||
expect (await screen.findByText ('投稿を編輯')).toBeInTheDocument ()
|
||||
expect (screen.getByText ('タイトルを確認してください.')).toBeInTheDocument ()
|
||||
expect (api.apiPost).toHaveBeenCalledTimes (1)
|
||||
const saved = JSON.parse (
|
||||
sessionStorage.getItem ('post-import-session:session') ?? '{}')
|
||||
expect (saved.rows[0]).toMatchObject ({
|
||||
importStatus: 'pending',
|
||||
validationErrors: { title: ['タイトルを確認してください.'] } })
|
||||
})
|
||||
|
||||
it ('keeps the dialogue open when result-page save validation fails', async () => {
|
||||
const row = buildPostImportRow ({
|
||||
importStatus: 'failed',
|
||||
importErrors: { base: ['old error'] } })
|
||||
savePostImportSession ('session', { source: row.url, rows: [row], repairMode: 'failed' })
|
||||
api.apiPost.mockResolvedValue ({
|
||||
rows: [buildPostImportRow ({
|
||||
sourceRow: row.sourceRow,
|
||||
validationErrors: {
|
||||
originalCreatedFrom: ['オリジナルの作成日時は分単位で入力してください.'] } })] })
|
||||
|
||||
renderPage ()
|
||||
fireEvent.click (await screen.findByRole ('button', { name: '編輯' }))
|
||||
fireEvent.click (await screen.findByRole ('button', { name: '編輯内容を保存' }))
|
||||
|
||||
expect (await screen.findByText ('投稿を編輯')).toBeInTheDocument ()
|
||||
expect (screen.getByText ('オリジナルの作成日時は分単位で入力してください.'))
|
||||
.toBeInTheDocument ()
|
||||
expect (api.apiPost).toHaveBeenCalledTimes (1)
|
||||
expect (screen.getAllByRole ('button', { name: '編輯' })).toHaveLength (1)
|
||||
expect (screen.getAllByRole ('button', { name: '再試行' })).toHaveLength (1)
|
||||
expect (screen.getByText ('サムネール画像を取得できませんでした.'))
|
||||
.toBeInTheDocument ()
|
||||
})
|
||||
})
|
||||
|
||||
新しい課題から参照
ユーザをブロックする