import { describe, it, expect } from 'vitest'; import { containsHTML, wrapHTMLInCodeBlock } from '../utils/htmlSecurity'; describe('HTML Security Detection', () => { describe('containsHTML', () => { describe('should detect dangerous HTML tags', () => { it('detects script tags', () => { expect(containsHTML('')).toBe(true); expect(containsHTML('')).toBe(true); expect(containsHTML('`')).toBe(false); expect(containsHTML('Here is `
` in inline code')).toBe(false); }); it('ignores plain text', () => { expect(containsHTML('This is just plain text')).toBe(false); expect(containsHTML('No HTML here!')).toBe(false); expect(containsHTML('')).toBe(false); }); it('ignores mathematical expressions', () => { expect(containsHTML('x < y && y > z')).toBe(false); expect(containsHTML('if (a < b && c > d)')).toBe(false); }); }); describe('edge cases', () => { it('handles mixed content correctly', () => { // Real HTML mixed with safe content expect(containsHTML('Visit and
click here
')).toBe(true); // Only safe content expect(containsHTML('Email about setup')).toBe(false); }); it('handles malformed HTML', () => { expect(containsHTML('
')).toBe(false); expect(containsHTML('< div >')).toBe(false); }); }); }); describe('wrapHTMLInCodeBlock', () => { describe('should wrap dangerous HTML', () => { it('wraps single line HTML', () => { const input = ''; const expected = '```html\n\n```'; expect(wrapHTMLInCodeBlock(input)).toBe(expected); }); it('wraps HTML comments', () => { const input = ''; const expected = '```html\n\n```'; expect(wrapHTMLInCodeBlock(input)).toBe(expected); }); it('wraps mixed content selectively', () => { const input = `Normal text
This should be wrapped
More normal text`; const expected = `Normal text \`\`\`html
This should be wrapped
\`\`\` More normal text`; expect(wrapHTMLInCodeBlock(input)).toBe(expected); }); }); describe('should preserve safe content', () => { it('preserves auto-links', () => { const input = 'Visit for more info'; expect(wrapHTMLInCodeBlock(input)).toBe(input); }); it('preserves email addresses', () => { const input = 'Contact for help'; expect(wrapHTMLInCodeBlock(input)).toBe(input); }); it('preserves TypeScript generics', () => { const input = 'const arr: Array = []'; expect(wrapHTMLInCodeBlock(input)).toBe(input); }); it('preserves existing code blocks', () => { const input = `# Title \`\`\`javascript const x = "
this is safe
"; \`\`\` Normal text`; expect(wrapHTMLInCodeBlock(input)).toBe(input); }); it('preserves inline code', () => { const input = 'Use `
` for line breaks'; expect(wrapHTMLInCodeBlock(input)).toBe(input); }); }); describe('complex scenarios', () => { it('handles multiple HTML lines correctly', () => { const input = `# Test Message Normal paragraph
First HTML line
Second HTML line More normal text`; const expected = `# Test Message Normal paragraph \`\`\`html
First HTML line
\`\`\` \`\`\`html Second HTML line \`\`\` More normal text`; expect(wrapHTMLInCodeBlock(input)).toBe(expected); }); it('respects existing code block boundaries', () => { const input = `Before code block \`\`\`html
This is already safe
\`\`\`
This should be wrapped
`; const expected = `Before code block \`\`\`html
This is already safe
\`\`\` \`\`\`html
This should be wrapped
\`\`\``; expect(wrapHTMLInCodeBlock(input)).toBe(expected); }); it('handles the test suite scenarios', () => { // Test Message 1: One-liners const test1 = ` \`\``; expect(wrapHTMLInCodeBlock(test1)).toBe(test1); // Test Message 2: Mixed content - our function wraps the entire line, not just the HTML part const test2 = `Here's a link and HTML
content
`; const expected2 = `\`\`\`html Here's a link and HTML
content
\`\`\``; expect(wrapHTMLInCodeBlock(test2)).toBe(expected2); // Test Message 7: Comment-only const test7 = ``; const expected7 = `\`\`\`html \`\`\``; expect(wrapHTMLInCodeBlock(test7)).toBe(expected7); }); }); describe('edge cases', () => { it('handles empty input', () => { expect(wrapHTMLInCodeBlock('')).toBe(''); }); it('handles only whitespace', () => { const input = ' \n \n '; expect(wrapHTMLInCodeBlock(input)).toBe(input); }); it('handles nested code block scenarios', () => { const input = `\`\`\`
safe in code block
\`\`\`
unsafe outside
\`\`\` also safe in code block \`\`\``; const expected = `\`\`\`
safe in code block
\`\`\` \`\`\`html
unsafe outside
\`\`\` \`\`\` also safe in code block \`\`\``; expect(wrapHTMLInCodeBlock(input)).toBe(expected); }); }); }); });