Restructure omni services and add Chatwoot research snapshot
This commit is contained in:
23
research/chatwoot/spec/models/channel/api_spec.rb
Normal file
23
research/chatwoot/spec/models/channel/api_spec.rb
Normal file
@@ -0,0 +1,23 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Channel::Api do
|
||||
# This validation happens in ApplicationRecord
|
||||
describe 'length validations' do
|
||||
let(:channel_api) { create(:channel_api) }
|
||||
|
||||
context 'when it validates webhook_url length' do
|
||||
it 'valid when within limit' do
|
||||
channel_api.webhook_url = 'a' * Limits::URL_LENGTH_LIMIT
|
||||
expect(channel_api.valid?).to be true
|
||||
end
|
||||
|
||||
it 'invalid when crossed the limit' do
|
||||
channel_api.webhook_url = 'a' * (Limits::URL_LENGTH_LIMIT + 1)
|
||||
channel_api.valid?
|
||||
expect(channel_api.errors[:webhook_url]).to include("is too long (maximum is #{Limits::URL_LENGTH_LIMIT} characters)")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
49
research/chatwoot/spec/models/channel/email_spec.rb
Normal file
49
research/chatwoot/spec/models/channel/email_spec.rb
Normal file
@@ -0,0 +1,49 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
require Rails.root.join 'spec/models/concerns/reauthorizable_shared.rb'
|
||||
|
||||
RSpec.describe Channel::Email do
|
||||
let(:channel) { create(:channel_email) }
|
||||
|
||||
describe 'concerns' do
|
||||
it_behaves_like 'reauthorizable'
|
||||
|
||||
context 'when prompt_reauthorization!' do
|
||||
it 'calls channel notifier mail for email' do
|
||||
admin_mailer = double
|
||||
mailer_double = double
|
||||
expect(AdministratorNotifications::ChannelNotificationsMailer).to receive(:with).and_return(admin_mailer)
|
||||
expect(admin_mailer).to receive(:email_disconnect).with(channel.inbox).and_return(mailer_double)
|
||||
expect(mailer_double).to receive(:deliver_later)
|
||||
channel.prompt_reauthorization!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'has a valid name' do
|
||||
expect(channel.name).to eq('Email')
|
||||
end
|
||||
|
||||
context 'when microsoft?' do
|
||||
it 'returns false' do
|
||||
expect(channel.microsoft?).to be(false)
|
||||
end
|
||||
|
||||
it 'returns true' do
|
||||
channel.provider = 'microsoft'
|
||||
expect(channel.microsoft?).to be(true)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when google?' do
|
||||
it 'returns false' do
|
||||
expect(channel.google?).to be(false)
|
||||
end
|
||||
|
||||
it 'returns true' do
|
||||
channel.provider = 'google'
|
||||
expect(channel.google?).to be(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
38
research/chatwoot/spec/models/channel/facebook_page_spec.rb
Normal file
38
research/chatwoot/spec/models/channel/facebook_page_spec.rb
Normal file
@@ -0,0 +1,38 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
require Rails.root.join 'spec/models/concerns/reauthorizable_shared.rb'
|
||||
|
||||
RSpec.describe Channel::FacebookPage do
|
||||
before do
|
||||
stub_request(:post, /graph.facebook.com/)
|
||||
end
|
||||
|
||||
let(:channel) { create(:channel_facebook_page) }
|
||||
|
||||
it { is_expected.to validate_presence_of(:account_id) }
|
||||
# it { is_expected.to validate_uniqueness_of(:page_id).scoped_to(:account_id) }
|
||||
it { is_expected.to belong_to(:account) }
|
||||
it { is_expected.to have_one(:inbox).dependent(:destroy_async) }
|
||||
|
||||
describe 'concerns' do
|
||||
it_behaves_like 'reauthorizable'
|
||||
|
||||
context 'when prompt_reauthorization!' do
|
||||
it 'calls channel notifier mail for facebook' do
|
||||
admin_mailer = double
|
||||
mailer_double = double
|
||||
|
||||
expect(AdministratorNotifications::ChannelNotificationsMailer).to receive(:with).and_return(admin_mailer)
|
||||
expect(admin_mailer).to receive(:facebook_disconnect).with(channel.inbox).and_return(mailer_double)
|
||||
expect(mailer_double).to receive(:deliver_later)
|
||||
|
||||
channel.prompt_reauthorization!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'has a valid name' do
|
||||
expect(channel.name).to eq('Facebook')
|
||||
end
|
||||
end
|
||||
35
research/chatwoot/spec/models/channel/instagram_spec.rb
Normal file
35
research/chatwoot/spec/models/channel/instagram_spec.rb
Normal file
@@ -0,0 +1,35 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
require Rails.root.join 'spec/models/concerns/reauthorizable_shared.rb'
|
||||
|
||||
RSpec.describe Channel::Instagram do
|
||||
let(:channel) { create(:channel_instagram) }
|
||||
|
||||
it { is_expected.to validate_presence_of(:account_id) }
|
||||
it { is_expected.to validate_presence_of(:access_token) }
|
||||
it { is_expected.to validate_presence_of(:instagram_id) }
|
||||
it { is_expected.to belong_to(:account) }
|
||||
it { is_expected.to have_one(:inbox).dependent(:destroy_async) }
|
||||
|
||||
it 'has a valid name' do
|
||||
expect(channel.name).to eq('Instagram')
|
||||
end
|
||||
|
||||
describe 'concerns' do
|
||||
it_behaves_like 'reauthorizable'
|
||||
|
||||
context 'when prompt_reauthorization!' do
|
||||
it 'calls channel notifier mail for instagram' do
|
||||
admin_mailer = double
|
||||
mailer_double = double
|
||||
|
||||
expect(AdministratorNotifications::ChannelNotificationsMailer).to receive(:with).and_return(admin_mailer)
|
||||
expect(admin_mailer).to receive(:instagram_disconnect).with(channel.inbox).and_return(mailer_double)
|
||||
expect(mailer_double).to receive(:deliver_later)
|
||||
|
||||
channel.prompt_reauthorization!
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
174
research/chatwoot/spec/models/channel/telegram_spec.rb
Normal file
174
research/chatwoot/spec/models/channel/telegram_spec.rb
Normal file
@@ -0,0 +1,174 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Channel::Telegram do
|
||||
let(:telegram_channel) { create(:channel_telegram) }
|
||||
|
||||
describe '#convert_markdown_to_telegram_html' do
|
||||
subject { telegram_channel.send(:convert_markdown_to_telegram_html, text) }
|
||||
|
||||
context 'when text contains multiple newline characters' do
|
||||
let(:text) { "Line one\nLine two\n\nLine four" }
|
||||
|
||||
it 'preserves multiple newline characters' do
|
||||
expect(subject).to eq("Line one\nLine two\n\nLine four")
|
||||
end
|
||||
end
|
||||
|
||||
context 'when text contains broken markdown' do
|
||||
let(:text) { 'This is a **broken markdown with <b>HTML</b> tags.' }
|
||||
|
||||
it 'does not break and properly converts to Telegram HTML format and escapes html tags' do
|
||||
expect(subject).to eq('This is a **broken markdown with <b>HTML</b> tags.')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when text contains markdown and HTML elements' do
|
||||
let(:text) { "Hello *world*! This is <b>bold</b> and this is <i>italic</i>.\nThis is a new line." }
|
||||
|
||||
it 'converts markdown to Telegram HTML format and escapes other html' do
|
||||
expect(subject).to eq("Hello <em>world</em>! This is <b>bold</b> and this is <i>italic</i>.\nThis is a new line.")
|
||||
end
|
||||
end
|
||||
|
||||
context 'when text contains unsupported HTML tags' do
|
||||
let(:text) { 'This is a <span>test</span> with unsupported tags.' }
|
||||
|
||||
it 'removes unsupported HTML tags' do
|
||||
expect(subject).to eq('This is a <span>test</span> with unsupported tags.')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when text contains special characters' do
|
||||
let(:text) { 'Special characters: & < >' }
|
||||
|
||||
it 'escapes special characters' do
|
||||
expect(subject).to eq('Special characters: & < >')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when text contains markdown links' do
|
||||
let(:text) { 'Check this [link](http://example.com) out!' }
|
||||
|
||||
it 'converts markdown links to Telegram HTML format' do
|
||||
expect(subject).to eq('Check this <a href="http://example.com">link</a> out!')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when a valid message and empty attachments' do
|
||||
it 'send message' do
|
||||
message = create(:message, message_type: :outgoing, content: 'test',
|
||||
conversation: create(:conversation, inbox: telegram_channel.inbox, additional_attributes: { 'chat_id' => '123' }))
|
||||
|
||||
stub_request(:post, "https://api.telegram.org/bot#{telegram_channel.bot_token}/sendMessage")
|
||||
.with(
|
||||
body: 'chat_id=123&text=test&reply_markup=&parse_mode=HTML&reply_to_message_id='
|
||||
)
|
||||
.to_return(
|
||||
status: 200,
|
||||
body: { result: { message_id: 'telegram_123' } }.to_json,
|
||||
headers: { 'Content-Type' => 'application/json' }
|
||||
)
|
||||
|
||||
expect(telegram_channel.send_message_on_telegram(message)).to eq('telegram_123')
|
||||
end
|
||||
|
||||
it 'send message with markdown converted to telegram HTML' do
|
||||
message = create(:message, message_type: :outgoing, content: '**test** *test* ~test~',
|
||||
conversation: create(:conversation, inbox: telegram_channel.inbox, additional_attributes: { 'chat_id' => '123' }))
|
||||
|
||||
stub_request(:post, "https://api.telegram.org/bot#{telegram_channel.bot_token}/sendMessage")
|
||||
.with(
|
||||
body: "chat_id=123&text=#{
|
||||
ERB::Util.url_encode('<strong>test</strong> <em>test</em> ~test~')
|
||||
}&reply_markup=&parse_mode=HTML&reply_to_message_id="
|
||||
)
|
||||
.to_return(
|
||||
status: 200,
|
||||
body: { result: { message_id: 'telegram_123' } }.to_json,
|
||||
headers: { 'Content-Type' => 'application/json' }
|
||||
)
|
||||
|
||||
expect(telegram_channel.send_message_on_telegram(message)).to eq('telegram_123')
|
||||
end
|
||||
|
||||
it 'send message with reply_markup' do
|
||||
message = create(
|
||||
:message, message_type: :outgoing, content: 'test', content_type: 'input_select',
|
||||
content_attributes: { 'items' => [{ 'title' => 'test', 'value' => 'test' }] },
|
||||
conversation: create(:conversation, inbox: telegram_channel.inbox, additional_attributes: { 'chat_id' => '123' })
|
||||
)
|
||||
|
||||
stub_request(:post, "https://api.telegram.org/bot#{telegram_channel.bot_token}/sendMessage")
|
||||
.with(
|
||||
body: 'chat_id=123&text=test' \
|
||||
'&reply_markup=%7B%22one_time_keyboard%22%3Atrue%2C%22inline_keyboard%22%3A%5B%5B%7B%22text%22%3A%22test%22%2C%22' \
|
||||
'callback_data%22%3A%22test%22%7D%5D%5D%7D&parse_mode=HTML&reply_to_message_id='
|
||||
)
|
||||
.to_return(
|
||||
status: 200,
|
||||
body: { result: { message_id: 'telegram_123' } }.to_json,
|
||||
headers: { 'Content-Type' => 'application/json' }
|
||||
)
|
||||
|
||||
expect(telegram_channel.send_message_on_telegram(message)).to eq('telegram_123')
|
||||
end
|
||||
|
||||
it 'sends message with business_connection_id' do
|
||||
additional_attributes = { 'chat_id' => '123', 'business_connection_id' => 'eooW3KF5WB5HxTD7T826' }
|
||||
message = create(:message, message_type: :outgoing, content: 'test',
|
||||
conversation: create(:conversation, inbox: telegram_channel.inbox, additional_attributes: additional_attributes))
|
||||
|
||||
stub_request(:post, "https://api.telegram.org/bot#{telegram_channel.bot_token}/sendMessage")
|
||||
.with(
|
||||
body: 'chat_id=123&text=test&reply_markup=&parse_mode=HTML&reply_to_message_id=&business_connection_id=eooW3KF5WB5HxTD7T826'
|
||||
)
|
||||
.to_return(
|
||||
status: 200,
|
||||
body: { result: { message_id: 'telegram_123' } }.to_json,
|
||||
headers: { 'Content-Type' => 'application/json' }
|
||||
)
|
||||
|
||||
expect(telegram_channel.send_message_on_telegram(message)).to eq('telegram_123')
|
||||
end
|
||||
|
||||
it 'send text message failed' do
|
||||
message = create(:message, message_type: :outgoing, content: 'test',
|
||||
conversation: create(:conversation, inbox: telegram_channel.inbox, additional_attributes: { 'chat_id' => '123' }))
|
||||
|
||||
stub_request(:post, "https://api.telegram.org/bot#{telegram_channel.bot_token}/sendMessage")
|
||||
.with(
|
||||
body: 'chat_id=123&text=test&reply_markup=&parse_mode=HTML&reply_to_message_id='
|
||||
)
|
||||
.to_return(
|
||||
status: 403,
|
||||
headers: { 'Content-Type' => 'application/json' },
|
||||
body: {
|
||||
ok: false,
|
||||
error_code: '403',
|
||||
description: 'Forbidden: bot was blocked by the user'
|
||||
}.to_json
|
||||
)
|
||||
telegram_channel.send_message_on_telegram(message)
|
||||
expect(message.reload.status).to eq('failed')
|
||||
expect(message.reload.external_error).to eq('403, Forbidden: bot was blocked by the user')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when message contains attachments' do
|
||||
let(:message) do
|
||||
create(:message, message_type: :outgoing, content: nil,
|
||||
conversation: create(:conversation, inbox: telegram_channel.inbox, additional_attributes: { 'chat_id' => '123' }))
|
||||
end
|
||||
|
||||
it 'calls send attachment service' do
|
||||
telegram_attachment_service = double
|
||||
attachment = message.attachments.new(account_id: message.account_id, file_type: :image)
|
||||
attachment.file.attach(io: Rails.root.join('spec/assets/avatar.png').open, filename: 'avatar.png', content_type: 'image/png')
|
||||
|
||||
allow(Telegram::SendAttachmentsService).to receive(:new).with(message: message).and_return(telegram_attachment_service)
|
||||
allow(telegram_attachment_service).to receive(:perform).and_return('telegram_456')
|
||||
expect(telegram_channel.send_message_on_telegram(message)).to eq('telegram_456')
|
||||
end
|
||||
end
|
||||
end
|
||||
85
research/chatwoot/spec/models/channel/twilio_sms_spec.rb
Normal file
85
research/chatwoot/spec/models/channel/twilio_sms_spec.rb
Normal file
@@ -0,0 +1,85 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Channel::TwilioSms do
|
||||
describe '#validations' do
|
||||
context 'with phone number blank' do
|
||||
let!(:sms_channel) { create(:channel_twilio_sms, medium: :sms, phone_number: nil) }
|
||||
|
||||
it 'allows channel to create with blank phone number' do
|
||||
sms_channel_1 = create(:channel_twilio_sms, medium: :sms, phone_number: '')
|
||||
|
||||
expect(sms_channel_1).to be_valid
|
||||
expect(sms_channel_1.messaging_service_sid).to be_present
|
||||
expect(sms_channel_1.phone_number).to be_blank
|
||||
expect(sms_channel.phone_number).to be_nil
|
||||
|
||||
sms_channel_1 = create(:channel_twilio_sms, medium: :sms, phone_number: nil)
|
||||
expect(sms_channel_1.phone_number).to be_blank
|
||||
expect(sms_channel_1.messaging_service_sid).to be_present
|
||||
end
|
||||
|
||||
it 'throws error for whatsapp channel' do
|
||||
whatsapp_channel_1 = create(:channel_twilio_sms, medium: :sms, phone_number: '', messaging_service_sid: 'MGec8130512b5dd462cfe03095ec1111ed')
|
||||
expect do
|
||||
create(:channel_twilio_sms, medium: :whatsapp, phone_number: 'whatsapp', messaging_service_sid: 'MGec8130512b5dd462cfe03095ec1111ed')
|
||||
end.to raise_error(ActiveRecord::RecordInvalid) { |error| expect(error.message).to eq 'Validation failed: Phone number must be blank' }
|
||||
|
||||
expect(whatsapp_channel_1).to be_valid
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#send_message' do
|
||||
let(:channel) { create(:channel_twilio_sms) }
|
||||
|
||||
let(:twilio_client) { instance_double(Twilio::REST::Client) }
|
||||
let(:twilio_messages) { double }
|
||||
|
||||
before do
|
||||
allow(Twilio::REST::Client).to receive(:new).and_return(twilio_client)
|
||||
allow(twilio_client).to receive(:messages).and_return(twilio_messages)
|
||||
end
|
||||
|
||||
it 'sends via twilio client' do
|
||||
expect(twilio_messages).to receive(:create).with(
|
||||
messaging_service_sid: channel.messaging_service_sid,
|
||||
to: '+15555550111',
|
||||
body: 'hello world',
|
||||
status_callback: 'http://localhost:3000/twilio/delivery_status'
|
||||
).once
|
||||
|
||||
channel.send_message(to: '+15555550111', body: 'hello world')
|
||||
end
|
||||
|
||||
context 'with a "from" phone number' do
|
||||
let(:channel) { create(:channel_twilio_sms, :with_phone_number) }
|
||||
|
||||
it 'sends via twilio client' do
|
||||
expect(twilio_messages).to receive(:create).with(
|
||||
from: channel.phone_number,
|
||||
to: '+15555550111',
|
||||
body: 'hello world',
|
||||
status_callback: 'http://localhost:3000/twilio/delivery_status'
|
||||
).once
|
||||
|
||||
channel.send_message(to: '+15555550111', body: 'hello world')
|
||||
end
|
||||
end
|
||||
|
||||
context 'with media urls' do
|
||||
it 'supplies a media url' do
|
||||
expect(twilio_messages).to receive(:create).with(
|
||||
messaging_service_sid: channel.messaging_service_sid,
|
||||
to: '+15555550111',
|
||||
body: 'hello world',
|
||||
media_url: ['https://example.com/1.jpg'],
|
||||
status_callback: 'http://localhost:3000/twilio/delivery_status'
|
||||
).once
|
||||
|
||||
channel.send_message(to: '+15555550111', body: 'hello world', media_url: ['https://example.com/1.jpg'])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
15
research/chatwoot/spec/models/channel/web_widget_spec.rb
Normal file
15
research/chatwoot/spec/models/channel/web_widget_spec.rb
Normal file
@@ -0,0 +1,15 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Channel::WebWidget do
|
||||
context 'when
|
||||
web widget channel' do
|
||||
let!(:channel_widget) { create(:channel_widget) }
|
||||
|
||||
it 'pre chat options' do
|
||||
expect(channel_widget.pre_chat_form_options['pre_chat_message']).to eq 'Share your queries or comments here.'
|
||||
expect(channel_widget.pre_chat_form_options['pre_chat_fields'].length).to eq 3
|
||||
end
|
||||
end
|
||||
end
|
||||
212
research/chatwoot/spec/models/channel/whatsapp_spec.rb
Normal file
212
research/chatwoot/spec/models/channel/whatsapp_spec.rb
Normal file
@@ -0,0 +1,212 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
require Rails.root.join 'spec/models/concerns/reauthorizable_shared.rb'
|
||||
|
||||
RSpec.describe Channel::Whatsapp do
|
||||
describe 'concerns' do
|
||||
let(:channel) { create(:channel_whatsapp) }
|
||||
|
||||
before do
|
||||
stub_request(:post, 'https://waba.360dialog.io/v1/configs/webhook')
|
||||
stub_request(:get, 'https://waba.360dialog.io/v1/configs/templates')
|
||||
end
|
||||
|
||||
it_behaves_like 'reauthorizable'
|
||||
|
||||
context 'when prompt_reauthorization!' do
|
||||
it 'calls channel notifier mail for whatsapp' do
|
||||
admin_mailer = double
|
||||
mailer_double = double
|
||||
|
||||
expect(AdministratorNotifications::ChannelNotificationsMailer).to receive(:with).and_return(admin_mailer)
|
||||
expect(admin_mailer).to receive(:whatsapp_disconnect).with(channel.inbox).and_return(mailer_double)
|
||||
expect(mailer_double).to receive(:deliver_later)
|
||||
|
||||
channel.prompt_reauthorization!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'validate_provider_config' do
|
||||
let(:channel) { build(:channel_whatsapp, provider: 'whatsapp_cloud', account: create(:account)) }
|
||||
|
||||
it 'validates false when provider config is wrong' do
|
||||
stub_request(:get, 'https://graph.facebook.com/v14.0//message_templates?access_token=test_key').to_return(status: 401)
|
||||
expect(channel.save).to be(false)
|
||||
end
|
||||
|
||||
it 'validates true when provider config is right' do
|
||||
stub_request(:get, 'https://graph.facebook.com/v14.0//message_templates?access_token=test_key')
|
||||
.to_return(status: 200,
|
||||
body: { data: [{
|
||||
id: '123456789', name: 'test_template'
|
||||
}] }.to_json)
|
||||
expect(channel.save).to be(true)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'webhook_verify_token' do
|
||||
before do
|
||||
# Stub webhook setup to prevent HTTP calls during channel creation
|
||||
setup_service = instance_double(Whatsapp::WebhookSetupService)
|
||||
allow(Whatsapp::WebhookSetupService).to receive(:new).and_return(setup_service)
|
||||
allow(setup_service).to receive(:perform)
|
||||
end
|
||||
|
||||
it 'generates webhook_verify_token if not present' do
|
||||
channel = create(:channel_whatsapp,
|
||||
provider_config: {
|
||||
'webhook_verify_token' => nil,
|
||||
'api_key' => 'test_key',
|
||||
'business_account_id' => '123456789'
|
||||
},
|
||||
provider: 'whatsapp_cloud',
|
||||
account: create(:account),
|
||||
validate_provider_config: false,
|
||||
sync_templates: false)
|
||||
|
||||
expect(channel.provider_config['webhook_verify_token']).not_to be_nil
|
||||
end
|
||||
|
||||
it 'does not generate webhook_verify_token if present' do
|
||||
channel = create(:channel_whatsapp,
|
||||
provider: 'whatsapp_cloud',
|
||||
provider_config: {
|
||||
'webhook_verify_token' => '123',
|
||||
'api_key' => 'test_key',
|
||||
'business_account_id' => '123456789'
|
||||
},
|
||||
account: create(:account),
|
||||
validate_provider_config: false,
|
||||
sync_templates: false)
|
||||
|
||||
expect(channel.provider_config['webhook_verify_token']).to eq '123'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'webhook setup after creation' do
|
||||
let(:account) { create(:account) }
|
||||
let(:webhook_service) { instance_double(Whatsapp::WebhookSetupService) }
|
||||
|
||||
before do
|
||||
allow(Whatsapp::WebhookSetupService).to receive(:new).and_return(webhook_service)
|
||||
allow(webhook_service).to receive(:perform)
|
||||
end
|
||||
|
||||
context 'when channel is created through embedded signup' do
|
||||
it 'does not raise error if webhook setup fails' do
|
||||
allow(webhook_service).to receive(:perform).and_raise(StandardError, 'Webhook error')
|
||||
|
||||
expect do
|
||||
create(:channel_whatsapp,
|
||||
account: account,
|
||||
provider: 'whatsapp_cloud',
|
||||
provider_config: {
|
||||
'source' => 'embedded_signup',
|
||||
'business_account_id' => 'test_waba_id',
|
||||
'api_key' => 'test_access_token'
|
||||
},
|
||||
validate_provider_config: false,
|
||||
sync_templates: false)
|
||||
end.not_to raise_error
|
||||
end
|
||||
end
|
||||
|
||||
context 'when channel is created through manual setup' do
|
||||
it 'setups webhooks via after_commit callback' do
|
||||
expect(Whatsapp::WebhookSetupService).to receive(:new).and_return(webhook_service)
|
||||
expect(webhook_service).to receive(:perform)
|
||||
|
||||
# Explicitly set source to nil to test manual setup behavior (not embedded_signup)
|
||||
create(:channel_whatsapp,
|
||||
account: account,
|
||||
provider: 'whatsapp_cloud',
|
||||
provider_config: {
|
||||
'business_account_id' => 'test_waba_id',
|
||||
'api_key' => 'test_access_token',
|
||||
'source' => nil
|
||||
},
|
||||
validate_provider_config: false,
|
||||
sync_templates: false)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when channel is created with different provider' do
|
||||
it 'does not setup webhooks for 360dialog provider' do
|
||||
expect(Whatsapp::WebhookSetupService).not_to receive(:new)
|
||||
|
||||
create(:channel_whatsapp,
|
||||
account: account,
|
||||
provider: 'default',
|
||||
provider_config: {
|
||||
'source' => 'embedded_signup',
|
||||
'api_key' => 'test_360dialog_key'
|
||||
},
|
||||
validate_provider_config: false,
|
||||
sync_templates: false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#teardown_webhooks' do
|
||||
let(:account) { create(:account) }
|
||||
|
||||
context 'when channel is whatsapp_cloud with embedded_signup' do
|
||||
it 'calls WebhookTeardownService on destroy' do
|
||||
# Mock the setup service to prevent HTTP calls during creation
|
||||
setup_service = instance_double(Whatsapp::WebhookSetupService)
|
||||
allow(Whatsapp::WebhookSetupService).to receive(:new).and_return(setup_service)
|
||||
allow(setup_service).to receive(:perform)
|
||||
|
||||
channel = create(:channel_whatsapp,
|
||||
account: account,
|
||||
provider: 'whatsapp_cloud',
|
||||
provider_config: {
|
||||
'source' => 'embedded_signup',
|
||||
'business_account_id' => 'test_waba_id',
|
||||
'api_key' => 'test_access_token',
|
||||
'phone_number_id' => '123456789'
|
||||
},
|
||||
validate_provider_config: false,
|
||||
sync_templates: false)
|
||||
|
||||
teardown_service = instance_double(Whatsapp::WebhookTeardownService)
|
||||
allow(Whatsapp::WebhookTeardownService).to receive(:new).with(channel).and_return(teardown_service)
|
||||
allow(teardown_service).to receive(:perform)
|
||||
|
||||
channel.destroy
|
||||
|
||||
expect(Whatsapp::WebhookTeardownService).to have_received(:new).with(channel)
|
||||
expect(teardown_service).to have_received(:perform)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when channel is not embedded_signup' do
|
||||
it 'calls WebhookTeardownService on destroy' do
|
||||
# Mock the setup service to prevent HTTP calls during creation
|
||||
setup_service = instance_double(Whatsapp::WebhookSetupService)
|
||||
allow(Whatsapp::WebhookSetupService).to receive(:new).and_return(setup_service)
|
||||
allow(setup_service).to receive(:perform)
|
||||
|
||||
channel = create(:channel_whatsapp,
|
||||
account: account,
|
||||
provider: 'whatsapp_cloud',
|
||||
provider_config: {
|
||||
'business_account_id' => 'test_waba_id',
|
||||
'api_key' => 'test_access_token'
|
||||
},
|
||||
validate_provider_config: false,
|
||||
sync_templates: false)
|
||||
|
||||
teardown_service = instance_double(Whatsapp::WebhookTeardownService)
|
||||
allow(Whatsapp::WebhookTeardownService).to receive(:new).with(channel).and_return(teardown_service)
|
||||
allow(teardown_service).to receive(:perform)
|
||||
|
||||
channel.destroy
|
||||
|
||||
expect(teardown_service).to have_received(:perform)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user