require 'rails_helper' RSpec.describe DispararEventosAgendadosJob do let!(:evento) do create(:evento_notificacao, gatilho: 'agendado', frequencia: 'diaria', hora: 8, ativo: true) end let(:agora) { Time.zone.local(2026, 8, 24, 9, 0) } let(:resumo) do instance_double(Analytics::ResumoOperacao, vazio?: false, numeros: { 'entregues' => '10', 'recusas' => '1', 'pendentes' => '0', 'retentativas' => '0', 'fora_operacao' => '0' }) end before do allow(Analytics::ResumoOperacao).to receive(:new).and_return(resumo) allow(Notificacao::Despachante).to receive(:disparar) end it 'dispara o evento vencido e marca o disparo' do described_class.perform_now(agora) expect(Notificacao::Despachante).to have_received(:disparar) expect(evento.reload.ultimo_disparo_em).to be_present end # `vencido?` depende de ultimo_disparo_em; sem gravar, a varredura horária # mandaria a mesma mensagem a cada hora até o dia virar. it 'não repete no mesmo dia' do described_class.perform_now(agora) described_class.perform_now(agora + 1.hour) expect(Notificacao::Despachante).to have_received(:disparar).once end it 'não dispara antes da hora configurada' do described_class.perform_now(Time.zone.local(2026, 8, 24, 7, 0)) expect(Notificacao::Despachante).not_to have_received(:disparar) end it 'ignora evento desativado' do evento.update!(ativo: false) described_class.perform_now(agora) expect(Notificacao::Despachante).not_to have_received(:disparar) end # Resumo zerado só treinaria o leitor a ignorar a mensagem — mas precisa # marcar como disparado, senão tenta de hora em hora. it 'período sem movimento: não envia, mas marca o disparo' do allow(resumo).to receive(:vazio?).and_return(true) described_class.perform_now(agora) expect(Notificacao::Despachante).not_to have_received(:disparar) expect(evento.reload.ultimo_disparo_em).to be_present end describe 'janela do resumo (recortes FECHADOS, para o número não mudar depois de enviado)' do it 'diária cobre o dia anterior' do described_class.perform_now(agora) expect(Analytics::ResumoOperacao).to have_received(:new) .with(inicio: Date.new(2026, 8, 23), fim: Date.new(2026, 8, 23)) end it 'semanal cobre os 7 dias anteriores' do evento.update!(frequencia: 'semanal', dia_semana: agora.to_date.wday) described_class.perform_now(agora) expect(Analytics::ResumoOperacao).to have_received(:new) .with(inicio: Date.new(2026, 8, 17), fim: Date.new(2026, 8, 23)) end end end