From 1b3011b27beecb7f4098f4e1387e5824c3c39829 Mon Sep 17 00:00:00 2001 From: Tejaswini Chile Date: Sun, 24 Apr 2022 12:02:40 +0530 Subject: [PATCH] fix: Add Attachment endpoint to save file against automation rule (#4480) Co-authored-by: fayazara Co-authored-by: Pranav Raj S --- .../accounts/automation_rules_controller.rb | 25 +++- app/javascript/dashboard/api/automation.js | 8 ++ .../widgets/AutomationActionInput.vue | 12 ++ .../widgets/AutomationFileInput.vue | 117 ++++++++++++++++++ .../dashboard/helper/actionQueryGenerator.js | 10 +- .../dashboard/i18n/locale/en/automation.json | 7 ++ .../automation/EditAutomationRule.vue | 15 +++ .../settings/automation/constants.js | 40 +++--- .../dashboard/store/modules/automations.js | 8 ++ .../FluentIcon/dashboard-icons.json | 1 + app/models/attachment.rb | 1 - app/models/automation_rule.rb | 18 ++- app/policies/automation_rule_policy.rb | 4 + .../automation_rules/action_service.rb | 13 +- .../partials/_automation_rule.json.jbuilder | 1 + config/routes.rb | 1 + .../automation_rules_controller_spec.rb | 58 +++++---- .../automation_rule_listener_spec.rb | 9 ++ 18 files changed, 291 insertions(+), 57 deletions(-) create mode 100644 app/javascript/dashboard/components/widgets/AutomationFileInput.vue diff --git a/app/controllers/api/v1/accounts/automation_rules_controller.rb b/app/controllers/api/v1/accounts/automation_rules_controller.rb index 41296db62..5e649b6e0 100644 --- a/app/controllers/api/v1/accounts/automation_rules_controller.rb +++ b/app/controllers/api/v1/accounts/automation_rules_controller.rb @@ -17,6 +17,16 @@ class Api::V1::Accounts::AutomationRulesController < Api::V1::Accounts::BaseCont @automation_rule end + def attach_file + file_blob = ActiveStorage::Blob.create_and_upload!( + key: nil, + io: params[:attachment].tempfile, + filename: params[:attachment].original_filename, + content_type: params[:attachment].content_type + ) + render json: { blob_key: file_blob.key, blob_id: file_blob.id } + end + def show; end def update @@ -25,6 +35,7 @@ class Api::V1::Accounts::AutomationRulesController < Api::V1::Accounts::BaseCont @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 @@ -43,17 +54,19 @@ class Api::V1::Accounts::AutomationRulesController < Api::V1::Accounts::BaseCont @automation_rule = new_rule end - private - def process_attachments - return if params[:attachments].blank? + actions = @automation_rule.actions.filter_map { |k, _v| k if k['action_name'] == 'send_attachment' } + return if actions.blank? - params[:attachments].each do |uploaded_attachment| - @automation_rule.files.attach(uploaded_attachment) + actions.each do |action| + blob_id = action['action_params'] + blob = ActiveStorage::Blob.find_by(id: blob_id) + @automation_rule.files.attach(blob) end - @automation_rule end + private + def automation_rules_permit params.permit( :name, :description, :event_name, :account_id, :active, diff --git a/app/javascript/dashboard/api/automation.js b/app/javascript/dashboard/api/automation.js index e83ece3d1..eef39d12c 100644 --- a/app/javascript/dashboard/api/automation.js +++ b/app/javascript/dashboard/api/automation.js @@ -9,6 +9,14 @@ class AutomationsAPI extends ApiClient { clone(automationId) { return axios.post(`${this.url}/${automationId}/clone`); } + + attachment(file) { + return axios.post(`${this.url}/attach_file`, file, { + headers: { + 'Content-Type': 'multipart/form-data', + }, + }); + } } export default new AutomationsAPI(); diff --git a/app/javascript/dashboard/components/widgets/AutomationActionInput.vue b/app/javascript/dashboard/components/widgets/AutomationActionInput.vue index baa66afb4..8230c6963 100644 --- a/app/javascript/dashboard/components/widgets/AutomationActionInput.vue +++ b/app/javascript/dashboard/components/widgets/AutomationActionInput.vue @@ -52,6 +52,11 @@ class="answer--text-input" placeholder="Enter url" /> + import AutomationActionTeamMessageInput from './AutomationActionTeamMessageInput.vue'; +import AutomationActionFileInput from './AutomationFileInput.vue'; export default { components: { AutomationActionTeamMessageInput, + AutomationActionFileInput, }, props: { value: { @@ -109,6 +116,10 @@ export default { type: Boolean, default: true, }, + initialFileName: { + type: String, + default: '', + }, }, computed: { action_name: { @@ -187,6 +198,7 @@ export default { .filter__answer--wrap { margin-right: var(--space-smaller); flex-grow: 1; + max-width: 50%; input { margin-bottom: 0; diff --git a/app/javascript/dashboard/components/widgets/AutomationFileInput.vue b/app/javascript/dashboard/components/widgets/AutomationFileInput.vue new file mode 100644 index 000000000..595faa8fb --- /dev/null +++ b/app/javascript/dashboard/components/widgets/AutomationFileInput.vue @@ -0,0 +1,117 @@ + + + + + diff --git a/app/javascript/dashboard/helper/actionQueryGenerator.js b/app/javascript/dashboard/helper/actionQueryGenerator.js index 7ef5fa56f..965c5b238 100644 --- a/app/javascript/dashboard/helper/actionQueryGenerator.js +++ b/app/javascript/dashboard/helper/actionQueryGenerator.js @@ -1,7 +1,15 @@ +const allElementsString = arr => { + return arr.every(elem => typeof elem === 'string'); +}; + +const allElementsNumbers = arr => { + return arr.every(elem => typeof elem === 'number'); +}; + const formatArray = params => { if (params.length <= 0) { params = []; - } else if (params.every(elem => typeof elem === 'string')) { + } else if (allElementsString(params) || allElementsNumbers(params)) { params = [...params]; } else { params = params.map(val => val.id); diff --git a/app/javascript/dashboard/i18n/locale/en/automation.json b/app/javascript/dashboard/i18n/locale/en/automation.json index 0d2076b65..5d291814e 100644 --- a/app/javascript/dashboard/i18n/locale/en/automation.json +++ b/app/javascript/dashboard/i18n/locale/en/automation.json @@ -104,6 +104,13 @@ "DEACTIVATION_ERROR": "Could not Deactivate Automation, Please try again later", "CONFIRMATION_LABEL": "Yes", "CANCEL_LABEL": "No" + }, + "ATTACHMENT": { + "UPLOAD_ERROR": "Could not upload attachment, Please try again", + "LABEL_IDLE": "Upload Attachment", + "LABEL_UPLOADING": "Uploading...", + "LABEL_UPLOADED": "Succesfully Uploaded", + "LABEL_UPLOAD_FAILED": "Upload Failed" } } } diff --git a/app/javascript/dashboard/routes/dashboard/settings/automation/EditAutomationRule.vue b/app/javascript/dashboard/routes/dashboard/settings/automation/EditAutomationRule.vue index 6c5d03962..668b44d51 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/automation/EditAutomationRule.vue +++ b/app/javascript/dashboard/routes/dashboard/settings/automation/EditAutomationRule.vue @@ -101,6 +101,12 @@ showActionInput(automation.actions[i].action_name) " :v="$v.automation.actions.$each[i]" + :initial-file-name=" + getFileName( + automation.actions[i].action_params[0], + automation.actions[i].action_name + ) + " @removeAction="removeAction(i)" />
@@ -507,6 +513,15 @@ export default { if (type === null) return false; return true; }, + getFileName(id, actionType) { + if (!id) return ''; + if (actionType === 'send_attachment') { + const file = this.automation.files.find(item => item.blob_id === id); + // replace `blob_id.toString()` with file name once api is fixed. + if (file) return file.filename.toString(); + } + return ''; + }, }, }; diff --git a/app/javascript/dashboard/routes/dashboard/settings/automation/constants.js b/app/javascript/dashboard/routes/dashboard/settings/automation/constants.js index 3d1dac355..387d0d407 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/automation/constants.js +++ b/app/javascript/dashboard/routes/dashboard/settings/automation/constants.js @@ -119,11 +119,11 @@ export const AUTOMATIONS = { name: 'Send Webhook Event', attributeI18nKey: 'SEND_WEBHOOK_EVENT', }, - // { - // key: 'send_attachment', - // name: 'Send Attachment', - // attributeI18nKey: 'SEND_ATTACHMENT', - // }, + { + key: 'send_attachment', + name: 'Send Attachment', + attributeI18nKey: 'SEND_ATTACHMENT', + }, ], }, conversation_created: { @@ -210,11 +210,11 @@ export const AUTOMATIONS = { name: 'Send Webhook Event', attributeI18nKey: 'SEND_WEBHOOK_EVENT', }, - // { - // key: 'send_attachment', - // name: 'Send Attachment', - // attributeI18nKey: 'SEND_ATTACHMENT', - // }, + { + key: 'send_attachment', + name: 'Send Attachment', + attributeI18nKey: 'SEND_ATTACHMENT', + }, ], }, conversation_updated: { @@ -315,11 +315,11 @@ export const AUTOMATIONS = { name: 'Send Webhook Event', attributeI18nKey: 'SEND_WEBHOOK_EVENT', }, - // { - // key: 'send_attachment', - // name: 'Send Attachment', - // attributeI18nKey: 'SEND_ATTACHMENT', - // }, + { + key: 'send_attachment', + name: 'Send Attachment', + attributeI18nKey: 'SEND_ATTACHMENT', + }, ], }, }; @@ -380,11 +380,11 @@ export const AUTOMATION_ACTION_TYPES = [ label: 'Send Webhook Event', inputType: 'url', }, - // { - // key: 'send_attachment', - // label: 'Send Attachment', - // inputType: 'file', - // }, + { + key: 'send_attachment', + label: 'Send Attachment', + inputType: 'attachment', + }, { key: 'send_message', label: 'Send a message', diff --git a/app/javascript/dashboard/store/modules/automations.js b/app/javascript/dashboard/store/modules/automations.js index a588d9ae7..7d9f4cb69 100644 --- a/app/javascript/dashboard/store/modules/automations.js +++ b/app/javascript/dashboard/store/modules/automations.js @@ -76,6 +76,14 @@ export const actions = { commit(types.SET_AUTOMATION_UI_FLAG, { isCloning: false }); } }, + uploadAttachment: async (_, file) => { + try { + const { data } = await AutomationAPI.attachment(file); + return data.blob_id; + } catch (error) { + throw new Error(error); + } + }, }; export const mutations = { diff --git a/app/javascript/shared/components/FluentIcon/dashboard-icons.json b/app/javascript/shared/components/FluentIcon/dashboard-icons.json index f145159d1..54dc0b627 100644 --- a/app/javascript/shared/components/FluentIcon/dashboard-icons.json +++ b/app/javascript/shared/components/FluentIcon/dashboard-icons.json @@ -68,6 +68,7 @@ "emoji-outline": "M12 1.999c5.524 0 10.002 4.478 10.002 10.002 0 5.523-4.478 10.001-10.002 10.001-5.524 0-10.002-4.478-10.002-10.001C1.998 6.477 6.476 1.999 12 1.999Zm0 1.5a8.502 8.502 0 1 0 0 17.003A8.502 8.502 0 0 0 12 3.5ZM8.462 14.784A4.491 4.491 0 0 0 12 16.502a4.492 4.492 0 0 0 3.535-1.714.75.75 0 1 1 1.177.93A5.991 5.991 0 0 1 12 18.002a5.991 5.991 0 0 1-4.716-2.29.75.75 0 0 1 1.178-.928ZM9 8.75a1.25 1.25 0 1 1 0 2.499A1.25 1.25 0 0 1 9 8.75Zm6 0a1.25 1.25 0 1 1 0 2.499 1.25 1.25 0 0 1 0-2.499Z", "error-circle-outline": "M12 2c5.523 0 10 4.478 10 10s-4.477 10-10 10S2 17.522 2 12 6.477 2 12 2Zm0 1.667c-4.595 0-8.333 3.738-8.333 8.333 0 4.595 3.738 8.333 8.333 8.333 4.595 0 8.333-3.738 8.333-8.333 0-4.595-3.738-8.333-8.333-8.333Zm-.001 10.835a.999.999 0 1 1 0 1.998.999.999 0 0 1 0-1.998ZM11.994 7a.75.75 0 0 1 .744.648l.007.101.004 4.502a.75.75 0 0 1-1.493.103l-.007-.102-.004-4.501a.75.75 0 0 1 .75-.751Z", "filter-outline": "M13.5 16a.75.75 0 0 1 0 1.5h-3a.75.75 0 0 1 0-1.5h3Zm3-5a.75.75 0 0 1 0 1.5h-9a.75.75 0 0 1 0-1.5h9Zm3-5a.75.75 0 0 1 0 1.5h-15a.75.75 0 0 1 0-1.5h15Z", + "file-upload-outline": "M6 2a2 2 0 0 0-2 2v5.207a5.48 5.48 0 0 1 1-.185V4a1 1 0 0 1 1-1h4v3.5A1.5 1.5 0 0 0 11.5 8H15v8a1 1 0 0 1-1 1h-3.6a5.507 5.507 0 0 1-.657 1H14a2 2 0 0 0 2-2V7.414a1.5 1.5 0 0 0-.44-1.06l-3.914-3.915A1.5 1.5 0 0 0 10.586 2H6Zm8.793 5H11.5a.5.5 0 0 1-.5-.5V3.207L14.793 7ZM5.5 19a4.5 4.5 0 1 0 0-9a4.5 4.5 0 0 0 0 9Zm2.354-4.854a.5.5 0 1 1-.708.708L6 13.707V16.5a.5.5 0 0 1-1 0v-2.793l-1.146 1.147a.5.5 0 1 1-.708-.707l2-2A.5.5 0 0 1 5.497 12h.006a.498.498 0 0 1 .348.144l.003.003l2 2Z", "flash-on-outline": "m8.294 14-1.767 7.068c-.187.746.736 1.256 1.269.701L19.79 9.27A.75.75 0 0 0 19.25 8h-4.46l1.672-5.013A.75.75 0 0 0 15.75 2h-7a.75.75 0 0 0-.721.544l-3 10.5A.75.75 0 0 0 5.75 14h2.544Zm4.745-5.487a.75.75 0 0 0 .711.987h3.74l-8.824 9.196 1.316-5.264a.75.75 0 0 0-.727-.932h-2.51l2.57-9h5.394l-1.67 5.013Z", "folder-outline": "M8.207 4c.46 0 .908.141 1.284.402l.156.12L12.022 6.5h7.728a2.25 2.25 0 0 1 2.229 1.938l.016.158.005.154v9a2.25 2.25 0 0 1-2.096 2.245L19.75 20H4.25a2.25 2.25 0 0 1-2.245-2.096L2 17.75V6.25a2.25 2.25 0 0 1 2.096-2.245L4.25 4h3.957Zm1.44 5.979a2.25 2.25 0 0 1-1.244.512l-.196.009-4.707-.001v7.251c0 .38.282.694.648.743l.102.007h15.5a.75.75 0 0 0 .743-.648l.007-.102v-9a.75.75 0 0 0-.648-.743L19.75 8h-7.729L9.647 9.979ZM8.207 5.5H4.25a.75.75 0 0 0-.743.648L3.5 6.25v2.749L8.207 9a.75.75 0 0 0 .395-.113l.085-.06 1.891-1.578-1.89-1.575a.75.75 0 0 0-.377-.167L8.207 5.5Z", "globe-desktop-outline": "M22.002 12C22.002 6.477 17.524 2 12 2 6.476 1.999 2 6.477 2 12.001c0 5.186 3.947 9.45 9.001 9.952V20.11c-.778-.612-1.478-1.905-1.939-3.61h1.94V15H8.737a18.969 18.969 0 0 1-.135-5h6.794c.068.64.105 1.31.105 2h1.5c0-.684-.033-1.353-.095-2h3.358c.154.64.237 1.31.237 2h1.5ZM4.786 16.5h2.722l.102.396c.317 1.17.748 2.195 1.27 3.015a8.532 8.532 0 0 1-4.094-3.41ZM3.736 10h3.358a20.847 20.847 0 0 0-.095 2c0 1.043.075 2.051.217 3H4.043a8.483 8.483 0 0 1-.544-3c0-.682.08-1.347.232-1.983L3.736 10Zm5.122-5.902.023-.008C8.16 5.222 7.611 6.748 7.298 8.5H4.25c.905-2 2.56-3.587 4.608-4.402Zm3.026-.594L12 3.5l.126.006c1.262.126 2.48 2.125 3.045 4.995H8.83c.568-2.878 1.79-4.88 3.055-4.996Zm3.343.76-.107-.174.291.121a8.533 8.533 0 0 1 4.339 4.29h-3.048c-.298-1.665-.806-3.125-1.475-4.237Z M12 19a1 1 0 0 0 1 1h3v2h-.5a.5.5 0 1 0 0 1h4a.5.5 0 0 0 0-1H19v-2h3a1 1 0 0 0 1-1v-5a1 1 0 0 0-1-1h-9a1 1 0 0 0-1 1v5Z", diff --git a/app/models/attachment.rb b/app/models/attachment.rb index 43ae583ea..2a8e575f3 100644 --- a/app/models/attachment.rb +++ b/app/models/attachment.rb @@ -28,7 +28,6 @@ class Attachment < ApplicationRecord application/vnd.openxmlformats-officedocument.spreadsheetml.sheet application/vnd.openxmlformats-officedocument.wordprocessingml.document ].freeze - belongs_to :account belongs_to :message has_one_attached :file diff --git a/app/models/automation_rule.rb b/app/models/automation_rule.rb index 8211de98b..d76f2058e 100644 --- a/app/models/automation_rule.rb +++ b/app/models/automation_rule.rb @@ -18,6 +18,8 @@ # index_automation_rules_on_account_id (account_id) # class AutomationRule < ApplicationRecord + include Rails.application.routes.url_helpers + belongs_to :account has_many_attached :files @@ -28,7 +30,21 @@ class AutomationRule < ApplicationRecord scope :active, -> { where(active: true) } CONDITIONS_ATTRS = %w[content email country_code status message_type browser_language assignee_id team_id referer city company inbox_id].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_attachment].freeze + + def file_base_data + files.map do |file| + { + id: file.id, + automation_rule_id: id, + file_type: file.content_type, + account_id: account_id, + file_url: url_for(file), + blob_id: file.blob_id, + filename: file.filename.to_s + } + end + end private diff --git a/app/policies/automation_rule_policy.rb b/app/policies/automation_rule_policy.rb index 431b32964..b0e33437d 100644 --- a/app/policies/automation_rule_policy.rb +++ b/app/policies/automation_rule_policy.rb @@ -7,6 +7,10 @@ class AutomationRulePolicy < ApplicationPolicy @account_user.administrator? end + def attach_file? + @account_user.administrator? + end + def show? @account_user.administrator? end diff --git a/app/services/automation_rules/action_service.rb b/app/services/automation_rules/action_service.rb index 887e82b38..e88ca06dd 100644 --- a/app/services/automation_rules/action_service.rb +++ b/app/services/automation_rules/action_service.rb @@ -21,9 +21,14 @@ class AutomationRules::ActionService private - def send_attachments(_file_params) - blobs = @rule.files.map { |file, _| file.blob } - params = { content: nil, private: false, attachments: blobs } + def send_attachment(blob_ids) + return unless @rule.files.attached? + + blob = ActiveStorage::Blob.find(blob_ids) + + return if blob.blank? + + params = { content: nil, private: false, attachments: blob } mb = Messages::MessageBuilder.new(nil, @conversation, params) mb.perform end @@ -51,7 +56,7 @@ class AutomationRules::ActionService end def send_webhook_event(webhook_url) - payload = @conversation.webhook_data.merge(event: "automation_event: #{@rule.event_name}") + payload = @conversation.webhook_data.merge(event: "automation_event.#{@rule.event_name}") WebhookJob.perform_later(webhook_url[0], payload) end diff --git a/app/views/api/v1/accounts/automation_rules/partials/_automation_rule.json.jbuilder b/app/views/api/v1/accounts/automation_rules/partials/_automation_rule.json.jbuilder index b0e01c824..a1047c82f 100644 --- a/app/views/api/v1/accounts/automation_rules/partials/_automation_rule.json.jbuilder +++ b/app/views/api/v1/accounts/automation_rules/partials/_automation_rule.json.jbuilder @@ -7,3 +7,4 @@ json.conditions automation_rule.conditions json.actions automation_rule.actions json.created_on automation_rule.created_at.to_i json.active automation_rule.active? +json.files automation_rule.file_base_data if automation_rule.files.any? diff --git a/config/routes.rb b/config/routes.rb index a2afa4f09..7ed667160 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -55,6 +55,7 @@ Rails.application.routes.draw do resources :canned_responses, only: [:index, :create, :update, :destroy] resources :automation_rules, only: [:index, :create, :show, :update, :destroy] do post :clone + post :attach_file, on: :collection end resources :campaigns, only: [:index, :create, :show, :update, :destroy] diff --git a/spec/controllers/api/v1/accounts/automation_rules_controller_spec.rb b/spec/controllers/api/v1/accounts/automation_rules_controller_spec.rb index 2039daf15..4513773bc 100644 --- a/spec/controllers/api/v1/accounts/automation_rules_controller_spec.rb +++ b/spec/controllers/api/v1/accounts/automation_rules_controller_spec.rb @@ -133,29 +133,35 @@ RSpec.describe 'Api::V1::Accounts::AutomationRulesController', type: :request do it 'Saves file in the automation actions to send an attachments' do file = fixture_file_upload(Rails.root.join('spec/assets/avatar.png'), 'image/png') - params[:attachments] = [file] + + expect(account.automation_rules.count).to eq(0) + + post "/api/v1/accounts/#{account.id}/automation_rules/attach_file", + headers: administrator.create_new_auth_token, + params: { attachment: file } + + expect(response).to have_http_status(:success) + + blob = JSON.parse(response.body) + + expect(blob['blob_key']).to be_present + expect(blob['blob_id']).to be_present + params[:actions] = [ { action_name: :send_message, action_params: ['Welcome to the chatwoot platform.'] }, { - action_name: :update_additional_attributes, - action_params: [{ intiated_at: '2021-12-03 17:25:26.844536 +0530' }] - }, - { - action_name: :send_attachments + action_name: :send_attachment, + action_params: [blob['blob_id']] } ] - expect(account.automation_rules.count).to eq(0) - post "/api/v1/accounts/#{account.id}/automation_rules", headers: administrator.create_new_auth_token, params: params - expect(response).to have_http_status(:success) - expect(account.automation_rules.count).to eq(1) automation_rule = account.automation_rules.first expect(automation_rule.files.presence).to be_truthy expect(automation_rule.files.count).to eq(1) @@ -163,32 +169,36 @@ RSpec.describe 'Api::V1::Accounts::AutomationRulesController', type: :request do it 'Saves files in the automation actions to send multiple attachments' do file_1 = fixture_file_upload(Rails.root.join('spec/assets/avatar.png'), 'image/png') - file_2 = fixture_file_upload(Rails.root.join('spec/assets/sample.pdf'), 'image/png') - params[:attachments] = [file_1, file_2] + file_2 = fixture_file_upload(Rails.root.join('spec/assets/sample.png'), 'image/png') + + post "/api/v1/accounts/#{account.id}/automation_rules/attach_file", + headers: administrator.create_new_auth_token, + params: { attachment: file_1 } + + blob_1 = JSON.parse(response.body) + + post "/api/v1/accounts/#{account.id}/automation_rules/attach_file", + headers: administrator.create_new_auth_token, + params: { attachment: file_2 } + + blob_2 = JSON.parse(response.body) + params[:actions] = [ { - action_name: :send_message, - action_params: ['Welcome to the chatwoot platform.'] + action_name: :send_attachment, + action_params: [blob_1['blob_id']] }, { - action_name: :update_additional_attributes, - action_params: [{ intiated_at: '2021-12-03 17:25:26.844536 +0530' }] - }, - { - action_name: :send_attachments + action_name: :send_attachment, + action_params: [blob_2['blob_id']] } ] - expect(account.automation_rules.count).to eq(0) - post "/api/v1/accounts/#{account.id}/automation_rules", headers: administrator.create_new_auth_token, params: params - expect(response).to have_http_status(:success) - expect(account.automation_rules.count).to eq(1) automation_rule = account.automation_rules.first - expect(automation_rule.files.presence).to be_truthy expect(automation_rule.files.count).to eq(2) end end diff --git a/spec/listeners/automation_rule_listener_spec.rb b/spec/listeners/automation_rule_listener_spec.rb index 079b9bbd5..6213e4450 100644 --- a/spec/listeners/automation_rule_listener_spec.rb +++ b/spec/listeners/automation_rule_listener_spec.rb @@ -128,6 +128,15 @@ describe AutomationRuleListener do expect(conversation.messages.first.content).to eq('Send this message.') end + it 'triggers automation rule to mute conversation' do + expect(conversation).not_to be_muted + + listener.conversation_updated(event) + + conversation.reload + expect(conversation).to be_muted + end + it 'triggers automation_rule with contact standard attributes' do automation_rule.update!( conditions: [