# frozen_string_literal: true require 'rails_helper' RSpec.describe HelpscoutCreateConversationJob, type: :job do let(:api) { instance_double("Helpscout::API") } let(:email) { 'help@rspec.net' } let(:subject_text) { 'Bonjour' } let(:text) { "J'ai un pb" } let(:tags) { ["first tag"] } let(:question_type) { "lost" } let(:phone) { nil } let(:user) { nil } let(:contact_form) { create(:contact_form, email:, user:, subject: subject_text, text:, tags:, phone:, question_type:) } describe '#perform' do before do allow(Helpscout::API).to receive(:new).and_return(api) allow(api).to receive(:create_conversation) .and_return(double( success?: true, headers: { 'Resource-ID' => 'new-conversation-id' } )) allow(api).to receive(:add_tags) allow(api).to receive(:add_phone_number) if phone.present? end subject { described_class.perform_now(contact_form) } context 'when no file is attached' do it 'sends the form without a file' do subject expect(api).to have_received(:create_conversation).with(email, subject_text, text, nil) expect(api).to have_received(:add_tags).with("new-conversation-id", match_array(tags.concat(["contact form", question_type]))) expect(contact_form).to be_destroyed end end context 'when a file is attached' do before do file = fixture_file_upload('spec/fixtures/files/white.png', 'image/png') contact_form.piece_jointe.attach(file) end context 'when the file has not been scanned yet' do before do allow_any_instance_of(ActiveStorage::Blob).to receive(:virus_scanner).and_return(double('VirusScanner', pending?: true, safe?: false)) end it 'reenqueues job' do expect { subject }.to have_enqueued_job(described_class).with(contact_form) end end context 'when the file is safe' do before do allow_any_instance_of(ActiveStorage::Blob).to receive(:virus_scanner).and_return(double('VirusScanner', pending?: false, safe?: true)) end it 'sends the form with the file' do subject expect(api).to have_received(:create_conversation).with(email, subject_text, text, contact_form.piece_jointe) end end context 'when the file is not safe' do before do allow_any_instance_of(ActiveStorage::Blob).to receive(:virus_scanner).and_return(double('VirusScanner', pending?: false, safe?: false)) end it 'ignores the file' do subject expect(api).to have_received(:create_conversation).with(email, subject_text, text, nil) end end end context 'with a phone' do let(:phone) { "06" } it 'associates the phone number' do subject expect(api).to have_received(:add_phone_number).with(email, phone) end end context 'attached to an user' do let(:email) { nil } let(:user) { users(:default_user) } it 'associates the email from user' do subject expect(api).to have_received(:create_conversation).with(user.email, subject_text, text, nil) expect(contact_form).to be_destroyed expect(user.reload).to be_truthy end context 'having dossiers' do before do create(:dossier, user:) end it 'associates the email from user' do subject expect(api).to have_received(:create_conversation).with(user.email, subject_text, text, nil) expect(contact_form).to be_destroyed expect(user.reload).to be_truthy end end end context 'when max attempts are reached' do before do allow(api).to receive(:create_conversation).and_raise(StandardError) allow_any_instance_of(described_class).to receive(:executions).and_return(described_class.new.max_attempts) end it 'deletes the contact form' do expect { subject }.to raise_error(StandardError) expect(contact_form).to be_destroyed end it 'does not enqueue the job again' do expect { subject rescue nil }.not_to have_enqueued_job(described_class) end end end end