import { act, fireEvent, screen, waitFor } from '@testing-library/react' import { Route, Routes, useLocation, useNavigate } from 'react-router-dom' import { beforeEach, describe, expect, it, vi } from 'vitest' import HelpDetailPage from '@/pages/help/HelpDetailPage' import { helpFixture } from '@/test/helpFixtures' import { renderWithProviders } from '@/test/render' import type { ReactElement } from 'react' vi.mock ('@/lib/help', async () => (await import ('@/test/helpFixtures')).helpFixture.api) const Navigation = () => { const navigate = useNavigate () const location = useLocation () return ( <> {location.pathname}{location.search} ) } const renderDetail = (route = '/ja/help/guide') => renderWithProviders ( <> }/> , { route }) describe ('Help details', () => { beforeEach (() => helpFixture.reset ()) it.each (['2026-10-02', '2026-10-02.2', '2026-10-02.3', '2026-10-02.10']) ( 'displays a date without inventing a time for edition %s', async edition => { const { container } = renderDetail (`/ja/help/guide?edition=${ edition }`) await screen.findByRole ('heading') expect (container).toHaveTextContent ('10月2日') expect (container).not.toHaveTextContent ('Invalid Date') expect (container.textContent).not.toMatch (/\d{1,2}:\d{2}/) const revision = edition.split ('.')[1] if (revision != null) expect (container).toHaveTextContent (` .${ revision }`) expect (helpFixture.modules[`../../help/guide/editions/ja/${ edition }.mdx`]) .toHaveBeenCalled () }) it ('displays current_edition H1 and body even when newer files exist', async () => { renderDetail () expect (await screen.findByRole ('heading', { name: 'ホーム第十版' })) .toBeInTheDocument () expect (screen.getByText ('タグを検索する 第十版本文')).toBeInTheDocument () expect (screen.queryByText ('未公開限定本文')).not.toBeInTheDocument () await waitFor (() => expect (document.title).toContain ('ホーム第十版 ヘルプ')) }) it ('uses the historical H1 in both page and document titles', async () => { renderDetail ('/ja/help/guide?edition=2026-10-01') expect (await screen.findByRole ('heading', { name: '旧ホーム' })).toBeInTheDocument () expect (screen.getByText ('過去限定本文')).toBeInTheDocument () await waitFor (() => expect (document.title).toContain ('旧ホーム ヘルプ')) expect (screen.getByText ('(最古)')).toBeInTheDocument () expect (screen.getByRole ('link', { name: '新 >' })) .toHaveAttribute ('href', '/ja/help/guide?edition=2026-10-02') }) it ('navigates .2, .3 and .10 in numeric edition order', async () => { renderDetail ('/ja/help/guide?edition=2026-10-02.3') await screen.findByRole ('heading', { name: 'ホーム第三版' }) expect (screen.getByRole ('link', { name: '< 古' })) .toHaveAttribute ('href', '/ja/help/guide?edition=2026-10-02.2') const next = screen.getByRole ('link', { name: '新 >' }) expect (next).toHaveAttribute ('href', '/ja/help/guide?edition=2026-10-02.10') fireEvent.click (next) await screen.findByRole ('heading', { name: 'ホーム第十版' }) expect (screen.getByText ('(最新)')).toBeInTheDocument () expect (screen.queryByText ('第三版本文')).not.toBeInTheDocument () }) it.each (['/ja/help/missing', '/ja/help/guide?edition=missing', '/ja/help/guide?edition=2026-02-30', '/ja/help/guide?edition=2026-10-02.2.extra', '/ja/help/guide?edition=2026-10-02.11']) ( 'shows NotFound without redirecting %s', async route => { renderDetail (route) expect (await screen.findByText ('404')).toBeInTheDocument () expect (screen.getByTestId ('location')).toHaveTextContent (route) }) it ('hides the old body and title immediately while another article loads', async () => { let finish!: (value: { default: () => ReactElement }) => void const pending = new Promise<{ default: () => ReactElement }> (resolve => { finish = resolve }) helpFixture.modules['../../help/設定 手順/editions/ja/2026-10-03.mdx'] .mockReturnValueOnce (pending) renderDetail () await screen.findByRole ('heading', { name: 'ホーム第十版' }) fireEvent.click (screen.getByRole ('button', { name: 'switch article' })) expect (screen.queryByText ('タグを検索する 第十版本文')).not.toBeInTheDocument () await waitFor (() => expect (document.title).not.toContain ('ホーム')) await act (async () => finish ({ default: () =>

設定

})) await screen.findByRole ('heading', { name: '設定' }) await waitFor (() => expect (document.title).toContain ('設定 ヘルプ')) }) it ('ignores a late response for the previous edition', async () => { let finish!: (value: { default: () => ReactElement }) => void const pending = new Promise<{ default: () => ReactElement }> (resolve => { finish = resolve }) const loader = helpFixture.modules['../../help/guide/editions/ja/2026-10-02.10.mdx'] loader.mockReturnValueOnce (pending) renderDetail () await waitFor (() => expect (loader).toHaveBeenCalled ()) fireEvent.click (screen.getByRole ('button', { name: 'switch edition' })) await screen.findByRole ('heading', { name: 'ホーム第三版' }) await act (async () => finish ({ default: () =>

遅延した旧本文

})) expect (screen.queryByText ('遅延した旧本文')).not.toBeInTheDocument () expect (screen.getByRole ('heading', { name: 'ホーム第三版' })).toBeInTheDocument () await waitFor (() => expect (document.title).toContain ('ホーム第三版 ヘルプ')) }) })