93 lines
4.7 KiB
TypeScript
93 lines
4.7 KiB
TypeScript
import { flushPromises, mount, type VueWrapper } from '@vue/test-utils'
|
|
import { afterEach, describe, expect, it, vi } from 'vitest'
|
|
import { NImage } from 'naive-ui'
|
|
import AssetImage from '@/components/ui/AssetImage.vue'
|
|
|
|
let wrapper: VueWrapper | undefined
|
|
afterEach(() => {
|
|
wrapper?.unmount()
|
|
wrapper = undefined
|
|
document.body.innerHTML = ''
|
|
vi.useRealTimers()
|
|
vi.unstubAllGlobals()
|
|
})
|
|
|
|
describe('资源图片展示与原图预览', () => {
|
|
it('默认使用 cover 并禁用预览,不干扰历史缩略图选择', async () => {
|
|
wrapper = mount(AssetImage, {
|
|
attachTo: document.body,
|
|
props: { src: '/storage/history.png', alt: '历史图片' }
|
|
})
|
|
expect(wrapper.getComponent(NImage).props()).toMatchObject({ objectFit: 'cover', previewDisabled: true })
|
|
expect(wrapper.get<HTMLImageElement>('img').element.style.objectFit).toBe('cover')
|
|
await wrapper.get('img').trigger('click')
|
|
await flushPromises()
|
|
expect(document.querySelector('.n-image-preview-container')).toBeNull()
|
|
})
|
|
|
|
it('特殊展示仍可显式选择 contain,样式交由 NImage 控制', () => {
|
|
wrapper = mount(AssetImage, {
|
|
props: { src: '/storage/reference.png', alt: '完整参考图', objectFit: 'contain' }
|
|
})
|
|
expect(wrapper.getComponent(NImage).props('objectFit')).toBe('contain')
|
|
expect(wrapper.get<HTMLImageElement>('img').element.style.objectFit).toBe('contain')
|
|
})
|
|
|
|
it('图片加载前显示轻量骨架占位,加载完成后直接淡入图片并移除占位', async () => {
|
|
wrapper = mount(AssetImage, { props: { src: '/storage/reveal.png', alt: '加载中的图片' } })
|
|
expect(wrapper.get('.reveal-image').attributes('aria-busy')).toBe('true')
|
|
expect(wrapper.find('.reveal-image-placeholder').exists()).toBe(true)
|
|
expect(wrapper.find('.reveal-image-grid').exists()).toBe(false)
|
|
await wrapper.get('img').trigger('load')
|
|
expect(wrapper.get('.reveal-image').classes()).toContain('is-loaded')
|
|
expect(wrapper.get('.reveal-image').attributes('aria-busy')).toBe('false')
|
|
expect(wrapper.find('.reveal-image-placeholder').exists()).toBe(false)
|
|
})
|
|
|
|
it('cover 仅裁切卡片,点击使用 Naive 原生预览展示同一完整资源,遮罩可关闭', async () => {
|
|
wrapper = mount(AssetImage, {
|
|
attachTo: document.body,
|
|
props: { src: '/storage/original.png', alt: '林默 · 基础形态', objectFit: 'cover', preview: true }
|
|
})
|
|
const source = wrapper.get('img').attributes('src')
|
|
expect(wrapper.getComponent(NImage).props()).toMatchObject({
|
|
objectFit: 'cover',
|
|
previewDisabled: false,
|
|
previewSrc: source
|
|
})
|
|
expect(wrapper.get<HTMLImageElement>('img').element.style.objectFit).toBe('cover')
|
|
await wrapper.get('img').trigger('click')
|
|
await flushPromises()
|
|
const image = document.querySelector<HTMLImageElement>('.n-image-preview')!
|
|
expect(image).not.toBeNull()
|
|
expect(image.getAttribute('src')).toBe(source)
|
|
expect(image.alt).toBe('林默 · 基础形态')
|
|
expect(image.getAttribute('referrerpolicy')).toBe('no-referrer')
|
|
expect(image.style.objectFit).not.toBe('cover')
|
|
expect(document.querySelector('.n-image-preview-toolbar')).not.toBeNull()
|
|
expect(wrapper.element.contains(image)).toBe(false)
|
|
document.querySelector<HTMLElement>('.n-image-preview-overlay')!.click()
|
|
await flushPromises()
|
|
expect(document.querySelector<HTMLElement>('.n-image-preview-wrapper')?.style.display ?? 'none').toBe('none')
|
|
})
|
|
|
|
it('资源加载失败只显示重试占位,不打开空预览', async () => {
|
|
wrapper = mount(AssetImage, {
|
|
attachTo: document.body,
|
|
props: { src: '/storage/missing.png', alt: '失败图片', objectFit: 'cover', preview: true }
|
|
})
|
|
await wrapper.get('img').trigger('error')
|
|
expect(wrapper.text()).toContain('图片无法加载')
|
|
expect(wrapper.findComponent(NImage).exists()).toBe(false)
|
|
expect(document.querySelector('.n-image-preview-container')).toBeNull()
|
|
await wrapper.get('button').trigger('click')
|
|
expect(wrapper.getComponent(NImage).props('previewDisabled')).toBe(false)
|
|
})
|
|
|
|
it.each([null, 'javascript:alert(1)', 'data:text/html,test'])('空地址或危险地址 %s 不进入原图预览', src => {
|
|
wrapper = mount(AssetImage, { props: { src, alt: '图片', objectFit: 'cover', preview: true } })
|
|
expect(wrapper.findComponent(NImage).exists()).toBe(false)
|
|
expect(wrapper.find('img').exists()).toBe(false)
|
|
})
|
|
})
|