From 113e2f8ce9ce18d8feba754563efb62d894a76cd Mon Sep 17 00:00:00 2001 From: Kevin Aleman Date: Fri, 6 Oct 2023 12:27:29 -0600 Subject: [PATCH 1/6] More tests for validating monitor data access --- .../livechat-enterprise/server/lib/units.ts | 2 +- .../server/methods/getUnitsFromUserRoles.ts | 4 +- .../end-to-end/api/livechat/22-monitors.ts | 216 ++++++++++++++++++ 3 files changed, 219 insertions(+), 3 deletions(-) create mode 100644 apps/meteor/tests/end-to-end/api/livechat/22-monitors.ts diff --git a/apps/meteor/ee/app/livechat-enterprise/server/lib/units.ts b/apps/meteor/ee/app/livechat-enterprise/server/lib/units.ts index 58a75abc943c3..309834f2d1e8e 100644 --- a/apps/meteor/ee/app/livechat-enterprise/server/lib/units.ts +++ b/apps/meteor/ee/app/livechat-enterprise/server/lib/units.ts @@ -8,7 +8,7 @@ async function hasUnits(): Promise { } // Units should't change really often, so we can cache the result -const memoizedHasUnits = mem(hasUnits, { maxAge: 10000 }); +const memoizedHasUnits = mem(hasUnits, { maxAge: process.env.TEST_MODE ? 1 : 10000 }); export async function getUnitsFromUser(): Promise<{ [k: string]: any }[] | undefined> { if (!(await memoizedHasUnits())) { diff --git a/apps/meteor/ee/app/livechat-enterprise/server/methods/getUnitsFromUserRoles.ts b/apps/meteor/ee/app/livechat-enterprise/server/methods/getUnitsFromUserRoles.ts index 47929f384d8fa..18ed1b1ea646c 100644 --- a/apps/meteor/ee/app/livechat-enterprise/server/methods/getUnitsFromUserRoles.ts +++ b/apps/meteor/ee/app/livechat-enterprise/server/methods/getUnitsFromUserRoles.ts @@ -14,8 +14,8 @@ async function getDepartmentsFromUserRoles(user: string): Promise { return (await LivechatDepartmentAgents.findByAgentId(user).toArray()).map((department) => department.departmentId); } -const memoizedGetUnitFromUserRoles = mem(getUnitsFromUserRoles, { maxAge: 10000 }); -const memoizedGetDepartmentsFromUserRoles = mem(getDepartmentsFromUserRoles, { maxAge: 5000 }); +const memoizedGetUnitFromUserRoles = mem(getUnitsFromUserRoles, { maxAge: process.env.TEST_MODE ? 1 : 10000 }); +const memoizedGetDepartmentsFromUserRoles = mem(getDepartmentsFromUserRoles, { maxAge: process.env.TEST_MODE ? 1 : 10000 }); export const getUnitsFromUser = async (user: string): Promise => { if (!user || (await hasAnyRoleAsync(user, ['admin', 'livechat-manager']))) { diff --git a/apps/meteor/tests/end-to-end/api/livechat/22-monitors.ts b/apps/meteor/tests/end-to-end/api/livechat/22-monitors.ts new file mode 100644 index 0000000000000..2c43cdc2dfa35 --- /dev/null +++ b/apps/meteor/tests/end-to-end/api/livechat/22-monitors.ts @@ -0,0 +1,216 @@ +/* eslint-disable @typescript-eslint/no-non-null-assertion */ +import type { ILivechatDepartment, IUser } from '@rocket.chat/core-typings'; +import { expect } from 'chai'; +import { before, it, describe } from 'mocha'; + +import { getCredentials, api, request } from '../../../data/api-data'; +import { addOrRemoveAgentFromDepartment, createDepartment } from '../../../data/livechat/department'; +import { + createAgent, + createLivechatRoom, + createManager, + createVisitor, + getLivechatRoomInfo, + makeAgentAvailable, +} from '../../../data/livechat/rooms'; +import { createMonitor, createUnit } from '../../../data/livechat/units'; +import { updateSetting } from '../../../data/permissions.helper'; +import { password } from '../../../data/user'; +import { createUser, login, setUserActiveStatus } from '../../../data/users.helper'; +import { IS_EE } from '../../../e2e/config/constants'; + +type TestUser = { user: IUser; credentials: { 'X-Auth-Token': string; 'X-User-Id': string } }; + +(IS_EE ? describe : describe.skip)('Omnichannel - Monitors', () => { + let manager: TestUser; + let monitor: TestUser; + let noUnitDepartment: ILivechatDepartment; + let unitDepartment: ILivechatDepartment; + + before((done) => getCredentials(done)); + before(async () => { + await updateSetting('Livechat_accept_chats_with_no_agents', true); + await setUserActiveStatus('rocketchat.internal.admin.test', true); + await createAgent(); + await makeAgentAvailable(); + }); + before(async () => { + const user: IUser = await createUser(); + const userCredentials = await login(user.username, password); + if (!user.username) { + throw new Error('user not created'); + } + await createManager(user.username); + + manager = { + user, + credentials: userCredentials, + }; + }); + before(async () => { + const user: IUser = await createUser(); + const userCredentials = await login(user.username, password); + if (!user.username) { + throw new Error('user not created'); + } + await createMonitor(user.username); + + monitor = { + user, + credentials: userCredentials, + }; + }); + before(async () => { + noUnitDepartment = await createDepartment(); + unitDepartment = await createDepartment(); + + await createUnit(monitor.user._id, monitor.user.username!, [unitDepartment._id]); + }); + + describe('Monitors & Rooms', () => { + let room1: any; + let room2: any; + it('should not return a room of a department that the monitor is not assigned to', async () => { + const visitor = await createVisitor(noUnitDepartment._id); + const room = await createLivechatRoom(visitor.token); + + const { body } = await request + .get(api('livechat/rooms')) + .set(monitor.credentials) + .expect('Content-Type', 'application/json') + .expect(200); + + expect(body).to.have.property('rooms').that.is.an('array'); + expect(body.rooms.find((r: any) => r._id === room._id)).to.not.exist; + room1 = room; + }); + it('should return a room of a department the monitor is assigned to', async () => { + const visitor = await createVisitor(unitDepartment._id); + const room = await createLivechatRoom(visitor.token); + + const { body } = await request + .get(api('livechat/rooms')) + .set(monitor.credentials) + .expect('Content-Type', 'application/json') + .expect(200); + + expect(body).to.have.property('rooms').that.is.an('array'); + expect(body.rooms.find((r: any) => r._id === room._id)).to.exist; + room2 = room; + }); + it('should return both created rooms to a manager', async () => { + const { body } = await request + .get(api('livechat/rooms')) + .query({ + sort: '{ "_updatedAt": 1 }', + }) + .set(manager.credentials) + .expect('Content-Type', 'application/json') + .expect(200); + + expect(body).to.have.property('rooms').that.is.an('array'); + expect(body.rooms.find((r: any) => r._id === room1._id)).to.exist; + expect(body.rooms.find((r: any) => r._id === room2._id)).to.exist; + }); + }); + + describe('Monitors & Departments', () => { + it('should not return a department that the monitor is not assigned to', async () => { + const { body } = await request + .get(api('livechat/department')) + .query({ onlyMyDepartments: true }) + .set(monitor.credentials) + .expect('Content-Type', 'application/json') + .expect(200); + + expect(body).to.have.property('departments').that.is.an('array'); + expect(body.departments.find((d: any) => d._id === noUnitDepartment._id)).to.not.exist; + }); + it('should return a department that the monitor is assigned to', async () => { + const { body } = await request + .get(api('livechat/department')) + .query({ onlyMyDepartments: true }) + .set(monitor.credentials) + .expect('Content-Type', 'application/json') + .expect(200); + + expect(body).to.have.property('departments').that.is.an('array'); + expect(body.departments.length).to.be.equal(1); + expect(body.departments.find((d: any) => d._id === unitDepartment._id)).to.exist; + }); + it('should return both created departments to a manager', async () => { + const { body } = await request + .get(api('livechat/department')) + .query({ onlyMyDepartments: true, sort: '{ "_updatedAt": 1 }' }) + .set(manager.credentials) + .expect('Content-Type', 'application/json') + .expect(200); + + expect(body).to.have.property('departments').that.is.an('array'); + expect(body.departments.find((d: any) => d._id === noUnitDepartment._id)).to.exist; + expect(body.departments.find((d: any) => d._id === unitDepartment._id)).to.exist; + }); + it('should not return a department when monitor is only assigned as agent there', async () => { + await createAgent(monitor.user.username!); + await addOrRemoveAgentFromDepartment( + noUnitDepartment._id, + { agentId: monitor.user._id, username: monitor.user.username!, count: 0, order: 0 }, + true, + ); + + const { body } = await request + .get(api('livechat/department')) + .query({ onlyMyDepartments: true }) + .set(monitor.credentials) + .expect('Content-Type', 'application/json') + .expect(200); + + expect(body).to.have.property('departments').that.is.an('array'); + expect(body.departments.length).to.be.equal(1); + expect(body.departments.find((d: any) => d._id === noUnitDepartment._id)).to.not.exist; + }); + }); + + describe('Monitors & Forward', () => { + it('should successfully forward a room to another agent', async () => { + const visitor = await createVisitor(unitDepartment._id); + const room = await createLivechatRoom(visitor.token); + + const { body } = await request + .post(api('livechat/room.forward')) + .set(monitor.credentials) + .send({ + roomId: room._id, + userId: 'rocketchat.internal.admin.test', + }) + .expect('Content-Type', 'application/json') + .expect(200); + + expect(body).to.have.property('success', true); + + const room2 = await getLivechatRoomInfo(room._id); + + expect(room2).to.have.property('servedBy').that.is.an('object'); + expect(room2.servedBy).to.have.property('_id', 'rocketchat.internal.admin.test'); + }); + it('should successfully forward a room to a department', async () => { + const visitor = await createVisitor(noUnitDepartment._id); + const room = await createLivechatRoom(visitor.token); + + const { body } = await request + .post(api('livechat/room.forward')) + .set(monitor.credentials) + .send({ + roomId: room._id, + departmentId: unitDepartment._id, + }) + .expect('Content-Type', 'application/json') + .expect(200); + + expect(body).to.have.property('success', true); + + const room2 = await getLivechatRoomInfo(room._id); + expect(room2.departmentId).to.be.equal(unitDepartment._id); + }); + }); +}); From 5492fed2853ccd6722a26c613f86526ae62d8e38 Mon Sep 17 00:00:00 2001 From: Kevin Aleman Date: Mon, 9 Oct 2023 14:12:52 -0600 Subject: [PATCH 2/6] Update 22-monitors.ts --- .../tests/end-to-end/api/livechat/22-monitors.ts | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/apps/meteor/tests/end-to-end/api/livechat/22-monitors.ts b/apps/meteor/tests/end-to-end/api/livechat/22-monitors.ts index 2c43cdc2dfa35..418ce095c7451 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/22-monitors.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/22-monitors.ts @@ -98,20 +98,6 @@ type TestUser = { user: IUser; credentials: { 'X-Auth-Token': string; 'X-User-Id expect(body.rooms.find((r: any) => r._id === room._id)).to.exist; room2 = room; }); - it('should return both created rooms to a manager', async () => { - const { body } = await request - .get(api('livechat/rooms')) - .query({ - sort: '{ "_updatedAt": 1 }', - }) - .set(manager.credentials) - .expect('Content-Type', 'application/json') - .expect(200); - - expect(body).to.have.property('rooms').that.is.an('array'); - expect(body.rooms.find((r: any) => r._id === room1._id)).to.exist; - expect(body.rooms.find((r: any) => r._id === room2._id)).to.exist; - }); }); describe('Monitors & Departments', () => { From 39f94fcb08806e9a06aa956162eb62bf4a3b821e Mon Sep 17 00:00:00 2001 From: Kevin Aleman Date: Mon, 9 Oct 2023 14:56:36 -0600 Subject: [PATCH 3/6] Update 22-monitors.ts --- apps/meteor/tests/end-to-end/api/livechat/22-monitors.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/apps/meteor/tests/end-to-end/api/livechat/22-monitors.ts b/apps/meteor/tests/end-to-end/api/livechat/22-monitors.ts index 418ce095c7451..5b5768b92b277 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/22-monitors.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/22-monitors.ts @@ -68,8 +68,6 @@ type TestUser = { user: IUser; credentials: { 'X-Auth-Token': string; 'X-User-Id }); describe('Monitors & Rooms', () => { - let room1: any; - let room2: any; it('should not return a room of a department that the monitor is not assigned to', async () => { const visitor = await createVisitor(noUnitDepartment._id); const room = await createLivechatRoom(visitor.token); @@ -82,7 +80,6 @@ type TestUser = { user: IUser; credentials: { 'X-Auth-Token': string; 'X-User-Id expect(body).to.have.property('rooms').that.is.an('array'); expect(body.rooms.find((r: any) => r._id === room._id)).to.not.exist; - room1 = room; }); it('should return a room of a department the monitor is assigned to', async () => { const visitor = await createVisitor(unitDepartment._id); @@ -96,7 +93,6 @@ type TestUser = { user: IUser; credentials: { 'X-Auth-Token': string; 'X-User-Id expect(body).to.have.property('rooms').that.is.an('array'); expect(body.rooms.find((r: any) => r._id === room._id)).to.exist; - room2 = room; }); }); From 7912f7919cda82e8b0f11a4f2054778fec234462 Mon Sep 17 00:00:00 2001 From: Kevin Aleman Date: Tue, 10 Oct 2023 07:23:40 -0600 Subject: [PATCH 4/6] restore permission to monitors too --- apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts b/apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts index 8dcbad1182173..b1ff5790ba8d1 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts @@ -1313,7 +1313,7 @@ describe('LIVECHAT - rooms', function () { expect(body.history.length).to.equal(0); }); it('should return the transfer history for a room', async () => { - await updatePermission('view-l-room', ['admin', 'livechat-manager', 'livechat-agent']); + await updatePermission('view-l-room', ['admin', 'livechat-manager', 'livechat-agent', 'livechat-monitor']); const initialAgentAssignedToChat: IUser = await createUser(); const initialAgentCredentials = await login(initialAgentAssignedToChat.username, password); await createAgent(initialAgentAssignedToChat.username); From 8370e00ef984decd3e529787202b5c6198aea600 Mon Sep 17 00:00:00 2001 From: Kevin Aleman Date: Tue, 10 Oct 2023 08:21:18 -0600 Subject: [PATCH 5/6] ouch --- apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts | 2 +- apps/meteor/tests/end-to-end/api/livechat/22-monitors.ts | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts b/apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts index b1ff5790ba8d1..8dcbad1182173 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts @@ -1313,7 +1313,7 @@ describe('LIVECHAT - rooms', function () { expect(body.history.length).to.equal(0); }); it('should return the transfer history for a room', async () => { - await updatePermission('view-l-room', ['admin', 'livechat-manager', 'livechat-agent', 'livechat-monitor']); + await updatePermission('view-l-room', ['admin', 'livechat-manager', 'livechat-agent']); const initialAgentAssignedToChat: IUser = await createUser(); const initialAgentCredentials = await login(initialAgentAssignedToChat.username, password); await createAgent(initialAgentAssignedToChat.username); diff --git a/apps/meteor/tests/end-to-end/api/livechat/22-monitors.ts b/apps/meteor/tests/end-to-end/api/livechat/22-monitors.ts index 5b5768b92b277..b31d5fad96cdc 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/22-monitors.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/22-monitors.ts @@ -14,7 +14,7 @@ import { makeAgentAvailable, } from '../../../data/livechat/rooms'; import { createMonitor, createUnit } from '../../../data/livechat/units'; -import { updateSetting } from '../../../data/permissions.helper'; +import { updateSetting, updatePermission } from '../../../data/permissions.helper'; import { password } from '../../../data/user'; import { createUser, login, setUserActiveStatus } from '../../../data/users.helper'; import { IS_EE } from '../../../e2e/config/constants'; @@ -66,6 +66,9 @@ type TestUser = { user: IUser; credentials: { 'X-Auth-Token': string; 'X-User-Id await createUnit(monitor.user._id, monitor.user.username!, [unitDepartment._id]); }); + before(async () => { + await updatePermission('view-l-room', ['admin', 'livechat-manager', 'livechat-agent', 'livechat-monitor']); + }); describe('Monitors & Rooms', () => { it('should not return a room of a department that the monitor is not assigned to', async () => { From bc2fcba765cfe379b80e7986acae6b47b5b41006 Mon Sep 17 00:00:00 2001 From: Kevin Aleman Date: Tue, 10 Oct 2023 09:47:52 -0600 Subject: [PATCH 6/6] Update 22-monitors.ts --- apps/meteor/tests/end-to-end/api/livechat/22-monitors.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/meteor/tests/end-to-end/api/livechat/22-monitors.ts b/apps/meteor/tests/end-to-end/api/livechat/22-monitors.ts index b31d5fad96cdc..d4c2fd59211c5 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/22-monitors.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/22-monitors.ts @@ -67,7 +67,7 @@ type TestUser = { user: IUser; credentials: { 'X-Auth-Token': string; 'X-User-Id await createUnit(monitor.user._id, monitor.user.username!, [unitDepartment._id]); }); before(async () => { - await updatePermission('view-l-room', ['admin', 'livechat-manager', 'livechat-agent', 'livechat-monitor']); + await updatePermission('transfer-livechat-guest', ['admin', 'livechat-manager', 'livechat-agent', 'livechat-monitor']); }); describe('Monitors & Rooms', () => {