iachat/spec/services/whatsapp/zapi_handlers/message_status_callback_spec.rb
Gabriel Jablonski 8ff5834ee8
fix(zapi): support for LID-only conversations (#123)
* fix: ignore action events

* feat(zapi): allow updating instance ID

* feat: handle `chatLid` field

* test: break down handler specs into separate files

* feat: update send_message method to use recipient_id logic for zapi provider

* fix: use identifier instead of source_id for zapi

* test: fix specs

* feat: prioritize senderName over chatName for contact naming in received callback
2025-10-23 10:12:38 -03:00

156 lines
4.3 KiB
Ruby

require 'rails_helper'
describe Whatsapp::ZapiHandlers::MessageStatusCallback do
let!(:whatsapp_channel) do
create(:channel_whatsapp, provider: 'zapi', validate_provider_config: false)
end
let(:inbox) { whatsapp_channel.inbox }
let(:service) { Whatsapp::IncomingMessageZapiService.new(inbox: inbox, params: params) }
describe '#process_message_status_callback' do
let(:message1) { create(:message, inbox: inbox, source_id: 'msg_123') }
let(:message2) { create(:message, inbox: inbox, source_id: 'msg_456') }
let(:params) do
{
type: 'MessageStatusCallback',
ids: [message1.source_id, message2.source_id],
status: 'SENT'
}
end
it 'updates message status to sent when Z-API status is SENT' do
service.perform
expect(message1.reload.status).to eq('sent')
expect(message2.reload.status).to eq('sent')
end
it 'updates message status to delivered for DELIVERED status' do
params[:status] = 'DELIVERED'
service.perform
expect(message1.reload.status).to eq('delivered')
expect(message2.reload.status).to eq('delivered')
end
it 'updates message status to delivered for RECEIVED status' do
params[:status] = 'RECEIVED'
service.perform
expect(message1.reload.status).to eq('delivered')
expect(message2.reload.status).to eq('delivered')
end
it 'updates message status to read for READ status' do
params[:status] = 'READ'
service.perform
expect(message1.reload.status).to eq('read')
expect(message2.reload.status).to eq('read')
end
it 'updates message status to read for READ_BY_ME status' do
params[:status] = 'READ_BY_ME'
service.perform
expect(message1.reload.status).to eq('read')
expect(message2.reload.status).to eq('read')
end
it 'updates message status to read for PLAYED status' do
params[:status] = 'PLAYED'
service.perform
expect(message1.reload.status).to eq('read')
expect(message2.reload.status).to eq('read')
end
it 'does not update status on unknown status and logs warning' do
params[:status] = 'UNKNOWN_STATUS'
allow(Rails.logger).to receive(:warn)
expect do
service.perform
end.not_to(change { [message1.reload.status, message2.reload.status] })
expect(Rails.logger).to have_received(:warn).with('Unknown ZAPI status: UNKNOWN_STATUS')
end
context 'when status transition is not allowed' do
it 'does not downgrade read message to delivered' do
message1.update!(status: 'read')
params[:status] = 'DELIVERED'
expect do
service.perform
end.not_to(change { message1.reload.status })
end
it 'does not downgrade read message to sent' do
message1.update!(status: 'read')
params[:status] = 'SENT'
expect do
service.perform
end.not_to(change { message1.reload.status })
expect(message1.status).to eq('read')
end
it 'does not downgrade delivered message to sent' do
message1.update!(status: 'delivered')
params[:status] = 'SENT'
expect do
service.perform
end.not_to(change { message1.reload.status })
expect(message1.status).to eq('delivered')
end
it 'allows upgrading delivered message to read' do
message1.update!(status: 'delivered')
params[:status] = 'READ'
service.perform
expect(message1.reload.status).to eq('read')
end
it 'allows upgrading sent message to delivered' do
message1.update!(status: 'sent')
params[:status] = 'DELIVERED'
service.perform
expect(message1.reload.status).to eq('delivered')
end
it 'allows upgrading sent message to read' do
message1.update!(status: 'sent')
params[:status] = 'READ'
service.perform
expect(message1.reload.status).to eq('read')
end
it 'handles mixed status transitions correctly' do
message1.update!(status: 'sent')
message2.update!(status: 'read')
params[:status] = 'DELIVERED'
service.perform
expect(message1.reload.status).to eq('delivered')
expect(message2.reload.status).to eq('read')
end
end
end
end