Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: livechat agent status set to available after reactivation #31651

Merged
merged 7 commits into from
Mar 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/nice-ducks-shout.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@rocket.chat/meteor': patch
---

Fixed auto-availability of reactivated livechat agents; they now stay 'Not Available' until manually set to 'Available'
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const handleDeactivateUser = async (user: IUser) => {

const handleActivateUser = async (user: IUser) => {
if (isAgent(user) && user.username) {
await LivechatTyped.addAgent(user.username);
abhinavkrin marked this conversation as resolved.
Show resolved Hide resolved
await LivechatTyped.afterAgentUserActivated(user);
}
};

Expand Down
8 changes: 8 additions & 0 deletions apps/meteor/app/livechat/server/lib/LivechatTyped.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1682,6 +1682,14 @@ class LivechatClass {
return false;
}

async afterAgentUserActivated(user: IUser) {
if (!user.roles.includes('livechat-agent')) {
throw new Error('invalid-user-role');
}
await Users.setOperator(user._id, true);
callbacks.runAsync('livechat.onNewAgentCreated', user._id);
}

async addManager(username: string) {
check(username, String);

Expand Down
9 changes: 8 additions & 1 deletion apps/meteor/tests/data/livechat/users.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { faker } from "@faker-js/faker";
import type { IUser } from "@rocket.chat/core-typings";
import type { ILivechatAgent, IUser } from "@rocket.chat/core-typings";
import { IUserCredentialsHeader, password } from "../user";
import { createUser, login } from "../users.helper";
import { createAgent, makeAgentAvailable } from "./rooms";
Expand All @@ -24,6 +24,13 @@ export const createBotAgent = async (): Promise<{

export const getRandomVisitorToken = (): string => faker.string.alphanumeric(17);

export const getAgent = async (userId: string): Promise<ILivechatAgent> => {
const { body } = await request.get(api(`livechat/users/agent/${userId}`))
.set(credentials)
.expect(200);
return body.user;
}

export const removeAgent = async (userId: string): Promise<void> => {
await request.delete(api(`livechat/users/agent/${userId}`))
.set(credentials)
Expand Down
56 changes: 56 additions & 0 deletions apps/meteor/tests/end-to-end/api/01-users.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { getCredentials, api, request, credentials, apiEmail, apiUsername, log,
import { MAX_BIO_LENGTH, MAX_NICKNAME_LENGTH } from '../../data/constants.ts';
import { customFieldText, clearCustomFields, setCustomFields } from '../../data/custom-fields.js';
import { imgURL } from '../../data/interactions';
import { createAgent, makeAgentAvailable } from '../../data/livechat/rooms';
import { removeAgent, getAgent } from '../../data/livechat/users';
import { updatePermission, updateSetting } from '../../data/permissions.helper';
import { createRoom, deleteRoom } from '../../data/rooms.helper';
import { adminEmail, preferences, password, adminUsername } from '../../data/user';
Expand Down Expand Up @@ -3114,6 +3116,21 @@ describe('[Users]', function () {

describe('[/users.setActiveStatus]', () => {
let user;
let agent;
let agentUser;

before(async () => {
agentUser = await createUser();
const agentUserCredentials = await login(agentUser.username, password);
await createAgent(agentUser.username);
await makeAgentAvailable(agentUserCredentials);

agent = {
user: agentUser,
credentials: agentUserCredentials,
};
});

before((done) => {
const username = `user.test.${Date.now()}`;
const email = `${username}@rocket.chat`;
Expand Down Expand Up @@ -3156,6 +3173,12 @@ describe('[Users]', function () {
.end(() => updatePermission('edit-other-user-active-status', ['admin']).then(done));
user = undefined;
});

after(async () => {
await removeAgent(agent.user._id);
await deleteUser(agent.user);
});

it('should set other user active status to false when the logged user has the necessary permission(edit-other-user-active-status)', (done) => {
request
.post(api('users.setActiveStatus'))
Expand Down Expand Up @@ -3484,6 +3507,39 @@ describe('[Users]', function () {

await deleteUser(testUser);
});
it('should make agents not-available when the user is deactivated', async () => {
await makeAgentAvailable(agent.credentials);
await request
.post(api('users.setActiveStatus'))
.set(credentials)
.send({
activeStatus: false,
userId: agent.user._id,
})
.expect('Content-Type', 'application/json')
.expect(200);

const agentInfo = await getAgent(agent.user._id);
expect(agentInfo).to.have.property('statusLivechat', 'not-available');
});

it('should not make agents available when the user is activated', async () => {
let agentInfo = await getAgent(agent.user._id);
expect(agentInfo).to.have.property('statusLivechat', 'not-available');

await request
.post(api('users.setActiveStatus'))
.set(credentials)
.send({
activeStatus: true,
userId: agent.user._id,
})
.expect('Content-Type', 'application/json')
.expect(200);

agentInfo = await getAgent(agent.user._id);
expect(agentInfo).to.have.property('statusLivechat', 'not-available');
});
});

describe('[/users.deactivateIdle]', () => {
Expand Down
Loading