From 42af31eadbf413c7ad9f8c5465734db09a2c750a Mon Sep 17 00:00:00 2001 From: Martin Schoeler Date: Mon, 22 Jul 2024 15:50:37 -0300 Subject: [PATCH] fix(livechat): make trigger use correct dep on agent.next (#32692) --- .changeset/dry-pumas-draw.md | 6 + ...omnichannel-triggers-setDepartment.spec.ts | 127 ++++++++++++++++++ .../omnichannel-livechat-embedded.ts | 4 + packages/livechat/src/lib/triggerUtils.ts | 8 +- 4 files changed, 142 insertions(+), 3 deletions(-) create mode 100644 .changeset/dry-pumas-draw.md create mode 100644 apps/meteor/tests/e2e/omnichannel/omnichannel-triggers-setDepartment.spec.ts diff --git a/.changeset/dry-pumas-draw.md b/.changeset/dry-pumas-draw.md new file mode 100644 index 0000000000000..b66ca5157cd58 --- /dev/null +++ b/.changeset/dry-pumas-draw.md @@ -0,0 +1,6 @@ +--- +"@rocket.chat/meteor": patch +"@rocket.chat/livechat": patch +--- + +Fixed an issue that caused the widget to set the wrong department when using the setDepartment Livechat api endpoint in conjunction with a Livechat Trigger diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-triggers-setDepartment.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-triggers-setDepartment.spec.ts new file mode 100644 index 0000000000000..0c6415dd058ed --- /dev/null +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-triggers-setDepartment.spec.ts @@ -0,0 +1,127 @@ +import { IS_EE } from '../config/constants'; +import { createAuxContext } from '../fixtures/createAuxContext'; +import { Users } from '../fixtures/userStates'; +import { HomeOmnichannel, OmnichannelLiveChatEmbedded } from '../page-objects'; +import { createAgent } from '../utils/omnichannel/agents'; +import { addAgentToDepartment, createDepartment } from '../utils/omnichannel/departments'; +import { test, expect } from '../utils/test'; + +declare const window: Window & { + RocketChat: { livechat: { setDepartment: (dep: string) => void; maximizeWidget: () => void } }; +}; + +test.use({ storageState: Users.admin.state }); +test.describe('OC - Livechat Triggers - SetDepartment', () => { + test.skip(!IS_EE, 'Enterprise Only'); + let poLiveChat: OmnichannelLiveChatEmbedded; + let departments: Awaited>[]; + let departmentA: Awaited>['data']; + let departmentB: Awaited>['data']; + let agents: Awaited>[]; + let agent1: Awaited>['data']; + let agent2: Awaited>['data']; + let poHomeOmnichannelAgent1: HomeOmnichannel; + let poHomeOmnichannelAgent2: HomeOmnichannel; + + test.beforeAll(async ({ api }) => { + // Assign agents & departments + agents = await Promise.all([createAgent(api, 'user1'), createAgent(api, 'user2')]); + [agent1, agent2] = agents.map(({ data }) => data); + departments = await Promise.all([ + createDepartment(api, { showOnRegistration: true }), + createDepartment(api, { showOnRegistration: true }), + ]); + + [departmentA, departmentB] = departments.map(({ data }) => data); + + await Promise.all([ + addAgentToDepartment(api, { department: departmentA, agentId: agent1._id }), + addAgentToDepartment(api, { department: departmentB, agentId: agent2._id }), + api.post( + '/livechat/triggers', + + { + name: 'open', + description: '', + enabled: true, + runOnce: false, + conditions: [ + { + name: 'chat-opened-by-visitor', + value: '', + }, + ], + actions: [ + { + name: 'send-message', + params: { + name: '', + msg: 'This is a trigger message open by visitor', + sender: 'queue', + }, + }, + ], + }, + ), + ]); + }); + + test.beforeEach(async ({ browser, page }) => { + const { page: agent1Page } = await createAuxContext(browser, Users.user1, '/', true); + poHomeOmnichannelAgent1 = new HomeOmnichannel(agent1Page); + const { page: agent2Page } = await createAuxContext(browser, Users.user2, '/', true); + poHomeOmnichannelAgent2 = new HomeOmnichannel(agent2Page); + + poLiveChat = new OmnichannelLiveChatEmbedded(page); + }); + + test.afterEach(async ({ page }) => { + await poHomeOmnichannelAgent1.page.close(); + await poHomeOmnichannelAgent2.page.close(); + await poLiveChat.page.close(); + await page.close(); + }); + + test.afterAll(async ({ api }) => { + const ids = (await (await api.get('/livechat/triggers')).json()).triggers.map( + (trigger: { _id: string }) => trigger._id, + ) as unknown as string[]; + + await Promise.all(ids.map((id) => api.delete(`/livechat/triggers/${id}`))); + expect((await api.post('/settings/Omnichannel_enable_department_removal', { value: true })).status()).toBe(200); + await Promise.all([...agents.map((agent) => agent.delete())]); + await Promise.all([...departments.map((department) => department.delete())]); + expect((await api.post('/settings/Omnichannel_enable_department_removal', { value: false })).status()).toBe(200); + await api.post('/settings/Livechat_registration_form', { value: true }); + }); + + test('OC - Livechat Triggers - setDepartment should affect agent.next call', async () => { + await poLiveChat.page.goto('/packages/rocketchat_livechat/assets/demo.html'); + + const depId = departmentB._id; + + await poLiveChat.page.evaluate((depId) => window.RocketChat.livechat.setDepartment(depId), depId); + + await poLiveChat.openLiveChat(); + + await expect(poLiveChat.txtChatMessage('This is a trigger message open by visitor')).toBeVisible(); + + await expect(poLiveChat.headerTitle).toContainText(agent2.username); + }); + + test('OC - Livechat Triggers - setDepartment should affect agent.next call - Register Form Disabled', async ({ api }) => { + await api.post('/settings/Livechat_registration_form', { value: false }); + + await poLiveChat.page.goto('/packages/rocketchat_livechat/assets/demo.html'); + + const depId = departmentB._id; + + await poLiveChat.page.evaluate((depId) => window.RocketChat.livechat.setDepartment(depId), depId); + + await poLiveChat.openLiveChat(); + + await expect(poLiveChat.txtChatMessage('This is a trigger message open by visitor')).toBeVisible(); + + await expect(poLiveChat.headerTitle).toContainText(agent2.username); + }); +}); diff --git a/apps/meteor/tests/e2e/page-objects/omnichannel-livechat-embedded.ts b/apps/meteor/tests/e2e/page-objects/omnichannel-livechat-embedded.ts index 79d1e9532677e..3990d5fce7bbb 100644 --- a/apps/meteor/tests/e2e/page-objects/omnichannel-livechat-embedded.ts +++ b/apps/meteor/tests/e2e/page-objects/omnichannel-livechat-embedded.ts @@ -35,6 +35,10 @@ export class OmnichannelLiveChatEmbedded { return this.page.frameLocator('#rocketchat-iframe').locator('div >> text="Chat Finished"'); } + get headerTitle(): Locator { + return this.page.frameLocator('#rocketchat-iframe').locator('[data-qa="header-title"]'); + } + get btnChatNow(): Locator { return this.page.frameLocator('#rocketchat-iframe').locator('[type="button"] >> text="Chat now"'); } diff --git a/packages/livechat/src/lib/triggerUtils.ts b/packages/livechat/src/lib/triggerUtils.ts index ca66e2bea0f94..ecce283ccf2a4 100644 --- a/packages/livechat/src/lib/triggerUtils.ts +++ b/packages/livechat/src/lib/triggerUtils.ts @@ -17,16 +17,18 @@ const isAgentWithInfo = (agent: any): agent is Serialized => !ag const getNextAgentFromQueue = async () => { const { defaultAgent, - iframe: { guest: { department } = {} }, + iframe: { defaultDepartment, guest: { department } = {} }, } = store.state; if (defaultAgent?.ts && Date.now() - defaultAgent.ts < agentCacheExpiry) { return defaultAgent; // cache valid for 1 hour } + const dep = department || defaultDepartment; + let agent = null; try { - const tempAgent = await Livechat.nextAgent({ department }); + const tempAgent = await Livechat.nextAgent({ department: dep }); if (isAgentWithInfo(tempAgent?.agent)) { agent = tempAgent.agent; @@ -35,7 +37,7 @@ const getNextAgentFromQueue = async () => { return Promise.reject(error); } - store.setState({ defaultAgent: { ...agent, department, ts: Date.now() } as Agent }); + store.setState({ defaultAgent: { ...agent, department: dep, ts: Date.now() } as Agent }); return agent; };