From 82b8178963f5df0b1cfacf6f43eb855c03667dee Mon Sep 17 00:00:00 2001 From: robstax Date: Fri, 20 Dec 2024 12:28:08 -0500 Subject: [PATCH] fix(conversation): pass actorId to addReaction and deleteReaction (#4037) Co-authored-by: rstachof --- .../src/conversation.js | 28 +++--- .../test/unit/spec/conversation.js | 85 +++++++++++++------ 2 files changed, 74 insertions(+), 39 deletions(-) diff --git a/packages/@webex/internal-plugin-conversation/src/conversation.js b/packages/@webex/internal-plugin-conversation/src/conversation.js index ebdc02019d9..81ef930d3f2 100644 --- a/packages/@webex/internal-plugin-conversation/src/conversation.js +++ b/packages/@webex/internal-plugin-conversation/src/conversation.js @@ -303,15 +303,16 @@ const Conversation = WebexPlugin.extend({ }, /** - * delete a reaction - * @param {Object} conversation - * @param {Object} reactionId, - * @param {String} recipientId, + * create a reaction + * @param {Object} conversation the conversation in which the reaction will be added + * @param {Object} reactionId reaction activity to be deleted + * @param {Object} actorId id of person object who is reacting + * @param {String} recipientId used when reacting to direct IMC messages * @returns {Promise} */ - deleteReaction(conversation, reactionId, recipientId) { + deleteReaction(conversation, reactionId, actorId, recipientId) { const deleteReactionPayload = { - actor: {objectType: 'person', id: this.webex.internal.device.userId}, + actor: {objectType: 'person', id: actorId ?? this.webex.internal.device.userId}, object: { id: reactionId, objectType: 'activity', @@ -334,20 +335,21 @@ const Conversation = WebexPlugin.extend({ /** * create a reaction - * @param {Object} conversation + * @param {Object} conversation the conversation in which the reaction will be added * @param {Object} displayName must be 'celebrate', 'heart', 'thumbsup', 'smiley', 'haha', 'confused', 'sad' - * @param {Object} activity activity object from convo we are reacting to - * @param {String} recipientId, + * @param {Object} parentActivity activity object from that we are reacting to + * @param {Object} actorId id of person object who is reacting + * @param {String} recipientId used when reacting to direct IMC messages * @returns {Promise} */ - async addReaction(conversation, displayName, activity, recipientId) { + async addReaction(conversation, displayName, parentActivity, actorId, recipientId) { let hmac; if (this.config.includeEncryptionTransforms) { - hmac = await this.createReactionHmac(displayName, activity); + hmac = await this.createReactionHmac(displayName, parentActivity); } const addReactionPayload = { - actor: {objectType: 'person', id: this.webex.internal.device.userId}, + actor: {objectType: 'person', id: actorId ?? this.webex.internal.device.userId}, target: { id: conversation.id, objectType: 'conversation', @@ -356,7 +358,7 @@ const Conversation = WebexPlugin.extend({ objectType: 'activity', parent: { type: 'reaction', - id: activity.id, + id: parentActivity.id, }, object: { objectType: 'reaction2', diff --git a/packages/@webex/internal-plugin-conversation/test/unit/spec/conversation.js b/packages/@webex/internal-plugin-conversation/test/unit/spec/conversation.js index 05a6f117352..4029c4a94b1 100644 --- a/packages/@webex/internal-plugin-conversation/test/unit/spec/conversation.js +++ b/packages/@webex/internal-plugin-conversation/test/unit/spec/conversation.js @@ -37,45 +37,78 @@ describe('plugin-conversation', () => { }); describe('addReaction()', () => { - it('should add recipients to the payload if provided', () => { - const {conversation} = webex.internal; - const recipientId = 'example-recipient-id'; - const expected = {items: [{id: recipientId, objectType: 'person'}]}; - conversation.config.includeEncryptionTransforms = true; + let conversation; + let recipientId; + let expectedRecipients; + let actorId; + + beforeEach(() => { + conversation = webex.internal.conversation; + recipientId = 'example-recipient-id'; + actorId = 'actorId-123'; + expectedRecipients = {items: [{id: recipientId, objectType: 'person'}]}; conversation.sendReaction = sinon.stub().returns(Promise.resolve()); conversation.createReactionHmac = sinon.stub().returns(Promise.resolve('hmac')); + }); + it('should add recipients to the payload if provided', async () => { + conversation.config.includeEncryptionTransforms = true; - return conversation.addReaction({}, 'example-display-name', {}, recipientId).then(() => { - assert.called(conversation.createReactionHmac); - assert.deepEqual(conversation.sendReaction.args[0][1].recipients, expected); - }); + await conversation.addReaction({}, 'example-display-name', {}, actorId, recipientId); + assert.called(conversation.createReactionHmac); + assert.deepEqual(conversation.sendReaction.args[0][1].recipients, expectedRecipients); }); - it('will not call createReactionHmac if config prohibits', () => { - const {conversation} = webex.internal; - const recipientId = 'example-recipient-id'; - const expected = {items: [{id: recipientId, objectType: 'person'}]}; + it('will not call createReactionHmac if config prohibits', async () => { conversation.config.includeEncryptionTransforms = false; - conversation.sendReaction = sinon.stub().returns(Promise.resolve()); - conversation.createReactionHmac = sinon.stub(); - return conversation.addReaction({}, 'example-display-name', {}, recipientId).then(() => { - assert.deepEqual(conversation.sendReaction.args[0][1].recipients, expected); - assert.notCalled(conversation.createReactionHmac); - }); + await conversation.addReaction({}, 'example-display-name', {}, actorId, recipientId); + assert.deepEqual(conversation.sendReaction.args[0][1].recipients, expectedRecipients); + assert.notCalled(conversation.createReactionHmac); + }); + + it('should use actorId if provided', async () => { + await conversation.addReaction({}, 'example-display-name', {}, actorId, recipientId); + assert.equal(conversation.sendReaction.args[0][1].actor.id, actorId); + }); + + it('should use fallback device.userId if no actorId provided', async () => { + const defaultUserId = 'fallback-id'; + webex.internal.device.userId = defaultUserId; + await conversation.addReaction({}, 'example-display-name', {}, undefined, recipientId); + assert.equal(conversation.sendReaction.args[0][1].actor.id, defaultUserId); }); }); describe('deleteReaction()', () => { - it('should add recipients to the payload if provided', () => { - const {conversation} = webex.internal; - const recipientId = 'example-recipient-id'; - const expected = {items: [{id: recipientId, objectType: 'person'}]}; + let conversation; + let recipientId; + let expectedRecipients; + let actorId; + + beforeEach(() => { + conversation = webex.internal.conversation; + recipientId = 'example-recipient-id'; + actorId = 'actorId-123'; + expectedRecipients = {items: [{id: recipientId, objectType: 'person'}]}; conversation.sendReaction = sinon.stub().returns(Promise.resolve()); + conversation.createReactionHmac = sinon.stub().returns(Promise.resolve('hmac')); + }); - return conversation.deleteReaction({}, 'example-reaction-id', recipientId).then(() => { - assert.deepEqual(conversation.sendReaction.args[0][1].recipients, expected); - }); + it('should add recipients to the payload if provided', async () => { + await conversation.deleteReaction({}, 'example-reaction-id', actorId, recipientId); + assert.deepEqual(conversation.sendReaction.args[0][1].recipients, expectedRecipients); + }); + + it('should use actorId if provided', async () => { + await conversation.deleteReaction({}, 'example-reaction-id', actorId, recipientId); + assert.equal(conversation.sendReaction.args[0][1].actor.id, actorId); + }); + + it('should use fallback device.userId if no actorId provided', async () => { + const defaultUserId = 'fallback-id'; + webex.internal.device.userId = defaultUserId; + await conversation.deleteReaction({}, 'example-reaction-id', undefined, recipientId); + assert.equal(conversation.sendReaction.args[0][1].actor.id, defaultUserId); }); });