import { describe, test, expect } from 'vitest'; import { HeroSimple } from './HeroSimple'; const toHtml = (HeroSimple as any).toHtml; describe('HeroSimple.toHtml textAlign enum sink (attacker-controlled prop, not enforced at runtime)', () => { test('malicious textAlign value cannot break out of the content div style attribute', () => { const { html } = toHtml({ heading: 'Hi', subtitle: 'There', textAlign: 'center;">', }, ''); expect(html).not.toContain(''); expect(html).not.toContain('center;">'); }); test('unrecognized textAlign value falls back to a safe default rather than being echoed raw', () => { const { html } = toHtml({ heading: 'Hi', subtitle: 'There', textAlign: 'not-a-real-value' as any }, ''); expect(html).not.toContain('text-align:not-a-real-value'); }); test('valid textAlign values are preserved', () => { const { html: left } = toHtml({ heading: 'Hi', subtitle: 'There', textAlign: 'left' }, ''); expect(left).toContain('text-align:left'); const { html: right } = toHtml({ heading: 'Hi', subtitle: 'There', textAlign: 'right' }, ''); expect(right).toContain('text-align:right'); }); test('normal default render is sane', () => { const { html } = toHtml({ heading: 'Welcome', subtitle: 'Sub text' }, ''); expect(html).toContain('Welcome'); expect(html).toContain('Sub text'); expect(html).toContain('text-align:center'); }); }); describe('HeroSimple.toHtml palette token fallback (Refs #44)', () => { test('buttonBgColor absent/empty -> primary token on the CTA', () => { for (const buttonBgColor of [undefined, '']) { const { html } = toHtml({ heading: 'H', buttonText: 'Go', buttonLink: '#', buttonBgColor }, ''); expect(html).toContain('var(--wsb-primary)'); expect(html).not.toContain('#3b82f6'); } }); test('explicit buttonBgColor wins', () => { const { html } = toHtml({ heading: 'H', buttonText: 'Go', buttonLink: '#', buttonBgColor: '#ff0000' }, ''); expect(html).toContain('#ff0000'); expect(html).not.toContain('var(--wsb-primary)'); }); }); describe('HeroSimple.toHtml bgPosition focal point (#55)', () => { const base = { heading: 'Hi', subtitle: 'There', bgType: 'image', bgImage: 'assets/a.jpg' }; test('bgPosition is emitted as background-position', () => { const { html } = toHtml({ ...base, bgPosition: 'left top' }, ''); expect(html).toContain('background-position:left top'); expect(html).not.toContain('background-position:center'); }); test('blank or missing bgPosition keeps center', () => { expect(toHtml({ ...base, bgPosition: '' }, '').html).toContain('background-position:center'); expect(toHtml(base, '').html).toContain('background-position:center'); }); test('a malicious bgPosition cannot break out of the style attribute', () => { const { html } = toHtml({ ...base, bgPosition: 'left";}' }, ''); expect(html).not.toContain('