import { describe, it, expect, vi, beforeEach } from 'vitest' import { mount, flushPromises } from '@vue/test-utils' import ImageCardPage from './ImageCardPage.vue' const { api } = vi.hoisted(() => ({ api: { authMe: vi.fn(), listImageCardScenes: vi.fn(), getImageCardQuota: vi.fn(), listProfiles: vi.fn(), createProfile: vi.fn(), updateProfile: vi.fn(), drawImageCard: vi.fn(), createOrder: vi.fn(), payMock: vi.fn(), getReport: vi.fn(), }, })) vi.mock('../api/client', () => ({ api })) vi.mock('vue-router', () => ({ useRoute: () => ({ query: {}, fullPath: '/cards' }), useRouter: () => ({ back: vi.fn(), replace: vi.fn() }), })) describe('ImageCardPage', () => { beforeEach(() => { vi.clearAllMocks() api.authMe.mockResolvedValue({ id: 'u1' }) api.listImageCardScenes.mockResolvedValue({ items: [ { key: '情绪整理', label: '情绪整理' }, { key: '关系', label: '关系' }, ], }) api.getImageCardQuota.mockResolvedValue({ remaining: 3, daily_free: 3, unlimited: false }) }) it('boots scenes and draws a card', async () => { api.listProfiles.mockResolvedValue({ items: [] }) api.createProfile.mockResolvedValue({ id: 'p1' }) api.drawImageCard.mockResolvedValue({ scene: '情绪整理', quota_left: 2, cards: [ { id: 'c01', title: '微光小路', imagery: '一条小路', prompt: '你想靠近什么?', tip: '走一小步', }, ], report: { id: 'r-card', has_deep_access: false, summary: { headline: '意象·探索' }, detail: null, }, }) const w = mount(ImageCardPage) await flushPromises() expect(w.text()).toContain('意象卡片') expect(w.text()).toContain('投射整理') expect(w.text()).toContain('今日剩余') expect(w.text()).toContain('情绪整理') const inputs = w.findAll('input[type="number"]') await inputs[0].setValue('1990') await inputs[1].setValue('5') await inputs[2].setValue('12') await w.findAll('button').find((b) => b.text().includes('抽取卡片'))!.trigger('click') await flushPromises() expect(api.drawImageCard).toHaveBeenCalled() expect(w.text()).toContain('微光小路') expect(w.text()).toContain('走一小步') }) })