chore: Automation bug fix (#4442)

This commit is contained in:
Tejaswini Chile 2022-04-12 20:23:34 +05:30 committed by GitHub
parent b6ad468eb4
commit 923b4637db
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 47 additions and 164 deletions

View file

@ -194,7 +194,7 @@ export default {
required: requiredIf(prop => { required: requiredIf(prop => {
return !( return !(
prop.action_name === 'mute_conversation' || prop.action_name === 'mute_conversation' ||
prop.action_name === 'snooze_convresation' || prop.action_name === 'snooze_conversation' ||
prop.action_name === 'resolve_convresation' prop.action_name === 'resolve_convresation'
); );
}), }),

View file

@ -198,7 +198,7 @@ export default {
required: requiredIf(prop => { required: requiredIf(prop => {
return !( return !(
prop.action_name === 'mute_conversation' || prop.action_name === 'mute_conversation' ||
prop.action_name === 'snooze_convresation' || prop.action_name === 'snooze_conversation' ||
prop.action_name === 'resolve_convresation' prop.action_name === 'resolve_convresation'
); );
}), }),

View file

@ -92,7 +92,7 @@ export const AUTOMATIONS = {
attributeI18nKey: 'MUTE_CONVERSATION', attributeI18nKey: 'MUTE_CONVERSATION',
}, },
{ {
key: 'snooze_convresation', key: 'snooze_conversation',
name: 'Snooze conversation', name: 'Snooze conversation',
attributeI18nKey: 'MUTE_CONVERSATION', attributeI18nKey: 'MUTE_CONVERSATION',
}, },
@ -166,7 +166,7 @@ export const AUTOMATIONS = {
attributeI18nKey: 'MUTE_CONVERSATION', attributeI18nKey: 'MUTE_CONVERSATION',
}, },
{ {
key: 'snooze_convresation', key: 'snooze_conversation',
name: 'Snooze conversation', name: 'Snooze conversation',
attributeI18nKey: 'MUTE_CONVERSATION', attributeI18nKey: 'MUTE_CONVERSATION',
}, },
@ -254,7 +254,7 @@ export const AUTOMATIONS = {
attributeI18nKey: 'MUTE_CONVERSATION', attributeI18nKey: 'MUTE_CONVERSATION',
}, },
{ {
key: 'snooze_convresation', key: 'snooze_conversation',
name: 'Snooze conversation', name: 'Snooze conversation',
attributeI18nKey: 'MUTE_CONVERSATION', attributeI18nKey: 'MUTE_CONVERSATION',
}, },
@ -314,7 +314,7 @@ export const AUTOMATION_ACTION_TYPES = [
inputType: null, inputType: null,
}, },
{ {
key: 'snooze_convresation', key: 'snooze_conversation',
label: 'Snooze conversation', label: 'Snooze conversation',
inputType: null, inputType: null,
}, },

View file

@ -1,5 +1,7 @@
class AutomationRuleListener < BaseListener class AutomationRuleListener < BaseListener
def conversation_updated(event_obj) def conversation_updated(event_obj)
return if performed_by_automation?(event_obj)
conversation = event_obj.data[:conversation] conversation = event_obj.data[:conversation]
account = conversation.account account = conversation.account
@ -11,19 +13,9 @@ class AutomationRuleListener < BaseListener
end end
end end
def conversation_status_changed(event_obj)
conversation = event_obj.data[:conversation]
account = conversation.account
return unless rule_present?('conversation_status_changed', account)
@rules.each do |rule|
conditions_match = ::AutomationRules::ConditionsFilterService.new(rule, conversation).perform
AutomationRules::ActionService.new(rule, account, conversation).perform if conditions_match.present?
end
end
def conversation_created(event_obj) def conversation_created(event_obj)
return if performed_by_automation?(event_obj)
conversation = event_obj.data[:conversation] conversation = event_obj.data[:conversation]
account = conversation.account account = conversation.account
@ -36,6 +28,8 @@ class AutomationRuleListener < BaseListener
end end
def message_created(event_obj) def message_created(event_obj)
return if performed_by_automation?(event_obj)
message = event_obj.data[:message] message = event_obj.data[:message]
account = message.try(:account) account = message.try(:account)
@ -57,4 +51,8 @@ class AutomationRuleListener < BaseListener
) )
@rules.any? @rules.any?
end end
def performed_by_automation?(event_obj)
event_obj.data[:performed_by].present? && event_obj.data[:performed_by].instance_of?(AutomationRule)
end
end end

View file

@ -35,18 +35,14 @@ class TeamNotifications::AutomationNotificationMailer < ApplicationMailer
private private
def send_an_email_to_team def send_an_email_to_team
@agents.each do |agent| subject = 'This email has been sent via automation rule actions.'
subject = "#{agent.user.available_name}, This email has been sent via automation rule actions." @action_url = app_account_conversation_url(account_id: @conversation.account_id, id: @conversation.display_id)
@action_url = app_account_conversation_url(account_id: @conversation.account_id, id: @conversation.display_id) @agent_emails = @agents.collect(&:user).pluck(:email)
@agent = agent send_mail_with_liquid(to: @agent_emails, subject: subject) and return
send_mail_with_liquid(to: @agent.user.email, subject: subject)
end
end end
def liquid_droppables def liquid_droppables
super.merge!({ super.merge!({
user: @agent.user,
conversation: @conversation, conversation: @conversation,
inbox: @conversation.inbox inbox: @conversation.inbox
}) })

View file

@ -214,10 +214,9 @@ class Conversation < ApplicationRecord
end end
def dispatcher_dispatch(event_name, changed_attributes = nil) def dispatcher_dispatch(event_name, changed_attributes = nil)
return if Current.executed_by.present? && Current.executed_by.instance_of?(AutomationRule)
Rails.configuration.dispatcher.dispatch(event_name, Time.zone.now, conversation: self, notifiable_assignee_change: notifiable_assignee_change?, Rails.configuration.dispatcher.dispatch(event_name, Time.zone.now, conversation: self, notifiable_assignee_change: notifiable_assignee_change?,
changed_attributes: changed_attributes) changed_attributes: changed_attributes,
performed_by: Current.executed_by)
end end
def conversation_status_changed_to_open? def conversation_status_changed_to_open?

View file

@ -166,19 +166,15 @@ class Message < ApplicationRecord
end end
def dispatch_create_events def dispatch_create_events
return if Current.executed_by.present? && Current.executed_by.instance_of?(AutomationRule) Rails.configuration.dispatcher.dispatch(MESSAGE_CREATED, Time.zone.now, message: self, performed_by: Current.executed_by)
Rails.configuration.dispatcher.dispatch(MESSAGE_CREATED, Time.zone.now, message: self)
if outgoing? && conversation.messages.outgoing.count == 1 if outgoing? && conversation.messages.outgoing.count == 1
Rails.configuration.dispatcher.dispatch(FIRST_REPLY_CREATED, Time.zone.now, message: self) Rails.configuration.dispatcher.dispatch(FIRST_REPLY_CREATED, Time.zone.now, message: self, performed_by: Current.executed_by)
end end
end end
def dispatch_update_event def dispatch_update_event
return if Current.executed_by.present? && Current.executed_by.instance_of?(AutomationRule) Rails.configuration.dispatcher.dispatch(MESSAGE_UPDATED, Time.zone.now, message: self, performed_by: Current.executed_by)
Rails.configuration.dispatcher.dispatch(MESSAGE_UPDATED, Time.zone.now, message: self)
end end
def send_reply def send_reply

View file

@ -41,7 +41,7 @@ class AutomationRules::ActionService
end end
def snooze_conversation(_params) def snooze_conversation(_params)
@conversation.ensure_snooze_until_reset @conversation.snoozed!
end end
def change_status(status) def change_status(status)

View file

@ -1,5 +1,4 @@
<p>Hi {{user.available_name}}</p> <p>This is the mail from Automation System</p>
<p>{{ custom_message }}</p> <p>{{ custom_message }}</p>

View file

@ -259,7 +259,7 @@ RSpec.describe 'Api::V1::Accounts::AutomationRulesController', type: :request do
end end
context 'when it is an authenticated user' do context 'when it is an authenticated user' do
it 'returns for cloned automation_rule for account' do it 'returns for updated automation_rule for account' do
params = { name: 'Update name' } params = { name: 'Update name' }
expect(account.automation_rules.count).to eq(1) expect(account.automation_rules.count).to eq(1)
@ -271,6 +271,20 @@ RSpec.describe 'Api::V1::Accounts::AutomationRulesController', type: :request do
body = JSON.parse(response.body, symbolize_names: true) body = JSON.parse(response.body, symbolize_names: true)
expect(body[:payload][:name]).to eq('Update name') expect(body[:payload][:name]).to eq('Update name')
end end
it 'returns for updated active flag for automation_rule' do
expect(automation_rule.active).to eq(true)
params = { active: false }
patch "/api/v1/accounts/#{account.id}/automation_rules/#{automation_rule.id}",
headers: administrator.create_new_auth_token,
params: params
expect(response).to have_http_status(:success)
body = JSON.parse(response.body, symbolize_names: true)
expect(body[:payload][:active]).to eq(false)
expect(automation_rule.reload.active).to eq(false)
end
end end
end end

View file

@ -50,125 +50,6 @@ describe AutomationRuleListener do
automation_rule.save automation_rule.save
end end
describe '#conversation_status_changed' do
context 'when rule matches' do
it 'triggers automation rule send webhook events' do
payload = conversation.webhook_data.merge(event: "automation_event: #{automation_rule.event_name}")
automation_rule
expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_creation)
expect(WebhookJob).to receive(:perform_later).with('https://www.example.com', payload).once
listener.conversation_status_changed(event)
end
it 'triggers automation rule to assign team' do
expect(conversation.team_id).not_to eq(team.id)
automation_rule
expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_creation)
listener.conversation_status_changed(event)
conversation.reload
expect(conversation.team_id).to eq(team.id)
end
it 'triggers automation rule to add label' do
expect(conversation.labels).to eq([])
automation_rule
expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_creation)
listener.conversation_status_changed(event)
conversation.reload
expect(conversation.labels.pluck(:name)).to contain_exactly('support', 'priority_customer')
end
it 'triggers automation rule to assign best agents' do
expect(conversation.assignee).to be_nil
automation_rule
expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_creation)
listener.conversation_status_changed(event)
conversation.reload
expect(conversation.assignee).to eq(user_1)
end
it 'triggers automation rule send message to the contacts' do
expect(conversation.messages).to be_empty
automation_rule
expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_creation)
listener.conversation_status_changed(event)
conversation.reload
expect(conversation.messages.first.content).to eq('Send this message.')
end
it 'triggers automation rule changes status to snoozed' do
expect(conversation.status).to eq('resolved')
automation_rule
expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_creation)
listener.conversation_status_changed(event)
conversation.reload
expect(conversation.status).to eq('snoozed')
end
it 'triggers automation rule send email transcript to the mentioned email' do
mailer = double
automation_rule
expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_creation)
listener.conversation_status_changed(event)
conversation.reload
allow(mailer).to receive(:conversation_transcript)
end
it 'triggers automation rule send email to the team' do
automation_rule
expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_creation)
listener.conversation_status_changed(event)
end
it 'triggers automation rule send attachments in messages' do
automation_rule
expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_creation)
listener.conversation_status_changed(event)
conversation.reload
expect(conversation.messages.last.attachments.count).to eq(1)
end
end
end
describe '#conversation_updated with contacts attributes' do describe '#conversation_updated with contacts attributes' do
before do before do
conversation.contact.update!(custom_attributes: { customer_type: 'platinum', signed_in_at: '2022-01-19' }, conversation.contact.update!(custom_attributes: { customer_type: 'platinum', signed_in_at: '2022-01-19' },

View file

@ -55,7 +55,7 @@ RSpec.describe Conversation, type: :model do
# send_events # send_events
expect(Rails.configuration.dispatcher).to have_received(:dispatch) expect(Rails.configuration.dispatcher).to have_received(:dispatch)
.with(described_class::CONVERSATION_CREATED, kind_of(Time), conversation: conversation, notifiable_assignee_change: false, .with(described_class::CONVERSATION_CREATED, kind_of(Time), conversation: conversation, notifiable_assignee_change: false,
changed_attributes: nil) changed_attributes: nil, performed_by: nil)
end end
end end
@ -121,16 +121,16 @@ RSpec.describe Conversation, type: :model do
expect(Rails.configuration.dispatcher).to have_received(:dispatch) expect(Rails.configuration.dispatcher).to have_received(:dispatch)
.with(described_class::CONVERSATION_RESOLVED, kind_of(Time), conversation: conversation, notifiable_assignee_change: true, .with(described_class::CONVERSATION_RESOLVED, kind_of(Time), conversation: conversation, notifiable_assignee_change: true,
changed_attributes: status_change) changed_attributes: status_change, performed_by: nil)
expect(Rails.configuration.dispatcher).to have_received(:dispatch) expect(Rails.configuration.dispatcher).to have_received(:dispatch)
.with(described_class::CONVERSATION_READ, kind_of(Time), conversation: conversation, notifiable_assignee_change: true, .with(described_class::CONVERSATION_READ, kind_of(Time), conversation: conversation, notifiable_assignee_change: true,
changed_attributes: nil) changed_attributes: nil, performed_by: nil)
expect(Rails.configuration.dispatcher).to have_received(:dispatch) expect(Rails.configuration.dispatcher).to have_received(:dispatch)
.with(described_class::ASSIGNEE_CHANGED, kind_of(Time), conversation: conversation, notifiable_assignee_change: true, .with(described_class::ASSIGNEE_CHANGED, kind_of(Time), conversation: conversation, notifiable_assignee_change: true,
changed_attributes: nil) changed_attributes: nil, performed_by: nil)
expect(Rails.configuration.dispatcher).to have_received(:dispatch) expect(Rails.configuration.dispatcher).to have_received(:dispatch)
.with(described_class::CONVERSATION_UPDATED, kind_of(Time), conversation: conversation, notifiable_assignee_change: true, .with(described_class::CONVERSATION_UPDATED, kind_of(Time), conversation: conversation, notifiable_assignee_change: true,
changed_attributes: changed_attributes) changed_attributes: changed_attributes, performed_by: nil)
end end
it 'will not run conversation_updated event for empty updates' do it 'will not run conversation_updated event for empty updates' do