import { describe, it, expect } from 'vitest' import JSZip from 'jszip' import { exportPage } from '@/lib/exporter/html' import { buildZip } from '@/lib/exporter/zip' import { AssetManager } from '@/lib/assets/assetManager' import { pageSchema, type Page } from '@/lib/schema/page' function makePageWithLocalAsset(): { page: Page; am: AssetManager } { const am = new AssetManager({ maxBytes: 1024 * 1024, allowedExts: ['png','svg','jpg','jpeg','webp'] }) // simulate adding a local image and referencing it by original name via local: prefix const bytes = new Uint8Array([7,8,9]) // add as "hero.png" am.add({ name: 'hero.png', type: 'image/png', bytes }) const base: Page = pageSchema.parse({ title: 'Integrated ZIP', locale: 'en', theme: { primaryColor: '#2563eb', fontFamily: 'Inter' }, sections: [ { type: 'hero', props: { heading: 'Hello', subheading: 'World', imageUrl: 'local:hero.png' } }, { type: 'cta', props: { text: 'Go', href: '#' } }, ], form: { actionUrl: '', fields: [], spamProtection: { honeypotFieldName: '_hp', minSubmitSeconds: 2 } }, analytics: { ga4MeasurementId: 'G-TEST', metaPixelId: '', customHeadHtml: '' }, seo: { title: 't', description: 'd' }, }) return { page: base, am } } describe('Export ZIP 통합 검증', () => { it('exportPage 출력 + buildZip 결과에서 assets 경로/메타가 보존된다', async () => { const { page, am } = makePageWithLocalAsset() const out = exportPage(page, { assetManager: am }) const assets = am.toZipStructure() const zipBytes = await buildZip({ html: out.html, css: out.css, js: out.js, assets }) const zip = await JSZip.loadAsync(zipBytes) const names = Object.keys(zip.files) // assets 파일이 존재해야 함 const assetKey = Object.keys(assets)[0] expect(names).toContain(assetKey) // index.html에 canonical/meta/ga4 스니펫 보존 const html = await zip.files['index.html'].async('string') expect(html).toMatch(/]*src="([^"]+)"/) expect(match && match[1]).toBe(assetKey) }) })