広場投稿追加画面の刷新 (#399) (#413)

Reviewed-on: http://git.miteruzo.com/miteruzo/btrc-hub/pulls/413
Co-authored-by: miteruzo <miteruzo@naver.com>
Co-committed-by: miteruzo <miteruzo@naver.com>
このコミットはプルリクエスト #413 でマージされました。
このコミットが含まれているのは:
2026-07-19 00:03:10 +09:00
committed by みてるぞ
コミット f1181e8510
99個のファイルの変更、10242行の追加、1126行の削除
-10
ファイルの表示
@@ -1,10 +0,0 @@
import { describe, it } from 'vitest'
describe ('pending high-level browser coverage', () => {
it.todo ('adds MSW-backed API boundary tests in a follow-up issue')
it.todo ('covers TheatreDetailPage with timer polling, comment posting, and next-post updates')
it.todo ('covers NicoTagListPage linking and pagination against realistic API payloads')
it.todo ('covers TagDetailSidebar drag/drop parent-child editing with pointer-event fidelity')
it.todo ('covers TopNav desktop and mobile menu flows as browser-level integration tests')
it.todo ('covers full App bootstrap for user creation, user verification, and 503 handling')
})
+53
ファイルの表示
@@ -0,0 +1,53 @@
import type { PostImportRow } from '@/lib/postImportTypes'
export const buildPostImportRow = (
overrides: Partial<PostImportRow> = {},
): PostImportRow => {
const attributes = {
title: '',
thumbnailBase: '',
originalCreatedFrom: '',
originalCreatedBefore: '',
duration: '',
tags: '',
parentPostIds: '',
...overrides.attributes }
const provenance = {
url: 'manual' as const,
title: 'automatic' as const,
thumbnailBase: 'automatic' as const,
originalCreatedFrom: 'automatic' as const,
originalCreatedBefore: 'automatic' as const,
duration: 'automatic' as const,
tags: 'automatic' as const,
parentPostIds: 'automatic' as const,
...overrides.provenance }
const fieldWarnings = { ...overrides.fieldWarnings }
const baseWarnings = [...(overrides.baseWarnings ?? [])]
const tagSources = {
automatic: overrides.tagSources?.automatic ?? '',
manual: overrides.tagSources?.manual ?? '' }
const url = overrides.url ?? 'https://example.com/post'
return {
...overrides,
sourceRow: overrides.sourceRow ?? 1,
url,
attributes,
fieldWarnings,
baseWarnings,
validationErrors: overrides.validationErrors ?? {},
provenance,
tagSources,
status: overrides.status ?? 'ready',
recoverable: overrides.recoverable,
resetSnapshot: overrides.resetSnapshot ?? {
url,
attributes: { ...attributes },
provenance: { ...provenance },
tagSources: { ...tagSources },
fieldWarnings: Object.fromEntries (
Object.entries (fieldWarnings).map (([key, values]) => [key, [...values]])),
baseWarnings: [...baseWarnings],
metadataUrl: overrides.metadataUrl } }
}
+33 -15
ファイルの表示
@@ -1,7 +1,8 @@
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { render } from '@testing-library/react'
import { createContext, useContext, useState } from 'react'
import { HelmetProvider } from 'react-helmet-async'
import { MemoryRouter } from 'react-router-dom'
import { createMemoryRouter, RouterProvider } from 'react-router-dom'
import DialogueProvider from '@/components/dialogues/DialogueProvider'
import { KeyboardShortcutsProvider } from '@/lib/useKeyboardShortcuts'
@@ -13,6 +14,20 @@ type Options = {
route?: string
}
const TestContentContext = createContext<ReactNode> (null)
const TestRoute = () => {
const children = useContext (TestContentContext)
return (
<UnsavedChangesGuardProvider>
<KeyboardShortcutsProvider>
{children}
</KeyboardShortcutsProvider>
</UnsavedChangesGuardProvider>)
}
export const renderWithProviders = (
ui: ReactElement,
options: Options = {},
@@ -22,20 +37,23 @@ export const renderWithProviders = (
queries: { retry: false } },
})
const Wrapper = ({ children }: { children: ReactNode }) => (
<QueryClientProvider client={queryClient}>
<HelmetProvider>
<MemoryRouter initialEntries={[options.route ?? '/']}>
<DialogueProvider>
<UnsavedChangesGuardProvider>
<KeyboardShortcutsProvider>
{children}
</KeyboardShortcutsProvider>
</UnsavedChangesGuardProvider>
</DialogueProvider>
</MemoryRouter>
</HelmetProvider>
</QueryClientProvider>)
const Wrapper = ({ children }: { children: ReactNode }) => {
const [router] = useState (() => createMemoryRouter ([{
path: '*',
element: <TestRoute/> }], {
initialEntries: [options.route ?? '/'] }))
return (
<QueryClientProvider client={queryClient}>
<HelmetProvider>
<DialogueProvider>
<TestContentContext.Provider value={children}>
<RouterProvider router={router}/>
</TestContentContext.Provider>
</DialogueProvider>
</HelmetProvider>
</QueryClientProvider>)
}
return {
queryClient,