このコミットが含まれているのは:
@@ -1,4 +1,4 @@
|
|||||||
import { render, screen } from '@testing-library/react'
|
import { fireEvent, render, screen } from '@testing-library/react'
|
||||||
import { describe, expect, it } from 'vitest'
|
import { describe, expect, it } from 'vitest'
|
||||||
|
|
||||||
import PostThumbnailPreview from '@/components/posts/PostThumbnailPreview'
|
import PostThumbnailPreview from '@/components/posts/PostThumbnailPreview'
|
||||||
@@ -9,4 +9,28 @@ describe ('PostThumbnailPreview', () => {
|
|||||||
|
|
||||||
expect (screen.getByRole ('img')).toHaveAttribute ('src', 'blob:preview')
|
expect (screen.getByRole ('img')).toHaveAttribute ('src', 'blob:preview')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it ('renders an empty thumbnail frame without text when the URL is empty', () => {
|
||||||
|
const { container } = render (
|
||||||
|
<PostThumbnailPreview url="" className="h-10 w-10"/>)
|
||||||
|
|
||||||
|
expect (screen.queryByRole ('img')).toBeNull ()
|
||||||
|
expect (screen.queryByText ('サムネールを表示できません')).toBeNull ()
|
||||||
|
expect (screen.queryByText ('なし')).toBeNull ()
|
||||||
|
expect (container.querySelector ('div.rounded.border.bg-muted')).not.toBeNull ()
|
||||||
|
expect (container.textContent).toBe ('')
|
||||||
|
})
|
||||||
|
|
||||||
|
it ('renders an empty thumbnail frame without text when image loading fails', () => {
|
||||||
|
const { container } = render (
|
||||||
|
<PostThumbnailPreview url="blob:preview" className="h-10 w-10"/>)
|
||||||
|
|
||||||
|
fireEvent.error (screen.getByRole ('img'))
|
||||||
|
|
||||||
|
expect (screen.queryByRole ('img')).toBeNull ()
|
||||||
|
expect (screen.queryByText ('サムネールを表示できません')).toBeNull ()
|
||||||
|
expect (screen.queryByText ('なし')).toBeNull ()
|
||||||
|
expect (container.querySelector ('div.rounded.border.bg-muted')).not.toBeNull ()
|
||||||
|
expect (container.textContent).toBe ('')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -19,30 +19,13 @@ const PostThumbnailPreview: FC<Props> = (
|
|||||||
setFailed (false)
|
setFailed (false)
|
||||||
}, [url])
|
}, [url])
|
||||||
|
|
||||||
if (!(url))
|
if (!(url) || failed)
|
||||||
{
|
{
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={cn (
|
className={cn (
|
||||||
className,
|
className,
|
||||||
'flex items-center justify-center rounded border',
|
'rounded border border-border bg-muted')}/>)
|
||||||
'border-border bg-muted text-xs text-muted-foreground')}>
|
|
||||||
なし
|
|
||||||
</div>)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (failed)
|
|
||||||
{
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className={cn (
|
|
||||||
className,
|
|
||||||
'flex items-center justify-center rounded border',
|
|
||||||
'border-amber-300 bg-amber-50 p-2 text-center text-xs',
|
|
||||||
'text-amber-700 dark:border-amber-900 dark:bg-amber-950',
|
|
||||||
'dark:text-amber-200')}>
|
|
||||||
サムネールを表示できません
|
|
||||||
</div>)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -38,12 +38,18 @@ describe ('PostImportThumbnailPreview', () => {
|
|||||||
it ('does not render the unsafe URL directly when preview fetching fails', async () => {
|
it ('does not render the unsafe URL directly when preview fetching fails', async () => {
|
||||||
api.apiGet.mockRejectedValueOnce (new Error ('unsafe'))
|
api.apiGet.mockRejectedValueOnce (new Error ('unsafe'))
|
||||||
|
|
||||||
render (
|
const { container } = render (
|
||||||
<PostImportThumbnailPreview
|
<PostImportThumbnailPreview
|
||||||
url="http://127.0.0.1/private.png"
|
url="http://127.0.0.1/private.png"
|
||||||
className="h-10 w-10"/>)
|
className="h-10 w-10"/>)
|
||||||
|
|
||||||
expect (await screen.findByText ('サムネールを表示できません')).toBeInTheDocument ()
|
await waitFor (() => {
|
||||||
|
expect (screen.queryByRole ('img')).toBeNull ()
|
||||||
|
})
|
||||||
|
expect (screen.queryByText ('サムネールを表示できません')).toBeNull ()
|
||||||
|
expect (screen.queryByText ('なし')).toBeNull ()
|
||||||
|
expect (container.querySelector ('div.rounded.border.bg-muted')).not.toBeNull ()
|
||||||
|
expect (container.textContent).toBe ('')
|
||||||
expect (screen.queryByRole ('img')).toBeNull ()
|
expect (screen.queryByRole ('img')).toBeNull ()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import { useEffect, useRef, useState } from 'react'
|
|||||||
|
|
||||||
import PostThumbnailPreview from '@/components/posts/PostThumbnailPreview'
|
import PostThumbnailPreview from '@/components/posts/PostThumbnailPreview'
|
||||||
import { apiGet } from '@/lib/api'
|
import { apiGet } from '@/lib/api'
|
||||||
import { cn } from '@/lib/utils'
|
|
||||||
|
|
||||||
import type { FC } from 'react'
|
import type { FC } from 'react'
|
||||||
|
|
||||||
@@ -18,7 +17,6 @@ const PostImportThumbnailPreview: FC<Props> = (
|
|||||||
className = 'h-16 w-16' },
|
className = 'h-16 w-16' },
|
||||||
) => {
|
) => {
|
||||||
const [previewUrl, setPreviewUrl] = useState ('')
|
const [previewUrl, setPreviewUrl] = useState ('')
|
||||||
const [unavailable, setUnavailable] = useState (false)
|
|
||||||
const previewUrlRef = useRef ('')
|
const previewUrlRef = useRef ('')
|
||||||
|
|
||||||
useEffect (() => {
|
useEffect (() => {
|
||||||
@@ -28,7 +26,6 @@ const PostImportThumbnailPreview: FC<Props> = (
|
|||||||
previewUrlRef.current = ''
|
previewUrlRef.current = ''
|
||||||
}
|
}
|
||||||
setPreviewUrl ('')
|
setPreviewUrl ('')
|
||||||
setUnavailable (false)
|
|
||||||
|
|
||||||
if (!(url))
|
if (!(url))
|
||||||
return
|
return
|
||||||
@@ -51,7 +48,7 @@ const PostImportThumbnailPreview: FC<Props> = (
|
|||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
if (active)
|
if (active)
|
||||||
setUnavailable (true)
|
setPreviewUrl ('')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,20 +64,6 @@ const PostImportThumbnailPreview: FC<Props> = (
|
|||||||
}
|
}
|
||||||
}, [url])
|
}, [url])
|
||||||
|
|
||||||
if (unavailable)
|
|
||||||
{
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className={cn (
|
|
||||||
className,
|
|
||||||
'flex items-center justify-center rounded border',
|
|
||||||
'border-amber-300 bg-amber-50 p-2 text-center text-xs',
|
|
||||||
'text-amber-700 dark:border-amber-900 dark:bg-amber-950',
|
|
||||||
'dark:text-amber-200')}>
|
|
||||||
サムネールを表示できません
|
|
||||||
</div>)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PostThumbnailPreview
|
<PostThumbnailPreview
|
||||||
url={previewUrl}
|
url={previewUrl}
|
||||||
|
|||||||
新しい課題から参照
ユーザをブロックする