test(zip): 통합/메타 스냅샷 테스트 추가(exportPage+buildZip, SEO/OG/Analytics 보존)
Auto PR / open-pr (push) Successful in 21s
CI / test (pull_request) Failing after 11m23s
Auto Label PR / add-automerge-label (pull_request) Failing after 11m30s

This commit is contained in:
2025-11-14 23:53:28 +09:00
parent 46a9c5c83d
commit 678b081364
2 changed files with 81 additions and 0 deletions
@@ -0,0 +1,53 @@
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(/<link rel="canonical" href="\//)
expect(html).toMatch(/<meta name="description" content="d"/)
expect(html).toMatch(/gtag\('config', 'G-TEST'\)/)
// hero 이미지가 재작성된 경로를 사용한다
const match = html.match(/<img[^>]*src="([^"]+)"/)
expect(match && match[1]).toBe(assetKey)
})
})