import { describe, test, expect } from 'vitest'; import { FeaturesGrid } from './FeaturesGrid'; const toHtml = (FeaturesGrid as any).toHtml; describe('FeaturesGrid.toHtml image sink uses safeImageUrl (data:image/svg+xml allowed)', () => { test('feat.image as a data:image/svg+xml value emits a non-empty ', () => { const svgDataUri = 'data:image/svg+xml,%3Csvg%2F%3E'; const features = [ { title: 'Feature', description: 'Desc', icon: '⚡', image: svgDataUri, imageAlt: 'alt' }, ]; const { html } = toHtml({ features }, ''); expect(html).toContain(` { const features = [ { title: 'Feature', description: 'Desc', icon: '⚡', buttonText: 'Go', buttonUrl: 'data:image/svg+xml,' }, ]; const { html } = toHtml({ features }, ''); expect(html).toMatch(/ { test('animation, animationDelay, and all 3 hideOn* flags are declared (blank/false defaults)', () => { const props = (FeaturesGrid as any).craft.props; expect(props).toHaveProperty('animation', ''); expect(props).toHaveProperty('animationDelay', ''); expect(props).toHaveProperty('hideOnDesktop', false); expect(props).toHaveProperty('hideOnTablet', false); expect(props).toHaveProperty('hideOnMobile', false); }); }); describe('FeaturesGrid.toHtml palette token fallback (Refs #44)', () => { test('feature button background is the primary token', () => { const features = [{ title: 'F', description: 'D', buttonText: 'More', buttonUrl: '/x' }]; const { html } = toHtml({ features }, ''); expect(html).toContain('background:var(--wsb-primary)'); expect(html).not.toContain('#3b82f6'); }); }); describe('FeaturesGrid.toHtml design tokens (#44)', () => { test('default export references var(--wsb-*) and no longer carries the old hard-coded hex', () => { const { html } = toHtml({}, ''); const lower = html.toLowerCase(); for (const t of ["bg", "border", "text", "muted"]) expect(html, `token ${t}`).toContain(`var(--wsb-${t})`); for (const hex of ["#f8fafc", "#e2e8f0", "#18181b", "#64748b", "#fff"]) expect(lower, `old ${hex}`).not.toContain(hex); }); });