mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 10:31:13 -05:00
118 lines
3.8 KiB
TypeScript
118 lines
3.8 KiB
TypeScript
/**
|
|
* Unit Tests for Sanitization Utilities
|
|
*/
|
|
|
|
import { describe, it, expect } from '@playwright/test';
|
|
import { sanitizeHTML, sanitizeURL, sanitizePlainText, containsSuspiciousContent } from '@/lib/sanitize';
|
|
|
|
describe('sanitizeURL', () => {
|
|
it('should allow valid http URLs', () => {
|
|
expect(sanitizeURL('http://example.com')).toBe('http://example.com');
|
|
});
|
|
|
|
it('should allow valid https URLs', () => {
|
|
expect(sanitizeURL('https://example.com/path?query=value')).toBe('https://example.com/path?query=value');
|
|
});
|
|
|
|
it('should allow valid mailto URLs', () => {
|
|
expect(sanitizeURL('mailto:user@example.com')).toBe('mailto:user@example.com');
|
|
});
|
|
|
|
it('should block javascript: protocol', () => {
|
|
expect(sanitizeURL('javascript:alert("XSS")')).toBe('#');
|
|
});
|
|
|
|
it('should block data: protocol', () => {
|
|
expect(sanitizeURL('data:text/html,<script>alert("XSS")</script>')).toBe('#');
|
|
});
|
|
|
|
it('should handle invalid URLs', () => {
|
|
expect(sanitizeURL('not a url')).toBe('#');
|
|
expect(sanitizeURL('')).toBe('#');
|
|
});
|
|
|
|
it('should handle null/undefined gracefully', () => {
|
|
expect(sanitizeURL(null as any)).toBe('#');
|
|
expect(sanitizeURL(undefined as any)).toBe('#');
|
|
});
|
|
});
|
|
|
|
describe('sanitizePlainText', () => {
|
|
it('should escape HTML entities', () => {
|
|
expect(sanitizePlainText('<script>alert("XSS")</script>'))
|
|
.toBe('<script>alert("XSS")</script>');
|
|
});
|
|
|
|
it('should escape ampersands', () => {
|
|
expect(sanitizePlainText('Tom & Jerry')).toBe('Tom & Jerry');
|
|
});
|
|
|
|
it('should escape quotes', () => {
|
|
expect(sanitizePlainText('"Hello" \'World\'')).toContain('"');
|
|
expect(sanitizePlainText('"Hello" \'World\'')).toContain(''');
|
|
});
|
|
|
|
it('should handle plain text without changes', () => {
|
|
expect(sanitizePlainText('Hello World')).toBe('Hello World');
|
|
});
|
|
|
|
it('should handle empty strings', () => {
|
|
expect(sanitizePlainText('')).toBe('');
|
|
});
|
|
});
|
|
|
|
describe('containsSuspiciousContent', () => {
|
|
it('should detect script tags', () => {
|
|
expect(containsSuspiciousContent('<script>alert(1)</script>')).toBe(true);
|
|
expect(containsSuspiciousContent('<SCRIPT>alert(1)</SCRIPT>')).toBe(true);
|
|
});
|
|
|
|
it('should detect javascript: protocol', () => {
|
|
expect(containsSuspiciousContent('javascript:alert(1)')).toBe(true);
|
|
expect(containsSuspiciousContent('JAVASCRIPT:alert(1)')).toBe(true);
|
|
});
|
|
|
|
it('should detect event handlers', () => {
|
|
expect(containsSuspiciousContent('<img onerror="alert(1)">')).toBe(true);
|
|
expect(containsSuspiciousContent('<div onclick="alert(1)">')).toBe(true);
|
|
});
|
|
|
|
it('should detect iframes', () => {
|
|
expect(containsSuspiciousContent('<iframe src="evil.com"></iframe>')).toBe(true);
|
|
});
|
|
|
|
it('should not flag safe content', () => {
|
|
expect(containsSuspiciousContent('This is a safe message')).toBe(false);
|
|
expect(containsSuspiciousContent('Email: user@example.com')).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('sanitizeHTML', () => {
|
|
it('should allow safe tags', () => {
|
|
const html = '<p>Hello <strong>world</strong></p>';
|
|
const result = sanitizeHTML(html);
|
|
expect(result).toContain('<p>');
|
|
expect(result).toContain('<strong>');
|
|
});
|
|
|
|
it('should remove script tags', () => {
|
|
const html = '<p>Hello</p><script>alert("XSS")</script>';
|
|
const result = sanitizeHTML(html);
|
|
expect(result).not.toContain('<script>');
|
|
expect(result).toContain('<p>');
|
|
});
|
|
|
|
it('should remove event handlers', () => {
|
|
const html = '<p onclick="alert(1)">Click me</p>';
|
|
const result = sanitizeHTML(html);
|
|
expect(result).not.toContain('onclick');
|
|
});
|
|
|
|
it('should allow safe links', () => {
|
|
const html = '<a href="https://example.com" target="_blank" rel="noopener">Link</a>';
|
|
const result = sanitizeHTML(html);
|
|
expect(result).toContain('href');
|
|
expect(result).toContain('target');
|
|
});
|
|
});
|