Files
site-builder/craft/src/components/sections/FeaturesGrid.toHtml.test.ts
T
shadowdaoandClaude Sonnet 5.5 2877bc06fa feat(site-builder): tokenise colours hard-coded inside components
Component render/toHtml now use var(--wsb-*) instead of hex so Site Design
palette changes reach FeaturesGrid, Testimonials, Accordion, PricingTable,
CTA/CallToAction, forms, Gallery, Tabs and others. Exemption lists removed.

Refs #44

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 12:44:39 -07:00

53 lines
2.4 KiB
TypeScript

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 <img src>', () => {
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(`<img src="${svgDataUri}"`);
});
test('feat.buttonUrl stays on safeUrl (data:image/svg+xml blocked as a navigation target)', () => {
const features = [
{ title: 'Feature', description: 'Desc', icon: '⚡', buttonText: 'Go', buttonUrl: 'data:image/svg+xml,<svg onload=alert(1)>' },
];
const { html } = toHtml({ features }, '');
expect(html).toMatch(/<a href=""/);
});
});
describe('FeaturesGrid.craft.props includes the box-model/animation/visibility rollout props', () => {
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);
});
});