Files
upstream-mirror 30810eecd7
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
Code scanning - action / CodeQL-Build (push) Failing after 2s
Auto-close duplicate issues / auto-close-duplicates (push) Failing after 1s
snapshot of https://github.com/RocketChat/Rocket.Chat.git (develop, 2026-09-16; blobs > 131072B omitted)
2026-09-16 01:21:02 +05:00

789 lines
27 KiB
TypeScript

import type { Credentials } from '@rocket.chat/api-client';
import { UserStatus } from '@rocket.chat/core-typings';
import type { ILivechatVisitor, IOmnichannelRoom, ILivechatAgent, ILivechatDepartment, IRoom, IUser } from '@rocket.chat/core-typings';
import { Random } from '@rocket.chat/random';
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 { disableDefaultBusinessHour, makeDefaultBusinessHourActiveAndClosed } from '../../../data/livechat/businessHours';
import { createDepartment, deleteDepartment } from '../../../data/livechat/department';
import {
createAgent,
createManager,
createVisitor,
createLivechatRoom,
takeInquiry,
fetchInquiry,
makeAgentAvailable,
startANewLivechatRoomAndTakeIt,
moveBackToQueue,
closeOmnichannelRoom,
deleteVisitor,
} from '../../../data/livechat/rooms';
import {
removePermissionFromAllRoles,
restorePermissionToRoles,
updateEESetting,
updatePermission,
updateSetting,
} from '../../../data/permissions.helper';
import { password } from '../../../data/user';
import { createUser, deleteUser, getMe, login, setUserStatus } from '../../../data/users.helper';
import { IS_EE } from '../../../e2e/config/constants';
describe('LIVECHAT - Agents', () => {
let agent: ILivechatAgent;
let manager: ILivechatAgent;
let agent2: { user: IUser; credentials: Credentials };
before((done) => getCredentials(done));
before(async () => {
await updateSetting('Livechat_enabled', true);
await updateSetting('Livechat_Routing_Method', 'Manual_Selection');
await updateEESetting('Livechat_Require_Contact_Verification', 'never');
await updateSetting('Omnichannel_enable_department_removal', true);
agent = await createAgent();
manager = await createManager();
});
before(async () => {
const user = await createUser();
const userCredentials = await login(user.username, password);
await createAgent(user.username);
await makeAgentAvailable(userCredentials);
agent2 = {
user,
credentials: userCredentials,
};
});
after(async () => {
await updateSetting('Omnichannel_enable_department_removal', false);
await deleteUser(agent2.user);
});
// TODO: missing test cases for POST method
describe('GET livechat/users/:type', () => {
describe('with no permissions', () => {
before(async () => {
await updatePermission('edit-omnichannel-contact', []);
await updatePermission('transfer-livechat-guest', []);
await updatePermission('manage-livechat-agents', []);
});
after(async () => {
await updatePermission('edit-omnichannel-contact', ['admin']);
await updatePermission('transfer-livechat-guest', ['admin']);
await updatePermission('manage-livechat-agents', ['admin']);
});
it('should return an "unauthorized error" when the user does not have the necessary permission', async () => {
await request.get(api('livechat/users/agent')).set(credentials).expect('Content-Type', 'application/json').expect(403);
});
});
it('should throw an error when the type is invalid', async () => {
await request
.get(api('livechat/users/invalid-type'))
.set(credentials)
.expect('Content-Type', 'application/json')
.expect(400)
.expect((res: Response) => {
expect(res.body).to.have.property('success', false);
expect(res.body.error).to.be.equal('Invalid type');
});
});
it('should return an array of agents', async () => {
await request
.get(api('livechat/users/agent'))
.set(credentials)
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res: Response) => {
expect(res.body).to.have.property('success', true);
expect(res.body.users).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');
const agentRecentlyCreated = (res.body.users as ILivechatAgent[]).find((user) => agent._id === user._id);
expect(agentRecentlyCreated?._id).to.be.equal(agent._id);
});
});
it('should return an array of available agents', async () => {
await request
.get(api('livechat/users/agent'))
.set(credentials)
.expect('Content-Type', 'application/json')
.query({ onlyAvailable: true })
.expect(200)
.expect((res: Response) => {
expect(res.body).to.have.property('success', true);
expect(res.body.users).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');
expect(res.body.users.every((u: { statusLivechat: string }) => u.statusLivechat === 'available')).to.be.true;
});
});
it('should return an array of available/unavailable agents when onlyAvailable is false', async () => {
await request
.get(api('livechat/users/agent'))
.set(credentials)
.expect('Content-Type', 'application/json')
.query({ onlyAvailable: false })
.expect(200)
.expect((res: Response) => {
expect(res.body).to.have.property('success', true);
expect(res.body.users).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');
expect(
res.body.users.every(
(u: { statusLivechat: string }) => !u.statusLivechat || ['available', 'not-available'].includes(u.statusLivechat),
),
).to.be.true;
});
});
it('should return offline agents when showIdleAgents is true', async () => {
await setUserStatus(agent2.credentials, UserStatus.OFFLINE);
await request
.get(api('livechat/users/agent'))
.set(credentials)
.expect('Content-Type', 'application/json')
.query({ showIdleAgents: true })
.expect(200)
.expect((res: Response) => {
expect(res.body).to.have.property('success', true);
expect(res.body.users).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');
expect(
res.body.users.every(
(u: { status: UserStatus }) =>
!u.status || [UserStatus.ONLINE, UserStatus.OFFLINE, UserStatus.AWAY, UserStatus.BUSY].includes(u.status),
),
).to.be.true;
});
});
it('should return only online agents when showIdleAgents is false', async () => {
await setUserStatus(agent2.credentials, UserStatus.ONLINE);
await request
.get(api('livechat/users/agent'))
.set(credentials)
.expect('Content-Type', 'application/json')
.query({ showIdleAgents: false })
.expect(200)
.expect((res: Response) => {
expect(res.body).to.have.property('success', true);
expect(res.body.users).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');
expect(res.body.users.every((u: { status: UserStatus }) => u.status !== UserStatus.OFFLINE)).to.be.true;
});
});
it('should return an array of managers', async () => {
await request
.get(api('livechat/users/manager'))
.set(credentials)
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res: Response) => {
expect(res.body).to.have.property('success', true);
expect(res.body.users).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');
const managerRecentlyCreated = (res.body.users as ILivechatAgent[]).find((user) => manager._id === user._id);
expect(managerRecentlyCreated?._id).to.be.equal(manager._id);
});
});
});
describe('POST livechat/users/:type', () => {
describe('with no permission', () => {
before(async () => {
await updatePermission('view-livechat-manager', []);
});
after(async () => {
await updatePermission('view-livechat-manager', ['admin']);
});
it('should return an "unauthorized error" when the user does not have the necessary permission', async () => {
await request
.post(api('livechat/users/agent'))
.set(credentials)
.send({
username: 'test-agent',
})
.expect('Content-Type', 'application/json')
.expect(403);
});
});
it('should return an error when type is invalid', async () => {
await request
.post(api('livechat/users/invalid-type'))
.set(credentials)
.send({
username: 'test-agent',
})
.expect('Content-Type', 'application/json')
.expect(400);
});
it('should return an error when username is invalid', async () => {
await request
.post(api('livechat/users/agent'))
.set(credentials)
.send({
username: 'mr-not-valid',
})
.expect('Content-Type', 'application/json')
.expect(400);
});
it('should return a valid user when all goes fine', async () => {
const user = await createUser();
await request
.post(api('livechat/users/agent'))
.set(credentials)
.send({
username: user.username,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res: Response) => {
expect(res.body).to.have.property('success', true);
expect(res.body).to.have.property('user');
expect(res.body.user).to.have.property('_id');
expect(res.body.user).to.have.property('username');
});
// cleanup
await deleteUser(user);
});
it('should properly create a manager', async () => {
const user = await createUser();
await request
.post(api('livechat/users/manager'))
.set(credentials)
.send({
username: user.username,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res: Response) => {
expect(res.body).to.have.property('success', true);
expect(res.body).to.have.property('user');
expect(res.body.user).to.have.property('_id');
expect(res.body.user).to.have.property('username');
});
// cleanup
await deleteUser(user);
});
});
describe('GET livechat/users/:type/:_id', () => {
describe('with no permission', () => {
before(async () => {
await updatePermission('view-livechat-manager', []);
});
after(async () => {
await updatePermission('view-livechat-manager', ['admin']);
});
it('should return an "unauthorized error" when the user does not have the necessary permission', async () => {
await request
.get(api(`livechat/users/agent/id${agent._id}`))
.set(credentials)
.expect('Content-Type', 'application/json')
.expect(403);
});
});
describe('with new user', () => {
let user: IUser;
before(async () => {
user = await createUser();
});
after(async () => {
await deleteUser(user);
});
it('should return an error when type is invalid', async () => {
await request
.get(api(`livechat/users/invalid-type/${agent._id}`))
.set(credentials)
.expect('Content-Type', 'application/json')
.expect(400);
}).timeout(5000);
it('should return a valid user when all goes fine', async () => {
await request
.get(api(`livechat/users/agent/${agent._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('user');
expect(res.body.user).to.have.property('_id');
expect(res.body.user).to.have.property('username');
expect(res.body.user).to.not.have.property('roles');
});
});
it('should return { user: null } when user is not an agent', async () => {
await request
.get(api(`livechat/users/agent/${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('user');
expect(res.body.user).to.be.null;
});
});
it('should return { user: null } when user is not a manager', async () => {
await request
.get(api(`livechat/users/manager/${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('user');
expect(res.body.user).to.be.null;
});
});
});
});
describe('DELETE livechat/users/:type/:_id', () => {
describe('with no permission', () => {
before(async () => {
await updatePermission('view-livechat-manager', []);
});
after(async () => {
await updatePermission('view-livechat-manager', ['admin']);
});
it('should return an "unauthorized error" when the user does not have the necessary permission', async () => {
await request.delete(api(`livechat/users/agent/id`)).set(credentials).expect('Content-Type', 'application/json').expect(403);
}).timeout(5000);
});
it('should return an error when type is invalid', async () => {
await request.delete(api(`livechat/users/invalid-type/id`)).set(credentials).expect('Content-Type', 'application/json').expect(400);
}).timeout(5000);
it('should return an error when _id is invalid', async () => {
await request.delete(api('livechat/users/agent/invalid-id')).set(credentials).expect('Content-Type', 'application/json').expect(400);
}).timeout(5000);
it('should return a valid user when all goes fine', async () => {
const agent = await createAgent();
await request
.delete(api(`livechat/users/agent/${agent._id}`))
.set(credentials)
.expect('Content-Type', 'application/json')
.expect(200);
});
});
(IS_EE ? describe : describe.skip)('livechat/agents/:agentId/departments', () => {
let dep1: ILivechatDepartment;
let dep2: ILivechatDepartment;
before(async () => {
dep1 = await createDepartment(
{
enabled: true,
name: Random.id(),
showOnRegistration: true,
email: `${Random.id()}@example.com`,
showOnOfflineForm: true,
},
[{ agentId: credentials['X-User-Id'] }],
);
dep2 = await createDepartment(
{
enabled: false,
name: Random.id(),
email: `${Random.id()}@example.com`,
showOnRegistration: true,
showOnOfflineForm: true,
},
[{ agentId: credentials['X-User-Id'] }],
);
});
after(async () => {
await deleteDepartment(dep1._id);
await deleteDepartment(dep2._id);
});
describe('with no permission', () => {
before(async () => {
await updatePermission('view-l-room', []);
});
after(async () => {
await updatePermission('view-l-room', ['livechat-manager', 'livechat-agent', 'admin']);
});
it('should return an "unauthorized error" when the user does not have the necessary permission', async () => {
await request
.get(api(`livechat/agents/${agent._id}/departments`))
.set(credentials)
.expect('Content-Type', 'application/json')
.expect(403);
});
});
it('should return an empty array of departments when the agentId is invalid', async () => {
await request
.get(api('livechat/agents/invalid-id/departments'))
.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('departments').and.to.be.an('array');
});
});
it('should return an array of departments when the agentId is valid', async () => {
await request
.get(api(`livechat/agents/${agent._id}/departments`))
.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('departments').and.to.be.an('array');
expect(res.body.departments.length).to.be.equal(2);
(res.body.departments as ILivechatDepartment[]).forEach((department) => {
expect(department.agentId).to.be.equal(agent._id);
expect(department).to.have.property('departmentName').that.is.a('string');
});
});
});
it('should return only enabled departments when param `enabledDepartmentsOnly` is true ', async () => {
await request
.get(api(`livechat/agents/${agent._id}/departments`))
.set(credentials)
.query({ enabledDepartmentsOnly: true })
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res: Response) => {
expect(res.body).to.have.property('success', true);
expect(res.body).to.have.property('departments').and.to.be.an('array');
expect(res.body.departments.length).to.be.equal(1);
expect(res.body.departments[0].departmentEnabled).to.be.true;
});
});
});
describe('livechat/agent.info/:rid/:token', () => {
let room: IOmnichannelRoom;
let visitor: ILivechatVisitor;
before(async () => {
visitor = await createVisitor();
room = await createLivechatRoom(visitor.token);
});
after(async () => {
await closeOmnichannelRoom(room._id);
await deleteVisitor(visitor.token);
});
it('should fail when token in url params is not valid', async () => {
await request.get(api(`livechat/agent.info/soemthing/invalid-token`)).expect(400);
});
it('should fail when token is valid but rid isnt', async () => {
const visitor = await createVisitor();
await request.get(api(`livechat/agent.info/invalid-rid/${visitor.token}`)).expect(400);
await deleteVisitor(visitor.token);
});
/* it('should fail when room is not being served by any agent', async () => {
await updateSetting('Livechat_Routing_Method', 'Manual_Selection');
const visitor = await createVisitor();
const room = await createLivechatRoom(visitor.token);
await request.get(api(`livechat/agent.info/${room._id}/${visitor.token}`)).expect(400);
}); */
it('should return a valid agent when the room is being served and the room belongs to visitor', async () => {
const inq = await fetchInquiry(room._id);
await takeInquiry(inq._id, agent2.credentials);
const { body } = await request.get(api(`livechat/agent.info/${room._id}/${visitor.token}`));
expect(body).to.have.property('success', true);
expect(body).to.have.property('agent');
expect(body.agent).to.have.property('_id', agent2.user._id);
});
});
describe('livechat/agent.next/:token', () => {
let visitor: ILivechatVisitor;
let room: IOmnichannelRoom;
before(async () => {
visitor = await createVisitor();
room = await createLivechatRoom(visitor.token);
});
after(async () => {
await closeOmnichannelRoom(room._id);
await deleteVisitor(visitor.token);
});
it('should fail when token in url params is not valid', async () => {
await request.get(api(`livechat/agent.next/invalid-token`)).expect(400);
});
it('should return success when visitor with token has an open room', async () => {
await request.get(api(`livechat/agent.next/${visitor.token}`)).expect(200);
});
// TODO: test cases when algo is Auto_Selection
});
describe('livechat/agent.next/:token - with manual selection', () => {
before(async () => {
await updateSetting('Livechat_Routing_Method', 'Manual_Selection');
});
after(async () => {
await updateSetting('Livechat_Routing_Method', 'Auto_Selection');
});
it('should fail if theres no open room for visitor and algo is manual selection', async () => {
const visitor = await createVisitor();
await request.get(api(`livechat/agent.next/${visitor.token}`)).expect(400);
await deleteVisitor(visitor.token);
});
});
describe('livechat/agent.status', () => {
describe('with no view-l permission', () => {
before(async () => {
await removePermissionFromAllRoles('view-l-room');
});
after(async () => {
await restorePermissionToRoles('view-l-room');
});
it('should return an "unauthorized error" when the user does not have the necessary permission to change its own status', async () => {
await request.post(api('livechat/agent.status')).set(credentials).send({ status: 'not-available' }).expect(403);
});
});
describe('with no manage-agent permission', () => {
before(async () => {
await request
.post(api('livechat/agent.status'))
.set(credentials)
.send({ status: 'not-available', agentId: agent2.user._id })
.expect(200);
await removePermissionFromAllRoles('manage-livechat-agents');
});
after(async () => {
await restorePermissionToRoles('manage-livechat-agents');
});
it('should return an "unauthorized error" when the user does not have the necessary permission to change other status', async () => {
await request
.post(api('livechat/agent.status'))
.set(credentials)
.send({ status: 'available', agentId: agent2.user._id })
.expect(403);
});
});
it('should return an error if user is not an agent', async () => {
const user = await createUser({ roles: ['livechat-manager'] });
const userCredentials = await login(user.username, password);
await request
.post(api('livechat/agent.status'))
.set(userCredentials)
.send({ status: 'available', agentId: user._id })
.expect(404)
.expect((res: Response) => {
expect(res.body).to.have.property('success', false);
expect(res.body).to.have.property('error', 'Agent not found');
});
// cleanup
await deleteUser(user);
});
it('should return an error if status is not valid', async () => {
await request
.post(api('livechat/agent.status'))
.set(agent2.credentials)
.send({ status: 'invalid-status', agentId: agent2.user._id })
.expect(400)
.expect((res: Response) => {
expect(res.body).to.have.property('success', false);
expect(res.body).to.have.property('error');
});
});
it('should return an error if agentId param is not valid', async () => {
await request
.post(api('livechat/agent.status'))
.set(agent2.credentials)
.send({ status: 'available', agentId: 'invalid-agent-id' })
.expect(404)
.expect((res: Response) => {
expect(res.body).to.have.property('success', false);
expect(res.body).to.have.property('error', 'Agent not found');
});
});
describe('cases for valid agents', () => {
let currentUser: ILivechatAgent;
before(async () => {
currentUser = await getMe(agent2.credentials);
});
afterEach(async () => {
await request
.post(api('livechat/agent.status'))
.set(agent2.credentials)
.send({ status: 'not-available', agentId: currentUser._id })
.expect(200);
});
it('should be able to set a logged in users status to available', async () => {
await request
.post(api('livechat/agent.status'))
.set(agent2.credentials)
.send({ status: 'available', agentId: currentUser._id })
.expect(200)
.expect((res: Response) => {
expect(res.body).to.have.property('success', true);
expect(res.body).to.have.property('status', 'available');
});
});
it('should allow managers to set other agents status to available', async () => {
await request
.post(api('livechat/agent.status'))
.set(credentials)
.send({ status: 'available', agentId: currentUser._id })
.expect(200)
.expect((res: Response) => {
expect(res.body).to.have.property('success', true);
expect(res.body).to.have.property('status', 'available');
});
});
describe('outside of business hours', () => {
before(async () => {
await makeDefaultBusinessHourActiveAndClosed();
await request
.post(api('livechat/agent.status'))
.set(agent2.credentials)
.send({ status: 'not-available', agentId: currentUser._id })
.expect(200);
});
after(async () => {
await disableDefaultBusinessHour();
});
it('should throw an error if agent tries to make themselves available outside of Business hour', async () => {
await request
.post(api('livechat/agent.status'))
.set(agent2.credentials)
.send({ status: 'available', agentId: currentUser._id })
.expect(400)
.expect((res: Response) => {
expect(res.body).to.have.property('success', false);
expect(res.body).to.have.property('error', 'error-business-hours-are-closed');
});
});
it('should return success but not change the agent when admin make try other agents available outside business hour', async () => {
await request
.post(api('livechat/agent.status'))
.set(credentials)
.send({ status: 'available', agentId: currentUser._id })
.expect(200)
.expect((res: Response) => {
expect(res.body).to.have.property('success', true);
expect(res.body).to.have.property('status', 'not-available');
});
});
});
});
});
describe('Agent sidebar', () => {
let testUser: { user: IUser; credentials: Credentials };
before(async () => {
const user = await createUser();
await createAgent(user.username);
const credentials2 = await login(user.username, password);
await makeAgentAvailable(credentials2);
testUser = {
user,
credentials: credentials2,
};
});
after(async () => {
await deleteUser(testUser.user);
});
it('should return an empty list of rooms for a newly created agent', async () => {
const { body } = await request.get(api('rooms.get')).set(testUser.credentials).send({}).expect(200);
expect(body).to.have.property('success', true);
expect(body.update.filter((r: IRoom) => r.t === 'l')).to.have.lengthOf(0);
});
describe('with a room', () => {
let room: IOmnichannelRoom;
let visitor: ILivechatVisitor;
before(async () => {
const { room: r, visitor: v } = await startANewLivechatRoomAndTakeIt({ agent: testUser.credentials });
room = r;
visitor = v;
});
after(async () => {
await closeOmnichannelRoom(room._id);
await deleteVisitor(visitor.token);
});
it('should have a new room in his sidebar after taking a conversation from the queue', async () => {
const { body } = await request.get(api('rooms.get')).set(testUser.credentials).send({}).expect(200);
expect(body).to.have.property('success', true);
const livechatRooms = body.update.filter((r: IRoom) => r.t === 'l');
expect(livechatRooms).to.have.lengthOf(1);
expect(body.update.find((r: { _id: string }) => r._id === room._id)).to.be.an('object');
expect(body.update.find((r: { _id: string }) => r._id === 'GENERAL')).to.be.an('object');
});
it('should not have the room if user moves room back to queue', async () => {
await moveBackToQueue(room._id, testUser.credentials);
const { body } = await request
.get(api('rooms.get'))
.set(testUser.credentials)
.query({ updatedSince: new Date(new Date().getTime() - 2000) })
.expect(200);
expect(body).to.have.property('success', true);
expect(body.update.find((r: { _id: string }) => r._id === room._id)).to.be.undefined;
});
});
it('should not have the room if the user closes the room', async () => {
const { room, visitor } = await startANewLivechatRoomAndTakeIt({ agent: testUser.credentials });
await closeOmnichannelRoom(room._id);
const { body } = await request.get(api('rooms.get')).set(testUser.credentials).expect(200);
expect(body.update.find((r: { _id: string }) => r._id === room._id)).to.be.undefined;
await deleteVisitor(visitor.token);
});
});
});