import { describe, it, expect } from 'vitest' import { pageSchema, type Page } from '@/lib/schema/page' import { exportPage } from '@/lib/exporter/html' const makeSamplePage = (): Page => pageSchema.parse({ title: 'Sample Landing', locale: 'en', theme: { primaryColor: '#0ea5e9', fontFamily: 'Inter' }, sections: [ { type: 'hero', props: { heading: 'Welcome', subheading: 'Build fast', imageUrl: 'https://cdn.example.com/hero.png', }, }, ], form: { actionUrl: '', fields: [ { type: 'text', name: 'name', label: 'Name', required: true }, { type: 'email', name: 'email', label: 'Email', required: true }, { type: 'checkbox', name: 'agree', label: 'Agree', required: true }, ], spamProtection: { honeypotFieldName: '_hp', minSubmitSeconds: 2 }, }, analytics: { ga4MeasurementId: '', metaPixelId: '' }, seo: { title: 'Sample Landing', description: 'desc', ogImage: 'https://cdn.example.com/og.png' }, }) describe('HTML Exporter', () => { it('페이지를 정적 HTML/CSS/JS로 내보낸다', () => { const page = makeSamplePage() const out = exportPage(page) expect(typeof out.html).toBe('string') expect(typeof out.css).toBe('string') expect(typeof out.js).toBe('string') // 기본 요소 포함 expect(out.html).toContain('') expect(out.html).toContain('') expect(out.html).toContain('Sample Landing') // OG/SEO expect(out.html).toContain('meta property="og:title"') expect(out.html).toContain('meta property="og:image"') // Hero 섹션 렌더링 expect(out.html).toContain('Welcome') expect(out.html).toContain('Build fast') expect(out.html).toContain('https://cdn.example.com/hero.png') // Form 렌더링 및 스팸방지 요소 expect(out.html).toContain('name="name"') expect(out.html).toContain('name="email"') expect(out.html).toContain('name="agree"') expect(out.html).toContain('type="hidden"') // honeypot 또는 타임스탬프 // actionUrl 미지정이면 data-hint 포함(향후 Sheets 연결 힌트) expect(out.html).toContain('data-sheets-fallback="true"') }) it('파일 input은 생성하지 않는다', () => { const page = makeSamplePage() const out = exportPage(page) expect(out.html).not.toMatch(/type=\"file\"/) }) })