import { fireEvent, render, screen, waitFor } from '@testing-library/react' import { beforeEach, describe, expect, it, vi } from 'vitest' import PostEmbed from '@/components/PostEmbed' import { buildPost } from '@/test/factories' const dialogue = vi.hoisted (() => ({ confirm: vi.fn (), })) const nicoViewer = vi.hoisted (() => ({ props: vi.fn (), })) vi.mock ('@/components/dialogues/DialogueProvider', () => ({ useDialogue: () => dialogue, })) vi.mock ('@/components/NicoViewer', () => ({ default: (props: { id: string }) => { nicoViewer.props (props) return
Nico:{props.id}
}, })) vi.mock ('react-youtube', () => ({ default: ({ videoId }: { videoId: string }) =>
YouTube:{videoId}
, })) describe ('PostEmbed', () => { beforeEach (() => { vi.clearAllMocks () }) it ('embeds nicovideo watch URLs', () => { render () expect (screen.getByText ('Nico:sm12345')).toBeInTheDocument () }) it ('reports niconico metadata as milliseconds', () => { const onVideoReady = vi.fn () const onPlaybackChange = vi.fn () render ( , ) nicoViewer.props.mock.calls[0][0].onMetadataChange ({ currentTime: 7_000, duration: 120_000, isVideoMetaDataLoaded: true, maximumBuffered: 30, muted: false, showComment: true, volume: 1, }) expect (onVideoReady).toHaveBeenCalledWith (120_000) expect (onPlaybackChange).toHaveBeenCalledWith (7_000) }) it ('reports niconico video readiness only once', () => { const onVideoReady = vi.fn () render ( , ) nicoViewer.props.mock.calls[0][0].onLoadComplete ({ title: '動画', videoId: 'sm12345', lengthInSeconds: 120, thumbnailUrl: 'https://example.com/thumb.jpg', description: '', viewCount: 1, commentCount: 2, mylistCount: 3, postedAt: '2026-01-02T03:04:05.000Z', watchId: 12345, }) nicoViewer.props.mock.calls[0][0].onMetadataChange ({ currentTime: 7_000, duration: 120_000, isVideoMetaDataLoaded: true, maximumBuffered: 30, muted: false, showComment: true, volume: 1, }) expect (onVideoReady).toHaveBeenCalledTimes (1) expect (onVideoReady).toHaveBeenCalledWith (120_000) }) it ('embeds x/twitter status URLs', () => { render () expect (screen.getByRole ('link', { name: '@someone' })).toBeInTheDocument () }) it ('embeds youtube watch URLs', () => { render () expect (screen.getByText ('YouTube:abc123')).toBeInTheDocument () }) it ('asks before framing unknown external pages', async () => { dialogue.confirm.mockResolvedValueOnce (true) render ( , ) fireEvent.click (screen.getByRole ('link', { name: '外部ページを表示' })) await waitFor (() => { expect (dialogue.confirm).toHaveBeenCalled () }) expect (await screen.findByTitle ('external')).toHaveAttribute ( 'src', 'https://example.com/page', ) }) })