import { fireEvent, screen } from '@testing-library/react' import { beforeEach, describe, expect, it, vi } from 'vitest' import PostImportSourcePage from '@/pages/posts/PostImportSourcePage' import { buildUser } from '@/test/factories' import { renderWithProviders } from '@/test/render' const router = vi.hoisted (() => ({ navigate: vi.fn () })) vi.mock ('react-router-dom', async importOriginal => ({ ...await importOriginal (), useNavigate: () => router.navigate })) describe ('PostImportSourcePage', () => { beforeEach (() => { sessionStorage.clear () vi.clearAllMocks () }) it ('validates an empty source only after Next is pressed', () => { renderWithProviders () expect (screen.queryByText ('URL を入力してください.')).not.toBeInTheDocument () fireEvent.click (screen.getByRole ('button', { name: '次へ' })) expect (screen.getByText ('URL を入力してください.')).toBeInTheDocument () expect (router.navigate).not.toHaveBeenCalled () }) it ('reports frontend URL issues with original line numbers', () => { renderWithProviders () const input = screen.getByRole ('textbox', { name: '' }) fireEvent.change (input, { target: { value: '\nftp://example.com/file\nhttps://example.com/valid' } }) fireEvent.click (screen.getByRole ('button', { name: '次へ' })) expect (screen.getByText (/2 行目: HTTP または HTTPS/)).toBeInTheDocument () expect (screen.getByText ('ftp://example.com/file')).toBeInTheDocument () expect (input).toHaveAttribute ('aria-invalid', 'true') expect (router.navigate).not.toHaveBeenCalled () }) it ('navigates with individually encoded URLs without calling an API', () => { renderWithProviders () fireEvent.change (screen.getByRole ('textbox', { name: '' }), { target: { value: 'https://example.com/one+a\nhttps://example.com/two?value=b+c' } }) fireEvent.click (screen.getByRole ('button', { name: '次へ' })) expect (router.navigate).toHaveBeenCalledWith ( '/posts/new?urls=https%3A%2F%2Fexample.com%2Fone%2Ba' + '+https%3A%2F%2Fexample.com%2Ftwo%3Fvalue%3Db%2Bc') }) it ('disables Next when the encoded request target reaches 4096 bytes', () => { renderWithProviders () const input = screen.getByRole ('textbox', { name: '' }) fireEvent.change (input, { target: { value: `https://example.com/${ 'a'.repeat (4_100) }` } }) expect (screen.getByRole ('button', { name: '次へ' })).toBeDisabled () }) })