fix(captain): keep responding to pending conversations on audience or schedule drift
This commit is contained in:
+27
-3
@@ -1,11 +1,11 @@
|
||||
import { mount } from '@vue/test-utils';
|
||||
import { nextTick } from 'vue';
|
||||
import { createStore } from 'vuex';
|
||||
import { useRoute } from 'vue-router';
|
||||
import InboxChannelsDialog from '../../inbox-setup/InboxChannelsDialog.vue';
|
||||
|
||||
vi.mock('vue-i18n', () => ({ useI18n: () => ({ t: key => key }) }));
|
||||
vi.mock('dashboard/composables/store', () => ({
|
||||
useMapGetter: () => ({ value: {} }),
|
||||
}));
|
||||
vi.mock('vue-router');
|
||||
vi.mock('../../inbox-setup/useChannelConnect', () => ({
|
||||
useChannelConnect: () => ({
|
||||
connectViaOAuth: vi.fn(),
|
||||
@@ -13,10 +13,30 @@ vi.mock('../../inbox-setup/useChannelConnect', () => ({
|
||||
}),
|
||||
}));
|
||||
|
||||
const store = createStore({
|
||||
modules: {
|
||||
globalConfig: {
|
||||
namespaced: true,
|
||||
getters: {
|
||||
get: () => ({}),
|
||||
isOnChatwootCloud: () => false,
|
||||
},
|
||||
},
|
||||
accounts: {
|
||||
namespaced: true,
|
||||
getters: {
|
||||
getAccount: () => () => ({ id: 1, features: {} }),
|
||||
isFeatureEnabledonAccount: () => () => false,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const mountDialog = () =>
|
||||
mount(InboxChannelsDialog, {
|
||||
props: { inboxes: [] },
|
||||
global: {
|
||||
plugins: [store],
|
||||
stubs: {
|
||||
Dialog: {
|
||||
template: '<div><slot /></div>',
|
||||
@@ -31,6 +51,10 @@ const mountDialog = () =>
|
||||
});
|
||||
|
||||
describe('InboxChannelsDialog Facebook gating', () => {
|
||||
beforeEach(() => {
|
||||
useRoute.mockReturnValue({ params: { accountId: '1' } });
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
delete window.chatwootConfig;
|
||||
});
|
||||
|
||||
@@ -50,7 +50,7 @@ module Enterprise::MessageTemplates::HookExecutionService
|
||||
end
|
||||
|
||||
def should_process_captain_response?
|
||||
conversation.pending? && message.incoming? && captain_should_engage?
|
||||
conversation.pending? && message.incoming? && captain_assistant_configured?
|
||||
end
|
||||
|
||||
def perform_handoff
|
||||
@@ -76,11 +76,10 @@ module Enterprise::MessageTemplates::HookExecutionService
|
||||
end
|
||||
|
||||
def captain_handling_conversation?
|
||||
conversation.pending? && captain_should_engage?
|
||||
conversation.pending? && captain_assistant_configured?
|
||||
end
|
||||
|
||||
def captain_should_engage?
|
||||
assistant = inbox.captain_assistant
|
||||
assistant.present? && assistant.engages?(conversation.contact, conversation)
|
||||
def captain_assistant_configured?
|
||||
inbox.captain_assistant.present?
|
||||
end
|
||||
end
|
||||
|
||||
+71
-15
@@ -126,21 +126,6 @@ RSpec.describe MessageTemplates::HookExecutionService do
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the contact is outside the assistant audience' do
|
||||
before do
|
||||
assistant.update!(config: assistant.config.merge('audience' => {
|
||||
'attribute_key' => 'country_code', 'filter_operator' => 'equal_to', 'values' => ['US']
|
||||
}))
|
||||
contact.update!(additional_attributes: { 'country_code' => 'CA' })
|
||||
end
|
||||
|
||||
it 'does not schedule captain response job' do
|
||||
expect(Captain::Conversation::ResponseBuilderJob).not_to receive(:perform_later)
|
||||
|
||||
create(:message, conversation: conversation, message_type: :incoming, account: account)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the contact is inside the assistant audience' do
|
||||
before do
|
||||
assistant.update!(config: assistant.config.merge('audience' => {
|
||||
@@ -156,6 +141,77 @@ RSpec.describe MessageTemplates::HookExecutionService do
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the conversation stops matching the audience mid-conversation' do
|
||||
it 'still schedules captain response job for the pending conversation' do
|
||||
conversation
|
||||
assistant.update!(config: assistant.config.merge('audience' => {
|
||||
'attribute_key' => 'country_code', 'filter_operator' => 'equal_to', 'values' => ['US']
|
||||
}))
|
||||
contact.update!(additional_attributes: { 'country_code' => 'CA' })
|
||||
|
||||
expect(Captain::Conversation::ResponseBuilderJob).to receive(:perform_later).with(conversation, assistant)
|
||||
|
||||
create(:message, conversation: conversation, message_type: :incoming, account: account)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the reply schedule stops matching mid-conversation' do
|
||||
before do
|
||||
inbox.update!(working_hours_enabled: true)
|
||||
inbox.working_hours.find_by(day_of_week: Time.current.in_time_zone(inbox.timezone).wday).update!(
|
||||
open_all_day: true,
|
||||
closed_all_day: false
|
||||
)
|
||||
end
|
||||
|
||||
it 'still schedules captain response job when business hours end after captain took the conversation' do
|
||||
assistant.update!(config: assistant.config.merge('response_window' => 'business_hours'))
|
||||
conversation
|
||||
inbox.working_hours.find_by(day_of_week: Time.current.in_time_zone(inbox.timezone).wday).update!(
|
||||
open_all_day: false,
|
||||
closed_all_day: true
|
||||
)
|
||||
|
||||
expect(Captain::Conversation::ResponseBuilderJob).to receive(:perform_later).with(conversation, assistant)
|
||||
|
||||
create(:message, conversation: conversation, message_type: :incoming, account: account)
|
||||
end
|
||||
|
||||
it 'still schedules captain response job when business hours begin after captain took the conversation' do
|
||||
assistant.update!(config: assistant.config.merge('response_window' => 'outside_business_hours'))
|
||||
inbox.working_hours.find_by(day_of_week: Time.current.in_time_zone(inbox.timezone).wday).update!(
|
||||
open_all_day: false,
|
||||
closed_all_day: true
|
||||
)
|
||||
conversation
|
||||
inbox.working_hours.find_by(day_of_week: Time.current.in_time_zone(inbox.timezone).wday).update!(
|
||||
open_all_day: true,
|
||||
closed_all_day: false
|
||||
)
|
||||
|
||||
expect(Captain::Conversation::ResponseBuilderJob).to receive(:perform_later).with(conversation, assistant)
|
||||
|
||||
create(:message, conversation: conversation, message_type: :incoming, account: account)
|
||||
end
|
||||
|
||||
it 'still schedules captain response job when both audience and schedule stop matching' do
|
||||
assistant.update!(config: assistant.config.merge('response_window' => 'business_hours'))
|
||||
conversation
|
||||
assistant.update!(config: assistant.config.merge('audience' => {
|
||||
'attribute_key' => 'country_code', 'filter_operator' => 'equal_to', 'values' => ['US']
|
||||
}))
|
||||
contact.update!(additional_attributes: { 'country_code' => 'CA' })
|
||||
inbox.working_hours.find_by(day_of_week: Time.current.in_time_zone(inbox.timezone).wday).update!(
|
||||
open_all_day: false,
|
||||
closed_all_day: true
|
||||
)
|
||||
|
||||
expect(Captain::Conversation::ResponseBuilderJob).to receive(:perform_later).with(conversation, assistant)
|
||||
|
||||
create(:message, conversation: conversation, message_type: :incoming, account: account)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when message is outgoing' do
|
||||
it 'does not schedule captain response job' do
|
||||
expect(Captain::Conversation::ResponseBuilderJob).not_to receive(:perform_later)
|
||||
|
||||
Reference in New Issue
Block a user