Files
leadchat/spec/services/whatsapp/incoming_message_whatsapp_cloud_service_spec.rb
Eduardo Policarpo 46b75e1b03 feat(whatsapp): add optional phone_number_id parameter to media retrieval API (#11823)
## Description

This pull request introduces an optional parameter, `phone_number_id`,
to the WhatsApp API call responsible for retrieving media. The addition
of this parameter allows for greater flexibility when interacting with
the WhatsApp API, as it can now accommodate scenarios where specifying a
particular phone number ID is necessary. This change is backward
compatible and does not affect existing functionality if the parameter
is not provided.

Fixes # (issue)

## Type of change

- [x] New feature (non-breaking change which adds functionality)

## How Has This Been Tested?

The changes were tested locally by invoking the WhatsApp media retrieval
API with and without the `phone_number_id` parameter. Both scenarios
were verified to ensure that:

- When `phone_number_id` is provided, the API call includes the
parameter and functions as expected.
- When `phone_number_id` is omitted, the API call continues to work as
before, maintaining backward compatibility.

No errors or warnings were observed during testing, and all relevant
unit tests passed successfully.

## Checklist

- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my code
- [x] I have commented on my code, particularly in hard-to-understand
areas
- [x] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [x] Any dependent changes have been merged and published in downstream
modules

---------

Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
2025-09-23 09:16:59 +05:30

156 lines
5.4 KiB
Ruby

require 'rails_helper'
describe Whatsapp::IncomingMessageWhatsappCloudService do
describe '#perform' do
let!(:whatsapp_channel) { create(:channel_whatsapp, provider: 'whatsapp_cloud', sync_templates: false, validate_provider_config: false) }
let(:params) do
{
phone_number: whatsapp_channel.phone_number,
object: 'whatsapp_business_account',
entry: [{
changes: [{
value: {
contacts: [{ profile: { name: 'Sojan Jose' }, wa_id: '2423423243' }],
messages: [{
from: '2423423243',
image: {
id: 'b1c68f38-8734-4ad3-b4a1-ef0c10d683',
mime_type: 'image/jpeg',
sha256: '29ed500fa64eb55fc19dc4124acb300e5dcca0f822a301ae99944db',
caption: 'Check out my product!'
},
timestamp: '1664799904', type: 'image'
}]
}
}]
}]
}.with_indifferent_access
end
context 'when valid attachment message params' do
it 'creates appropriate conversations, message and contacts' do
stub_media_url_request
stub_sample_png_request
described_class.new(inbox: whatsapp_channel.inbox, params: params).perform
expect_conversation_created
expect_contact_name
expect_message_content
expect_message_has_attachment
end
it 'increments reauthorization count if fetching attachment fails' do
stub_request(
:get,
whatsapp_channel.media_url(
'b1c68f38-8734-4ad3-b4a1-ef0c10d683',
whatsapp_channel.provider_config['phone_number_id']
)
).to_return(
status: 401
)
described_class.new(inbox: whatsapp_channel.inbox, params: params).perform
expect(whatsapp_channel.inbox.conversations.count).not_to eq(0)
expect(Contact.all.first.name).to eq('Sojan Jose')
expect(whatsapp_channel.inbox.messages.first.content).to eq('Check out my product!')
expect(whatsapp_channel.inbox.messages.first.attachments.present?).to be false
expect(whatsapp_channel.authorization_error_count).to eq(1)
end
end
context 'when invalid attachment message params' do
let(:error_params) do
{
phone_number: whatsapp_channel.phone_number,
object: 'whatsapp_business_account',
entry: [{
changes: [{
value: {
contacts: [{ profile: { name: 'Sojan Jose' }, wa_id: '2423423243' }],
messages: [{
from: '2423423243',
image: {
id: 'b1c68f38-8734-4ad3-b4a1-ef0c10d683',
mime_type: 'image/jpeg',
sha256: '29ed500fa64eb55fc19dc4124acb300e5dcca0f822a301ae99944db',
caption: 'Check out my product!'
},
errors: [{
code: 400,
details: 'Last error was: ServerThrottle. Http request error: HTTP response code said error. See logs for details',
title: 'Media download failed: Not retrying as download is not retriable at this time'
}],
timestamp: '1664799904', type: 'image'
}]
}
}]
}]
}.with_indifferent_access
end
it 'with attachment errors' do
described_class.new(inbox: whatsapp_channel.inbox, params: error_params).perform
expect(whatsapp_channel.inbox.conversations.count).not_to eq(0)
expect(Contact.all.first.name).to eq('Sojan Jose')
expect(whatsapp_channel.inbox.messages.count).to eq(0)
end
end
context 'when invalid params' do
it 'will not throw error' do
described_class.new(inbox: whatsapp_channel.inbox, params: { phone_number: whatsapp_channel.phone_number,
object: 'whatsapp_business_account', entry: {} }).perform
expect(whatsapp_channel.inbox.conversations.count).to eq(0)
expect(Contact.all.first).to be_nil
expect(whatsapp_channel.inbox.messages.count).to eq(0)
end
end
end
# Métodos auxiliares para reduzir o tamanho do exemplo
def stub_media_url_request
stub_request(
:get,
whatsapp_channel.media_url(
'b1c68f38-8734-4ad3-b4a1-ef0c10d683',
whatsapp_channel.provider_config['phone_number_id']
)
).to_return(
status: 200,
body: {
messaging_product: 'whatsapp',
url: 'https://chatwoot-assets.local/sample.png',
mime_type: 'image/jpeg',
sha256: 'sha256',
file_size: 'SIZE',
id: 'b1c68f38-8734-4ad3-b4a1-ef0c10d683'
}.to_json,
headers: { 'content-type' => 'application/json' }
)
end
def stub_sample_png_request
stub_request(:get, 'https://chatwoot-assets.local/sample.png').to_return(
status: 200,
body: File.read('spec/assets/sample.png')
)
end
def expect_conversation_created
expect(whatsapp_channel.inbox.conversations.count).not_to eq(0)
end
def expect_contact_name
expect(Contact.all.first.name).to eq('Sojan Jose')
end
def expect_message_content
expect(whatsapp_channel.inbox.messages.first.content).to eq('Check out my product!')
end
def expect_message_has_attachment
expect(whatsapp_channel.inbox.messages.first.attachments.present?).to be true
end
end