import { afterEach, describe, expect, it, vi } from 'vitest' import { flushPromises, mount, type VueWrapper } from '@vue/test-utils' import { createMemoryHistory, createRouter } from 'vue-router' import AssetLibraryPage from '@/features/project-assets/AssetLibraryPage.vue' let wrapper: VueWrapper | undefined afterEach(() => { wrapper?.unmount() wrapper = undefined document.body.innerHTML = '' vi.unstubAllGlobals() }) describe('全局资产库', () => { it('单次读取并直接显示全部剧本图片,支持按图片与剧本搜索', async () => { const fetcher = vi.fn().mockResolvedValue( new Response( JSON.stringify({ data: [ { id: 'asset-scene', projectId: 'project-one', name: '雨夜街道', type: 'image', category: 'scene', mimeType: 'image/png', extension: 'png', size: 4096, publicUrl: '/storage/scene.png', metadata: null, createdAt: '2026-09-22T00:00:00Z', updatedAt: '2026-09-22T00:00:00Z', project: { id: 'project-one', title: '记忆当铺', topic: '记忆交易', status: 'completed' } }, { id: 'asset-character', projectId: 'project-two', name: '林默正面照', type: 'image', category: 'character', mimeType: 'image/jpeg', extension: 'jpg', size: 8192, publicUrl: '/storage/character.jpg', metadata: null, createdAt: '2026-09-22T01:00:00Z', updatedAt: '2026-09-22T01:00:00Z', project: { id: 'project-two', title: '天降甘霖', topic: '乡村故事', status: 'completed' } } ] }) ) ) vi.stubGlobal('fetch', fetcher) const router = createRouter({ history: createMemoryHistory(), routes: [ { path: '/assets', component: AssetLibraryPage }, { path: '/projects/:projectId/assets', component: { template: '
' } } ] }) await router.push('/assets') wrapper = mount(AssetLibraryPage, { attachTo: document.body, global: { plugins: [router] } }) await flushPromises() expect(fetcher).toHaveBeenCalledOnce() expect(fetcher).toHaveBeenCalledWith('/api/assets', expect.objectContaining({ method: 'GET' })) expect(wrapper.findAll('.asset-library-card')).toHaveLength(2) expect(wrapper.text()).toContain('雨夜街道') expect(wrapper.text()).toContain('林默正面照') expect(wrapper.text()).toContain('记忆当铺') await wrapper.get('input[aria-label="搜索资产图片"]').setValue('天降甘霖') expect(wrapper.findAll('.asset-library-card')).toHaveLength(1) expect(wrapper.text()).toContain('林默正面照') expect(wrapper.text()).not.toContain('雨夜街道') }) })