diff --git a/apps/meteor/client/views/omnichannel/departments/DepartmentAgentsTable/AgentRow.tsx b/apps/meteor/client/views/omnichannel/departments/DepartmentAgentsTable/AgentRow.tsx index e732a84b0e80d..d93b9800e3f52 100644 --- a/apps/meteor/client/views/omnichannel/departments/DepartmentAgentsTable/AgentRow.tsx +++ b/apps/meteor/client/views/omnichannel/departments/DepartmentAgentsTable/AgentRow.tsx @@ -24,10 +24,10 @@ const AgentRow = ({ index, agent, register, onRemove }: AgentRowProps) => { - + - + @@ -35,4 +35,5 @@ const AgentRow = ({ index, agent, register, onRemove }: AgentRowProps) => { ); }; + export default memo(AgentRow); diff --git a/apps/meteor/tests/end-to-end/api/livechat/10-departments.ts b/apps/meteor/tests/end-to-end/api/livechat/10-departments.ts index 4e65439fb762c..34ee3ce32b4de 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/10-departments.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/10-departments.ts @@ -915,6 +915,7 @@ import { IS_EE } from '../../../e2e/config/constants'; .expect(200); expect(res.body).to.have.property('success', true); }); + it('should successfully remove an agent from a department', async () => { const [dep, agent] = await Promise.all([createDepartment(), createAgent()]); const res = await request @@ -940,6 +941,50 @@ import { IS_EE } from '../../../e2e/config/constants'; expect(res.body).to.have.property('success', true); await deleteDepartment(dep._id); }); + + describe('count and order validation', () => { + let dep: ILivechatDepartment; + let agent: IUser; + + before(async () => { + await updatePermission('manage-livechat-departments', ['admin']); + await updatePermission('add-livechat-department-agents', ['admin', 'livechat-manager']); + [dep, agent] = await Promise.all([createDepartment(), createAgent()]); + }); + + after(async () => { + await deleteDepartment(dep._id); + }); + + it('should fail if count is negative', async () => { + const res = await request + .post(api(`livechat/department/${dep._id}/agents`)) + .set(credentials) + .send({ upsert: [{ agentId: agent._id, username: agent.username, count: -1, order: 0 }], remove: [] }) + .expect(400); + expect(res.body).to.have.property('success', false); + expect(res.body.error).to.include('must be >= 0'); + }); + + it('should fail if order is negative', async () => { + const res = await request + .post(api(`livechat/department/${dep._id}/agents`)) + .set(credentials) + .send({ upsert: [{ agentId: agent._id, username: agent.username, count: 0, order: -1 }], remove: [] }) + .expect(400); + expect(res.body).to.have.property('success', false); + expect(res.body.error).to.include('must be >= 0'); + }); + + it('should successfully add an agent when count and order are 0', async () => { + const res = await request + .post(api(`livechat/department/${dep._id}/agents`)) + .set(credentials) + .send({ upsert: [{ agentId: agent._id, username: agent.username, count: 0, order: 0 }], remove: [] }) + .expect(200); + expect(res.body).to.have.property('success', true); + }); + }); }); describe('Department archivation', () => { diff --git a/packages/rest-typings/src/v1/omnichannel.ts b/packages/rest-typings/src/v1/omnichannel.ts index fe5988d3583c1..ab71119954dbc 100644 --- a/packages/rest-typings/src/v1/omnichannel.ts +++ b/packages/rest-typings/src/v1/omnichannel.ts @@ -186,9 +186,11 @@ const LivechatDepartmentDepartmentIdAgentsPOSTSchema = { name: { type: 'string' }, count: { type: 'number', + minimum: 0, }, order: { type: 'number', + minimum: 0, }, }, required: ['agentId', 'username'], @@ -211,9 +213,11 @@ const LivechatDepartmentDepartmentIdAgentsPOSTSchema = { }, count: { type: 'number', + minimum: 0, }, order: { type: 'number', + minimum: 0, }, departmentEnabled: { type: 'boolean' }, departmentId: { type: 'string' }, @@ -826,10 +830,12 @@ const POSTLivechatDepartmentSchema = { }, count: { type: 'number', + minimum: 0, nullable: true, }, order: { type: 'number', + minimum: 0, nullable: true, }, },