Previously, email replies were handled inside workers. There was no execution logs. This meant if emails silently failed (as reported by a customer), we had no way to trace where the issue happened, the only assumption was “no error = mail sent.” By moving email handling into jobs, we now have proper execution logs for each attempt. This makes it easier to debug delivery issues and would have better visibility when investigating customer reports. Fixes https://linear.app/chatwoot/issue/CW-5538/emails-are-not-sentdelivered-to-the-contact --------- Co-authored-by: Sojan Jose <sojan@pepalo.com> Co-authored-by: Shivam Mishra <scm.mymail@gmail.com>
140 lines
7.2 KiB
Ruby
140 lines
7.2 KiB
Ruby
require 'rails_helper'
|
|
|
|
RSpec.describe SendReplyJob do
|
|
subject(:job) { described_class.perform_later(message) }
|
|
|
|
let(:message) { create(:message) }
|
|
|
|
it 'enqueues the job' do
|
|
expect { job }.to have_enqueued_job(described_class)
|
|
.with(message)
|
|
.on_queue('high')
|
|
end
|
|
|
|
context 'when the job is triggered on a new message' do
|
|
let(:process_service) { double }
|
|
|
|
before do
|
|
allow(process_service).to receive(:perform)
|
|
end
|
|
|
|
it 'calls Facebook::SendOnFacebookService when its facebook message' do
|
|
stub_request(:post, /graph.facebook.com/)
|
|
facebook_channel = create(:channel_facebook_page)
|
|
facebook_inbox = create(:inbox, channel: facebook_channel)
|
|
message = create(:message, conversation: create(:conversation, inbox: facebook_inbox))
|
|
allow(Facebook::SendOnFacebookService).to receive(:new).with(message: message).and_return(process_service)
|
|
expect(Facebook::SendOnFacebookService).to receive(:new).with(message: message)
|
|
expect(process_service).to receive(:perform)
|
|
described_class.perform_now(message.id)
|
|
end
|
|
|
|
it 'calls ::Twitter::SendOnTwitterService when its twitter message' do
|
|
twitter_channel = create(:channel_twitter_profile)
|
|
twitter_inbox = create(:inbox, channel: twitter_channel)
|
|
message = create(:message, conversation: create(:conversation, inbox: twitter_inbox))
|
|
allow(Twitter::SendOnTwitterService).to receive(:new).with(message: message).and_return(process_service)
|
|
expect(Twitter::SendOnTwitterService).to receive(:new).with(message: message)
|
|
expect(process_service).to receive(:perform)
|
|
described_class.perform_now(message.id)
|
|
end
|
|
|
|
it 'calls ::Twilio::SendOnTwilioService when its twilio message' do
|
|
twilio_channel = create(:channel_twilio_sms)
|
|
message = create(:message, conversation: create(:conversation, inbox: twilio_channel.inbox))
|
|
allow(Twilio::SendOnTwilioService).to receive(:new).with(message: message).and_return(process_service)
|
|
expect(Twilio::SendOnTwilioService).to receive(:new).with(message: message)
|
|
expect(process_service).to receive(:perform)
|
|
described_class.perform_now(message.id)
|
|
end
|
|
|
|
it 'calls ::Telegram::SendOnTelegramService when its telegram message' do
|
|
telegram_channel = create(:channel_telegram)
|
|
message = create(:message, conversation: create(:conversation, inbox: telegram_channel.inbox))
|
|
allow(Telegram::SendOnTelegramService).to receive(:new).with(message: message).and_return(process_service)
|
|
expect(Telegram::SendOnTelegramService).to receive(:new).with(message: message)
|
|
expect(process_service).to receive(:perform)
|
|
described_class.perform_now(message.id)
|
|
end
|
|
|
|
it 'calls ::Line:SendOnLineService when its line message' do
|
|
line_channel = create(:channel_line)
|
|
message = create(:message, conversation: create(:conversation, inbox: line_channel.inbox))
|
|
allow(Line::SendOnLineService).to receive(:new).with(message: message).and_return(process_service)
|
|
expect(Line::SendOnLineService).to receive(:new).with(message: message)
|
|
expect(process_service).to receive(:perform)
|
|
described_class.perform_now(message.id)
|
|
end
|
|
|
|
it 'calls ::Whatsapp:SendOnWhatsappService when its whatsapp message' do
|
|
stub_request(:post, 'https://waba.360dialog.io/v1/configs/webhook')
|
|
whatsapp_channel = create(:channel_whatsapp, sync_templates: false)
|
|
message = create(:message, conversation: create(:conversation, inbox: whatsapp_channel.inbox))
|
|
allow(Whatsapp::SendOnWhatsappService).to receive(:new).with(message: message).and_return(process_service)
|
|
expect(Whatsapp::SendOnWhatsappService).to receive(:new).with(message: message)
|
|
expect(process_service).to receive(:perform)
|
|
described_class.perform_now(message.id)
|
|
end
|
|
|
|
it 'calls ::Sms::SendOnSmsService when its sms message' do
|
|
sms_channel = create(:channel_sms)
|
|
message = create(:message, conversation: create(:conversation, inbox: sms_channel.inbox))
|
|
allow(Sms::SendOnSmsService).to receive(:new).with(message: message).and_return(process_service)
|
|
expect(Sms::SendOnSmsService).to receive(:new).with(message: message)
|
|
expect(process_service).to receive(:perform)
|
|
described_class.perform_now(message.id)
|
|
end
|
|
|
|
it 'calls ::Instagram::Direct::SendOnInstagramService when its instagram message' do
|
|
instagram_channel = create(:channel_instagram)
|
|
message = create(:message, conversation: create(:conversation, inbox: instagram_channel.inbox))
|
|
allow(Instagram::SendOnInstagramService).to receive(:new).with(message: message).and_return(process_service)
|
|
expect(Instagram::SendOnInstagramService).to receive(:new).with(message: message)
|
|
expect(process_service).to receive(:perform)
|
|
described_class.perform_now(message.id)
|
|
end
|
|
|
|
it 'calls ::Instagram::Messenger::SendOnInstagramService when its an instagram_direct_message from facebook channel' do
|
|
stub_request(:post, /graph.facebook.com/)
|
|
facebook_channel = create(:channel_facebook_page)
|
|
facebook_inbox = create(:inbox, channel: facebook_channel)
|
|
conversation = create(:conversation,
|
|
inbox: facebook_inbox,
|
|
additional_attributes: { 'type' => 'instagram_direct_message' })
|
|
message = create(:message, conversation: conversation)
|
|
|
|
allow(Instagram::Messenger::SendOnInstagramService).to receive(:new).with(message: message).and_return(process_service)
|
|
expect(Instagram::Messenger::SendOnInstagramService).to receive(:new).with(message: message)
|
|
expect(process_service).to receive(:perform)
|
|
described_class.perform_now(message.id)
|
|
end
|
|
|
|
it 'calls ::Email::SendOnEmailService when its email message' do
|
|
email_channel = create(:channel_email)
|
|
message = create(:message, conversation: create(:conversation, inbox: email_channel.inbox))
|
|
allow(Email::SendOnEmailService).to receive(:new).with(message: message).and_return(process_service)
|
|
expect(Email::SendOnEmailService).to receive(:new).with(message: message)
|
|
expect(process_service).to receive(:perform)
|
|
described_class.perform_now(message.id)
|
|
end
|
|
|
|
it 'calls ::Messages::SendEmailNotificationService when its webwidget message' do
|
|
webwidget_channel = create(:channel_widget)
|
|
message = create(:message, conversation: create(:conversation, inbox: webwidget_channel.inbox))
|
|
allow(Messages::SendEmailNotificationService).to receive(:new).with(message: message).and_return(process_service)
|
|
expect(Messages::SendEmailNotificationService).to receive(:new).with(message: message)
|
|
expect(process_service).to receive(:perform)
|
|
described_class.perform_now(message.id)
|
|
end
|
|
|
|
it 'calls ::Messages::SendEmailNotificationService when its api channel message' do
|
|
api_channel = create(:channel_api)
|
|
message = create(:message, conversation: create(:conversation, inbox: api_channel.inbox))
|
|
allow(Messages::SendEmailNotificationService).to receive(:new).with(message: message).and_return(process_service)
|
|
expect(Messages::SendEmailNotificationService).to receive(:new).with(message: message)
|
|
expect(process_service).to receive(:perform)
|
|
described_class.perform_now(message.id)
|
|
end
|
|
end
|
|
end
|