Some checks failed
Create issues from TODOs / todos (push) Failing after 3s
Close inactive issues / close-issues (push) Has been cancelled
Deploy GitHub Pages / deploy-preview (push) Has been cancelled
CI / ⚙️ Variables Setup (push) Has been cancelled
CI / ⚙️ Test Guard (push) Has been cancelled
CI / 🚀 Notify external services - draft (push) Has been cancelled
CI / 📦 Build Packages (push) Has been cancelled
CI / 📦 Meteor Build (coverage) (push) Has been cancelled
CI / 📦 Meteor Build (production) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], fips) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Publish Docker Images (ghcr.io) (push) Has been cancelled
CI / 📦 Track Image Sizes (push) Has been cancelled
CI / 🔎 Code Check - Action Lint (push) Has been cancelled
CI / 🔎 Code Check (push) Has been cancelled
CI / 🔨 Test Storybook (push) Has been cancelled
CI / 🔨 Test Unit (push) Has been cancelled
CI / 🔨 Test API (CE) (push) Has been cancelled
CI / 🔨 Test API Livechat (CE) (push) Has been cancelled
CI / 🔨 Test UI (CE) (push) Has been cancelled
CI / 🔨 Test API (EE) (push) Has been cancelled
CI / 🔨 Test API Livechat (EE) (push) Has been cancelled
CI / 🔨 Test API Apps (deno-runtime - EE) (push) Has been cancelled
CI / 🔨 Test UI (EE) (push) Has been cancelled
CI / 🔨 Test API (FIPS) (push) Has been cancelled
CI / 🔨 Test API Livechat (FIPS) (push) Has been cancelled
CI / 🔨 Test UI (FIPS) (push) Has been cancelled
CI / 🔨 Test Federation Matrix (push) Has been cancelled
CI / 📊 Report Coverage (push) Has been cancelled
CI / ✅ Tests Done (push) Has been cancelled
CI / 🚀 Publish build assets (push) Has been cancelled
CI / 🚀 Publish Docker Images (DockerHub) (push) Has been cancelled
CI / 🚀 Notify external services (push) Has been cancelled
CI / Update Version Durability (push) Has been cancelled
Release / Release (push) Has been cancelled
Auto-close duplicate issues / auto-close-duplicates (push) Failing after 1s
Code scanning - action / CodeQL-Build (push) Failing after 2s
1480 lines
53 KiB
TypeScript
1480 lines
53 KiB
TypeScript
import { faker } from '@faker-js/faker';
|
|
import type { Credentials } from '@rocket.chat/api-client';
|
|
import type { ILivechatDepartment, ILivechatVisitor, IOmnichannelRoom, IUser } from '@rocket.chat/core-typings';
|
|
import { expect } from 'chai';
|
|
import { after, before, describe, it } from 'mocha';
|
|
import type { Response } from 'supertest';
|
|
|
|
import { getCredentials, api, request, credentials } from '../../../data/api-data';
|
|
import { createDepartmentWithAnOnlineAgent, deleteDepartment, addOrRemoveAgentFromDepartment } from '../../../data/livechat/department';
|
|
import {
|
|
createVisitor,
|
|
createLivechatRoom,
|
|
closeOmnichannelRoom,
|
|
deleteVisitor,
|
|
createAgent,
|
|
createDepartment,
|
|
getLivechatRoomInfo,
|
|
makeAgentAvailable,
|
|
updateDepartment,
|
|
startANewLivechatRoomAndTakeIt,
|
|
fetchInquiry,
|
|
takeInquiry,
|
|
} from '../../../data/livechat/rooms';
|
|
import { createAnOnlineAgent, updateLivechatSettingsForUser } from '../../../data/livechat/users';
|
|
import { sleep } from '../../../data/livechat/utils';
|
|
import { updateEESetting, updatePermission, updateSetting } from '../../../data/permissions.helper';
|
|
import { password } from '../../../data/user';
|
|
import { createUser, deleteUser, login } from '../../../data/users.helper';
|
|
import { IS_EE } from '../../../e2e/config/constants';
|
|
|
|
const cleanupRooms = async () => {
|
|
const response = await request
|
|
.get(api('livechat/queue'))
|
|
.set(credentials)
|
|
.query({ count: 100 })
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200);
|
|
|
|
const { queue } = response.body;
|
|
|
|
for await (const item of queue) {
|
|
const {
|
|
body: { rooms },
|
|
} = await request.get(api('livechat/rooms')).query({ 'agents[]': item.user._id }).set(credentials);
|
|
|
|
await Promise.all(
|
|
rooms.map((room: IOmnichannelRoom) =>
|
|
request.post(api('livechat/room.closeByUser')).set(credentials).send({ rid: room._id, comment: faker.lorem.sentence() }),
|
|
),
|
|
);
|
|
}
|
|
};
|
|
|
|
describe('LIVECHAT - Queue', () => {
|
|
before((done) => getCredentials(done));
|
|
|
|
before(async () =>
|
|
Promise.all([
|
|
updateSetting('Livechat_enabled', true),
|
|
updateSetting('Livechat_Routing_Method', 'Auto_Selection'),
|
|
updateEESetting('Livechat_Require_Contact_Verification', 'never'),
|
|
updateSetting('Omnichannel_enable_department_removal', true),
|
|
|
|
// this cleanup is required since previous tests left the DB dirty
|
|
cleanupRooms(),
|
|
]),
|
|
);
|
|
|
|
after(async () => {
|
|
await updateSetting('Omnichannel_enable_department_removal', false);
|
|
});
|
|
|
|
describe('livechat/queue', () => {
|
|
it('should return an "unauthorized error" when the user does not have the necessary permission', async () => {
|
|
await updatePermission('view-l-room', []);
|
|
await request.get(api('livechat/queue')).set(credentials).expect('Content-Type', 'application/json').expect(403);
|
|
await updatePermission('view-l-room', ['admin']);
|
|
});
|
|
|
|
it('should return an array of queued metrics', async () => {
|
|
await request
|
|
.get(api('livechat/queue'))
|
|
.set(credentials)
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res: Response) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body.queue).to.be.an('array');
|
|
expect(res.body).to.have.property('offset');
|
|
expect(res.body).to.have.property('total');
|
|
expect(res.body).to.have.property('count');
|
|
});
|
|
});
|
|
it('should return an array of queued metrics even requested with count and offset params', async () => {
|
|
await request
|
|
.get(api('livechat/queue'))
|
|
.set(credentials)
|
|
.query({
|
|
count: 5,
|
|
offset: 0,
|
|
})
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res: Response) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body.queue).to.be.an('array');
|
|
expect(res.body).to.have.property('offset');
|
|
expect(res.body).to.have.property('total');
|
|
expect(res.body).to.have.property('count');
|
|
});
|
|
});
|
|
it('should have an empty queue (cause we removed everything above)', async () => {
|
|
await request
|
|
.get(api('livechat/queue'))
|
|
.set(credentials)
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res: Response) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body.queue).to.be.an('array').that.is.empty;
|
|
expect(res.body).to.have.property('offset', 0);
|
|
expect(res.body).to.have.property('total', 0);
|
|
expect(res.body).to.have.property('count', 0);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('queue position', () => {
|
|
let agent1: { user: IUser };
|
|
let agent2: { user: IUser };
|
|
let agent3: { user: IUser };
|
|
let deptd1: ILivechatDepartment;
|
|
let deptd2: ILivechatDepartment;
|
|
|
|
const roomsToClose: IOmnichannelRoom[] = [];
|
|
const visitors: ILivechatVisitor[] = [];
|
|
const usersToDelete: IUser[] = [];
|
|
|
|
before(async () => {
|
|
const { department, agent } = await createDepartmentWithAnOnlineAgent();
|
|
|
|
deptd1 = department;
|
|
agent1 = agent;
|
|
|
|
usersToDelete.push(agent.user);
|
|
|
|
const newVisitor = await createVisitor(deptd1._id);
|
|
const newRoom = await createLivechatRoom(newVisitor.token);
|
|
|
|
roomsToClose.push(newRoom);
|
|
visitors.push(newVisitor);
|
|
});
|
|
|
|
after(async () => {
|
|
await deleteDepartment(deptd1._id);
|
|
|
|
if (deptd2) {
|
|
await deleteDepartment(deptd2._id);
|
|
}
|
|
|
|
await Promise.all(roomsToClose.map((room) => closeOmnichannelRoom(room._id)));
|
|
await Promise.all(visitors.map((visitor) => deleteVisitor(visitor.token)));
|
|
await Promise.all(usersToDelete.map((user) => deleteUser(user)));
|
|
});
|
|
|
|
it('should have one item in the queue', async () => {
|
|
await request
|
|
.get(api('livechat/queue'))
|
|
.set(credentials)
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res: Response) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('offset');
|
|
expect(res.body).to.have.property('total');
|
|
expect(res.body).to.have.property('count');
|
|
expect(res.body.queue).to.be.an('array').of.length(1);
|
|
|
|
const [queue] = res.body.queue;
|
|
|
|
expect(queue).to.have.property('chats', 1);
|
|
expect(queue).to.have.nested.property('user._id', agent1.user._id);
|
|
expect(queue).to.have.nested.property('department._id', deptd1._id);
|
|
});
|
|
});
|
|
|
|
it('should return empty results when filtering by another agent', async () => {
|
|
await request
|
|
.get(api('livechat/queue'))
|
|
.query({ agentId: 'another-agent' })
|
|
.set(credentials)
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res: Response) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('offset');
|
|
expect(res.body).to.have.property('total', 0);
|
|
expect(res.body).to.have.property('count', 0);
|
|
expect(res.body.queue).to.be.an('array').of.length(0);
|
|
});
|
|
});
|
|
|
|
it('should increase chats when a new room for same department is created', async () => {
|
|
const newVisitor = await createVisitor(deptd1._id);
|
|
const newRoom = await createLivechatRoom(newVisitor.token);
|
|
|
|
roomsToClose.push(newRoom);
|
|
visitors.push(newVisitor);
|
|
|
|
await request
|
|
.get(api('livechat/queue'))
|
|
.set(credentials)
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res: Response) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('offset');
|
|
expect(res.body).to.have.property('total');
|
|
expect(res.body).to.have.property('count');
|
|
expect(res.body.queue).to.be.an('array').of.length(1);
|
|
|
|
const [queue] = res.body.queue;
|
|
|
|
expect(queue).to.have.property('chats', 2);
|
|
expect(queue).to.have.nested.property('user._id', agent1.user._id);
|
|
expect(queue).to.have.nested.property('department._id', deptd1._id);
|
|
});
|
|
});
|
|
|
|
it('should have two items when create room for another agent', async () => {
|
|
const { user } = await createAnOnlineAgent();
|
|
await addOrRemoveAgentFromDepartment(deptd1._id, { agentId: user._id, username: user.username }, true);
|
|
|
|
agent2 = { user };
|
|
|
|
usersToDelete.push(user);
|
|
|
|
const newVisitor = await createVisitor(deptd1._id);
|
|
const newRoom = await createLivechatRoom(newVisitor.token);
|
|
|
|
roomsToClose.push(newRoom);
|
|
visitors.push(newVisitor);
|
|
|
|
await request
|
|
.get(api('livechat/queue'))
|
|
.set(credentials)
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res: Response) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('offset');
|
|
expect(res.body).to.have.property('total');
|
|
expect(res.body).to.have.property('count');
|
|
expect(res.body.queue).to.be.an('array').of.length(2);
|
|
|
|
const [queue1, queue2] = res.body.queue;
|
|
|
|
expect(queue1).to.have.property('chats', 2);
|
|
expect(queue1).to.have.nested.property('user._id', agent1.user._id);
|
|
expect(queue1).to.have.nested.property('department._id', deptd1._id);
|
|
|
|
expect(queue2).to.have.property('chats', 1);
|
|
expect(queue2).to.have.nested.property('user._id', agent2.user._id);
|
|
expect(queue2).to.have.nested.property('department._id', deptd1._id);
|
|
});
|
|
});
|
|
|
|
it('should be able to filter for second agent only', async () => {
|
|
await request
|
|
.get(api('livechat/queue'))
|
|
.query({ agentId: agent2.user._id })
|
|
.set(credentials)
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res: Response) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('offset');
|
|
expect(res.body).to.have.property('total');
|
|
expect(res.body).to.have.property('count');
|
|
expect(res.body.queue).to.be.an('array').of.length(1);
|
|
|
|
const [queue1] = res.body.queue;
|
|
|
|
expect(queue1).to.have.property('chats', 1);
|
|
expect(queue1).to.have.nested.property('user._id', agent2.user._id);
|
|
expect(queue1).to.have.nested.property('department._id', deptd1._id);
|
|
});
|
|
});
|
|
|
|
it('should return empty if filter for a department without chats', async () => {
|
|
await request
|
|
.get(api('livechat/queue'))
|
|
.query({ departmentId: 'no-chats' })
|
|
.set(credentials)
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res: Response) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('offset');
|
|
expect(res.body).to.have.property('total', 0);
|
|
expect(res.body).to.have.property('count', 0);
|
|
expect(res.body.queue).to.be.an('array').of.length(0);
|
|
});
|
|
});
|
|
|
|
it('should be able to filter for first department only', async () => {
|
|
await request
|
|
.get(api('livechat/queue'))
|
|
.query({ departmentId: deptd1._id })
|
|
.set(credentials)
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res: Response) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('offset');
|
|
expect(res.body).to.have.property('total');
|
|
expect(res.body).to.have.property('count');
|
|
expect(res.body.queue).to.be.an('array').of.length(2);
|
|
|
|
const [queue1] = res.body.queue;
|
|
|
|
expect(queue1).to.have.property('chats', 2);
|
|
expect(queue1).to.have.nested.property('user._id', agent1.user._id);
|
|
expect(queue1).to.have.nested.property('department._id', deptd1._id);
|
|
});
|
|
});
|
|
|
|
(IS_EE ? it : it.skip)('should have three items when create room for another department', async () => {
|
|
const { department: dep2, agent: ag3 } = await createDepartmentWithAnOnlineAgent();
|
|
|
|
agent3 = ag3;
|
|
|
|
usersToDelete.push(ag3.user);
|
|
|
|
deptd2 = dep2;
|
|
|
|
const newVisitor = await createVisitor(deptd2._id);
|
|
const newRoom = await createLivechatRoom(newVisitor.token);
|
|
|
|
roomsToClose.push(newRoom);
|
|
visitors.push(newVisitor);
|
|
|
|
await request
|
|
.get(api('livechat/queue'))
|
|
.set(credentials)
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res: Response) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('offset');
|
|
expect(res.body).to.have.property('total');
|
|
expect(res.body).to.have.property('count');
|
|
expect(res.body.queue).to.be.an('array').of.length(3);
|
|
|
|
const [queue1, queue2, queue3] = res.body.queue;
|
|
|
|
expect(queue1).to.have.property('chats', 2);
|
|
expect(queue1).to.have.nested.property('user._id', agent1.user._id);
|
|
expect(queue1).to.have.nested.property('department._id', deptd1._id);
|
|
|
|
expect(queue2).to.have.property('chats', 1);
|
|
expect(queue3).to.have.property('chats', 1);
|
|
});
|
|
});
|
|
|
|
(IS_EE ? it : it.skip)('should change the order when second department gets more rooms', async () => {
|
|
const newVisitor1 = await createVisitor(deptd2._id);
|
|
const newRoom1 = await createLivechatRoom(newVisitor1.token);
|
|
|
|
roomsToClose.push(newRoom1);
|
|
visitors.push(newVisitor1);
|
|
|
|
const newVisitor2 = await createVisitor(deptd2._id);
|
|
const newRoom2 = await createLivechatRoom(newVisitor2.token);
|
|
|
|
roomsToClose.push(newRoom2);
|
|
visitors.push(newVisitor2);
|
|
|
|
await request
|
|
.get(api('livechat/queue'))
|
|
.set(credentials)
|
|
.expect('Content-Type', 'application/json')
|
|
.expect(200)
|
|
.expect((res: Response) => {
|
|
expect(res.body).to.have.property('success', true);
|
|
expect(res.body).to.have.property('offset');
|
|
expect(res.body).to.have.property('total');
|
|
expect(res.body).to.have.property('count');
|
|
expect(res.body.queue).to.be.an('array').of.length(3);
|
|
|
|
const [queue1, queue2, queue3] = res.body.queue;
|
|
|
|
expect(queue1).to.have.property('chats', 3);
|
|
expect(queue1).to.have.nested.property('user._id', agent3.user._id);
|
|
expect(queue1).to.have.nested.property('department._id', deptd2._id);
|
|
|
|
expect(queue2).to.have.property('chats', 2);
|
|
expect(queue2).to.have.nested.property('user._id', agent1.user._id);
|
|
expect(queue2).to.have.nested.property('department._id', deptd1._id);
|
|
|
|
expect(queue3).to.have.property('chats', 1);
|
|
expect(queue3).to.have.nested.property('user._id', agent2.user._id);
|
|
expect(queue3).to.have.nested.property('department._id', deptd1._id);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
(IS_EE ? describe : describe.skip)('Livechat - Chat limits - AutoSelection', () => {
|
|
let testUser: { user: IUser; credentials: Credentials };
|
|
let testDepartment: ILivechatDepartment;
|
|
let testDepartment2: ILivechatDepartment;
|
|
const roomsToClose: IOmnichannelRoom[] = [];
|
|
const visitorsToDelete: ILivechatVisitor[] = [];
|
|
|
|
before((done) => getCredentials(done));
|
|
|
|
before(async () =>
|
|
Promise.all([
|
|
updateSetting('Livechat_enabled', true),
|
|
updateSetting('Livechat_Routing_Method', 'Auto_Selection'),
|
|
updateSetting('Omnichannel_enable_department_removal', true),
|
|
updateEESetting('Livechat_maximum_chats_per_agent', 0),
|
|
updateEESetting('Livechat_waiting_queue', true),
|
|
updateSetting('Omnichannel_queue_delay_timeout', 3),
|
|
]),
|
|
);
|
|
|
|
before(async () => {
|
|
const user = await createUser();
|
|
await createAgent(user.username);
|
|
const credentials3 = await login(user.username, password);
|
|
await makeAgentAvailable(credentials3);
|
|
|
|
testUser = {
|
|
user,
|
|
credentials: credentials3,
|
|
};
|
|
});
|
|
|
|
before(async () => {
|
|
testDepartment = await createDepartment([{ agentId: testUser.user._id }], `${new Date().toISOString()}-department`, true, {
|
|
maxNumberSimultaneousChat: 2,
|
|
});
|
|
testDepartment2 = await createDepartment([{ agentId: testUser.user._id }], `${new Date().toISOString()}-department2`, true, {
|
|
maxNumberSimultaneousChat: 2,
|
|
});
|
|
await updateLivechatSettingsForUser(testUser.user._id, { maxNumberSimultaneousChat: 1 }, [testDepartment._id, testDepartment2._id]);
|
|
});
|
|
|
|
after(async () => {
|
|
await Promise.all(roomsToClose.map((room) => closeOmnichannelRoom(room._id)));
|
|
await Promise.all(visitorsToDelete.map((visitor) => deleteVisitor(visitor.token)));
|
|
await Promise.all([
|
|
deleteUser(testUser.user),
|
|
updateEESetting('Livechat_maximum_chats_per_agent', 0),
|
|
updateEESetting('Livechat_waiting_queue', false),
|
|
updateSetting('Omnichannel_queue_delay_timeout', 5),
|
|
deleteDepartment(testDepartment._id),
|
|
deleteDepartment(testDepartment2._id),
|
|
]);
|
|
await updateSetting('Omnichannel_enable_department_removal', false);
|
|
});
|
|
|
|
it('should allow a user to take a chat on a department since agent limit is set to 1 and department limit is set to 2 (agent has 0 chats)', async () => {
|
|
const visitor = await createVisitor(testDepartment._id);
|
|
const room = await createLivechatRoom(visitor.token);
|
|
visitorsToDelete.push(visitor);
|
|
roomsToClose.push(room);
|
|
|
|
await sleep(5000);
|
|
|
|
const roomInfo = await getLivechatRoomInfo(room._id);
|
|
|
|
expect(roomInfo.servedBy).to.be.an('object');
|
|
expect(roomInfo.servedBy?._id).to.be.equal(testUser.user._id);
|
|
});
|
|
|
|
let previousChat: string;
|
|
it('should not allow a user to take a chat on a department since agent limit is set to 1 and department limit is set to 2 (agent has 1 chat)', async () => {
|
|
const visitor = await createVisitor(testDepartment._id);
|
|
const room = await createLivechatRoom(visitor.token);
|
|
visitorsToDelete.push(visitor);
|
|
roomsToClose.push(room);
|
|
|
|
await sleep(5000);
|
|
|
|
const roomInfo = await getLivechatRoomInfo(room._id);
|
|
|
|
expect(roomInfo.servedBy).to.be.undefined;
|
|
previousChat = room._id;
|
|
});
|
|
|
|
it('should allow a user to take a chat on a department when agent limit is increased to 2 and department limit is set to 2 (agent has 1 chat)', async () => {
|
|
await updateLivechatSettingsForUser(testUser.user._id, { maxNumberSimultaneousChat: 2 }, [testDepartment._id, testDepartment2._id]);
|
|
await sleep(5000);
|
|
const roomInfo = await getLivechatRoomInfo(previousChat);
|
|
|
|
expect(roomInfo.servedBy).to.be.an('object');
|
|
expect(roomInfo.servedBy?._id).to.be.equal(testUser.user._id);
|
|
});
|
|
|
|
it('should not allow user to take chat on department B when agent limit is 2 and already has 2 chats', async () => {
|
|
const visitor = await createVisitor(testDepartment2._id);
|
|
const room = await createLivechatRoom(visitor.token);
|
|
visitorsToDelete.push(visitor);
|
|
roomsToClose.push(room);
|
|
|
|
await sleep(5000);
|
|
|
|
const roomInfo = await getLivechatRoomInfo(room._id);
|
|
|
|
expect(roomInfo.servedBy).to.be.undefined;
|
|
previousChat = room._id;
|
|
});
|
|
|
|
it('should allow user to take a chat on department B when agent limit is increased to 3 and user has 2 chats on department A', async () => {
|
|
await updateLivechatSettingsForUser(testUser.user._id, { maxNumberSimultaneousChat: 3 }, [testDepartment._id, testDepartment2._id]);
|
|
|
|
await sleep(5000);
|
|
const roomInfo = await getLivechatRoomInfo(previousChat);
|
|
|
|
expect(roomInfo.servedBy).to.be.an('object');
|
|
expect(roomInfo.servedBy?._id).to.be.equal(testUser.user._id);
|
|
});
|
|
|
|
it('should allow a user to take a chat on department B when agent limit is 0 and department B limit is 2 (user has 3 chats)', async () => {
|
|
await updateLivechatSettingsForUser(testUser.user._id, { maxNumberSimultaneousChat: 0 }, [testDepartment._id, testDepartment2._id]);
|
|
const visitor = await createVisitor(testDepartment2._id);
|
|
const room = await createLivechatRoom(visitor.token);
|
|
visitorsToDelete.push(visitor);
|
|
roomsToClose.push(room);
|
|
|
|
await sleep(5000);
|
|
const roomInfo = await getLivechatRoomInfo(room._id);
|
|
|
|
expect(roomInfo.servedBy).to.be.an('object');
|
|
expect(roomInfo.servedBy?._id).to.be.equal(testUser.user._id);
|
|
});
|
|
|
|
it('should not allow user to take a chat on department B when is on the limit (user has 4 chats, 2 chats on department B)', async () => {
|
|
const visitor = await createVisitor(testDepartment2._id);
|
|
const room = await createLivechatRoom(visitor.token);
|
|
visitorsToDelete.push(visitor);
|
|
roomsToClose.push(room);
|
|
|
|
await sleep(5000);
|
|
const roomInfo = await getLivechatRoomInfo(room._id);
|
|
|
|
expect(roomInfo.servedBy).to.be.undefined;
|
|
previousChat = room._id;
|
|
});
|
|
|
|
it('should not allow user to take a chat on department B even if global limit allows it (user has 4 chats)', async () => {
|
|
await updateEESetting('Livechat_maximum_chats_per_agent', 6);
|
|
|
|
await sleep(5000);
|
|
const roomInfo = await getLivechatRoomInfo(previousChat);
|
|
|
|
expect(roomInfo.servedBy).to.be.undefined;
|
|
});
|
|
it('should allow user to take a chat when department B limit is removed and its below global limit (user has 4 chats)', async () => {
|
|
await updateDepartment({ departmentId: testDepartment2._id, opts: { maxNumberSimultaneousChat: 0 }, userCredentials: credentials });
|
|
await sleep(5000);
|
|
const roomInfo = await getLivechatRoomInfo(previousChat);
|
|
|
|
expect(roomInfo.servedBy).to.be.an('object');
|
|
expect(roomInfo.servedBy?._id).to.be.equal(testUser.user._id);
|
|
});
|
|
|
|
it('should allow user to take a chat on department B (user has 5 chats, global limit is 6, department limit is 0)', async () => {
|
|
const visitor = await createVisitor(testDepartment2._id);
|
|
const room = await createLivechatRoom(visitor.token);
|
|
visitorsToDelete.push(visitor);
|
|
roomsToClose.push(room);
|
|
|
|
await sleep(5000);
|
|
const roomInfo = await getLivechatRoomInfo(room._id);
|
|
|
|
expect(roomInfo.servedBy).to.be.an('object');
|
|
expect(roomInfo.servedBy?._id).to.be.equal(testUser.user._id);
|
|
});
|
|
|
|
it('should not allow user to take a chat on department B (user has 6 chats, global limit is 6, department limit is 0)', async () => {
|
|
const visitor = await createVisitor(testDepartment2._id);
|
|
const room = await createLivechatRoom(visitor.token);
|
|
visitorsToDelete.push(visitor);
|
|
roomsToClose.push(room);
|
|
|
|
await sleep(5000);
|
|
const roomInfo = await getLivechatRoomInfo(room._id);
|
|
|
|
expect(roomInfo.servedBy).to.be.undefined;
|
|
previousChat = room._id;
|
|
});
|
|
|
|
it('should allow user to take chat once the global limit is removed (user has 7 chats)', async () => {
|
|
await updateEESetting('Livechat_maximum_chats_per_agent', 0);
|
|
|
|
await sleep(5000);
|
|
const roomInfo = await getLivechatRoomInfo(previousChat);
|
|
|
|
expect(roomInfo.servedBy).to.be.an('object');
|
|
expect(roomInfo.servedBy?._id).to.be.equal(testUser.user._id);
|
|
});
|
|
|
|
it('should not allow user to take chat on department A (as limit for it hasnt changed)', async () => {
|
|
const visitor = await createVisitor(testDepartment._id);
|
|
const room = await createLivechatRoom(visitor.token);
|
|
visitorsToDelete.push(visitor);
|
|
roomsToClose.push(room);
|
|
|
|
await sleep(5000);
|
|
const roomInfo = await getLivechatRoomInfo(room._id);
|
|
|
|
expect(roomInfo.servedBy).to.be.undefined;
|
|
});
|
|
|
|
it('should allow user to take a chat on department A when its limit gets removed (no agent, global or department filter are applied)', async () => {
|
|
await updateDepartment({ departmentId: testDepartment._id, opts: { maxNumberSimultaneousChat: 0 }, userCredentials: credentials });
|
|
|
|
await sleep(5000);
|
|
const roomInfo = await getLivechatRoomInfo(previousChat);
|
|
|
|
expect(roomInfo.servedBy).to.be.an('object');
|
|
expect(roomInfo.servedBy?._id).to.be.equal(testUser.user._id);
|
|
});
|
|
|
|
it('should honor agent limit over global limit when both are set (user has 8 chats)', async () => {
|
|
await updateEESetting('Livechat_maximum_chats_per_agent', 100000);
|
|
await updateLivechatSettingsForUser(testUser.user._id, { maxNumberSimultaneousChat: 4 }, [testDepartment._id, testDepartment2._id]);
|
|
|
|
const visitor = await createVisitor(testDepartment._id);
|
|
const room = await createLivechatRoom(visitor.token);
|
|
visitorsToDelete.push(visitor);
|
|
roomsToClose.push(room);
|
|
|
|
await sleep(5000);
|
|
const roomInfo = await getLivechatRoomInfo(room._id);
|
|
|
|
expect(roomInfo.servedBy).to.be.undefined;
|
|
previousChat = room._id;
|
|
});
|
|
|
|
// We already tested this case but this way the queue ends up empty :)
|
|
it('should receive the chat after agent limit is removed', async () => {
|
|
await updateLivechatSettingsForUser(testUser.user._id, { maxNumberSimultaneousChat: 0 }, [testDepartment._id, testDepartment2._id]);
|
|
|
|
await sleep(5000);
|
|
const roomInfo = await getLivechatRoomInfo(previousChat);
|
|
|
|
expect(roomInfo.servedBy).to.be.an('object');
|
|
expect(roomInfo.servedBy?._id).to.be.equal(testUser.user._id);
|
|
});
|
|
});
|
|
|
|
// Note: didn't add for LoadRotation as everything that changes is how the agent is selected
|
|
// but the limits applicable are the same as load balance and autoselection
|
|
(IS_EE ? describe : describe.skip)('Livechat - Chat limits - LoadBalance', () => {
|
|
let testUser: { user: IUser; credentials: Credentials };
|
|
let testUser2: { user: IUser; credentials: Credentials };
|
|
let testDepartment: ILivechatDepartment;
|
|
let testDepartment2: ILivechatDepartment;
|
|
let testDepartment3: ILivechatDepartment;
|
|
const roomsToClose: IOmnichannelRoom[] = [];
|
|
const visitorsToDelete: ILivechatVisitor[] = [];
|
|
|
|
before((done) => getCredentials(done));
|
|
|
|
before(async () =>
|
|
Promise.all([
|
|
updateSetting('Livechat_enabled', true),
|
|
updateSetting('Livechat_Routing_Method', 'Load_Balancing'),
|
|
updateSetting('Omnichannel_enable_department_removal', true),
|
|
updateEESetting('Livechat_maximum_chats_per_agent', 0),
|
|
updateSetting('Omnichannel_queue_delay_timeout', 3),
|
|
updateEESetting('Livechat_waiting_queue', true),
|
|
]),
|
|
);
|
|
|
|
before(async () => {
|
|
const user = await createUser();
|
|
const user2 = await createUser();
|
|
await createAgent(user.username);
|
|
await createAgent(user2.username);
|
|
const credentials3 = await login(user.username, password);
|
|
const credentials4 = await login(user2.username, password);
|
|
await makeAgentAvailable(credentials3);
|
|
await makeAgentAvailable(credentials4);
|
|
|
|
await updatePermission('transfer-livechat-guest', ['livechat-agent']);
|
|
|
|
testUser = {
|
|
user,
|
|
credentials: credentials3,
|
|
};
|
|
testUser2 = {
|
|
user: user2,
|
|
credentials: credentials4,
|
|
};
|
|
});
|
|
|
|
before(async () => {
|
|
testDepartment = await createDepartment([{ agentId: testUser.user._id }], `${new Date().toISOString()}-department`, true, {
|
|
maxNumberSimultaneousChat: 2,
|
|
});
|
|
testDepartment2 = await createDepartment([{ agentId: testUser.user._id }], `${new Date().toISOString()}-department2`, true, {
|
|
maxNumberSimultaneousChat: 2,
|
|
});
|
|
testDepartment3 = await createDepartment(
|
|
[{ agentId: testUser.user._id }, { agentId: testUser2.user._id }],
|
|
`${new Date().toISOString()}-department3`,
|
|
true,
|
|
{
|
|
maxNumberSimultaneousChat: 2,
|
|
},
|
|
);
|
|
|
|
await updateLivechatSettingsForUser(testUser.user._id, { maxNumberSimultaneousChat: 1 }, [
|
|
testDepartment._id,
|
|
testDepartment2._id,
|
|
testDepartment3._id,
|
|
]);
|
|
await updateLivechatSettingsForUser(testUser2.user._id, { maxNumberSimultaneousChat: 1 }, [testDepartment3._id]);
|
|
});
|
|
|
|
after(async () => {
|
|
await Promise.all(roomsToClose.map((room) => closeOmnichannelRoom(room._id)));
|
|
await Promise.all(visitorsToDelete.map((visitor) => deleteVisitor(visitor.token)));
|
|
await Promise.all([
|
|
deleteUser(testUser.user),
|
|
deleteUser(testUser2.user),
|
|
updateEESetting('Livechat_maximum_chats_per_agent', 0),
|
|
updateEESetting('Livechat_waiting_queue', false),
|
|
updateSetting('Livechat_Routing_Method', 'Auto_Selection'),
|
|
updateSetting('Omnichannel_queue_delay_timeout', 5),
|
|
deleteDepartment(testDepartment._id),
|
|
deleteDepartment(testDepartment2._id),
|
|
deleteDepartment(testDepartment3._id),
|
|
]);
|
|
await updateSetting('Omnichannel_enable_department_removal', false);
|
|
});
|
|
|
|
it('should allow a user to take a chat on a department since agent limit is set to 1 and department limit is set to 2 (agent has 0 chats)', async () => {
|
|
const visitor = await createVisitor(testDepartment._id);
|
|
const room = await createLivechatRoom(visitor.token);
|
|
visitorsToDelete.push(visitor);
|
|
roomsToClose.push(room);
|
|
|
|
await sleep(5000);
|
|
|
|
const roomInfo = await getLivechatRoomInfo(room._id);
|
|
|
|
expect(roomInfo.servedBy).to.be.an('object');
|
|
expect(roomInfo.servedBy?._id).to.be.equal(testUser.user._id);
|
|
});
|
|
|
|
let previousChat: string;
|
|
it('should not allow a user to take a chat on a department since agent limit is set to 1 and department limit is set to 2 (agent has 1 chat)', async () => {
|
|
const visitor = await createVisitor(testDepartment._id);
|
|
const room = await createLivechatRoom(visitor.token);
|
|
visitorsToDelete.push(visitor);
|
|
roomsToClose.push(room);
|
|
|
|
await sleep(5000);
|
|
|
|
const roomInfo = await getLivechatRoomInfo(room._id);
|
|
|
|
expect(roomInfo.servedBy).to.be.undefined;
|
|
previousChat = room._id;
|
|
});
|
|
|
|
it('should allow a user to take a chat on a department when agent limit is increased to 2 and department limit is set to 2 (agent has 1 chat)', async () => {
|
|
await updateLivechatSettingsForUser(testUser.user._id, { maxNumberSimultaneousChat: 2 }, [testDepartment._id, testDepartment2._id]);
|
|
await sleep(5000);
|
|
const roomInfo = await getLivechatRoomInfo(previousChat);
|
|
|
|
expect(roomInfo.servedBy).to.be.an('object');
|
|
expect(roomInfo.servedBy?._id).to.be.equal(testUser.user._id);
|
|
});
|
|
|
|
it('should not allow user to take chat on department B when agent limit is 2 and already has 2 chats', async () => {
|
|
const visitor = await createVisitor(testDepartment2._id);
|
|
const room = await createLivechatRoom(visitor.token);
|
|
visitorsToDelete.push(visitor);
|
|
roomsToClose.push(room);
|
|
|
|
await sleep(5000);
|
|
|
|
const roomInfo = await getLivechatRoomInfo(room._id);
|
|
|
|
expect(roomInfo.servedBy).to.be.undefined;
|
|
previousChat = room._id;
|
|
});
|
|
|
|
it('should allow user to take a chat on department B when agent limit is increased to 3 and user has 2 chats on department A', async () => {
|
|
await updateLivechatSettingsForUser(testUser.user._id, { maxNumberSimultaneousChat: 3 }, [testDepartment._id, testDepartment2._id]);
|
|
|
|
await sleep(5000);
|
|
const roomInfo = await getLivechatRoomInfo(previousChat);
|
|
|
|
expect(roomInfo.servedBy).to.be.an('object');
|
|
expect(roomInfo.servedBy?._id).to.be.equal(testUser.user._id);
|
|
});
|
|
|
|
it('should allow a user to take a chat on department B when agent limit is 0 and department B limit is 2 (user has 3 chats)', async () => {
|
|
await updateLivechatSettingsForUser(testUser.user._id, { maxNumberSimultaneousChat: 0 }, [testDepartment._id, testDepartment2._id]);
|
|
const visitor = await createVisitor(testDepartment2._id);
|
|
const room = await createLivechatRoom(visitor.token);
|
|
visitorsToDelete.push(visitor);
|
|
roomsToClose.push(room);
|
|
|
|
await sleep(5000);
|
|
const roomInfo = await getLivechatRoomInfo(room._id);
|
|
|
|
expect(roomInfo.servedBy).to.be.an('object');
|
|
expect(roomInfo.servedBy?._id).to.be.equal(testUser.user._id);
|
|
});
|
|
|
|
it('should not allow user to take a chat on department B when is on the limit (user has 4 chats, 2 chats on department B)', async () => {
|
|
const visitor = await createVisitor(testDepartment2._id);
|
|
const room = await createLivechatRoom(visitor.token);
|
|
visitorsToDelete.push(visitor);
|
|
roomsToClose.push(room);
|
|
|
|
await sleep(5000);
|
|
const roomInfo = await getLivechatRoomInfo(room._id);
|
|
|
|
expect(roomInfo.servedBy).to.be.undefined;
|
|
previousChat = room._id;
|
|
});
|
|
|
|
it('should not allow user to take a chat on department B even if global limit allows it (user has 4 chats)', async () => {
|
|
await updateEESetting('Livechat_maximum_chats_per_agent', 6);
|
|
|
|
await sleep(5000);
|
|
const roomInfo = await getLivechatRoomInfo(previousChat);
|
|
|
|
expect(roomInfo.servedBy).to.be.undefined;
|
|
});
|
|
it('should allow user to take a chat when department B limit is removed and its below global limit (user has 4 chats)', async () => {
|
|
await updateDepartment({ departmentId: testDepartment2._id, opts: { maxNumberSimultaneousChat: 0 }, userCredentials: credentials });
|
|
await sleep(5000);
|
|
const roomInfo = await getLivechatRoomInfo(previousChat);
|
|
|
|
expect(roomInfo.servedBy).to.be.an('object');
|
|
expect(roomInfo.servedBy?._id).to.be.equal(testUser.user._id);
|
|
});
|
|
|
|
it('should allow user to take a chat on department B (user has 5 chats, global limit is 6, department limit is 0)', async () => {
|
|
const visitor = await createVisitor(testDepartment2._id);
|
|
const room = await createLivechatRoom(visitor.token);
|
|
visitorsToDelete.push(visitor);
|
|
roomsToClose.push(room);
|
|
|
|
await sleep(5000);
|
|
const roomInfo = await getLivechatRoomInfo(room._id);
|
|
|
|
expect(roomInfo.servedBy).to.be.an('object');
|
|
expect(roomInfo.servedBy?._id).to.be.equal(testUser.user._id);
|
|
});
|
|
|
|
it('should not allow user to take a chat on department B (user has 6 chats, global limit is 6, department limit is 0)', async () => {
|
|
const visitor = await createVisitor(testDepartment2._id);
|
|
const room = await createLivechatRoom(visitor.token);
|
|
visitorsToDelete.push(visitor);
|
|
roomsToClose.push(room);
|
|
|
|
await sleep(5000);
|
|
const roomInfo = await getLivechatRoomInfo(room._id);
|
|
|
|
expect(roomInfo.servedBy).to.be.undefined;
|
|
previousChat = room._id;
|
|
});
|
|
|
|
it('should allow user to take chat once the global limit is removed (user has 7 chats)', async () => {
|
|
await updateEESetting('Livechat_maximum_chats_per_agent', 0);
|
|
|
|
await sleep(5000);
|
|
const roomInfo = await getLivechatRoomInfo(previousChat);
|
|
|
|
expect(roomInfo.servedBy).to.be.an('object');
|
|
expect(roomInfo.servedBy?._id).to.be.equal(testUser.user._id);
|
|
});
|
|
|
|
it('should not allow user to take chat on department A (as limit for it hasnt changed)', async () => {
|
|
const visitor = await createVisitor(testDepartment._id);
|
|
const room = await createLivechatRoom(visitor.token);
|
|
visitorsToDelete.push(visitor);
|
|
roomsToClose.push(room);
|
|
|
|
await sleep(5000);
|
|
const roomInfo = await getLivechatRoomInfo(room._id);
|
|
|
|
expect(roomInfo.servedBy).to.be.undefined;
|
|
});
|
|
|
|
it('should allow user to take a chat on department A when its limit gets removed (no agent, global or department filter are applied)', async () => {
|
|
await updateDepartment({ departmentId: testDepartment._id, opts: { maxNumberSimultaneousChat: 0 }, userCredentials: credentials });
|
|
|
|
await sleep(5000);
|
|
const roomInfo = await getLivechatRoomInfo(previousChat);
|
|
|
|
expect(roomInfo.servedBy).to.be.an('object');
|
|
expect(roomInfo.servedBy?._id).to.be.equal(testUser.user._id);
|
|
});
|
|
|
|
it('should honor agent limit over global limit when both are set (user has 8 chats)', async () => {
|
|
await updateEESetting('Livechat_maximum_chats_per_agent', 100000);
|
|
await updateLivechatSettingsForUser(testUser.user._id, { maxNumberSimultaneousChat: 4 }, [testDepartment._id, testDepartment2._id]);
|
|
|
|
const visitor = await createVisitor(testDepartment._id);
|
|
const room = await createLivechatRoom(visitor.token);
|
|
visitorsToDelete.push(visitor);
|
|
roomsToClose.push(room);
|
|
|
|
await sleep(5000);
|
|
const roomInfo = await getLivechatRoomInfo(room._id);
|
|
|
|
expect(roomInfo.servedBy).to.be.undefined;
|
|
previousChat = room._id;
|
|
});
|
|
|
|
// We already tested this case but this way the queue ends up empty :)
|
|
it('should receive the chat after agent limit is removed', async () => {
|
|
await updateLivechatSettingsForUser(testUser.user._id, { maxNumberSimultaneousChat: 0 }, [testDepartment._id, testDepartment2._id]);
|
|
|
|
await sleep(5000);
|
|
const roomInfo = await getLivechatRoomInfo(previousChat);
|
|
|
|
expect(roomInfo.servedBy).to.be.an('object');
|
|
expect(roomInfo.servedBy?._id).to.be.equal(testUser.user._id);
|
|
});
|
|
|
|
it('should route the chat to another agent if limit for agent A is reached and agent B is available', async () => {
|
|
await updateLivechatSettingsForUser(testUser.user._id, { maxNumberSimultaneousChat: 1 }, [
|
|
testDepartment._id,
|
|
testDepartment2._id,
|
|
testDepartment3._id,
|
|
]);
|
|
|
|
const visitor = await createVisitor(testDepartment3._id);
|
|
const room = await createLivechatRoom(visitor.token);
|
|
visitorsToDelete.push(visitor);
|
|
roomsToClose.push(room);
|
|
|
|
await sleep(5000);
|
|
const roomInfo = await getLivechatRoomInfo(room._id);
|
|
|
|
expect(roomInfo.servedBy).to.be.an('object');
|
|
expect(roomInfo.servedBy?._id).to.be.equal(testUser2.user._id);
|
|
});
|
|
|
|
describe('when forwarding a chat to an agent already at their limit', () => {
|
|
let forwardingRoom: { _id: string };
|
|
let otherRoom: { _id: string };
|
|
let visitor1: ILivechatVisitor;
|
|
let visitor2: ILivechatVisitor;
|
|
let forwardingDept: ILivechatDepartment;
|
|
let forwardUserA: { user: IUser; credentials: Credentials };
|
|
let forwardUserB: { user: IUser; credentials: Credentials };
|
|
|
|
before(async () => {
|
|
await updateSetting('Livechat_Routing_Method', 'Manual_Selection');
|
|
|
|
const userA = await createUser();
|
|
const userB = await createUser();
|
|
|
|
await createAgent(userA.username);
|
|
await createAgent(userB.username);
|
|
|
|
const credA = await login(userA.username, password);
|
|
const credB = await login(userB.username, password);
|
|
|
|
await makeAgentAvailable(credA);
|
|
await makeAgentAvailable(credB);
|
|
|
|
forwardUserA = { user: userA, credentials: credA };
|
|
forwardUserB = { user: userB, credentials: credB };
|
|
|
|
forwardingDept = await createDepartment(
|
|
[{ agentId: forwardUserA.user._id }, { agentId: forwardUserB.user._id }],
|
|
`${new Date().toISOString()}-forward-limit`,
|
|
true,
|
|
{
|
|
maxNumberSimultaneousChat: 1,
|
|
},
|
|
);
|
|
|
|
await updateLivechatSettingsForUser(forwardUserA.user._id, { maxNumberSimultaneousChat: 1 }, [forwardingDept._id]);
|
|
await updateLivechatSettingsForUser(forwardUserB.user._id, { maxNumberSimultaneousChat: 1 }, [forwardingDept._id]);
|
|
|
|
// Force agent A to take a room on the dedicated department
|
|
const { room: room1, visitor } = await startANewLivechatRoomAndTakeIt({
|
|
departmentId: forwardingDept._id,
|
|
agent: forwardUserA.credentials,
|
|
});
|
|
visitor1 = visitor;
|
|
|
|
const roomInfo1 = await getLivechatRoomInfo(room1._id);
|
|
expect(roomInfo1.servedBy).to.be.an('object');
|
|
expect(roomInfo1.servedBy?._id).to.be.equal(forwardUserA.user._id);
|
|
otherRoom = room1;
|
|
});
|
|
|
|
before(async () => {
|
|
// Force agent B to take another room on the same department
|
|
const { room: room2, visitor } = await startANewLivechatRoomAndTakeIt({
|
|
departmentId: forwardingDept!._id,
|
|
agent: forwardUserB.credentials,
|
|
});
|
|
visitor2 = visitor;
|
|
|
|
const roomInfo2 = await getLivechatRoomInfo(room2._id);
|
|
expect(roomInfo2.servedBy).to.be.an('object');
|
|
expect(roomInfo2.servedBy?._id).to.be.equal(forwardUserB.user._id);
|
|
|
|
forwardingRoom = room2;
|
|
});
|
|
|
|
after(async () => {
|
|
await closeOmnichannelRoom(forwardingRoom._id);
|
|
await closeOmnichannelRoom(otherRoom._id);
|
|
await deleteDepartment(forwardingDept._id);
|
|
await deleteVisitor(visitor1._id);
|
|
await deleteVisitor(visitor2._id);
|
|
await deleteUser(forwardUserA.user);
|
|
await deleteUser(forwardUserB.user);
|
|
});
|
|
|
|
it('should not allow forwarding and should not add system messages to the room', async () => {
|
|
const res = await request.post(api('livechat/room.forward')).set(forwardUserB.credentials).send({
|
|
roomId: forwardingRoom._id,
|
|
userId: forwardUserA.user._id,
|
|
clientAction: true,
|
|
comment: 'forward to agent at limit',
|
|
});
|
|
|
|
expect(res.status).to.equal(400);
|
|
expect(res.body).to.have.property('success', false);
|
|
|
|
const messagesResponse = await request.get(api('channels.messages')).set(credentials).query({ roomId: forwardingRoom._id });
|
|
|
|
expect(messagesResponse.status).to.equal(200);
|
|
expect(messagesResponse.body).to.have.property('messages');
|
|
const systemMessages = messagesResponse.body.messages.filter((msg: any) => msg.t === 'livechat_transfer_history');
|
|
expect(systemMessages).to.have.length(0);
|
|
});
|
|
|
|
it('should allow forwarding with the waiting queue disabled', async () => {
|
|
await updateEESetting('Livechat_waiting_queue', false);
|
|
|
|
const res = await request.post(api('livechat/room.forward')).set(forwardUserB.credentials).send({
|
|
roomId: forwardingRoom._id,
|
|
userId: forwardUserA.user._id,
|
|
clientAction: true,
|
|
comment: 'forward to agent at limit with waiting queue disabled',
|
|
});
|
|
|
|
expect(res.status).to.equal(200);
|
|
expect(res.body).to.have.property('success', true);
|
|
|
|
const messagesResponse = await request.get(api('channels.messages')).set(credentials).query({ roomId: forwardingRoom._id });
|
|
|
|
expect(messagesResponse.status).to.equal(200);
|
|
expect(messagesResponse.body).to.have.property('messages');
|
|
const systemMessages = messagesResponse.body.messages.filter((msg: any) => msg.t === 'livechat_transfer_history');
|
|
expect(systemMessages).to.have.length.greaterThan(0);
|
|
});
|
|
});
|
|
});
|
|
|
|
(IS_EE ? describe : describe.skip)('Livechat - Chat limits - Manual Selection', () => {
|
|
let manualUser: { user: IUser; credentials: Credentials };
|
|
let manualDepartment: ILivechatDepartment;
|
|
let manualDepartment2: ILivechatDepartment;
|
|
const manualRoomsToClose: IOmnichannelRoom[] = [];
|
|
const manualVisitorsToDelete: ILivechatVisitor[] = [];
|
|
|
|
before((done) => getCredentials(done));
|
|
|
|
before(async () => {
|
|
await Promise.all([
|
|
updateSetting('Livechat_enabled', true),
|
|
updateSetting('Livechat_Routing_Method', 'Manual_Selection'),
|
|
updateSetting('Omnichannel_enable_department_removal', true),
|
|
updateEESetting('Livechat_maximum_chats_per_agent', 0),
|
|
updateEESetting('Livechat_waiting_queue', true),
|
|
]);
|
|
|
|
await sleep(1000);
|
|
});
|
|
|
|
before(async () => {
|
|
const user = await createUser();
|
|
await createAgent(user.username);
|
|
const creds = await login(user.username, password);
|
|
await makeAgentAvailable(creds);
|
|
|
|
manualUser = { user, credentials: creds };
|
|
});
|
|
|
|
before(async () => {
|
|
manualDepartment = await createDepartment([{ agentId: manualUser.user._id }], `${new Date().toISOString()}-manual-dept`, true, {
|
|
maxNumberSimultaneousChat: 2,
|
|
});
|
|
manualDepartment2 = await createDepartment([{ agentId: manualUser.user._id }], `${new Date().toISOString()}-manual-dept2`, true, {
|
|
maxNumberSimultaneousChat: 2,
|
|
});
|
|
await updateLivechatSettingsForUser(manualUser.user._id, { maxNumberSimultaneousChat: 1 }, [
|
|
manualDepartment._id,
|
|
manualDepartment2._id,
|
|
]);
|
|
});
|
|
|
|
after(async () => {
|
|
await Promise.all(manualRoomsToClose.map((room) => closeOmnichannelRoom(room._id)));
|
|
await Promise.all(manualVisitorsToDelete.map((visitor) => deleteVisitor(visitor.token)));
|
|
await Promise.all([
|
|
deleteUser(manualUser.user),
|
|
updateEESetting('Livechat_maximum_chats_per_agent', 0),
|
|
updateEESetting('Livechat_waiting_queue', false),
|
|
updateSetting('Livechat_Routing_Method', 'Auto_Selection'),
|
|
deleteDepartment(manualDepartment._id),
|
|
deleteDepartment(manualDepartment2._id),
|
|
]);
|
|
await updateSetting('Omnichannel_enable_department_removal', false);
|
|
});
|
|
|
|
describe('when agent limit is 1 and has 0 chats', () => {
|
|
let room: IOmnichannelRoom;
|
|
let visitor: ILivechatVisitor;
|
|
|
|
before(async () => {
|
|
visitor = await createVisitor(manualDepartment._id);
|
|
room = await createLivechatRoom(visitor.token);
|
|
manualVisitorsToDelete.push(visitor);
|
|
manualRoomsToClose.push(room);
|
|
});
|
|
|
|
it('should allow agent to manually take the inquiry', async () => {
|
|
const inquiry = await fetchInquiry(room._id);
|
|
await takeInquiry(inquiry._id, manualUser.credentials);
|
|
|
|
const roomInfo = await getLivechatRoomInfo(room._id);
|
|
expect(roomInfo.servedBy).to.be.an('object');
|
|
expect(roomInfo.servedBy?._id).to.be.equal(manualUser.user._id);
|
|
});
|
|
});
|
|
|
|
describe('when agent limit is 1 and has 1 chat', () => {
|
|
let room: IOmnichannelRoom;
|
|
let visitor: ILivechatVisitor;
|
|
|
|
before(async () => {
|
|
visitor = await createVisitor(manualDepartment._id);
|
|
room = await createLivechatRoom(visitor.token);
|
|
manualVisitorsToDelete.push(visitor);
|
|
manualRoomsToClose.push(room);
|
|
});
|
|
|
|
it('should not allow agent to manually take the inquiry', async () => {
|
|
const inquiry = await fetchInquiry(room._id);
|
|
|
|
await request
|
|
.post(api('livechat/inquiries.take'))
|
|
.set(manualUser.credentials)
|
|
.send({ userId: manualUser.user._id, inquiryId: inquiry._id, options: { clientAction: true } })
|
|
.expect(400);
|
|
|
|
const roomInfo = await getLivechatRoomInfo(room._id);
|
|
expect(roomInfo.servedBy).to.be.undefined;
|
|
});
|
|
|
|
describe('when agent limit is increased to 2', () => {
|
|
before(async () => {
|
|
await updateLivechatSettingsForUser(manualUser.user._id, { maxNumberSimultaneousChat: 2 }, [
|
|
manualDepartment._id,
|
|
manualDepartment2._id,
|
|
]);
|
|
});
|
|
|
|
it('should allow agent to take the pending inquiry', async () => {
|
|
const inquiry = await fetchInquiry(room._id);
|
|
await takeInquiry(inquiry._id, manualUser.credentials);
|
|
|
|
const roomInfo = await getLivechatRoomInfo(room._id);
|
|
expect(roomInfo.servedBy).to.be.an('object');
|
|
expect(roomInfo.servedBy?._id).to.be.equal(manualUser.user._id);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('when agent limit is 2 and already has 2 chats on department A', () => {
|
|
let room: IOmnichannelRoom;
|
|
let visitor: ILivechatVisitor;
|
|
|
|
before(async () => {
|
|
visitor = await createVisitor(manualDepartment2._id);
|
|
room = await createLivechatRoom(visitor.token);
|
|
manualVisitorsToDelete.push(visitor);
|
|
manualRoomsToClose.push(room);
|
|
});
|
|
|
|
it('should not allow agent to take inquiry on department B', async () => {
|
|
const inquiry = await fetchInquiry(room._id);
|
|
|
|
await request
|
|
.post(api('livechat/inquiries.take'))
|
|
.set(manualUser.credentials)
|
|
.send({ userId: manualUser.user._id, inquiryId: inquiry._id, options: { clientAction: true } })
|
|
.expect(400);
|
|
|
|
const roomInfo = await getLivechatRoomInfo(room._id);
|
|
expect(roomInfo.servedBy).to.be.undefined;
|
|
});
|
|
|
|
describe('when agent limit is increased to 3', () => {
|
|
before(async () => {
|
|
await updateLivechatSettingsForUser(manualUser.user._id, { maxNumberSimultaneousChat: 3 }, [
|
|
manualDepartment._id,
|
|
manualDepartment2._id,
|
|
]);
|
|
});
|
|
|
|
it('should allow agent to take the pending inquiry on department B', async () => {
|
|
const inquiry = await fetchInquiry(room._id);
|
|
await takeInquiry(inquiry._id, manualUser.credentials);
|
|
|
|
const roomInfo = await getLivechatRoomInfo(room._id);
|
|
expect(roomInfo.servedBy).to.be.an('object');
|
|
expect(roomInfo.servedBy?._id).to.be.equal(manualUser.user._id);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('when agent limit is 0 and department B limit is 2 (agent has 3 chats)', () => {
|
|
let room: IOmnichannelRoom;
|
|
let visitor: ILivechatVisitor;
|
|
|
|
before(async () => {
|
|
await updateLivechatSettingsForUser(manualUser.user._id, { maxNumberSimultaneousChat: 0 }, [
|
|
manualDepartment._id,
|
|
manualDepartment2._id,
|
|
]);
|
|
|
|
visitor = await createVisitor(manualDepartment2._id);
|
|
room = await createLivechatRoom(visitor.token);
|
|
manualVisitorsToDelete.push(visitor);
|
|
manualRoomsToClose.push(room);
|
|
});
|
|
|
|
it('should allow agent to take inquiry on department B', async () => {
|
|
const inquiry = await fetchInquiry(room._id);
|
|
await takeInquiry(inquiry._id, manualUser.credentials);
|
|
|
|
const roomInfo = await getLivechatRoomInfo(room._id);
|
|
expect(roomInfo.servedBy).to.be.an('object');
|
|
expect(roomInfo.servedBy?._id).to.be.equal(manualUser.user._id);
|
|
});
|
|
});
|
|
|
|
describe('when agent has 4 chats and 2 on department B (at department limit)', () => {
|
|
let room: IOmnichannelRoom;
|
|
let visitor: ILivechatVisitor;
|
|
|
|
before(async () => {
|
|
visitor = await createVisitor(manualDepartment2._id);
|
|
room = await createLivechatRoom(visitor.token);
|
|
manualVisitorsToDelete.push(visitor);
|
|
manualRoomsToClose.push(room);
|
|
});
|
|
|
|
it('should not allow agent to take inquiry on department B', async () => {
|
|
const inquiry = await fetchInquiry(room._id);
|
|
|
|
await request
|
|
.post(api('livechat/inquiries.take'))
|
|
.set(manualUser.credentials)
|
|
.send({ userId: manualUser.user._id, inquiryId: inquiry._id, options: { clientAction: true } })
|
|
.expect(400);
|
|
|
|
const roomInfo = await getLivechatRoomInfo(room._id);
|
|
expect(roomInfo.servedBy).to.be.undefined;
|
|
});
|
|
|
|
describe('when global limit is set to 6', () => {
|
|
before(async () => {
|
|
await updateEESetting('Livechat_maximum_chats_per_agent', 6);
|
|
});
|
|
|
|
it('should not allow agent to take inquiry on department B even if global limit allows it', async () => {
|
|
const inquiry = await fetchInquiry(room._id);
|
|
|
|
await request
|
|
.post(api('livechat/inquiries.take'))
|
|
.set(manualUser.credentials)
|
|
.send({ userId: manualUser.user._id, inquiryId: inquiry._id, options: { clientAction: true } })
|
|
.expect(400);
|
|
|
|
const roomInfo = await getLivechatRoomInfo(room._id);
|
|
expect(roomInfo.servedBy).to.be.undefined;
|
|
});
|
|
|
|
describe('when department B limit is removed', () => {
|
|
before(async () => {
|
|
await updateDepartment({
|
|
departmentId: manualDepartment2._id,
|
|
opts: { maxNumberSimultaneousChat: 0 },
|
|
userCredentials: credentials,
|
|
});
|
|
});
|
|
|
|
it('should allow agent to take the pending inquiry', async () => {
|
|
const inquiry = await fetchInquiry(room._id);
|
|
await takeInquiry(inquiry._id, manualUser.credentials);
|
|
|
|
const roomInfo = await getLivechatRoomInfo(room._id);
|
|
expect(roomInfo.servedBy).to.be.an('object');
|
|
expect(roomInfo.servedBy?._id).to.be.equal(manualUser.user._id);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('when agent has 5 chats, global limit is 6, department limit is 0', () => {
|
|
let room: IOmnichannelRoom;
|
|
let visitor: ILivechatVisitor;
|
|
|
|
before(async () => {
|
|
visitor = await createVisitor(manualDepartment2._id);
|
|
room = await createLivechatRoom(visitor.token);
|
|
manualVisitorsToDelete.push(visitor);
|
|
manualRoomsToClose.push(room);
|
|
});
|
|
|
|
it('should allow agent to take inquiry on department B', async () => {
|
|
const inquiry = await fetchInquiry(room._id);
|
|
await takeInquiry(inquiry._id, manualUser.credentials);
|
|
|
|
const roomInfo = await getLivechatRoomInfo(room._id);
|
|
expect(roomInfo.servedBy).to.be.an('object');
|
|
expect(roomInfo.servedBy?._id).to.be.equal(manualUser.user._id);
|
|
});
|
|
});
|
|
|
|
describe('when agent has 6 chats, global limit is 6, department limit is 0', () => {
|
|
let room: IOmnichannelRoom;
|
|
let visitor: ILivechatVisitor;
|
|
|
|
before(async () => {
|
|
visitor = await createVisitor(manualDepartment2._id);
|
|
room = await createLivechatRoom(visitor.token);
|
|
manualVisitorsToDelete.push(visitor);
|
|
manualRoomsToClose.push(room);
|
|
});
|
|
|
|
it('should not allow agent to take inquiry on department B', async () => {
|
|
const inquiry = await fetchInquiry(room._id);
|
|
|
|
await request
|
|
.post(api('livechat/inquiries.take'))
|
|
.set(manualUser.credentials)
|
|
.send({ userId: manualUser.user._id, inquiryId: inquiry._id, options: { clientAction: true } })
|
|
.expect(400);
|
|
|
|
const roomInfo = await getLivechatRoomInfo(room._id);
|
|
expect(roomInfo.servedBy).to.be.undefined;
|
|
});
|
|
|
|
describe('when global limit is removed', () => {
|
|
before(async () => {
|
|
await updateEESetting('Livechat_maximum_chats_per_agent', 0);
|
|
});
|
|
|
|
it('should allow agent to take the pending inquiry', async () => {
|
|
const inquiry = await fetchInquiry(room._id);
|
|
await takeInquiry(inquiry._id, manualUser.credentials);
|
|
|
|
const roomInfo = await getLivechatRoomInfo(room._id);
|
|
expect(roomInfo.servedBy).to.be.an('object');
|
|
expect(roomInfo.servedBy?._id).to.be.equal(manualUser.user._id);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('when department A limit is still 2 (agent has 7 chats)', () => {
|
|
let room: IOmnichannelRoom;
|
|
let visitor: ILivechatVisitor;
|
|
|
|
before(async () => {
|
|
visitor = await createVisitor(manualDepartment._id);
|
|
room = await createLivechatRoom(visitor.token);
|
|
manualVisitorsToDelete.push(visitor);
|
|
manualRoomsToClose.push(room);
|
|
});
|
|
|
|
it('should not allow agent to take inquiry on department A', async () => {
|
|
const inquiry = await fetchInquiry(room._id);
|
|
|
|
await request
|
|
.post(api('livechat/inquiries.take'))
|
|
.set(manualUser.credentials)
|
|
.send({ userId: manualUser.user._id, inquiryId: inquiry._id, options: { clientAction: true } })
|
|
.expect(400);
|
|
|
|
const roomInfo = await getLivechatRoomInfo(room._id);
|
|
expect(roomInfo.servedBy).to.be.undefined;
|
|
});
|
|
|
|
describe('when department A limit is removed', () => {
|
|
before(async () => {
|
|
await updateDepartment({
|
|
departmentId: manualDepartment._id,
|
|
opts: { maxNumberSimultaneousChat: 0 },
|
|
userCredentials: credentials,
|
|
});
|
|
});
|
|
|
|
it('should allow agent to take the pending inquiry on department A', async () => {
|
|
const inquiry = await fetchInquiry(room._id);
|
|
await takeInquiry(inquiry._id, manualUser.credentials);
|
|
|
|
const roomInfo = await getLivechatRoomInfo(room._id);
|
|
expect(roomInfo.servedBy).to.be.an('object');
|
|
expect(roomInfo.servedBy?._id).to.be.equal(manualUser.user._id);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('when agent limit is set to 4 and global limit is high (agent has 8 chats)', () => {
|
|
let room: IOmnichannelRoom;
|
|
let visitor: ILivechatVisitor;
|
|
|
|
before(async () => {
|
|
await updateEESetting('Livechat_maximum_chats_per_agent', 100000);
|
|
await updateLivechatSettingsForUser(manualUser.user._id, { maxNumberSimultaneousChat: 4 }, [
|
|
manualDepartment._id,
|
|
manualDepartment2._id,
|
|
]);
|
|
|
|
visitor = await createVisitor(manualDepartment._id);
|
|
room = await createLivechatRoom(visitor.token);
|
|
manualVisitorsToDelete.push(visitor);
|
|
manualRoomsToClose.push(room);
|
|
});
|
|
|
|
it('should honor agent limit over global limit and not allow taking inquiry', async () => {
|
|
const inquiry = await fetchInquiry(room._id);
|
|
|
|
await request
|
|
.post(api('livechat/inquiries.take'))
|
|
.set(manualUser.credentials)
|
|
.send({ userId: manualUser.user._id, inquiryId: inquiry._id, options: { clientAction: true } })
|
|
.expect(400);
|
|
|
|
const roomInfo = await getLivechatRoomInfo(room._id);
|
|
expect(roomInfo.servedBy).to.be.undefined;
|
|
});
|
|
|
|
describe('when agent limit is removed', () => {
|
|
before(async () => {
|
|
await updateLivechatSettingsForUser(manualUser.user._id, { maxNumberSimultaneousChat: 0 }, [
|
|
manualDepartment._id,
|
|
manualDepartment2._id,
|
|
]);
|
|
});
|
|
|
|
it('should allow agent to take the pending inquiry', async () => {
|
|
const inquiry = await fetchInquiry(room._id);
|
|
await takeInquiry(inquiry._id, manualUser.credentials);
|
|
|
|
const roomInfo = await getLivechatRoomInfo(room._id);
|
|
expect(roomInfo.servedBy).to.be.an('object');
|
|
expect(roomInfo.servedBy?._id).to.be.equal(manualUser.user._id);
|
|
});
|
|
});
|
|
});
|
|
});
|