mirror of
https://github.com/langgenius/dify.git
synced 2026-09-05 08:40:37 +08:00
Co-authored-by: zhangx1n <zhangxin@dify.ai> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
113 lines
3.6 KiB
TypeScript
113 lines
3.6 KiB
TypeScript
import { renderHook, waitFor } from '@testing-library/react'
|
|
import { useAppFavicon } from './use-app-favicon'
|
|
|
|
vi.mock('@/utils/emoji', () => ({
|
|
searchEmoji: vi.fn(async () => '🤖'),
|
|
}))
|
|
|
|
const firstAppIcon = 'https://example.com/app-one.png'
|
|
const secondAppIcon = 'https://example.com/app-two.png'
|
|
|
|
describe('useAppFavicon', () => {
|
|
beforeEach(() => {
|
|
document.head.querySelectorAll('link[rel*="icon"]').forEach((link) => link.remove())
|
|
})
|
|
|
|
afterEach(() => {
|
|
document.head.querySelectorAll('link[rel*="icon"]').forEach((link) => link.remove())
|
|
})
|
|
|
|
it('leaves the framework favicon untouched and cleans up only its own icon', async () => {
|
|
const frameworkFavicon = document.createElement('link')
|
|
frameworkFavicon.rel = 'icon'
|
|
frameworkFavicon.href = '/favicon.ico'
|
|
document.head.appendChild(frameworkFavicon)
|
|
|
|
const { unmount } = renderHook(() =>
|
|
useAppFavicon({ icon_type: 'image', icon_url: firstAppIcon }),
|
|
)
|
|
|
|
await waitFor(() => {
|
|
expect(document.head.querySelector('link[data-dify-app-favicon]')).toHaveAttribute(
|
|
'href',
|
|
firstAppIcon,
|
|
)
|
|
})
|
|
expect(frameworkFavicon.isConnected).toBe(true)
|
|
expect(frameworkFavicon).toHaveAttribute('href', '/favicon.ico')
|
|
|
|
unmount()
|
|
|
|
expect(frameworkFavicon.isConnected).toBe(true)
|
|
expect(document.head.querySelector('link[data-dify-app-favicon]')).not.toBeInTheDocument()
|
|
})
|
|
|
|
it('replaces its managed icon when the image URL changes and removes it when disabled', async () => {
|
|
const { rerender } = renderHook(
|
|
({ enable, iconUrl }) => useAppFavicon({ enable, icon_type: 'image', icon_url: iconUrl }),
|
|
{
|
|
initialProps: { enable: true, iconUrl: firstAppIcon },
|
|
},
|
|
)
|
|
|
|
await waitFor(() => {
|
|
expect(document.head.querySelector('link[data-dify-app-favicon]')).toHaveAttribute(
|
|
'href',
|
|
firstAppIcon,
|
|
)
|
|
})
|
|
|
|
rerender({ enable: true, iconUrl: secondAppIcon })
|
|
|
|
await waitFor(() => {
|
|
expect(document.head.querySelector('link[data-dify-app-favicon]')).toHaveAttribute(
|
|
'href',
|
|
secondAppIcon,
|
|
)
|
|
})
|
|
expect(document.head.querySelectorAll('link[data-dify-app-favicon]')).toHaveLength(1)
|
|
|
|
rerender({ enable: false, iconUrl: secondAppIcon })
|
|
|
|
await waitFor(() => {
|
|
expect(document.head.querySelector('link[data-dify-app-favicon]')).not.toBeInTheDocument()
|
|
})
|
|
})
|
|
|
|
it('renders emoji icons as SVG favicons', async () => {
|
|
renderHook(() =>
|
|
useAppFavicon({ icon_type: 'emoji', icon: 'robot', icon_background: '#ffffff' }),
|
|
)
|
|
|
|
await waitFor(() => {
|
|
const favicon = document.head.querySelector('link[data-dify-app-favicon]')
|
|
expect(favicon).toHaveAttribute('rel', 'icon')
|
|
expect(favicon).toHaveAttribute('type', 'image/svg+xml')
|
|
expect(favicon?.getAttribute('href')).toContain('data:image/svg+xml')
|
|
expect(favicon?.getAttribute('href')).toContain('%23ffffff')
|
|
expect(favicon?.getAttribute('href')).toContain('🤖')
|
|
})
|
|
})
|
|
|
|
it('uses linked icons as direct favicon URLs', async () => {
|
|
renderHook(() => useAppFavicon({ icon_type: 'link', icon: firstAppIcon }))
|
|
|
|
await waitFor(() => {
|
|
expect(document.head.querySelector('link[data-dify-app-favicon]')).toHaveAttribute(
|
|
'href',
|
|
firstAppIcon,
|
|
)
|
|
})
|
|
})
|
|
|
|
it('preserves the fallback icon for legacy null icon metadata', async () => {
|
|
renderHook(() => useAppFavicon({ icon_type: null }))
|
|
|
|
await waitFor(() => {
|
|
expect(
|
|
document.head.querySelector('link[data-dify-app-favicon]')?.getAttribute('href'),
|
|
).toContain('🤖')
|
|
})
|
|
})
|
|
})
|