/** @jest-environment jsdom */ require('../sanitizer.js'); describe('htmlSanitizer', () => { it('escape() encodes special HTML chars', () => { const { escape } = window.htmlSanitizer; expect(escape('
')).toBe('<div>'); expect(escape('Tom & Jerry')).toBe('Tom & Jerry'); expect(escape('"quotes" and \'apostrophes\'')).toContain('"'); }); it('sanitize() returns safe HTML and does not double-escape plain text', () => { const { sanitize, escape } = window.htmlSanitizer; const dirty = '

Hello

'; const clean = sanitize(dirty); expect(clean).toContain('Hello

'); expect(clean).not.toMatch(/onerror/i); const text = 'bold'; const escaped = escape(text); const sanitizedEscaped = sanitize(escaped); expect(sanitizedEscaped).toBe(escaped); }); it('setSafeHTML sets sanitized HTML on the element', () => { const el = document.createElement('div'); const dirty = '

Hello

'; window.setSafeHTML(el, dirty); expect(el.innerHTML).toContain('Hello

'); expect(el.innerHTML).not.toMatch(/onerror/i); }); it('setSafeHTML uses DOMPurify when it becomes available after first call', () => { // Ensure not present initially delete window.DOMPurify; const el = document.createElement('div'); const html = 'hello'; // First call: fallback sanitizer (no DOMPurify) window.setSafeHTML(el, html); // Now make DOMPurify available const mockPurify = { sanitize: jest.fn((h) => `CLEAN:${h}`) }; window.DOMPurify = mockPurify; // Second call should use DOMPurify window.setSafeHTML(el, html); expect(mockPurify.sanitize).toHaveBeenCalledTimes(1); expect(el.innerHTML).toBe(`CLEAN:${html}`); }); });