From eb1bd018bf8f26d1bd22bce7d2bd3bc5226cc32f Mon Sep 17 00:00:00 2001 From: Kevin Aleman Date: Mon, 21 Nov 2022 10:13:27 -0800 Subject: [PATCH] [IMPROVE] Add searchTerm support for livechat/rid/messages API (#27214) --- .../livechat/imports/server/rest/visitors.ts | 3 +- apps/meteor/server/models/raw/Messages.ts | 3 +- .../tests/end-to-end/api/livechat/00-rooms.ts | 57 +++++++++++++++++++ .../src/models/IMessagesModel.ts | 2 +- packages/rest-typings/src/v1/omnichannel.ts | 6 +- 5 files changed, 67 insertions(+), 4 deletions(-) diff --git a/apps/meteor/app/livechat/imports/server/rest/visitors.ts b/apps/meteor/app/livechat/imports/server/rest/visitors.ts index 43dff642c4b..1409b30ab04 100644 --- a/apps/meteor/app/livechat/imports/server/rest/visitors.ts +++ b/apps/meteor/app/livechat/imports/server/rest/visitors.ts @@ -163,6 +163,7 @@ API.v1.addRoute( async get() { const { offset, count } = this.getPaginationItems(); const { sort } = this.parseJsonQuery(); + const { searchTerm } = this.requestParams(); const room = LivechatRooms.findOneById(this.urlParams.rid); @@ -174,7 +175,7 @@ API.v1.addRoute( throw new Error('not-allowed'); } - const { cursor, totalCount } = Messages.findLivechatClosedMessages(this.urlParams.rid, { + const { cursor, totalCount } = Messages.findLivechatClosedMessages(this.urlParams.rid, searchTerm, { sort: sort || { ts: -1 }, skip: offset, limit: count, diff --git a/apps/meteor/server/models/raw/Messages.ts b/apps/meteor/server/models/raw/Messages.ts index e5e587088fa..74a29de0e70 100644 --- a/apps/meteor/server/models/raw/Messages.ts +++ b/apps/meteor/server/models/raw/Messages.ts @@ -221,11 +221,12 @@ export class MessagesRaw extends BaseRaw implements IMessagesModel { return this.col.aggregate(params).toArray(); } - findLivechatClosedMessages(rid: IRoom['_id'], options: FindOptions): FindPaginated> { + findLivechatClosedMessages(rid: IRoom['_id'], searchTerm?: string, options?: FindOptions): FindPaginated> { return this.findPaginated( { rid, $or: [{ t: { $exists: false } }, { t: 'livechat-close' }], + ...(searchTerm && { msg: new RegExp(escapeRegExp(searchTerm), 'ig') }), }, options, ); diff --git a/apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts b/apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts index f633fd7a538..61ee8674aae 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts @@ -687,6 +687,63 @@ describe('LIVECHAT - rooms', function () { expect(body.total).to.be.an('number').equal(1); expect(body.messages[0]).to.have.property('msg', 'Hello'); }); + it('should return the messages of the room matching by searchTerm', async () => { + const visitor = await createVisitor(); + const room = await createLivechatRoom(visitor.token); + await sendMessage(room._id, 'Hello', visitor.token); + await sendMessage(room._id, 'Random', visitor.token); + + const { body } = await request + .get(api(`livechat/${room._id}/messages`)) + .query({ searchTerm: 'Ran' }) + .set(credentials) + .expect('Content-Type', 'application/json') + .expect(200); + + expect(body).to.have.property('success', true); + expect(body).to.have.property('messages'); + expect(body.messages).to.be.an('array'); + expect(body.total).to.be.an('number').equal(1); + expect(body.messages[0]).to.have.property('msg', 'Random'); + }); + it('should return the messages of the room matching by partial searchTerm', async () => { + const visitor = await createVisitor(); + const room = await createLivechatRoom(visitor.token); + await sendMessage(room._id, 'Hello', visitor.token); + await sendMessage(room._id, 'Random', visitor.token); + + const { body } = await request + .get(api(`livechat/${room._id}/messages`)) + .query({ searchTerm: 'ndo' }) + .set(credentials) + .expect('Content-Type', 'application/json') + .expect(200); + + expect(body).to.have.property('success', true); + expect(body).to.have.property('messages'); + expect(body.messages).to.be.an('array'); + expect(body.total).to.be.an('number').equal(1); + expect(body.messages[0]).to.have.property('msg', 'Random'); + }); + it('should return everything when searchTerm is ""', async () => { + const visitor = await createVisitor(); + const room = await createLivechatRoom(visitor.token); + await sendMessage(room._id, 'Hello', visitor.token); + await sendMessage(room._id, 'Random', visitor.token); + + const { body } = await request + .get(api(`livechat/${room._id}/messages`)) + .query({ searchTerm: '' }) + .set(credentials) + .expect('Content-Type', 'application/json') + .expect(200); + + expect(body).to.have.property('success', true); + expect(body).to.have.property('messages'); + expect(body.messages).to.be.an('array'); + expect(body.messages).to.be.an('array').with.lengthOf.greaterThan(1); + expect(body.messages[0]).to.have.property('msg'); + }); }); describe('[GET] livechat/message/:_id', () => { diff --git a/packages/model-typings/src/models/IMessagesModel.ts b/packages/model-typings/src/models/IMessagesModel.ts index 7550ad37989..c9d925165b6 100644 --- a/packages/model-typings/src/models/IMessagesModel.ts +++ b/packages/model-typings/src/models/IMessagesModel.ts @@ -34,7 +34,7 @@ export interface IMessagesModel extends IBaseModel { getTotalOfMessagesSentByDate(params: { start: Date; end: Date; options?: any }): Promise; - findLivechatClosedMessages(rid: IRoom['_id'], options: FindOptions): FindPaginated>; + findLivechatClosedMessages(rid: IRoom['_id'], searchTerm?: string, options?: FindOptions): FindPaginated>; countRoomsWithStarredMessages(options: AggregateOptions): Promise; diff --git a/packages/rest-typings/src/v1/omnichannel.ts b/packages/rest-typings/src/v1/omnichannel.ts index 0eb1913331c..0f0764411b4 100644 --- a/packages/rest-typings/src/v1/omnichannel.ts +++ b/packages/rest-typings/src/v1/omnichannel.ts @@ -964,7 +964,7 @@ const LivechatRoomsSchema = { export const isLivechatRoomsProps = ajv.compile(LivechatRoomsSchema); -type LivechatRidMessagesProps = PaginatedRequest; +type LivechatRidMessagesProps = PaginatedRequest<{ searchTerm?: string }>; const LivechatRidMessagesSchema = { type: 'object', @@ -981,6 +981,10 @@ const LivechatRidMessagesSchema = { type: 'string', nullable: true, }, + searchTerm: { + type: 'string', + nullable: true, + }, }, required: [], additionalProperties: false,