feat: Add send message, fix issues with message conditions (#4423)

Co-authored-by: Tejaswini <tejaswini@chatwoot.com>
This commit is contained in:
Fayaz Ahmed
2022-04-14 13:36:55 +05:30
committed by GitHub
parent d4be268cc3
commit 337a74a10c
15 changed files with 231 additions and 86 deletions

View File

@@ -20,9 +20,15 @@ class Api::V1::Accounts::AutomationRulesController < Api::V1::Accounts::BaseCont
def show; end def show; end
def update def update
@automation_rule.update(automation_rules_permit) ActiveRecord::Base.transaction do
process_attachments @automation_rule.update!(automation_rules_permit)
@automation_rule @automation_rule.actions = params[:actions] if params[:actions]
@automation_rule.save!
process_attachments
rescue StandardError => e
Rails.logger.error e
render json: { error: @automation_rule.errors.messages }.to_json, status: :unprocessable_entity
end
end end
def destroy def destroy
@@ -45,6 +51,7 @@ class Api::V1::Accounts::AutomationRulesController < Api::V1::Accounts::BaseCont
params[:attachments].each do |uploaded_attachment| params[:attachments].each do |uploaded_attachment|
@automation_rule.files.attach(uploaded_attachment) @automation_rule.files.attach(uploaded_attachment)
end end
@automation_rule
end end
def automation_rules_permit def automation_rules_permit

View File

@@ -7,7 +7,7 @@
<select <select
v-model="action_name" v-model="action_name"
class="action__question" class="action__question"
:class="{ 'full-width': !inputType }" :class="{ 'full-width': !showActionInput }"
@change="resetAction()" @change="resetAction()"
> >
<option <option
@@ -61,6 +61,18 @@
@click="removeAction" @click="removeAction"
/> />
</div> </div>
<automation-action-team-message-input
v-if="inputType === 'team_message'"
v-model="action_params"
:teams="dropdownValues"
/>
<textarea
v-if="inputType === 'textarea'"
v-model="action_params"
rows="4"
:placeholder="$t('AUTOMATION.ACTION.TEAM_MESSAGE_INPUT_PLACEHOLDER')"
class="action-message"
></textarea>
<p <p
v-if="v.action_params.$dirty && v.action_params.$error" v-if="v.action_params.$dirty && v.action_params.$error"
class="filter-error" class="filter-error"
@@ -71,7 +83,11 @@
</template> </template>
<script> <script>
import AutomationActionTeamMessageInput from './AutomationActionTeamMessageInput.vue';
export default { export default {
components: {
AutomationActionTeamMessageInput,
},
props: { props: {
value: { value: {
type: Object, type: Object,
@@ -211,4 +227,7 @@ export default {
.multiselect { .multiselect {
margin-bottom: var(--space-zero); margin-bottom: var(--space-zero);
} }
.action-message {
margin: var(--space-small) 0 0;
}
</style> </style>

View File

@@ -0,0 +1,62 @@
<template>
<div>
<div class="multiselect-wrap--small">
<multiselect
v-model="selectedTeams"
track-by="id"
label="name"
:placeholder="$t('AUTOMATION.ACTION.TEAM_DROPDOWN_PLACEHOLDER')"
:multiple="true"
selected-label
:select-label="$t('FORMS.MULTISELECT.ENTER_TO_SELECT')"
deselect-label=""
:max-height="160"
:options="teams"
:allow-empty="false"
@input="updateValue"
/>
<textarea
v-model="message"
rows="4"
:placeholder="$t('AUTOMATION.ACTION.TEAM_MESSAGE_INPUT_PLACEHOLDER')"
@input="updateValue"
></textarea>
</div>
</div>
</template>
<script>
export default {
// The value types are dynamic, hence prop validation removed to work with our action schema
// eslint-disable-next-line vue/require-prop-types
props: ['teams', 'value'],
data() {
return {
selectedTeams: [],
message: '',
};
},
mounted() {
const { team_ids: teamIds } = this.value;
this.selectedTeams = teamIds;
this.message = this.value.message;
},
methods: {
updateValue() {
this.$emit('input', {
team_ids: this.selectedTeams.map(team => team.id),
message: this.message,
});
},
},
};
</script>
<style scoped>
.multiselect {
margin: var(--space-smaller) var(--space-zero);
}
textarea {
margin-bottom: var(--space-zero);
}
</style>

View File

@@ -89,7 +89,9 @@
"DELETE_MESSAGE": "You need to have atleast one condition to save" "DELETE_MESSAGE": "You need to have atleast one condition to save"
}, },
"ACTION": { "ACTION": {
"DELETE_MESSAGE": "You need to have atleast one action to save" "DELETE_MESSAGE": "You need to have atleast one action to save",
"TEAM_MESSAGE_INPUT_PLACEHOLDER": "Enter your message here",
"TEAM_DROPDOWN_PLACEHOLDER": "Select teams"
}, },
"TOGGLE": { "TOGGLE": {
"ACTIVATION_TITLE": "Activate Automation Rule", "ACTIVATION_TITLE": "Activate Automation Rule",

View File

@@ -192,10 +192,11 @@ export default {
$each: { $each: {
action_params: { action_params: {
required: requiredIf(prop => { required: requiredIf(prop => {
if (prop.action_name === 'send_email_to_team') return true;
return !( return !(
prop.action_name === 'mute_conversation' || prop.action_name === 'mute_conversation' ||
prop.action_name === 'snooze_conversation' || prop.action_name === 'snooze_conversation' ||
prop.action_name === 'resolve_convresation' prop.action_name === 'resolve_conversation'
); );
}), }),
}, },
@@ -361,6 +362,7 @@ export default {
getActionDropdownValues(type) { getActionDropdownValues(type) {
switch (type) { switch (type) {
case 'assign_team': case 'assign_team':
case 'send_email_to_team':
return this.$store.getters['teams/getTeams']; return this.$store.getters['teams/getTeams'];
case 'add_label': case 'add_label':
return this.$store.getters['labels/getLabels'].map(i => { return this.$store.getters['labels/getLabels'].map(i => {
@@ -443,6 +445,8 @@ export default {
return true; return true;
}, },
showActionInput(actionName) { showActionInput(actionName) {
if (actionName === 'send_email_to_team' || actionName === 'send_message')
return false;
const type = AUTOMATION_ACTION_TYPES.find( const type = AUTOMATION_ACTION_TYPES.find(
action => action.key === actionName action => action.key === actionName
).inputType; ).inputType;

View File

@@ -199,7 +199,7 @@ export default {
return !( return !(
prop.action_name === 'mute_conversation' || prop.action_name === 'mute_conversation' ||
prop.action_name === 'snooze_conversation' || prop.action_name === 'snooze_conversation' ||
prop.action_name === 'resolve_convresation' prop.action_name === 'resolve_conversation'
); );
}), }),
}, },
@@ -360,6 +360,7 @@ export default {
getActionDropdownValues(type) { getActionDropdownValues(type) {
switch (type) { switch (type) {
case 'assign_team': case 'assign_team':
case 'send_email_to_team':
return this.$store.getters['teams/getTeams']; return this.$store.getters['teams/getTeams'];
case 'add_label': case 'add_label':
return this.$store.getters['labels/getLabels'].map(i => { return this.$store.getters['labels/getLabels'].map(i => {
@@ -475,6 +476,15 @@ export default {
actionParams = [ actionParams = [
...this.getActionDropdownValues(action.action_name), ...this.getActionDropdownValues(action.action_name),
].filter(item => [...action.action_params].includes(item.id)); ].filter(item => [...action.action_params].includes(item.id));
} else if (inputType === 'team_message') {
actionParams = {
team_ids: [
...this.getActionDropdownValues(action.action_name),
].filter(item =>
[...action.action_params[0].team_ids].includes(item.id)
),
message: action.action_params[0].message,
};
} else actionParams = [...action.action_params]; } else actionParams = [...action.action_params];
} }
return { return {
@@ -489,6 +499,8 @@ export default {
}; };
}, },
showActionInput(actionName) { showActionInput(actionName) {
if (actionName === 'send_email_to_team' || actionName === 'send_message')
return false;
const type = AUTOMATION_ACTION_TYPES.find( const type = AUTOMATION_ACTION_TYPES.find(
action => action.key === actionName action => action.key === actionName
).inputType; ).inputType;

View File

@@ -253,7 +253,7 @@ export default {
: this.$t('AUTOMATION.TOGGLE.ACTIVATION_DESCRIPTION', { : this.$t('AUTOMATION.TOGGLE.ACTIVATION_DESCRIPTION', {
automationName: automation.name, automationName: automation.name,
}); });
// Check if uses confirms to proceed // Check if user confirms to proceed
const ok = await this.$refs.confirmDialog.showConfirmation(); const ok = await this.$refs.confirmDialog.showConfirmation();
if (ok) { if (ok) {
await await this.$store.dispatch('automations/update', { await await this.$store.dispatch('automations/update', {

View File

@@ -76,11 +76,16 @@ export const AUTOMATIONS = {
name: 'Add a label', name: 'Add a label',
attributeI18nKey: 'ADD_LABEL', attributeI18nKey: 'ADD_LABEL',
}, },
// { {
// key: 'send_email_to_team', key: 'send_email_to_team',
// name: 'Send an email to team', name: 'Send an email to team',
// attributeI18nKey: 'SEND_MESSAGE', attributeI18nKey: 'SEND_EMAIL_TO_TEAM',
// }, },
{
key: 'send_message',
name: 'Send a message',
attributeI18nKey: 'SEND_MESSAGE',
},
{ {
key: 'send_email_transcript', key: 'send_email_transcript',
name: 'Send an email transcript', name: 'Send an email transcript',
@@ -96,8 +101,9 @@ export const AUTOMATIONS = {
name: 'Snooze conversation', name: 'Snooze conversation',
attributeI18nKey: 'MUTE_CONVERSATION', attributeI18nKey: 'MUTE_CONVERSATION',
}, },
{ {
key: 'resolve_convresation', key: 'resolve_conversation',
name: 'Resolve conversation', name: 'Resolve conversation',
attributeI18nKey: 'RESOLVE_CONVERSATION', attributeI18nKey: 'RESOLVE_CONVERSATION',
}, },
@@ -106,6 +112,11 @@ export const AUTOMATIONS = {
name: 'Send Webhook Event', name: 'Send Webhook Event',
attributeI18nKey: 'SEND_WEBHOOK_EVENT', attributeI18nKey: 'SEND_WEBHOOK_EVENT',
}, },
// {
// key: 'send_attachment',
// name: 'Send Attachment',
// attributeI18nKey: 'SEND_ATTACHMENT',
// },
], ],
}, },
conversation_created: { conversation_created: {
@@ -132,7 +143,7 @@ export const AUTOMATIONS = {
filterOperators: OPERATOR_TYPES_1, filterOperators: OPERATOR_TYPES_1,
}, },
{ {
key: 'referrer', key: 'referer',
name: 'Referrer Link', name: 'Referrer Link',
attributeI18nKey: 'REFERER_LINK', attributeI18nKey: 'REFERER_LINK',
inputType: 'plain_text', inputType: 'plain_text',
@@ -150,11 +161,16 @@ export const AUTOMATIONS = {
name: 'Assign an agent', name: 'Assign an agent',
attributeI18nKey: 'ASSIGN_AGENT', attributeI18nKey: 'ASSIGN_AGENT',
}, },
// { {
// key: 'send_email_to_team', key: 'send_email_to_team',
// name: 'Send an email to team', name: 'Send an email to team',
// attributeI18nKey: 'SEND_MESSAGE', attributeI18nKey: 'SEND_EMAIL_TO_TEAM',
// }, },
{
key: 'send_message',
name: 'Send a message',
attributeI18nKey: 'SEND_MESSAGE',
},
{ {
key: 'send_email_transcript', key: 'send_email_transcript',
name: 'Send an email transcript', name: 'Send an email transcript',
@@ -171,7 +187,7 @@ export const AUTOMATIONS = {
attributeI18nKey: 'MUTE_CONVERSATION', attributeI18nKey: 'MUTE_CONVERSATION',
}, },
{ {
key: 'resolve_convresation', key: 'resolve_conversation',
name: 'Resolve conversation', name: 'Resolve conversation',
attributeI18nKey: 'RESOLVE_CONVERSATION', attributeI18nKey: 'RESOLVE_CONVERSATION',
}, },
@@ -180,6 +196,11 @@ export const AUTOMATIONS = {
name: 'Send Webhook Event', name: 'Send Webhook Event',
attributeI18nKey: 'SEND_WEBHOOK_EVENT', attributeI18nKey: 'SEND_WEBHOOK_EVENT',
}, },
// {
// key: 'send_attachment',
// name: 'Send Attachment',
// attributeI18nKey: 'SEND_ATTACHMENT',
// },
], ],
}, },
conversation_updated: { conversation_updated: {
@@ -238,11 +259,16 @@ export const AUTOMATIONS = {
name: 'Assign an agent', name: 'Assign an agent',
attributeI18nKey: 'ASSIGN_AGENT', attributeI18nKey: 'ASSIGN_AGENT',
}, },
// { {
// key: 'send_email_to_team', key: 'send_email_to_team',
// name: 'Send an email to team', name: 'Send an email to team',
// attributeI18nKey: 'SEND_MESSAGE', attributeI18nKey: 'SEND_EMAIL_TO_TEAM',
// }, },
{
key: 'send_message',
name: 'Send a message',
attributeI18nKey: 'SEND_MESSAGE',
},
{ {
key: 'send_email_transcript', key: 'send_email_transcript',
name: 'Send an email transcript', name: 'Send an email transcript',
@@ -259,7 +285,7 @@ export const AUTOMATIONS = {
attributeI18nKey: 'MUTE_CONVERSATION', attributeI18nKey: 'MUTE_CONVERSATION',
}, },
{ {
key: 'resolve_convresation', key: 'resolve_conversation',
name: 'Resolve conversation', name: 'Resolve conversation',
attributeI18nKey: 'RESOLVE_CONVERSATION', attributeI18nKey: 'RESOLVE_CONVERSATION',
}, },
@@ -268,6 +294,11 @@ export const AUTOMATIONS = {
name: 'Send Webhook Event', name: 'Send Webhook Event',
attributeI18nKey: 'SEND_WEBHOOK_EVENT', attributeI18nKey: 'SEND_WEBHOOK_EVENT',
}, },
// {
// key: 'send_attachment',
// name: 'Send Attachment',
// attributeI18nKey: 'SEND_ATTACHMENT',
// },
], ],
}, },
}; };
@@ -298,11 +329,11 @@ export const AUTOMATION_ACTION_TYPES = [
label: 'Add a label', label: 'Add a label',
inputType: 'multi_select', inputType: 'multi_select',
}, },
// { {
// key: 'send_email_to_team', key: 'send_email_to_team',
// label: 'Send an email to team', label: 'Send an email to team',
// inputType: 'multi_select', inputType: 'team_message',
// }, },
{ {
key: 'send_email_transcript', key: 'send_email_transcript',
label: 'Send an email transcript', label: 'Send an email transcript',
@@ -319,7 +350,7 @@ export const AUTOMATION_ACTION_TYPES = [
inputType: null, inputType: null,
}, },
{ {
key: 'resolve_convresation', key: 'resolve_conversation',
label: 'Resolve conversation', label: 'Resolve conversation',
inputType: null, inputType: null,
}, },
@@ -328,4 +359,14 @@ export const AUTOMATION_ACTION_TYPES = [
label: 'Send Webhook Event', label: 'Send Webhook Event',
inputType: 'url', inputType: 'url',
}, },
// {
// key: 'send_attachment',
// label: 'Send Attachment',
// inputType: 'file',
// },
{
key: 'send_message',
label: 'Send a message',
inputType: 'textarea',
},
]; ];

View File

@@ -36,7 +36,7 @@ class AutomationRuleListener < BaseListener
return unless rule_present?('message_created', account) return unless rule_present?('message_created', account)
@rules.each do |rule| @rules.each do |rule|
conditions_match = ::AutomationRules::ConditionsFilterService.new(rule, message.conversation).message_conditions conditions_match = ::AutomationRules::ConditionsFilterService.new(rule, message.conversation, { message: message }).message_conditions
::AutomationRules::ActionService.new(rule, account, message.conversation).perform if conditions_match.present? ::AutomationRules::ActionService.new(rule, account, message.conversation).perform if conditions_match.present?
end end
end end

View File

@@ -7,29 +7,7 @@ class TeamNotifications::AutomationNotificationMailer < ApplicationMailer
@custom_message = message @custom_message = message
@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)
send_an_email_to_team and return send_an_email_to_team
end
def conversation_updated(conversation, team, message)
return unless smtp_config_set_or_development?
@agents = team.team_members
@conversation = conversation
@custom_message = message
@action_url = app_account_conversation_url(account_id: @conversation.account_id, id: @conversation.display_id)
send_an_email_to_team and return
end
def message_created(conversation, team, message)
return unless smtp_config_set_or_development?
@agents = team.team_members
@conversation = conversation
@custom_message = message
@action_url = app_account_conversation_url(account_id: @conversation.account_id, id: @conversation.display_id)
send_an_email_to_team and return
end end
private private

View File

@@ -27,7 +27,7 @@ class AutomationRule < ApplicationRecord
scope :active, -> { where(active: true) } scope :active, -> { where(active: true) }
CONDITIONS_ATTRS = %w[content email country_code status message_type browser_language assignee_id team_id referrer city company].freeze CONDITIONS_ATTRS = %w[content email country_code status message_type browser_language assignee_id team_id referer city company].freeze
ACTIONS_ATTRS = %w[send_message add_label send_email_to_team assign_team assign_best_agents send_attachments].freeze ACTIONS_ATTRS = %w[send_message add_label send_email_to_team assign_team assign_best_agents send_attachments].freeze
private private

View File

@@ -22,8 +22,6 @@ class AutomationRules::ActionService
private private
def send_attachments(_file_params) def send_attachments(_file_params)
return if @rule.event_name == 'message_created'
blobs = @rule.files.map { |file, _| file.blob } blobs = @rule.files.map { |file, _| file.blob }
params = { content: nil, private: false, attachments: blobs } params = { content: nil, private: false, attachments: blobs }
mb = Messages::MessageBuilder.new(nil, @conversation, params) mb = Messages::MessageBuilder.new(nil, @conversation, params)
@@ -44,6 +42,10 @@ class AutomationRules::ActionService
@conversation.snoozed! @conversation.snoozed!
end end
def resolve_conversation(_params)
@conversation.resolved!
end
def change_status(status) def change_status(status)
@conversation.update!(status: status[0]) @conversation.update!(status: status[0])
end end
@@ -54,8 +56,6 @@ class AutomationRules::ActionService
end end
def send_message(message) def send_message(message)
return if @rule.event_name == 'message_created'
params = { content: message[0], private: false } params = { content: message[0], private: false }
mb = Messages::MessageBuilder.new(nil, @conversation, params) mb = Messages::MessageBuilder.new(nil, @conversation, params)
mb.perform mb.perform
@@ -82,15 +82,10 @@ class AutomationRules::ActionService
end end
def send_email_to_team(params) def send_email_to_team(params)
team = Team.find(params[:team_ids][0]) teams = Team.where(id: params[0][:team_ids])
case @rule.event_name teams.each do |team|
when 'conversation_created', 'conversation_status_changed' TeamNotifications::AutomationNotificationMailer.conversation_creation(@conversation, team, params[0][:message])&.deliver_now
TeamNotifications::AutomationNotificationMailer.conversation_creation(@conversation, team, params[:message])&.deliver_now
when 'conversation_updated'
TeamNotifications::AutomationNotificationMailer.conversation_updated(@conversation, team, params[:message])&.deliver_now
when 'message_created'
TeamNotifications::AutomationNotificationMailer.message_created(@conversation, team, params[:message])&.deliver_now
end end
end end

View File

@@ -3,13 +3,14 @@ require 'json'
class AutomationRules::ConditionsFilterService < FilterService class AutomationRules::ConditionsFilterService < FilterService
ATTRIBUTE_MODEL = 'contact_attribute'.freeze ATTRIBUTE_MODEL = 'contact_attribute'.freeze
def initialize(rule, conversation = nil) def initialize(rule, conversation = nil, options = {})
super([], nil) super([], nil)
@rule = rule @rule = rule
@conversation = conversation @conversation = conversation
@account = conversation.account @account = conversation.account
file = File.read('./lib/filters/filter_keys.json') file = File.read('./lib/filters/filter_keys.json')
@filters = JSON.parse(file) @filters = JSON.parse(file)
@options = options
end end
def perform def perform
@@ -41,7 +42,7 @@ class AutomationRules::ConditionsFilterService < FilterService
current_filter = message_filters[query_hash['attribute_key']] current_filter = message_filters[query_hash['attribute_key']]
@query_string += message_query_string(current_filter, query_hash.with_indifferent_access, current_index) @query_string += message_query_string(current_filter, query_hash.with_indifferent_access, current_index)
end end
records = Message.where(conversation: @conversation).where(@query_string, @filter_values.with_indifferent_access) records = Message.where(id: @options[:message].id).where(@query_string, @filter_values.with_indifferent_access)
records.any? records.any?
end end

View File

@@ -259,17 +259,41 @@ 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 updated automation_rule for account' do let(:update_params) do
params = { name: 'Update name' } {
description: 'Update description',
name: 'Update name',
conditions: [
{
attribute_key: 'browser_language',
filter_operator: 'equal_to',
values: ['en'],
query_operator: 'AND'
}
],
actions: [
{
action_name: :update_additional_attributes,
action_params: [{ intiated_at: '2021-12-03 17:25:26.844536 +0530' }]
}
]
}.with_indifferent_access
end
it 'returns for cloned automation_rule for account' do
expect(account.automation_rules.count).to eq(1) expect(account.automation_rules.count).to eq(1)
expect(account.automation_rules.first.actions.size).to eq(4)
patch "/api/v1/accounts/#{account.id}/automation_rules/#{automation_rule.id}", patch "/api/v1/accounts/#{account.id}/automation_rules/#{automation_rule.id}",
headers: administrator.create_new_auth_token, headers: administrator.create_new_auth_token,
params: params params: update_params
expect(response).to have_http_status(:success) expect(response).to have_http_status(:success)
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')
expect(body[:payload][:description]).to eq('Update description')
expect(body[:payload][:conditions].size).to eq(1)
expect(body[:payload][:actions].size).to eq(1)
end end
it 'returns for updated active flag for automation_rule' do it 'returns for updated active flag for automation_rule' do

View File

@@ -30,10 +30,10 @@ describe AutomationRuleListener do
automation_rule.update!(actions: automation_rule.update!(actions:
[ [
{ {
'action_name' => 'send_email_to_team', 'action_params' => { 'action_name' => 'send_email_to_team', 'action_params' => [{
'message' => 'Please pay attention to this conversation, its from high priority customer', 'message' => 'Please pay attention to this conversation, its from high priority customer',
'team_ids' => [team.id] 'team_ids' => [team.id]
} }]
}, },
{ 'action_name' => 'assign_team', 'action_params' => [team.id] }, { 'action_name' => 'assign_team', 'action_params' => [team.id] },
{ 'action_name' => 'add_label', 'action_params' => %w[support priority_customer] }, { 'action_name' => 'add_label', 'action_params' => %w[support priority_customer] },
@@ -104,7 +104,7 @@ describe AutomationRuleListener do
it 'triggers automation rule send email transcript to the mentioned email' do it 'triggers automation rule send email transcript to the mentioned email' do
mailer = double mailer = double
expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_updated) expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_creation)
listener.conversation_updated(event) listener.conversation_updated(event)
@@ -116,7 +116,7 @@ describe AutomationRuleListener do
it 'triggers automation rule send message to the contacts' do it 'triggers automation rule send message to the contacts' do
expect(conversation.messages).to be_empty expect(conversation.messages).to be_empty
expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_updated) expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_creation)
listener.conversation_updated(event) listener.conversation_updated(event)
@@ -202,7 +202,7 @@ describe AutomationRuleListener do
automation_rule automation_rule
expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_updated) expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_creation)
listener.conversation_updated(event) listener.conversation_updated(event)
@@ -214,7 +214,7 @@ describe AutomationRuleListener do
it 'triggers automation rule send email to the team' do it 'triggers automation rule send email to the team' do
automation_rule automation_rule
expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_updated) expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_creation)
listener.conversation_updated(event) listener.conversation_updated(event)
end end
@@ -224,7 +224,7 @@ describe AutomationRuleListener do
automation_rule automation_rule
expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_updated) expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_creation)
listener.conversation_updated(event) listener.conversation_updated(event)
@@ -256,7 +256,7 @@ describe AutomationRuleListener do
automation_rule automation_rule
expect(TeamNotifications::AutomationNotificationMailer).to receive(:message_created) expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_creation)
listener.message_created(event) listener.message_created(event)
@@ -269,7 +269,7 @@ describe AutomationRuleListener do
automation_rule automation_rule
expect(TeamNotifications::AutomationNotificationMailer).to receive(:message_created) expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_creation)
listener.message_created(event) listener.message_created(event)
@@ -281,7 +281,7 @@ describe AutomationRuleListener do
expect(conversation.assignee).to be_nil expect(conversation.assignee).to be_nil
automation_rule automation_rule
expect(TeamNotifications::AutomationNotificationMailer).to receive(:message_created) expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_creation)
listener.message_created(event) listener.message_created(event)
@@ -295,7 +295,7 @@ describe AutomationRuleListener do
automation_rule automation_rule
expect(TeamNotifications::AutomationNotificationMailer).to receive(:message_created) expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_creation)
listener.message_created(event) listener.message_created(event)