Skip to content

Commit

Permalink
feat: Add the ability to self-assign conversations in macros (#8048)
Browse files Browse the repository at this point in the history
Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
  • Loading branch information
sojan-official and muhsin-k committed Oct 10, 2023
1 parent 759a66d commit 6a07251
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 4 deletions.
2 changes: 1 addition & 1 deletion app/javascript/dashboard/mixins/macrosMixin.js
Expand Up @@ -7,7 +7,7 @@ export default {
case 'send_email_to_team':
return this.teams;
case 'assign_agent':
return this.agents;
return [{ id: 'self', name: 'Self' }, ...this.agents];
case 'add_label':
case 'remove_label':
return this.labels.map(i => {
Expand Down
5 changes: 4 additions & 1 deletion app/javascript/dashboard/mixins/specs/macros.spec.js
Expand Up @@ -37,7 +37,10 @@ describe('webhookMixin', () => {
expect(wrapper.vm.getDropdownValues('assign_team')).toEqual(teams);
expect(wrapper.vm.getDropdownValues('send_email_to_team')).toEqual(teams);
expect(wrapper.vm.getDropdownValues('add_label')).toEqual(resolvedLabels);
expect(wrapper.vm.getDropdownValues('assign_agent')).toEqual(agents);
expect(wrapper.vm.getDropdownValues('assign_agent')).toEqual([
{ id: 'self', name: 'Self' },
...agents,
]);
expect(wrapper.vm.getDropdownValues('change_priority')).toEqual(
PRIORITY_CONDITION_VALUES
);
Expand Down
5 changes: 5 additions & 0 deletions app/services/macros/execution_service.rb
Expand Up @@ -22,6 +22,11 @@ def perform

private

def assign_agent(agent_ids)
agent_ids = agent_ids.map { |id| id == 'self' ? @user.id : id }
super(agent_ids)
end

def add_private_note(message)
return if conversation_a_tweet?

Expand Down
2 changes: 0 additions & 2 deletions spec/services/action_service_spec.rb
Expand Up @@ -40,6 +40,4 @@
expect(conversation.reload.assignee).to be_nil
end
end

# TODO: Expand this test suite
end
150 changes: 150 additions & 0 deletions spec/services/macros/execution_service_spec.rb
@@ -0,0 +1,150 @@
require 'rails_helper'

RSpec.describe Macros::ExecutionService, type: :service do
let(:account) { create(:account) }
let(:conversation) { create(:conversation, account: account) }
let(:user) { create(:user, account: account) }
let(:macro) { create(:macro, account: account) }
let(:service) { described_class.new(macro, conversation, user) }

before do
create(:inbox_member, user: user, inbox: conversation.inbox)
end

describe '#perform' do
context 'when actions are present' do
before do
allow(macro).to receive(:actions).and_return([
{ action_name: 'assign_agent', action_params: ['self'] },
{ action_name: 'add_private_note', action_params: ['Test note'] },
{ action_name: 'send_message', action_params: ['Test message'] },
{ action_name: 'send_attachment', action_params: [1, 2] }
])
end

it 'executes the actions' do
expect(service).to receive(:assign_agent).with(['self']).and_call_original
expect(service).to receive(:add_private_note).with(['Test note']).and_call_original
expect(service).to receive(:send_message).with(['Test message']).and_call_original
expect(service).to receive(:send_attachment).with([1, 2]).and_call_original

service.perform
end

context 'when an action raises an error' do
let(:exception_tracker) { instance_spy(ChatwootExceptionTracker) }

before do
allow(ChatwootExceptionTracker).to receive(:new).and_return(exception_tracker)
end

it 'captures the exception' do
allow(service).to receive(:assign_agent).and_raise(StandardError.new('Random error'))
expect(exception_tracker).to receive(:capture_exception)

service.perform
end
end
end
end

describe '#assign_agent' do
context 'when agent_ids contains self' do
it 'updates the conversation assignee to the current user' do
service.send(:assign_agent, ['self'])
expect(conversation.reload.assignee).to eq(user)
end
end

context 'when agent_ids does not contain self' do
let(:other_user) { create(:user, account: account) }

before do
create(:inbox_member, user: other_user, inbox: conversation.inbox)
end

it 'calls the super method' do
service.send(:assign_agent, [other_user.id])
expect(conversation.reload.assignee).to eq(other_user)
end
end
end

describe '#add_private_note' do
context 'when conversation is not a tweet' do
it 'creates a new private message' do
expect do
service.send(:add_private_note, ['Test private note'])
end.to change(Message, :count).by(1)

message = Message.last
expect(message.content).to eq('Test private note')
expect(message.private).to be(true)
end
end

context 'when conversation is a tweet' do
before { allow(service).to receive(:conversation_a_tweet?).and_return(true) }

it 'does not create a new message' do
expect do
service.send(:add_private_note, ['Test private note'])
end.not_to change(Message, :count)
end
end
end

describe '#send_message' do
context 'when conversation is not a tweet' do
it 'creates a new public message' do
expect do
service.send(:send_message, ['Test message'])
end.to change(Message, :count).by(1)

message = Message.last
expect(message.content).to eq('Test message')
expect(message.private).to be(false)
end
end

context 'when conversation is a tweet' do
before { allow(service).to receive(:conversation_a_tweet?).and_return(true) }

it 'does not create a new message' do
expect do
service.send(:send_message, ['Test message'])
end.not_to change(Message, :count)
end
end
end

describe '#send_attachment' do
before do
macro.files.attach(io: Rails.root.join('spec/assets/avatar.png').open, filename: 'avatar.png', content_type: 'image/png')
macro.save!
end

context 'when conversation is not a tweet and macro has files attached' do
before { allow(service).to receive(:conversation_a_tweet?).and_return(false) }

it 'creates a new message with attachments' do
expect do
service.send(:send_attachment, [macro.files.first.blob_id])
end.to change(Message, :count).by(1)

message = Message.last
expect(message.attachments).to be_present
end
end

context 'when conversation is a tweet or macro has no files attached' do
before { allow(service).to receive(:conversation_a_tweet?).and_return(true) }

it 'does not create a new message' do
expect do
service.send(:send_attachment, [macro.files.first.blob_id])
end.not_to change(Message, :count)
end
end
end
end

0 comments on commit 6a07251

Please sign in to comment.