import { describe, test, expect } from 'vitest'; import { HtmlBlock, purifyHtml } from './HtmlBlock'; const toHtml = (HtmlBlock as any).toHtml; describe('HtmlBlock.toHtml sanitizes raw code (A4.1)', () => { test('strips

hi

' }, ''); expect(html).not.toContain('hi

'); }); test('does not wrap output in an unsanitized element carrying the style prop raw', () => { // toHtml only ever returns the sanitized `code` blob -- there is no // wrapper
in the exported HTML, so a malicious // `style` prop (e.g. an attacker-controlled object with a breakout // toString()) has nothing to splice into. const malicious = { toString: () => 'color:red" onmouseover="alert(1)' } as any; const { html } = toHtml({ code: '

hi

', style: malicious }, ''); expect(html).not.toMatch(/onmouseover/); expect(html).not.toMatch(/
hi

'); }); }); test('toHtml never emits the style prop (the other half of the render/export contract)', () => { const out = (HtmlBlock as any).toHtml( { code: '

hi

', style: { backgroundColor: '#ff0000', padding: '40px' } }, '', ); expect(out.html).toBe('

hi

'); expect(out.html).not.toContain('background'); expect(out.html).not.toContain('40px'); }); describe('HtmlBlock.toHtml markup path (C1 review finding)', () => { test('a style attribute inside `code` (e.g. from the toolbar colour picker) reaches exported output', () => { const { html } = toHtml({ code: '

red text

' }, ''); expect(html).toBe('

red text

'); }); test('a table inside `code` reaches exported output', () => { const code = '
Cell
'; const { html } = toHtml({ code }, ''); expect(html).toBe(code); }); }); describe('HtmlBlock.toHtml -- Task 25: block-scoped

Hi

'; const { html } = toHtml({ code }, ''); expect(html).toBe(purifyHtml(code)); }); test('a