diff --git a/.changeset/thin-keys-impress.md b/.changeset/thin-keys-impress.md new file mode 100644 index 000000000000..8679299972fc --- /dev/null +++ b/.changeset/thin-keys-impress.md @@ -0,0 +1,5 @@ +--- +"@rocket.chat/livechat": patch +--- + +Fixes issue of the `setDepartment` Livechat API method not setting the store value properly (is was only setting on the guest object) diff --git a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-api.spec.ts b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-api.spec.ts index c8810fa4eb77..a8fa27eb5d2c 100644 --- a/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-api.spec.ts +++ b/apps/meteor/tests/e2e/omnichannel/omnichannel-livechat-api.spec.ts @@ -6,6 +6,7 @@ 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'; // TODO: Use official widget typing once that is merged @@ -32,7 +33,7 @@ declare const window: Window & { setAgent: (agent: { username: string; _id: string }) => void; setBusinessUnit: (businessUnit?: string) => void; setCustomField: (field: { key: string; value: string }) => void; - setDepartment: (department: { _id: string; name: string }) => void; + setDepartment: (dep: string) => void; setGuestEmail: (email: string) => void; setGuestName: (name: string) => void; setGuestToken: (token: string) => void; @@ -56,8 +57,8 @@ declare const window: Window & { }; test.describe('OC - Livechat API', () => { - // TODO: Check if there is a way to add livechat to the global window object - + // TODO: Check if there is a way to add livechat to the global window object + test.describe('Basic Widget Interactions', () => { // Tests that rely only on the widget itself, without requiring further interaction from the main RC app let poAuxContext: { page: Page; poHomeOmnichannel: HomeOmnichannel }; @@ -213,27 +214,24 @@ test.describe('OC - Livechat API', () => { test.skip(!IS_EE, 'Enterprise Only'); // Tests that requires interaction from an agent or more let poAuxContext: { page: Page; poHomeOmnichannel: HomeOmnichannel }; + let poAuxContext2: { page: Page; poHomeOmnichannel: HomeOmnichannel }; let poLiveChat: OmnichannelLiveChatEmbedded; let page: Page; - let depId: string; let agent: Awaited>; + let agent2: Awaited>; + let departments: Awaited>[]; + test.beforeAll(async ({ api }) => { agent = await createAgent(api, 'user1') - - const response = await api.post('/livechat/department', {department: { - enabled: true, - email: faker.internet.email(), - showOnRegistration: true, - showOnOfflineForm: true, - name: `new department ${Date.now()}`, - description: 'created from api', - }}); - - expect(response.status()).toBe(200); - - const resBody = await response.json(); - depId = resBody.department._id; + agent2 = await createAgent(api, 'user2') + + departments = await Promise.all([createDepartment(api), createDepartment(api)]); + const [departmentA, departmentB] = departments.map(({ data }) => data); + + await addAgentToDepartment(api, { department: departmentA, agentId: agent.data._id }) + await addAgentToDepartment(api, { department: departmentB, agentId: agent2.data._id }) + await expect((await api.post('/settings/Enable_CSP', { value: false })).status()).toBe(200); await expect((await api.post('/settings/Livechat_offline_email', { value: 'test@testing.com' })).status()).toBe(200); }); @@ -253,6 +251,11 @@ test.describe('OC - Livechat API', () => { await poAuxContext.poHomeOmnichannel.sidenav.switchStatus('online'); } + if (testInfo.title === 'OC - Livechat API - setDepartment') { + const { page: pageCtx2 } = await createAuxContext(browser, Users.user2); + poAuxContext2 = { page: pageCtx2, poHomeOmnichannel: new HomeOmnichannel(pageCtx) }; + } + await page.goto('/packages/rocketchat_livechat/assets/demo.html'); }); @@ -264,9 +267,10 @@ test.describe('OC - Livechat API', () => { test.afterAll(async ({ api }) => { await expect((await api.post('/settings/Enable_CSP', { value: true })).status()).toBe(200); await agent.delete(); + await agent2.delete(); + await expect((await api.post('/settings/Omnichannel_enable_department_removal', { value: true })).status()).toBe(200); - const response = await api.delete(`/livechat/department/${depId}`, { name: 'TestDep', email: 'TestDep@email.com' }); - expect(response.status()).toBe(200); + await Promise.all([...departments.map((department) => department.delete())]); await expect((await api.post('/settings/Omnichannel_enable_department_removal', { value: false })).status()).toBe(200); }); @@ -315,6 +319,47 @@ test.describe('OC - Livechat API', () => { }); }); + test('OC - Livechat API - setDepartment', async () => { + const [departmentA, departmentB] = departments.map(({ data }) => data); + const registerGuestVisitor = { + name: faker.person.firstName(), + email: faker.internet.email(), + token: faker.string.uuid(), + department: departmentA._id, + }; + + // Start Chat + await poLiveChat.page.evaluate(() => window.RocketChat.livechat.maximizeWidget()); + await expect(page.frameLocator('#rocketchat-iframe').getByText('Start Chat')).toBeVisible(); + + await poLiveChat.page.evaluate( + (registerGuestVisitor) => window.RocketChat.livechat.registerGuest(registerGuestVisitor), + registerGuestVisitor, + ); + + await expect(page.frameLocator('#rocketchat-iframe').getByText('Start Chat')).not.toBeVisible(); + + await poLiveChat.onlineAgentMessage.type('this_a_test_message_from_visitor'); + await poLiveChat.btnSendMessageToOnlineAgent.click(); + + await test.step('Expect registered guest to be in dep1', async () => { + await poAuxContext.poHomeOmnichannel.sidenav.openChat(registerGuestVisitor.name); + }); + + const depId = departmentB._id; + + await test.step('Expect setDepartment to change a guest department', async () => { + await poLiveChat.page.evaluate( + (depId) => window.RocketChat.livechat.setDepartment(depId), + depId, + ); + }); + + await test.step('Expect registered guest to be in dep2', async () => { + await poAuxContext2.poHomeOmnichannel.sidenav.openChat(registerGuestVisitor.name); + }); + }); + test('OC - Livechat API - registerGuest', async ({ browser }) => { const registerGuestVisitor = { name: faker.person.firstName(), @@ -495,14 +540,14 @@ test.describe('OC - Livechat API', () => { const { page: pageCtx } = await createAuxContext(browser, Users.user1); poAuxContext = { page: pageCtx, poHomeOmnichannel: new HomeOmnichannel(pageCtx) }; - + // This is needed since the livechat will not react to online/offline status changes if already loaded in a page if (testInfo.title === 'Expect onOfflineFormSubmit to trigger callback') { await poAuxContext.poHomeOmnichannel.sidenav.switchStatus('offline'); } else { await poAuxContext.poHomeOmnichannel.sidenav.switchStatus('online'); } - + await page.goto('/packages/rocketchat_livechat/assets/demo.html'); }); @@ -635,7 +680,7 @@ test.describe('OC - Livechat API', () => { await poLiveChat.sendMessage(newVisitor, false); await poLiveChat.onlineAgentMessage.type('this_a_test_message_from_visitor'); await poLiveChat.btnSendMessageToOnlineAgent.click(); - + const watchForTrigger = page.waitForFunction(() => window.onAgentStatusChange === true); @@ -717,5 +762,5 @@ test.describe('OC - Livechat API', () => { }); }); }); - + }); diff --git a/packages/livechat/src/lib/hooks.js b/packages/livechat/src/lib/hooks.js index 311cf0b2a00b..67e331371948 100644 --- a/packages/livechat/src/lib/hooks.js +++ b/packages/livechat/src/lib/hooks.js @@ -88,6 +88,7 @@ const api = { const department = departments.find((dep) => dep._id === value || dep.name === value)?._id || ''; updateIframeGuestData({ department }); + store.setState({ department }); if (defaultAgent && defaultAgent.department !== department) { store.setState({ defaultAgent: null }); diff --git a/packages/livechat/src/lib/room.js b/packages/livechat/src/lib/room.js index 1e4f975f1886..c1d2f0163a56 100644 --- a/packages/livechat/src/lib/room.js +++ b/packages/livechat/src/lib/room.js @@ -25,13 +25,13 @@ export const closeChat = async ({ transcriptRequested } = {}) => { await handleTranscript(); } - const { config: { settings: { clearLocalStorageWhenChatEnded } = {} } = {} } = store.state; + const { department, config: { settings: { clearLocalStorageWhenChatEnded } = {} } = {} } = store.state; if (clearLocalStorageWhenChatEnded) { // exclude UI-affecting flags const { iframe: currentIframe } = store.state; const { minimized, visible, undocked, expanded, businessUnit, config, iframe, ...initial } = initialState(); - initial.iframe = { ...currentIframe, guest: {} }; + initial.iframe = { ...currentIframe, guest: { department } }; await store.setState(initial); }