require 'rails_helper'

RSpec.describe Notificacao::Renderizador do
  let(:dados) { { 'contato' => 'Carlos', 'valor' => 'R$ 5.060,00', 'entregas' => '280' } }

  def render(blocos) = described_class.new(blocos, dados)

  describe 'as duas saídas do mesmo template' do
    let(:blocos) do
      [
        { 'tipo' => 'cabecalho', 'titulo' => 'Pagamento fechado', 'subtitulo' => 'UBS Norte' },
        { 'tipo' => 'texto', 'texto' => 'Olá {{contato}}!' },
        { 'tipo' => 'tabela', 'linhas' => [{ 'rotulo' => 'Entregas', 'valor' => '{{entregas}}' },
                                           { 'rotulo' => 'Valor', 'valor' => '{{valor}}' }] },
        { 'tipo' => 'botao', 'rotulo' => 'Ver extrato', 'url' => 'https://app.reem.com.br/motorista' }
      ]
    end

    it 'monta o texto do WhatsApp com negrito e bullets' do
      texto = render(blocos).texto
      expect(texto).to include('*Pagamento fechado*')
      expect(texto).to include('Olá Carlos!')
      expect(texto).to include('• Entregas: 280')
      expect(texto).to include('Ver extrato: https://app.reem.com.br/motorista')
    end

    it 'monta o HTML do e-mail com estilo inline' do
      html = render(blocos).html
      expect(html).to include('<h1')
      expect(html).to include('style=')          # cliente de e-mail não lê CSS externo
      expect(html).to include('Olá Carlos!')
      expect(html).to include('R$ 5.060,00')
      expect(html).to include('<a href="https://app.reem.com.br/motorista"')
    end
  end

  it 'variável sem valor vira vazio, não fica "{{cru}}" na mensagem' do
    texto = render([{ 'tipo' => 'texto', 'texto' => 'Oi {{inexistente}}!' }]).texto
    expect(texto).to eq('Oi !')
  end

  # O corpo é digitado numa tela e o preview usa este mesmo renderizador — um
  # escape faltando atingiria primeiro o próprio admin.
  it 'escapa HTML do texto digitado e do valor da variável' do
    r = described_class.new(
      [{ 'tipo' => 'texto', 'texto' => '<script>alert(1)</script> {{contato}}' }],
      { 'contato' => '<img src=x onerror=alert(2)>' }
    )
    html = r.html
    expect(html).not_to include('<script>')
    expect(html).not_to include('<img src=x')
    expect(html).to include('&lt;script&gt;')
  end

  # href montado na tela com `javascript:` seria clique armado dentro do e-mail.
  it 'ignora botão cuja URL não é http(s)' do
    html = render([{ 'tipo' => 'botao', 'rotulo' => 'Clique', 'url' => 'javascript:alert(1)' }]).html
    expect(html).not_to include('javascript:')
    expect(html).not_to include('<a ')
  end

  it 'descarta bloco de tipo desconhecido' do
    r = render([{ 'tipo' => 'malicioso', 'texto' => 'nada' },
                { 'tipo' => 'texto', 'texto' => 'ok' }])
    expect(r.texto).to eq('ok')
  end

  it 'não deixa bloco vazio virar linha em branco na mensagem' do
    texto = render([{ 'tipo' => 'texto', 'texto' => '' },
                    { 'tipo' => 'texto', 'texto' => 'único' }]).texto
    expect(texto).to eq('único')
  end
end
