import { describe, expect, it } from 'vitest'
import {
  createSafeHtmlFragment,
  createSafeMarkupFragment,
  escapeHtml,
  sanitizeHtml,
  setSafeHtml,
  setSafeIconHtml,
  setSafeIconMarkup,
  setSafeMarkup,
} from '../sanitize'

describe('sanitize utilities', () => {
  it('escapes and sanitizes markup', () => {
    expect(escapeHtml(`<img src="x" onerror='bad'>`)).toBe(
      '&lt;img src=&quot;x&quot; onerror=&#039;bad&#039;&gt;'
    )
    expect(sanitizeHtml('<p>safe</p><script>bad()</script>')).toBe('<p>safe</p>')
  })

  it('creates sanitized fragments and replaces element contents', () => {
    const host = document.createElement('div')

    setSafeMarkup(host, '<strong>safe</strong><script>bad()</script>')
    expect(host.querySelector('strong')?.textContent).toBe('safe')
    expect(host.querySelector('script')).toBeNull()

    setSafeHtml(host, '<em>safe html</em>')
    expect(host.querySelector('em')?.textContent).toBe('safe html')

    expect(createSafeMarkupFragment('<span>markup</span>').firstElementChild?.tagName).toBe('SPAN')
    expect(createSafeHtmlFragment('<span>html</span>').firstElementChild?.textContent).toBe('html')
  })

  it('preserves safe icon markup in html and svg contexts', () => {
    const host = document.createElement('span')
    setSafeIconMarkup(
      host,
      '<svg viewBox="0 0 10 10"><path d="M1 1L9 9" stroke="currentColor"/></svg><script>bad()</script>'
    )
    expect(host.querySelector('path')?.getAttribute('d')).toBe('M1 1L9 9')
    expect(host.querySelector('script')).toBeNull()

    const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
    setSafeIconHtml(svg, '<path d="M2 2L8 8" stroke="currentColor"/>')
    expect(svg.querySelector('path')?.getAttribute('d')).toBe('M2 2L8 8')
  })

  it('strips SVG tags when allowSvg is not set', () => {
    const result = sanitizeHtml('<p>text</p><svg><circle r="5"/></svg>')
    expect(result).not.toContain('<svg')
    expect(result).not.toContain('<circle')
    expect(result).toContain('<p>text</p>')
  })

  it('preserves SVG tags when allowSvg is true', () => {
    const result = sanitizeHtml('<p>text</p><svg><circle r="5"/></svg>', { allowSvg: true })
    expect(result).toContain('<svg')
    expect(result).toContain('<circle')
  })

  it('enforces rel="noopener noreferrer" on target="_blank" links', () => {
    const result = sanitizeHtml('<a href="https://example.com" target="_blank">link</a>')
    expect(result).toContain('rel="noopener noreferrer"')
  })

  it('does not add rel to links without target="_blank"', () => {
    const result = sanitizeHtml('<a href="https://example.com">link</a>')
    expect(result).not.toContain('noopener')
  })
})
