From a18d54b7064d6bb0fb2eec23da5d6453329cb92a Mon Sep 17 00:00:00 2001 From: Sojan Jose Date: Fri, 17 Jul 2020 00:32:32 +0530 Subject: [PATCH] Chore: Cleanup attachment handling for Facebook & Whatsapp (#1051) * Chore: Enable file upload for facebook messenger * Chore: Fix attachments * Chore: Fix Specs * Fix ReplyBox file attachment logic * Set default value for message Co-authored-by: Pranav Raj Sreepuram --- .../widgets/conversation/ReplyBox.vue | 178 ++++++++++-------- .../store/modules/conversations/index.js | 4 + .../shared/helpers/KeyboardHelpers.js | 11 ++ .../shared/helpers/MessageFormatter.js | 2 +- .../shared/helpers/MessageTypeHelper.js | 7 + .../helpers/specs/KeyboardHelpers.spec.js | 21 +++ app/jobs/send_reply_job.rb | 15 ++ app/models/message.rb | 9 +- .../facebook/send_on_facebook_service.rb | 11 +- docs/channels/supported-features.md | 4 +- spec/factories/messages.rb | 2 +- .../facebook/send_on_facebook_service_spec.rb | 19 +- .../twilio/send_on_twilio_service_spec.rb | 17 +- .../twitter/send_on_twitter_service_spec.rb | 20 +- 14 files changed, 212 insertions(+), 108 deletions(-) create mode 100644 app/javascript/shared/helpers/KeyboardHelpers.js create mode 100644 app/javascript/shared/helpers/specs/KeyboardHelpers.spec.js create mode 100644 app/jobs/send_reply_job.rb diff --git a/app/javascript/dashboard/components/widgets/conversation/ReplyBox.vue b/app/javascript/dashboard/components/widgets/conversation/ReplyBox.vue index 499394184..11fa825cf 100644 --- a/app/javascript/dashboard/components/widgets/conversation/ReplyBox.vue +++ b/app/javascript/dashboard/components/widgets/conversation/ReplyBox.vue @@ -15,9 +15,9 @@ /> - - + +
diff --git a/spec/factories/messages.rb b/spec/factories/messages.rb index 264e6cae9..dee821a4f 100644 --- a/spec/factories/messages.rb +++ b/spec/factories/messages.rb @@ -10,8 +10,8 @@ FactoryBot.define do after(:build) do |message| message.sender ||= create(:user, account: message.account) - message.conversation ||= create(:conversation, account: message.account) message.inbox ||= create(:inbox, account: message.account) + message.conversation ||= create(:conversation, account: message.account, inbox: message.inbox) end end end diff --git a/spec/services/facebook/send_on_facebook_service_spec.rb b/spec/services/facebook/send_on_facebook_service_spec.rb index 742044abd..25a84f9e7 100644 --- a/spec/services/facebook/send_on_facebook_service_spec.rb +++ b/spec/services/facebook/send_on_facebook_service_spec.rb @@ -6,6 +6,7 @@ describe Facebook::SendOnFacebookService do before do allow(Facebook::Messenger::Subscriptions).to receive(:subscribe).and_return(true) allow(bot).to receive(:deliver) + create(:message, message_type: :incoming, inbox: facebook_inbox, account: account, conversation: conversation) end let!(:account) { create(:account) } @@ -20,39 +21,43 @@ describe Facebook::SendOnFacebookService do describe '#perform' do context 'without reply' do it 'if message is private' do - create(:message, message_type: 'outgoing', private: true, inbox: facebook_inbox, account: account) + message = create(:message, message_type: 'outgoing', private: true, inbox: facebook_inbox, account: account) + ::Facebook::SendOnFacebookService.new(message: message).perform expect(bot).not_to have_received(:deliver) end it 'if inbox channel is not facebook page' do - create(:message, message_type: 'outgoing', inbox: widget_inbox, account: account) + message = create(:message, message_type: 'outgoing', inbox: widget_inbox, account: account) + expect { ::Facebook::SendOnFacebookService.new(message: message).perform }.to raise_error 'Invalid channel service was called' expect(bot).not_to have_received(:deliver) end it 'if message is not outgoing' do - create(:message, message_type: 'incoming', inbox: facebook_inbox, account: account) + message = create(:message, message_type: 'incoming', inbox: facebook_inbox, account: account) + ::Facebook::SendOnFacebookService.new(message: message).perform expect(bot).not_to have_received(:deliver) end it 'if message has an FB ID' do - create(:message, message_type: 'outgoing', inbox: facebook_inbox, account: account, source_id: SecureRandom.uuid) + message = create(:message, message_type: 'outgoing', inbox: facebook_inbox, account: account, source_id: SecureRandom.uuid) + ::Facebook::SendOnFacebookService.new(message: message).perform expect(bot).not_to have_received(:deliver) end end context 'with reply' do it 'if message is sent from chatwoot and is outgoing' do - create(:message, message_type: :incoming, inbox: facebook_inbox, account: account, conversation: conversation) - create(:message, message_type: 'outgoing', inbox: facebook_inbox, account: account, conversation: conversation) + message = create(:message, message_type: 'outgoing', inbox: facebook_inbox, account: account, conversation: conversation) + ::Facebook::SendOnFacebookService.new(message: message).perform expect(bot).to have_received(:deliver) end it 'if message with attachment is sent from chatwoot and is outgoing' do - create(:message, message_type: :incoming, inbox: facebook_inbox, account: account, conversation: conversation) message = build(:message, message_type: 'outgoing', inbox: facebook_inbox, account: account, conversation: conversation) attachment = message.attachments.new(account_id: message.account_id, file_type: :image) attachment.file.attach(io: File.open(Rails.root.join('spec/assets/avatar.png')), filename: 'avatar.png', content_type: 'image/png') message.save! + ::Facebook::SendOnFacebookService.new(message: message).perform expect(bot).to have_received(:deliver) end end diff --git a/spec/services/twilio/send_on_twilio_service_spec.rb b/spec/services/twilio/send_on_twilio_service_spec.rb index 56a8283c3..3f114a00b 100644 --- a/spec/services/twilio/send_on_twilio_service_spec.rb +++ b/spec/services/twilio/send_on_twilio_service_spec.rb @@ -25,22 +25,26 @@ describe Twilio::SendOnTwilioService do describe '#perform' do context 'without reply' do it 'if message is private' do - create(:message, message_type: 'outgoing', private: true, inbox: twilio_inbox, account: account) + message = create(:message, message_type: 'outgoing', private: true, inbox: twilio_inbox, account: account) + ::Twilio::SendOnTwilioService.new(message: message).perform expect(twilio_client).not_to have_received(:messages) end - it 'if inbox channel is not facebook page' do - create(:message, message_type: 'outgoing', inbox: widget_inbox, account: account) + it 'if inbox channel is not twilio' do + message = create(:message, message_type: 'outgoing', inbox: widget_inbox, account: account) + expect { ::Twilio::SendOnTwilioService.new(message: message).perform }.to raise_error 'Invalid channel service was called' expect(twilio_client).not_to have_received(:messages) end it 'if message is not outgoing' do - create(:message, message_type: 'incoming', inbox: twilio_inbox, account: account) + message = create(:message, message_type: 'incoming', inbox: twilio_inbox, account: account) + ::Twilio::SendOnTwilioService.new(message: message).perform expect(twilio_client).not_to have_received(:messages) end it 'if message has an source id' do - create(:message, message_type: 'outgoing', inbox: twilio_inbox, account: account, source_id: SecureRandom.uuid) + message = create(:message, message_type: 'outgoing', inbox: twilio_inbox, account: account, source_id: SecureRandom.uuid) + ::Twilio::SendOnTwilioService.new(message: message).perform expect(twilio_client).not_to have_received(:messages) end end @@ -53,6 +57,7 @@ describe Twilio::SendOnTwilioService do outgoing_message = create( :message, message_type: 'outgoing', inbox: twilio_inbox, account: account, conversation: conversation ) + ::Twilio::SendOnTwilioService.new(message: outgoing_message).perform expect(outgoing_message.reload.source_id).to eq('1234') end @@ -69,6 +74,8 @@ describe Twilio::SendOnTwilioService do attachment = message.attachments.new(account_id: message.account_id, file_type: :image) attachment.file.attach(io: File.open(Rails.root.join('spec/assets/avatar.png')), filename: 'avatar.png', content_type: 'image/png') message.save! + + ::Twilio::SendOnTwilioService.new(message: message).perform end end end diff --git a/spec/services/twitter/send_on_twitter_service_spec.rb b/spec/services/twitter/send_on_twitter_service_spec.rb index 017fcf27c..4e0f4e91e 100644 --- a/spec/services/twitter/send_on_twitter_service_spec.rb +++ b/spec/services/twitter/send_on_twitter_service_spec.rb @@ -41,22 +41,26 @@ describe Twitter::SendOnTwitterService do describe '#perform' do context 'without reply' do it 'if inbox channel is not twitter profile' do - create(:message, message_type: 'outgoing', inbox: widget_inbox, account: account) + message = create(:message, message_type: 'outgoing', inbox: widget_inbox, account: account) + expect { ::Twitter::SendOnTwitterService.new(message: message).perform }.to raise_error 'Invalid channel service was called' expect(twitter_client).not_to have_received(:send_direct_message) end it 'if message is private' do - create(:message, message_type: 'outgoing', private: true, inbox: twitter_inbox, account: account) + message = create(:message, message_type: 'outgoing', private: true, inbox: twitter_inbox, account: account) + ::Twitter::SendOnTwitterService.new(message: message).perform expect(twitter_client).not_to have_received(:send_direct_message) end it 'if message has source_id' do - create(:message, message_type: 'outgoing', source_id: '123', inbox: widget_inbox, account: account) + message = create(:message, message_type: 'outgoing', source_id: '123', inbox: twitter_inbox, account: account) + ::Twitter::SendOnTwitterService.new(message: message).perform expect(twitter_client).not_to have_received(:send_direct_message) end it 'if message is not outgoing' do - create(:message, message_type: 'incoming', inbox: twitter_inbox, account: account) + message = create(:message, message_type: 'incoming', inbox: twitter_inbox, account: account) + ::Twitter::SendOnTwitterService.new(message: message).perform expect(twitter_client).not_to have_received(:send_direct_message) end end @@ -64,15 +68,17 @@ describe Twitter::SendOnTwitterService do context 'with reply' do it 'if conversation is a direct message' do create(:message, message_type: :incoming, inbox: twitter_inbox, account: account, conversation: dm_conversation) - create(:message, message_type: :outgoing, inbox: twitter_inbox, account: account, conversation: dm_conversation) + message = create(:message, message_type: :outgoing, inbox: twitter_inbox, account: account, conversation: dm_conversation) + ::Twitter::SendOnTwitterService.new(message: message).perform expect(twitter_client).to have_received(:send_direct_message) end it 'if conversation is a tweet' do create(:message, message_type: :incoming, inbox: twitter_inbox, account: account, conversation: tweet_conversation) - tweet = create(:message, message_type: :outgoing, inbox: twitter_inbox, account: account, conversation: tweet_conversation) + message = create(:message, message_type: :outgoing, inbox: twitter_inbox, account: account, conversation: tweet_conversation) + ::Twitter::SendOnTwitterService.new(message: message).perform expect(twitter_client).to have_received(:send_tweet_reply) - expect(tweet.reload.source_id).to eq '12345' + expect(message.reload.source_id).to eq '12345' end end end