## Description Modified the phone number validation in Whatsapp::ChannelCreationService to check for duplicate phone numbers across ALL accounts, not just within the current account. ## Type of change - [ ] Bug fix (non-breaking change which fixes an issue) ## How Has This Been Tested? - Added test coverage for cross-account phone number validation - Using actual UI flow <img width="1493" height="532" alt="image" src="https://github.com/user-attachments/assets/67d2bb99-2eb9-4115-8d56-449e4785e0d8" /> ## Checklist: - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my code - [ ] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules
130 lines
4.8 KiB
Ruby
130 lines
4.8 KiB
Ruby
require 'rails_helper'
|
|
|
|
describe Whatsapp::ChannelCreationService do
|
|
let(:account) { create(:account) }
|
|
let(:waba_info) { { waba_id: 'test_waba_id', business_name: 'Test Business' } }
|
|
let(:phone_info) do
|
|
{
|
|
phone_number_id: 'test_phone_id',
|
|
phone_number: '+1234567890',
|
|
verified: true,
|
|
business_name: 'Test Business'
|
|
}
|
|
end
|
|
let(:access_token) { 'test_access_token' }
|
|
let(:service) { described_class.new(account, waba_info, phone_info, access_token) }
|
|
|
|
describe '#perform' do
|
|
before do
|
|
# Stub the webhook teardown service to prevent HTTP calls during cleanup
|
|
teardown_service = instance_double(Whatsapp::WebhookTeardownService)
|
|
allow(Whatsapp::WebhookTeardownService).to receive(:new).and_return(teardown_service)
|
|
allow(teardown_service).to receive(:perform)
|
|
|
|
# Clean up any existing channels to avoid phone number conflicts
|
|
Channel::Whatsapp.destroy_all
|
|
|
|
# Stub the webhook setup service to prevent HTTP calls during tests
|
|
webhook_service = instance_double(Whatsapp::WebhookSetupService)
|
|
allow(Whatsapp::WebhookSetupService).to receive(:new).and_return(webhook_service)
|
|
allow(webhook_service).to receive(:perform)
|
|
|
|
# Stub the provider validation and sync_templates
|
|
allow(Channel::Whatsapp).to receive(:new).and_wrap_original do |method, *args|
|
|
channel = method.call(*args)
|
|
allow(channel).to receive(:validate_provider_config)
|
|
allow(channel).to receive(:sync_templates)
|
|
channel
|
|
end
|
|
end
|
|
|
|
context 'when channel does not exist' do
|
|
it 'creates a new channel' do
|
|
expect { service.perform }.to change(Channel::Whatsapp, :count).by(1)
|
|
end
|
|
|
|
it 'creates channel with correct attributes' do
|
|
channel = service.perform
|
|
expect(channel.phone_number).to eq('+1234567890')
|
|
expect(channel.provider).to eq('whatsapp_cloud')
|
|
expect(channel.provider_config['api_key']).to eq(access_token)
|
|
expect(channel.provider_config['phone_number_id']).to eq('test_phone_id')
|
|
expect(channel.provider_config['business_account_id']).to eq('test_waba_id')
|
|
expect(channel.provider_config['source']).to eq('embedded_signup')
|
|
end
|
|
|
|
it 'creates an inbox for the channel' do
|
|
channel = service.perform
|
|
inbox = channel.inbox
|
|
expect(inbox).not_to be_nil
|
|
expect(inbox.name).to eq('Test Business WhatsApp')
|
|
expect(inbox.account).to eq(account)
|
|
end
|
|
end
|
|
|
|
context 'when channel already exists for the phone number' do
|
|
let(:different_account) { create(:account) }
|
|
|
|
before do
|
|
create(:channel_whatsapp, account: different_account, phone_number: '+1234567890',
|
|
provider: 'whatsapp_cloud', sync_templates: false, validate_provider_config: false)
|
|
end
|
|
|
|
it 'raises an error even if the channel belongs to a different account' do
|
|
expect { service.perform }.to raise_error(
|
|
RuntimeError,
|
|
I18n.t('errors.whatsapp.phone_number_already_exists', phone_number: '+1234567890')
|
|
)
|
|
end
|
|
end
|
|
|
|
context 'when required parameters are missing' do
|
|
it 'raises error when account is nil' do
|
|
service = described_class.new(nil, waba_info, phone_info, access_token)
|
|
expect { service.perform }.to raise_error(ArgumentError, 'Account is required')
|
|
end
|
|
|
|
it 'raises error when waba_info is nil' do
|
|
service = described_class.new(account, nil, phone_info, access_token)
|
|
expect { service.perform }.to raise_error(ArgumentError, 'WABA info is required')
|
|
end
|
|
|
|
it 'raises error when phone_info is nil' do
|
|
service = described_class.new(account, waba_info, nil, access_token)
|
|
expect { service.perform }.to raise_error(ArgumentError, 'Phone info is required')
|
|
end
|
|
|
|
it 'raises error when access_token is blank' do
|
|
service = described_class.new(account, waba_info, phone_info, '')
|
|
expect { service.perform }.to raise_error(ArgumentError, 'Access token is required')
|
|
end
|
|
end
|
|
|
|
context 'when business_name is in different places' do
|
|
context 'when business_name is only in phone_info' do
|
|
let(:waba_info) { { waba_id: 'test_waba_id' } }
|
|
|
|
it 'uses business_name from phone_info' do
|
|
channel = service.perform
|
|
expect(channel.inbox.name).to eq('Test Business WhatsApp')
|
|
end
|
|
end
|
|
|
|
context 'when business_name is only in waba_info' do
|
|
let(:phone_info) do
|
|
{
|
|
phone_number_id: 'test_phone_id',
|
|
phone_number: '+1234567890',
|
|
verified: true
|
|
}
|
|
end
|
|
|
|
it 'uses business_name from waba_info' do
|
|
channel = service.perform
|
|
expect(channel.inbox.name).to eq('Test Business WhatsApp')
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|