import React from 'react'
import { describe, expect, it, vi } from 'vitest'
import { fireEvent, renderWithProviders, screen } from '../../test/utils'
import AttachmentThumbnail from './Thumbnail'
vi.mock('./MediaPlayer', () => ({
default: ({
source,
mimeType,
poster,
controls,
loop,
muted,
}: {
source: string
mimeType: string
poster?: string
controls?: boolean
loop?: boolean
muted?: boolean
}) => (
),
}))
const LINKTREE_SOURCE = 'https://cdn.linktr.ee/attachment/photo.jpg'
const LINKTREE_THUMBNAIL = 'https://cdn.linktr.ee/attachment/poster.jpg'
const OPTIMIZED_SOURCE =
'https://cdn.linktr.ee/attachment/photo.jpg?io=true&size=messaging-attachment-v1_0'
const OPTIMIZED_THUMBNAIL =
'https://cdn.linktr.ee/attachment/poster.jpg?io=true&size=messaging-attachment-v1_0'
describe('AttachmentThumbnail', () => {
it('delegates video and audio sources to MediaPlayer with an optimized poster', () => {
const { rerender } = renderWithProviders(
)
const player = screen.getByTestId('media-player')
expect(player).toHaveAttribute('data-source', LINKTREE_SOURCE)
expect(player).toHaveAttribute('data-mime-type', 'video/mp4')
expect(player).toHaveAttribute('data-poster', OPTIMIZED_THUMBNAIL)
expect(player).toHaveAttribute('data-controls', 'false')
expect(player).toHaveAttribute('data-loop', 'true')
expect(player).toHaveAttribute('data-muted', 'true')
rerender(
)
expect(screen.getByTestId('media-player')).toHaveAttribute(
'data-source',
'https://external.example/track.mp3'
)
expect(screen.getByTestId('media-player')).toHaveAttribute(
'data-controls',
'true'
)
})
it('renders an image with an optimized source and contained fade-in transition', () => {
const { container } = renderWithProviders(
)
const image = screen.getByRole('img', { name: 'Photo' })
expect(image).toHaveAttribute('src', OPTIMIZED_SOURCE)
expect(image).toHaveClass('opacity-0')
fireEvent.load(image)
expect(image).toHaveClass('opacity-100')
expect(container.firstElementChild).toHaveClass('aspect-video')
})
it('renders a non-contained image and falls back to the raw URL', () => {
renderWithProviders(
)
expect(screen.getByRole('img')).toHaveAttribute(
'src',
'https://external.example/photo.jpg'
)
expect(screen.getByRole('img')).toHaveClass('block', 'w-full')
expect(screen.getByRole('img')).toHaveAttribute('alt', '')
})
it('renders document thumbnails contained or full width, using optimized URLs', () => {
const { rerender, container } = renderWithProviders(
)
const contained = screen.getByRole('img', { name: 'Document' })
expect(contained).toHaveAttribute('src', OPTIMIZED_THUMBNAIL)
expect(contained).toHaveClass('opacity-0')
fireEvent.load(contained)
expect(contained).toHaveClass('opacity-100')
expect(container.firstElementChild).toHaveClass('aspect-video')
rerender(
)
const fullWidth = screen.getByRole('img')
expect(fullWidth).toHaveAttribute(
'src',
'https://external.example/thumb.png'
)
expect(fullWidth).toHaveAttribute('alt', '')
expect(fullWidth).toHaveClass('block', 'w-full')
})
it('renders a document icon placeholder without a thumbnail', () => {
const dark = renderWithProviders(
)
const darkIcon = dark.container.querySelector('svg') as SVGElement
expect(darkIcon).toHaveClass('size-12', 'text-white/20')
expect(dark.container.firstElementChild).toHaveClass('bg-white/10')
dark.unmount()
const light = renderWithProviders(
)
const lightIcon = light.container.querySelector('svg') as SVGElement
expect(lightIcon).toHaveClass('size-12', 'text-black/20')
expect(light.container.firstElementChild).toHaveClass('bg-black/5')
})
it('renders the poster-only branch with variant-specific shell and alt fallback', () => {
const dark = renderWithProviders(
)
const darkImage = screen.getByRole('img', { name: 'Poster' })
expect(darkImage).toHaveAttribute('src', OPTIMIZED_THUMBNAIL)
expect(dark.container.firstElementChild).toHaveClass(
'aspect-video',
'bg-white/10'
)
dark.unmount()
const light = renderWithProviders(
)
expect(screen.getByRole('img')).toHaveAttribute('alt', '')
expect(light.container.firstElementChild).toHaveClass(
'aspect-video',
'bg-black/5'
)
})
it('renders the empty branch with a light placeholder', () => {
const { container } = renderWithProviders(
)
expect(container.querySelector('img')).toBeNull()
expect(container.querySelector('svg')).toHaveClass(
'size-12',
'text-black/20'
)
expect(container.firstElementChild).toHaveClass('bg-black/5')
})
})