import { describe, it, expect } from 'vitest'
import {
  buildActionButtonsHtml,
  escapeHtmlText,
  isAllowedHttpsUrl,
} from '../src/email/escape'
import { renderEmailTemplate } from '../src/email/render'

describe('renderEmailTemplate interpolation', () => {
  it('escapes HTML in text vars (title, body, subject)', () => {
    const payload = '<script>alert(1)</script>'
    const { html } = renderEmailTemplate({
      templateKey: 'invoice-sent',
      locale: 'en-US',
      vars: {
        subject: payload,
        title: payload,
        body: '<img src=x onerror=alert(1)>',
      },
    })

    expect(html).not.toContain('<script>')
    expect(html).toContain('&lt;script&gt;alert(1)&lt;/script&gt;')
    expect(html).toContain('&lt;img src=x onerror=alert(1)&gt;')
  })

  it('allows https href vars and rejects javascript: URLs', () => {
    const safe = renderEmailTemplate({
      templateKey: 'timer-magic-link',
      locale: 'en-US',
      vars: {
        subject: 'Timer',
        title: 'Timer',
        body: 'Click',
        link: 'https://app.zync.is/time/start?token=abc',
        ctaLabel: 'Start',
        expiryNote: 'Expires soon',
      },
    })
    expect(safe.html).toContain('href="https://app.zync.is/time/start?token=abc"')

    const unsafe = renderEmailTemplate({
      templateKey: 'timer-magic-link',
      locale: 'en-US',
      vars: {
        subject: 'Timer',
        title: 'Timer',
        body: 'Click',
        link: 'javascript:alert(1)',
        ctaLabel: 'Start',
        expiryNote: 'Expires soon',
      },
    })
    expect(unsafe.html).not.toContain('javascript:')
    expect(unsafe.html).toContain('href=""')
  })
})

describe('buildActionButtonsHtml', () => {
  it('escapes button labels', () => {
    const html = buildActionButtonsHtml([
      {
        label: '"><img src=x onerror=alert(1)>',
        url: 'https://app.zync.is/invoices/1',
      },
    ])

    expect(html).not.toContain('<img')
    expect(html).toContain('&quot;&gt;&lt;img src=x onerror=alert(1)&gt;')
  })

  it('rejects javascript: button URLs', () => {
    const html = buildActionButtonsHtml([
      {
        label: 'Pay now',
        url: 'javascript:alert(1)',
      },
    ])

    expect(html).toBe('')
    expect(isAllowedHttpsUrl('javascript:alert(1)')).toBe(false)
  })
})

describe('escapeHtmlText', () => {
  it('escapes all HTML-significant characters', () => {
    expect(escapeHtmlText('&<>"\'')).toBe('&amp;&lt;&gt;&quot;&#39;')
  })
})
