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: customFields ignored in livechat room creation #33047

Merged
merged 9 commits into from
Aug 19, 2024
5 changes: 5 additions & 0 deletions .changeset/twelve-windows-train.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@rocket.chat/meteor': patch
---

Fixed: Custom fields in extraData now correctly added to extraRoomInfo by livechat.beforeRoom callback during livechat room creation.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { OmnichannelServiceLevelAgreements } from '@rocket.chat/models';
import { Meteor } from 'meteor/meteor';

import { callbacks } from '../../../../../lib/callbacks';
import { isPlainObject } from '../../../../../lib/utils/isPlainObject';

callbacks.add(
'livechat.beforeRoom',
Expand All @@ -10,9 +11,11 @@ callbacks.add(
return roomInfo;
}

const { sla: searchTerm } = extraData;
const { sla: searchTerm, customFields } = extraData;
const roomInfoWithExtraData = { ...roomInfo, ...(isPlainObject(customFields) && { customFields }) };

if (!searchTerm) {
return roomInfo;
return roomInfoWithExtraData;
}

const sla = await OmnichannelServiceLevelAgreements.findOneByIdOrName(searchTerm);
Expand All @@ -23,7 +26,7 @@ callbacks.add(
}

const { _id: slaId } = sla;
return { ...roomInfo, slaId };
return { ...roomInfoWithExtraData, slaId };
},
callbacks.priority.MEDIUM,
'livechat-before-new-room',
Expand Down
3 changes: 3 additions & 0 deletions apps/meteor/lib/utils/isPlainObject.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function isPlainObject(value: unknown) {
return value !== null && typeof value === 'object' && !Array.isArray(value);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { expect } from 'chai';
import { describe, it, beforeEach } from 'mocha';
import proxyquire from 'proxyquire';
import sinon from 'sinon';

import { callbacks } from '../../../../../lib/callbacks';

const findStub = sinon.stub();

proxyquire.noCallThru().load('../../../../../ee/app/livechat-enterprise/server/hooks/beforeNewRoom.ts', {
'meteor/meteor': {
Meteor: {
Error,
},
},
'@rocket.chat/models': {
OmnichannelServiceLevelAgreements: {
findOneByIdOrName: findStub,
},
},
});

describe('livechat.beforeRoom', () => {
beforeEach(() => findStub.withArgs('high').resolves({ _id: 'high' }).withArgs('invalid').resolves(null));

it('should return roomInfo with customFields when provided', async () => {
const roomInfo = { name: 'test' };
const extraData = { customFields: { test: 'test' } };
const result = await callbacks.run('livechat.beforeRoom', roomInfo, extraData);
expect(result).to.deep.equal({ ...roomInfo, customFields: extraData.customFields });
});

it('should throw an error when provided with an invalid sla', async () => {
const roomInfo = { name: 'test' };
const extraData = { customFields: { test: 'test' }, sla: 'invalid' };
await expect(callbacks.run('livechat.beforeRoom', roomInfo, extraData)).to.be.rejectedWith(Error, 'error-invalid-sla');
});

it('should not include field in roomInfo when extraData has field other than customFields, sla', async () => {
const roomInfo = { name: 'test' };
const extraData = { customFields: { test: 'test' }, sla: 'high' };
KevLehman marked this conversation as resolved.
Show resolved Hide resolved
const result = await callbacks.run('livechat.beforeRoom', roomInfo, extraData);
expect(result).to.deep.equal({ ...roomInfo, customFields: extraData.customFields, slaId: 'high' });
});

it('should return roomInfo with no customFields when customFields is not an object', async () => {
const roomInfo = { name: 'test' };
const extraData = { customFields: 'not an object' };
const result = await callbacks.run('livechat.beforeRoom', roomInfo, extraData);
expect(result).to.deep.equal({ ...roomInfo });
});
});
Loading