import { applyThemeToCss, clearThemeCss, Theme, } from '../../frontend/src/app/core/services/bootstrap.types'; function makeClassicTheme(): Theme { return { id: 'classic', name: 'Classic', tokens: { primary: '#3b82f6', secondary: '#64748b', accent: '#f59e0b', surface: '#ffffff', text: '#0f172a', success: '#10b981', warning: '#f59e0b', danger: '#ef4444', fontFamily: 'system-ui, sans-serif', radii: { sm: '4px', md: '8px', lg: '16px' }, spacingScale: [4, 8, 12, 16, 24, 32, 48], }, }; } function makeMonochromeTheme(): Theme { return { id: 'monochrome', name: 'Monochrome', tokens: { primary: '#000000', secondary: '#525252', accent: '#a3a3a3', surface: '#ffffff', text: '#0a0a0a', success: '#404040', warning: '#737373', danger: '#171717', fontFamily: 'system-ui, sans-serif', radii: { sm: '0', md: '0', lg: '0' }, spacingScale: [4, 8, 12, 16, 24, 32, 48], }, }; } describe('applyThemeToCss', () => { beforeEach(() => { clearThemeCss(); }); it('writes all CSS custom properties from the Classic theme tokens', () => { applyThemeToCss(makeClassicTheme()); const root = document.documentElement.style; expect(root.getPropertyValue('--color-primary')).toBe('#3b82f6'); expect(root.getPropertyValue('--color-secondary')).toBe('#64748b'); expect(root.getPropertyValue('--color-accent')).toBe('#f59e0b'); expect(root.getPropertyValue('--color-surface')).toBe('#ffffff'); expect(root.getPropertyValue('--color-text')).toBe('#0f172a'); expect(root.getPropertyValue('--color-success')).toBe('#10b981'); expect(root.getPropertyValue('--color-warning')).toBe('#f59e0b'); expect(root.getPropertyValue('--color-danger')).toBe('#ef4444'); expect(root.getPropertyValue('--font-family')).toBe('system-ui, sans-serif'); expect(root.getPropertyValue('--radius-sm')).toBe('4px'); expect(root.getPropertyValue('--radius-md')).toBe('8px'); expect(root.getPropertyValue('--radius-lg')).toBe('16px'); }); it('returns false and is a no-op when the theme is missing tokens', () => { expect(applyThemeToCss(null)).toBe(false); expect(applyThemeToCss(undefined)).toBe(false); expect(applyThemeToCss({ id: 'x', name: 'X' } as unknown as Theme)).toBe(false); const root = document.documentElement.style; expect(root.getPropertyValue('--color-primary')).toBe(''); expect(root.getPropertyValue('--radius-md')).toBe(''); }); it('replaces Classic tokens with Monochrome tokens when re-applied', () => { applyThemeToCss(makeClassicTheme()); applyThemeToCss(makeMonochromeTheme()); const root = document.documentElement.style; expect(root.getPropertyValue('--color-primary')).toBe('#000000'); expect(root.getPropertyValue('--color-text')).toBe('#0a0a0a'); expect(root.getPropertyValue('--radius-md')).toBe('0'); expect(root.getPropertyValue('--radius-sm')).toBe('0'); expect(root.getPropertyValue('--radius-lg')).toBe('0'); }); it('treats the zero-valued Monochrome radius as a valid applied value', () => { applyThemeToCss(makeMonochromeTheme()); expect(document.documentElement.style.getPropertyValue('--radius-md')).toBe('0'); }); }); describe('clearThemeCss', () => { it('removes every theme CSS custom property set by applyThemeToCss', () => { applyThemeToCss(makeClassicTheme()); clearThemeCss(); const root = document.documentElement.style; expect(root.getPropertyValue('--color-primary')).toBe(''); expect(root.getPropertyValue('--color-text')).toBe(''); expect(root.getPropertyValue('--radius-md')).toBe(''); expect(root.getPropertyValue('--font-family')).toBe(''); }); });