import { describe, expect, it } from 'vitest'; import { purifyNationHtml } from '../src/security/nationHtml.js'; describe('nation HTML purification', () => { it('removes executable markup and unsafe URL/CSS vectors', () => { const dirty = [ '', '', '', 'unsafe link', '

notice

', '', '', 'svg', ].join(''); const clean = purifyNationHtml(dirty); expect(clean).not.toMatch(/script|onerror|onclick|onmouseover|onload|javascript:|background-image|attacker/i); expect(clean).not.toContain('unsafe link'); expect(clean).toContain('

notice

'); expect(clean).toContain(''); }); it('does not throw on malformed escaped filenames and preserves the raw basename as alt text', () => { expect(purifyNationHtml('')).toBe('%E0%A4%A'); expect(purifyNationHtml('')).toBe( 'a%20b.pngy' ); }); it('matches Ref iframe whitespace and case handling', () => { expect( purifyNationHtml( [ '', '', '', ].join('') ) ).toBe(''); }); it('preserves Ref-compatible formatting, data-flip, images, and safe video embeds', () => { const source = [ '
', '북벌
', '계획', '장수', '', '', '
', ].join(''); const clean = purifyNationHtml(source); expect(clean).toContain('class="notice"'); expect(clean).toContain('data-flip="horizontal"'); expect(clean).toContain('style="text-align:center;color:#00ffff"'); expect(clean).toContain('북벌
'); expect(clean).toContain('href="https://example.com/path"'); expect(clean).not.toContain('target="_blank"'); expect(clean).toContain('src="/image/icons/default.jpg"'); expect(clean).toContain('alt="장수"'); expect(clean).toContain('srcset="/image/icons/default.jpg 1x"'); expect(clean).toContain('//www.youtube-nocookie.com/embed/abc123'); expect(clean).toContain('https://player.vimeo.com/video/1234'); }); it('is idempotent for already-purified stored values', () => { const first = purifyNationHtml('

방침

'); expect(purifyNationHtml(first)).toBe(first); }); });