import { describe, test, expect } from 'vitest'; import { PricingTable } from './PricingTable'; const toHtml = (PricingTable as any).toHtml; const plans = [ { name: 'Basic', price: '$9', period: '/month', features: ['Feature A'], buttonText: 'Buy', buttonHref: '#', isFeatured: false }, { name: 'Pro', price: '$29', period: '/month', features: ['Feature B'], buttonText: 'Buy', buttonHref: '#', isFeatured: true }, ]; describe('PricingTable.toHtml regular-card color overrides (previously hard-coded, now real props)', () => { test('cardBg emits as the non-featured card background', () => { const { html } = toHtml({ plans, cardBg: '#f0f0f0' }, ''); expect(html).toContain('background-color:#f0f0f0'); }); test('textColor emits as the non-featured heading/price color', () => { const { html } = toHtml({ plans, textColor: '#123456' }, ''); expect(html).toContain('color:#123456'); }); test('subColor emits as the non-featured period text color', () => { const { html } = toHtml({ plans, subColor: '#abcdef' }, ''); expect(html).toContain('color:#abcdef'); }); test('featColor emits as the non-featured feature list text color', () => { const { html } = toHtml({ plans, featColor: '#334455' }, ''); expect(html).toContain('color:#334455'); }); test('checkColor emits as the non-featured bullet color', () => { const { html } = toHtml({ plans, checkColor: '#00ff00' }, ''); expect(html).toContain('color:#00ff00'); }); test('btnBg/btnColor emit as the non-featured button colors', () => { const { html } = toHtml({ plans, btnBg: '#111111', btnColor: '#eeeeee' }, ''); expect(html).toContain('background-color:#111111'); expect(html).toContain('color:#eeeeee'); }); test('unset overrides fall back to the exact prior literals (backward compatible)', () => { const { html } = toHtml({ plans }, ''); // Regular (non-featured) card literals unchanged from before these props existed. expect(html).toContain('background-color:#ffffff'); expect(html).toContain('color:#18181b'); expect(html).toContain('color:#64748b'); expect(html).toContain('color:#4b5563'); expect(html).toContain('color:#10b981'); }); test('unset btnBg falls back to featuredBg (original derivation)', () => { const { html } = toHtml({ plans, featuredBg: '#654321' }, ''); expect(html).toContain('background-color:#654321'); }); }); describe('PricingTable.toHtml XSS hardening (new card color props into style=)', () => { test('a cardBg breakout string cannot escape style=""', () => { const malicious = '#fff" onmouseover="alert(1)'; const { html } = toHtml({ plans, cardBg: malicious }, ''); expect(html).not.toMatch(/"\s+onmouseover="/); }); test('a textColor breakout string cannot escape style=""', () => { const malicious = '#000" onmouseover="alert(1)'; const { html } = toHtml({ plans, textColor: malicious }, ''); expect(html).not.toMatch(/"\s+onmouseover="/); }); test('a btnBg breakout string cannot escape style=""', () => { const malicious = '#000" onmouseover="alert(1)'; const { html } = toHtml({ plans, btnBg: malicious }, ''); expect(html).not.toMatch(/"\s+onmouseover="/); }); test('a btnColor breakout string cannot escape style=""', () => { const malicious = '#000" onmouseover="alert(1)'; const { html } = toHtml({ plans, btnColor: malicious }, ''); expect(html).not.toMatch(/"\s+onmouseover="/); }); }); describe('PricingTable.craft.props includes the box-model/animation/visibility rollout props', () => { test('the new regular-card color props are declared blank by default', () => { const props = (PricingTable as any).craft.props; expect(props).toHaveProperty('cardBg', ''); expect(props).toHaveProperty('textColor', ''); expect(props).toHaveProperty('subColor', ''); expect(props).toHaveProperty('featColor', ''); expect(props).toHaveProperty('checkColor', ''); expect(props).toHaveProperty('btnBg', ''); expect(props).toHaveProperty('btnColor', ''); }); test('animation, animationDelay, and all 3 hideOn* flags are declared (blank/false defaults)', () => { const props = (PricingTable 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); }); });