画面上でのテストは完了. 移行にす早さが求められるので,準備ができたらマージする. Reviewed-on: #430 Co-authored-by: miteruzo <miteruzo@naver.com>
このコミットはプルリクエスト #430 でマージされました。
このコミットが含まれているのは:
@@ -0,0 +1,126 @@
|
||||
import { QueryClient } from '@tanstack/react-query'
|
||||
import { fireEvent, screen, waitFor } from '@testing-library/react'
|
||||
import { Route, Routes, useLocation } from 'react-router-dom'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import PrefetchLink from '@/components/PrefetchLink'
|
||||
import * as prefetchers from '@/lib/prefetchers'
|
||||
import HelpDetailPage from '@/pages/help/HelpDetailPage'
|
||||
import HelpDiffPage from '@/pages/help/HelpDiffPage'
|
||||
import { helpFixture } from '@/test/helpFixtures'
|
||||
import { renderWithProviders } from '@/test/render'
|
||||
|
||||
const settings = vi.hoisted (() => ({ linkPreload: 'intent' }))
|
||||
vi.mock ('@/lib/useClientBehaviourSettings', () => ({
|
||||
useClientBehaviourSettings: () => settings }))
|
||||
vi.mock ('@/lib/help', async () => (await import ('@/test/helpFixtures')).helpFixture.api)
|
||||
|
||||
|
||||
const Location = () => {
|
||||
const location = useLocation ()
|
||||
return <output data-testid="location">{location.pathname}</output>
|
||||
}
|
||||
|
||||
|
||||
describe ('Help prefetch integration', () => {
|
||||
beforeEach (() => {
|
||||
helpFixture.reset ()
|
||||
settings.linkPreload = 'intent'
|
||||
vi.clearAllMocks ()
|
||||
})
|
||||
|
||||
it.each (['/help', '/help?title=ホーム&text=検索&page=2', '/help/guide', '/help/changes',
|
||||
'/help/guide/diff?from=2026-10-01&to=2026-10-02.10',
|
||||
'/help/%E8%A8%AD%E5%AE%9A%20%E6%89%8B%E9%A0%86?edition=2026-10-03']) (
|
||||
'registers a unique prefetcher for %s', path => {
|
||||
const url = new URL (path, window.location.origin)
|
||||
expect (prefetchers.routePrefetchers.filter (entry => entry.test (url))).toHaveLength (1)
|
||||
})
|
||||
|
||||
it ('loads and reuses the same MDX module for repeated prefetch and display', async () => {
|
||||
const { queryClient } = renderWithProviders (
|
||||
<>
|
||||
<PrefetchLink to="/help/guide">Help</PrefetchLink>
|
||||
<Routes>
|
||||
<Route path="/" element={null}/>
|
||||
<Route path="/help/:identifier" element={<HelpDetailPage/>}/>
|
||||
</Routes>
|
||||
</>)
|
||||
const loader = helpFixture.moduleLoads['../../help/guide/editions/ja/2026-10-02.10.mdx']
|
||||
await Promise.all ([
|
||||
prefetchers.prefetchForURL (queryClient, '/help/guide'),
|
||||
prefetchers.prefetchForURL (queryClient, '/help/guide')])
|
||||
expect (loader).toHaveBeenCalledTimes (1)
|
||||
fireEvent.click (screen.getByRole ('link', { name: 'Help' }))
|
||||
await screen.findByRole ('heading', { name: 'ホーム第十版' })
|
||||
expect (loader).toHaveBeenCalledTimes (1)
|
||||
})
|
||||
|
||||
it ('prefetches the requested identifier and edition independently', async () => {
|
||||
const client = new QueryClient ()
|
||||
await prefetchers.prefetchForURL (client, '/help/guide?edition=2026-10-02.3')
|
||||
await prefetchers.prefetchForURL (client, `/help/${encodeURIComponent ('設定 手順')}`)
|
||||
expect (helpFixture.modules['../../help/guide/editions/ja/2026-10-02.3.mdx'])
|
||||
.toHaveBeenCalledTimes (1)
|
||||
expect (helpFixture.modules['../../help/設定 手順/editions/ja/2026-10-03.mdx'])
|
||||
.toHaveBeenCalledTimes (1)
|
||||
expect (helpFixture.modules['../../help/guide/editions/en/2026-10-02.mdx'])
|
||||
.not.toHaveBeenCalled ()
|
||||
})
|
||||
|
||||
it ('loads history editions without treating changes as an article', async () => {
|
||||
const article = vi.spyOn (helpFixture.api, 'getHelpArticle')
|
||||
await prefetchers.prefetchForURL (new QueryClient (), '/help/changes')
|
||||
expect (article).not.toHaveBeenCalledWith ('changes')
|
||||
expect (helpFixture.loads.changes).toHaveBeenCalledTimes (1)
|
||||
Object.values (helpFixture.raw).forEach (load => expect (load).not.toHaveBeenCalled ())
|
||||
Object.values (helpFixture.modules).forEach (load => expect (load).not.toHaveBeenCalled ())
|
||||
})
|
||||
|
||||
it ('reuses two prefetched raw editions when displaying their diff', async () => {
|
||||
const path = '/help/guide/diff?from=2026-10-01&to=2026-10-02.10'
|
||||
const { queryClient } = renderWithProviders (
|
||||
<>
|
||||
<PrefetchLink to={path}>diff</PrefetchLink>
|
||||
<Routes>
|
||||
<Route path="/" element={null}/>
|
||||
<Route path="/help/:identifier/diff" element={<HelpDiffPage/>}/>
|
||||
</Routes>
|
||||
</>)
|
||||
await Promise.all ([prefetchers.prefetchForURL (queryClient, path),
|
||||
prefetchers.prefetchForURL (queryClient, path)])
|
||||
fireEvent.click (screen.getByRole ('link', { name: 'diff' }))
|
||||
expect (await screen.findByRole ('link', { name: '旧ホーム (2026-10-01)' }))
|
||||
.toHaveAttribute ('href', '/help/guide?edition=2026-10-01')
|
||||
expect (screen.getByText ('+ # ホーム第十版')).toBeInTheDocument ()
|
||||
Object.entries (helpFixture.raw).forEach (([name, load]) => {
|
||||
const expected = /\/ja\/(2026-10-01|2026-10-02\.10)\.mdx$/.test (name) ? 1 : 0
|
||||
expect (load).toHaveBeenCalledTimes (expected)
|
||||
})
|
||||
Object.values (helpFixture.modules).forEach (load => expect (load).not.toHaveBeenCalled ())
|
||||
})
|
||||
|
||||
it.each (['intent', 'off']) ('respects %s intent settings and still prefetches clicks',
|
||||
async mode => {
|
||||
settings.linkPreload = mode
|
||||
const run = vi.spyOn (prefetchers, 'prefetchForURL').mockResolvedValue ()
|
||||
renderWithProviders (<><Location/><PrefetchLink to="/help/guide">Help</PrefetchLink></>)
|
||||
const link = screen.getByRole ('link', { name: 'Help' })
|
||||
fireEvent.mouseEnter (link)
|
||||
fireEvent.touchStart (link)
|
||||
expect (run).toHaveBeenCalledTimes (mode === 'intent' ? 2 : 0)
|
||||
fireEvent.click (link)
|
||||
await waitFor (() => expect (screen.getByTestId ('location'))
|
||||
.toHaveTextContent ('/help/guide'))
|
||||
expect (run).toHaveBeenCalledTimes (mode === 'intent' ? 3 : 1)
|
||||
})
|
||||
|
||||
it ('continues navigation after prefetch failure', async () => {
|
||||
vi.spyOn (console, 'error').mockImplementation (() => {})
|
||||
vi.spyOn (prefetchers, 'prefetchForURL').mockRejectedValue (new Error ('offline'))
|
||||
renderWithProviders (<><Location/><PrefetchLink to="/help/guide">Help</PrefetchLink></>)
|
||||
fireEvent.click (screen.getByRole ('link', { name: 'Help' }))
|
||||
await waitFor (() => expect (screen.getByTestId ('location'))
|
||||
.toHaveTextContent ('/help/guide'))
|
||||
})
|
||||
})
|
||||
新しいイシューから参照
ユーザーをブロックする