175 lines
7.6 KiB
Ruby
175 lines
7.6 KiB
Ruby
require 'rails_helper'
|
|
|
|
RSpec.describe Notificacao::Despachante do
|
|
let(:evento) { create(:evento_notificacao) }
|
|
let(:diretoria) { create(:grupo_contato) }
|
|
let(:config) { ConfiguracaoNotificacao.instancia }
|
|
|
|
before do
|
|
config.update_columns(whatsapp_ativo: true, whatsapp_provedor: 'baileys',
|
|
email_notificacoes_ativo: true, whatsapp_intervalo_segundos: 0)
|
|
# Nunca tocar a ponte de verdade no teste.
|
|
allow(Notificacao::Whatsapp).to receive(:enviar)
|
|
.and_return(Notificacao::ClienteWhatsapp::Resposta.new(ok: true))
|
|
allow(ConfiguracaoNotificacao).to receive(:instancia).and_return(config)
|
|
end
|
|
|
|
def despachar(envolvido: nil, dados: {})
|
|
described_class.new(evento.reload, dados: dados, assunto: 'Assunto',
|
|
corpo: 'Corpo', envolvido: envolvido).executar
|
|
end
|
|
|
|
it 'envia para os contatos dos grupos assinantes e registra cada envio' do
|
|
contato = create(:contato, grupo_contato: diretoria, telefone: '11 92005-1157', email: 'dir@reem.com')
|
|
create(:grupo_evento_assinatura, grupo_contato: diretoria, evento_notificacao: evento)
|
|
|
|
expect { despachar }.to change(NotificacaoEnvio, :count).by(2) # whatsapp + email
|
|
|
|
expect(Notificacao::Whatsapp).to have_received(:enviar)
|
|
.with(hash_including(para: contato.telefone))
|
|
expect(NotificacaoEnvio.where(canal: 'whatsapp').first).to be_enviado
|
|
end
|
|
|
|
# A mesma pessoa pode ser contato de um grupo E a envolvida no fato — sem
|
|
# dedup ela receberia a mensagem duas vezes.
|
|
it 'não manda duas vezes para o mesmo número' do
|
|
create(:contato, grupo_contato: diretoria, telefone: '11 92005-1157', email: nil)
|
|
create(:grupo_evento_assinatura, grupo_contato: diretoria, evento_notificacao: evento, canal: 'whatsapp')
|
|
motorista = create(:motorista, telefone: '(11) 92005-1157')
|
|
|
|
despachar(envolvido: motorista)
|
|
|
|
expect(NotificacaoEnvio.where(canal: 'whatsapp').count).to eq(1)
|
|
end
|
|
|
|
it 'inclui o envolvido que não é contato de nenhum grupo' do
|
|
create(:grupo_evento_assinatura, grupo_contato: diretoria, evento_notificacao: evento)
|
|
motorista = create(:motorista, telefone: '(11) 98888-7777')
|
|
|
|
despachar(envolvido: motorista)
|
|
|
|
expect(NotificacaoEnvio.where(canal: 'whatsapp').pluck(:destino)).to eq(['+5511988887777'])
|
|
end
|
|
|
|
it 'não avisa o envolvido quando o evento diz para não avisar' do
|
|
evento.update!(notificar_envolvido: false)
|
|
motorista = create(:motorista, telefone: '(11) 98888-7777')
|
|
|
|
despachar(envolvido: motorista)
|
|
|
|
expect(NotificacaoEnvio.where(canal: 'whatsapp')).to be_empty
|
|
end
|
|
|
|
it 'registra a falha em vez de levantar — envio não pode travar um fechamento' do
|
|
create(:contato, grupo_contato: diretoria, telefone: '11 92005-1157', email: nil)
|
|
create(:grupo_evento_assinatura, grupo_contato: diretoria, evento_notificacao: evento, canal: 'whatsapp')
|
|
allow(Notificacao::Whatsapp).to receive(:enviar)
|
|
.and_return(Notificacao::ClienteWhatsapp::Resposta.new(ok: false, erro: 'whatsapp desconectado'))
|
|
|
|
expect { despachar }.not_to raise_error
|
|
|
|
envio = NotificacaoEnvio.last
|
|
expect(envio).to be_falhou
|
|
expect(envio.erro).to include('desconectado')
|
|
end
|
|
|
|
# O editor de blocos vence o texto padrão — e o fallback existe para que ligar
|
|
# o editor não apague as notificações dos eventos que já funcionavam.
|
|
describe 'template de blocos' do
|
|
before do
|
|
create(:contato, grupo_contato: diretoria, telefone: '11 92005-1157', email: 'dir@reem.com')
|
|
create(:grupo_evento_assinatura, grupo_contato: diretoria, evento_notificacao: evento)
|
|
end
|
|
|
|
it 'sem template, usa o corpo passado pelo chamador' do
|
|
despachar
|
|
expect(NotificacaoEnvio.find_by(canal: 'whatsapp').corpo).to eq('Corpo')
|
|
end
|
|
|
|
it 'com template, o corpo sai renderizado por canal' do
|
|
MensagemTemplate.create!(evento_notificacao: evento, canal: 'whatsapp', ativo: true,
|
|
blocos: [{ 'tipo' => 'texto', 'texto' => 'Oi {{contato}}, {{valor}}' }])
|
|
MensagemTemplate.create!(evento_notificacao: evento, canal: 'email', ativo: true,
|
|
assunto: 'Fechamento de {{contato}}',
|
|
blocos: [{ 'tipo' => 'texto', 'texto' => 'Corpo do e-mail' }])
|
|
|
|
despachar(dados: { 'valor' => 'R$ 10,00' })
|
|
|
|
zap = NotificacaoEnvio.find_by(canal: 'whatsapp')
|
|
expect(zap.corpo).to include('R$ 10,00')
|
|
|
|
email = NotificacaoEnvio.find_by(canal: 'email')
|
|
expect(email.corpo).to include('<p') # HTML montado
|
|
expect(email.assunto).to include('Fechamento')
|
|
end
|
|
|
|
# {{contato}} é o primeiro nome de QUEM RECEBE: um render compartilhado
|
|
# mandaria o nome da primeira pessoa para todo mundo.
|
|
it 'renderiza {{contato}} por destinatário' do
|
|
create(:contato, grupo_contato: diretoria, nome: 'Ana Paula', telefone: '11 93005-1157', email: nil)
|
|
MensagemTemplate.create!(evento_notificacao: evento, canal: 'whatsapp', ativo: true,
|
|
blocos: [{ 'tipo' => 'texto', 'texto' => 'Olá {{contato}}' }])
|
|
|
|
despachar
|
|
|
|
corpos = NotificacaoEnvio.where(canal: 'whatsapp').pluck(:corpo)
|
|
expect(corpos).to include(a_string_including('Ana'))
|
|
expect(corpos.uniq.size).to eq(corpos.size)
|
|
end
|
|
|
|
it 'template ativo mas vazio não substitui o texto padrão' do
|
|
MensagemTemplate.create!(evento_notificacao: evento, canal: 'whatsapp', ativo: true, blocos: [])
|
|
despachar
|
|
expect(NotificacaoEnvio.find_by(canal: 'whatsapp').corpo).to eq('Corpo')
|
|
end
|
|
end
|
|
|
|
it 'não envia nada quando o canal está desligado na configuração' do
|
|
create(:contato, grupo_contato: diretoria, telefone: '11 92005-1157', email: 'dir@reem.com')
|
|
create(:grupo_evento_assinatura, grupo_contato: diretoria, evento_notificacao: evento)
|
|
config.update_columns(whatsapp_ativo: false, email_notificacoes_ativo: false)
|
|
|
|
expect { despachar }.not_to change(NotificacaoEnvio, :count)
|
|
end
|
|
end
|
|
|
|
# Buscar o evento pela `chave` fazia só o de SISTEMA disparar: um evento criado
|
|
# pelo ADM com o mesmo gatilho ficava mudo para sempre, sem erro nenhum — a tela
|
|
# oferecia o gatilho e nada acontecia.
|
|
RSpec.describe Notificacao::Despachante, '.disparar_gatilho' do
|
|
it 'agenda TODOS os eventos ativos do gatilho, não só o de sistema' do
|
|
sistema = create(:evento_notificacao, gatilho: 'valor_alterado', chave: 'valor_alterado', sistema: true)
|
|
do_adm = create(:evento_notificacao, gatilho: 'valor_alterado', chave: 'aviso_extra')
|
|
create(:evento_notificacao, gatilho: 'pagamento_efetuado', chave: 'outro')
|
|
|
|
agendados = []
|
|
allow(NotificacaoJob).to receive(:perform_later) { |id, *| agendados << id }
|
|
|
|
described_class.disparar_gatilho(gatilho: 'valor_alterado', corpo: 'x')
|
|
|
|
expect(agendados).to contain_exactly(sistema.id, do_adm.id)
|
|
end
|
|
|
|
it 'ignora evento desativado' do
|
|
create(:evento_notificacao, gatilho: 'valor_alterado', chave: 'desligado', ativo: false)
|
|
allow(NotificacaoJob).to receive(:perform_later)
|
|
|
|
described_class.disparar_gatilho(gatilho: 'valor_alterado', corpo: 'x')
|
|
|
|
expect(NotificacaoJob).not_to have_received(:perform_later)
|
|
end
|
|
|
|
# O botão "disparar agora" mira UM evento — ali a chave é o identificador certo.
|
|
it '.disparar continua agendando só o evento da chave' do
|
|
alvo = create(:evento_notificacao, gatilho: 'manual', chave: 'so_este')
|
|
create(:evento_notificacao, gatilho: 'manual', chave: 'outro_manual')
|
|
|
|
agendados = []
|
|
allow(NotificacaoJob).to receive(:perform_later) { |id, *| agendados << id }
|
|
|
|
described_class.disparar(chave: 'so_este', corpo: 'x')
|
|
|
|
expect(agendados).to eq([alvo.id])
|
|
end
|
|
end
|