From 461249492321b1fcc950b8167111c3bcadc9b633 Mon Sep 17 00:00:00 2001 From: Pranav Raj S Date: Sat, 4 Jul 2020 19:46:17 +0530 Subject: [PATCH] Chore: Fix issues with conversation data models (#1000) Co-authored-by: Sojan --- .../widgets/conversation/ConversationCard.vue | 8 +- .../conversation/ConversationHeader.vue | 8 +- .../widgets/conversation/MessagesView.vue | 17 ---- .../widgets/conversation/ReplyBox.vue | 12 +-- .../dashboard/conversation/ContactPanel.vue | 5 +- .../dashboard/store/modules/contacts.js | 4 + .../store/modules/conversations/actions.js | 19 ++-- .../store/modules/conversations/index.js | 3 +- .../modules/specs/contacts/actions.spec.js | 20 +++-- .../specs/conversations/actions.spec.js | 88 +++++++++++++++++++ app/models/notification.rb | 3 +- .../conversations/event_data_presenter.rb | 3 +- .../partials/_conversation.json.jbuilder | 6 +- spec/models/conversation_spec.rb | 1 + .../event_data_presenter_spec.rb | 1 + 15 files changed, 147 insertions(+), 51 deletions(-) diff --git a/app/javascript/dashboard/components/widgets/conversation/ConversationCard.vue b/app/javascript/dashboard/components/widgets/conversation/ConversationCard.vue index 301717b51..9c7c78959 100644 --- a/app/javascript/dashboard/components/widgets/conversation/ConversationCard.vue +++ b/app/javascript/dashboard/components/widgets/conversation/ConversationCard.vue @@ -7,7 +7,7 @@ @@ -29,7 +29,7 @@ :allow-empty="true" deselect-label="Remove" placeholder="Select Agent" - selected-label="" + selected-label select-label="Assign" track-by="id" @select="assignAgent" @@ -81,6 +81,10 @@ export default { currentChat: 'getSelectedChat', }), + chatMetadata() { + return this.chat.meta; + }, + currentContact() { return this.$store.getters['contacts/getContact']( this.chat.meta.sender.id diff --git a/app/javascript/dashboard/components/widgets/conversation/MessagesView.vue b/app/javascript/dashboard/components/widgets/conversation/MessagesView.vue index 69d711955..7a67b4e46 100644 --- a/app/javascript/dashboard/components/widgets/conversation/MessagesView.vue +++ b/app/javascript/dashboard/components/widgets/conversation/MessagesView.vue @@ -121,23 +121,6 @@ export default { ); return chat; }, - // Get current FB Page ID - getPageId() { - let stateInbox; - if (this.inboxId) { - const inboxId = Number(this.inboxId); - [stateInbox] = this.inboxesList.filter( - inbox => inbox.channel_id === inboxId - ); - } else { - [stateInbox] = this.inboxesList; - } - return !stateInbox ? 0 : stateInbox.page_id; - }, - // Get current FB Page ID link - linkToMessage() { - return `https://m.me/${this.getPageId}`; - }, getReadMessages() { const chat = this.getMessages; return chat === undefined ? null : this.readMessages(chat); diff --git a/app/javascript/dashboard/components/widgets/conversation/ReplyBox.vue b/app/javascript/dashboard/components/widgets/conversation/ReplyBox.vue index c1aa4c718..499394184 100644 --- a/app/javascript/dashboard/components/widgets/conversation/ReplyBox.vue +++ b/app/javascript/dashboard/components/widgets/conversation/ReplyBox.vue @@ -121,12 +121,7 @@ export default { currentChat: 'getSelectedChat', }), channelType() { - const { - meta: { - sender: { channel }, - }, - } = this.currentChat; - return channel; + return this.currentChat.meta.channel; }, conversationType() { const { additional_attributes: additionalAttributes } = this.currentChat; @@ -145,10 +140,7 @@ export default { return 10000; }, showFileUpload() { - return ( - this.channelType === 'Channel::WebWidget' || - this.channelType === 'Channel::TwilioSms' - ); + return this.channelType === 'Channel::WebWidget'; }, replyButtonLabel() { if (this.isPrivate) { diff --git a/app/javascript/dashboard/routes/dashboard/conversation/ContactPanel.vue b/app/javascript/dashboard/routes/dashboard/conversation/ContactPanel.vue index 74a86070a..e9ed6b71b 100644 --- a/app/javascript/dashboard/routes/dashboard/conversation/ContactPanel.vue +++ b/app/javascript/dashboard/routes/dashboard/conversation/ContactPanel.vue @@ -8,7 +8,7 @@ @@ -158,6 +158,9 @@ export default { } = this.browser; return `${platformName || ''} ${platformVersion || ''}`; }, + channelType() { + return this.currentChat.meta?.channel; + }, contactId() { return this.currentChat.meta?.sender?.id; }, diff --git a/app/javascript/dashboard/store/modules/contacts.js b/app/javascript/dashboard/store/modules/contacts.js index 8f88639ea..ef2525cad 100644 --- a/app/javascript/dashboard/store/modules/contacts.js +++ b/app/javascript/dashboard/store/modules/contacts.js @@ -63,6 +63,10 @@ export const actions = { updatePresence: ({ commit }, data) => { commit(types.default.UPDATE_CONTACTS_PRESENCE, data); }, + + setContact({ commit }, data) { + commit(types.default.SET_CONTACT_ITEM, data); + }, }; export const mutations = { diff --git a/app/javascript/dashboard/store/modules/conversations/actions.js b/app/javascript/dashboard/store/modules/conversations/actions.js index e7784a13a..937d25afd 100644 --- a/app/javascript/dashboard/store/modules/conversations/actions.js +++ b/app/javascript/dashboard/store/modules/conversations/actions.js @@ -156,19 +156,24 @@ const actions = { commit(types.default.ADD_MESSAGE, message); }, - addConversation({ commit, state }, conversation) { + addConversation({ commit, state, dispatch }, conversation) { const { currentInbox } = state; - if (!currentInbox || Number(currentInbox) === conversation.inbox_id) { + const { + inbox_id: inboxId, + meta: { sender }, + } = conversation; + if (!currentInbox || Number(currentInbox) === inboxId) { commit(types.default.ADD_CONVERSATION, conversation); - commit( - `contacts/${types.default.SET_CONTACT_ITEM}`, - conversation.meta.sender - ); + dispatch('contacts/setContact', sender); } }, - updateConversation({ commit }, conversation) { + updateConversation({ commit, dispatch }, conversation) { + const { + meta: { sender }, + } = conversation; commit(types.default.UPDATE_CONVERSATION, conversation); + dispatch('contacts/setContact', sender); }, markMessagesRead: async ({ commit }, data) => { diff --git a/app/javascript/dashboard/store/modules/conversations/index.js b/app/javascript/dashboard/store/modules/conversations/index.js index 949894adf..af6a77307 100644 --- a/app/javascript/dashboard/store/modules/conversations/index.js +++ b/app/javascript/dashboard/store/modules/conversations/index.js @@ -140,9 +140,10 @@ const mutations = { c => c.id === conversation.id ); if (currentConversationIndex > -1) { + const { messages, ...conversationAttributes } = conversation; const currentConversation = { ...allConversations[currentConversationIndex], - ...conversation, + ...conversationAttributes, }; Vue.set(allConversations, currentConversationIndex, currentConversation); if (_state.selectedChat.id === conversation.id) { diff --git a/app/javascript/dashboard/store/modules/specs/contacts/actions.spec.js b/app/javascript/dashboard/store/modules/specs/contacts/actions.spec.js index 4defdadde..21c20e74e 100644 --- a/app/javascript/dashboard/store/modules/specs/contacts/actions.spec.js +++ b/app/javascript/dashboard/store/modules/specs/contacts/actions.spec.js @@ -9,7 +9,7 @@ jest.mock('axios'); describe('#actions', () => { describe('#get', () => { - it('sends correct actions if API is success', async () => { + it('sends correct mutations if API is success', async () => { axios.get.mockResolvedValue({ data: { payload: contactList } }); await actions.get({ commit }); expect(commit.mock.calls).toEqual([ @@ -18,7 +18,7 @@ describe('#actions', () => { [types.default.SET_CONTACT_UI_FLAG, { isFetching: false }], ]); }); - it('sends correct actions if API is error', async () => { + it('sends correct mutations if API is error', async () => { axios.get.mockRejectedValue({ message: 'Incorrect header' }); await actions.get({ commit }); expect(commit.mock.calls).toEqual([ @@ -29,7 +29,7 @@ describe('#actions', () => { }); describe('#show', () => { - it('sends correct actions if API is success', async () => { + it('sends correct mutations if API is success', async () => { axios.get.mockResolvedValue({ data: { payload: contactList[0] } }); await actions.show({ commit }, { id: contactList[0].id }); expect(commit.mock.calls).toEqual([ @@ -38,7 +38,7 @@ describe('#actions', () => { [types.default.SET_CONTACT_UI_FLAG, { isFetchingItem: false }], ]); }); - it('sends correct actions if API is error', async () => { + it('sends correct mutations if API is error', async () => { axios.get.mockRejectedValue({ message: 'Incorrect header' }); await actions.show({ commit }, { id: contactList[0].id }); expect(commit.mock.calls).toEqual([ @@ -49,7 +49,7 @@ describe('#actions', () => { }); describe('#update', () => { - it('sends correct actions if API is success', async () => { + it('sends correct mutations if API is success', async () => { axios.patch.mockResolvedValue({ data: { payload: contactList[0] } }); await actions.update({ commit }, contactList[0]); expect(commit.mock.calls).toEqual([ @@ -69,4 +69,14 @@ describe('#actions', () => { ]); }); }); + + describe('#setContact', () => { + it('returns correct mutations', () => { + const data = { id: 1, name: 'john doe', availability_status: 'online' }; + actions.setContact({ commit }, data); + expect(commit.mock.calls).toEqual([ + [types.default.SET_CONTACT_ITEM, data], + ]); + }); + }); }); diff --git a/app/javascript/dashboard/store/modules/specs/conversations/actions.spec.js b/app/javascript/dashboard/store/modules/specs/conversations/actions.spec.js index 815beb081..d44753732 100644 --- a/app/javascript/dashboard/store/modules/specs/conversations/actions.spec.js +++ b/app/javascript/dashboard/store/modules/specs/conversations/actions.spec.js @@ -3,6 +3,7 @@ import actions from '../../conversations/actions'; import * as types from '../../../mutation-types'; const commit = jest.fn(); +const dispatch = jest.fn(); global.axios = axios; jest.mock('axios'); @@ -39,4 +40,91 @@ describe('#actions', () => { expect(commit.mock.calls).toEqual([]); }); }); + + describe('#updateConversation', () => { + it('sends setContact action and update_conversation mutation', () => { + const conversation = { + id: 1, + messages: [], + meta: { sender: { id: 1, name: 'john-doe' } }, + }; + actions.updateConversation({ commit, dispatch }, conversation); + expect(commit.mock.calls).toEqual([ + [types.default.UPDATE_CONVERSATION, conversation], + ]); + expect(dispatch.mock.calls).toEqual([ + [ + 'contacts/setContact', + { + id: 1, + name: 'john-doe', + }, + ], + ]); + }); + }); + + describe('#addConversation', () => { + it('doesnot send mutation if conversation is from a different inbox', () => { + const conversation = { + id: 1, + messages: [], + meta: { sender: { id: 1, name: 'john-doe' } }, + inbox_id: 2, + }; + actions.addConversation( + { commit, dispatch, state: { currentInbox: 1 } }, + conversation + ); + expect(commit.mock.calls).toEqual([]); + expect(dispatch.mock.calls).toEqual([]); + }); + + it('sends correct mutations', () => { + const conversation = { + id: 1, + messages: [], + meta: { sender: { id: 1, name: 'john-doe' } }, + inbox_id: 1, + }; + actions.addConversation( + { commit, dispatch, state: { currentInbox: 1 } }, + conversation + ); + expect(commit.mock.calls).toEqual([ + [types.default.ADD_CONVERSATION, conversation], + ]); + expect(dispatch.mock.calls).toEqual([ + [ + 'contacts/setContact', + { + id: 1, + name: 'john-doe', + }, + ], + ]); + }); + + it('sends correct mutations if inbox filter is not available', () => { + const conversation = { + id: 1, + messages: [], + meta: { sender: { id: 1, name: 'john-doe' } }, + inbox_id: 1, + }; + actions.addConversation({ commit, dispatch, state: {} }, conversation); + expect(commit.mock.calls).toEqual([ + [types.default.ADD_CONVERSATION, conversation], + ]); + expect(dispatch.mock.calls).toEqual([ + [ + 'contacts/setContact', + { + id: 1, + name: 'john-doe', + }, + ], + ]); + }); + }); }); diff --git a/app/models/notification.rb b/app/models/notification.rb index 33c04dda2..08d7eca28 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -51,7 +51,8 @@ class Notification < ApplicationRecord read_at: read_at, secondary_actor: secondary_actor&.push_event_data, user: user&.push_event_data, - created_at: created_at + created_at: created_at, + account_id: account_id } end diff --git a/app/presenters/conversations/event_data_presenter.rb b/app/presenters/conversations/event_data_presenter.rb index bf1b4140d..c61792459 100644 --- a/app/presenters/conversations/event_data_presenter.rb +++ b/app/presenters/conversations/event_data_presenter.rb @@ -5,10 +5,11 @@ class Conversations::EventDataPresenter < SimpleDelegator def push_data { - id: display_id, additional_attributes: additional_attributes, + id: display_id, inbox_id: inbox_id, messages: push_messages, + channel: inbox.try(:channel_type), meta: push_meta, status: status, unread_count: unread_incoming_messages.count, diff --git a/app/views/api/v1/conversations/partials/_conversation.json.jbuilder b/app/views/api/v1/conversations/partials/_conversation.json.jbuilder index 187348b38..e9d796c31 100644 --- a/app/views/api/v1/conversations/partials/_conversation.json.jbuilder +++ b/app/views/api/v1/conversations/partials/_conversation.json.jbuilder @@ -1,10 +1,8 @@ json.meta do json.sender do - json.id conversation.contact.id - json.name conversation.contact.name - json.thumbnail conversation.contact.avatar_url - json.channel conversation.inbox.try(:channel_type) + json.partial! 'api/v1/models/contact.json.jbuilder', resource: conversation.contact end + json.channel conversation.inbox.try(:channel_type) json.assignee conversation.assignee end diff --git a/spec/models/conversation_spec.rb b/spec/models/conversation_spec.rb index 629b5fbf5..6e2e79be1 100644 --- a/spec/models/conversation_spec.rb +++ b/spec/models/conversation_spec.rb @@ -312,6 +312,7 @@ RSpec.describe Conversation, type: :model do inbox_id: conversation.inbox_id, status: conversation.status, timestamp: conversation.created_at.to_i, + channel: 'Channel::WebWidget', user_last_seen_at: conversation.user_last_seen_at.to_i, agent_last_seen_at: conversation.agent_last_seen_at.to_i, unread_count: 0 diff --git a/spec/presenters/conversations/event_data_presenter_spec.rb b/spec/presenters/conversations/event_data_presenter_spec.rb index 82a9dc771..76326b616 100644 --- a/spec/presenters/conversations/event_data_presenter_spec.rb +++ b/spec/presenters/conversations/event_data_presenter_spec.rb @@ -22,6 +22,7 @@ RSpec.describe Conversations::EventDataPresenter do messages: [], inbox_id: conversation.inbox_id, status: conversation.status, + channel: conversation.inbox.channel_type, timestamp: conversation.created_at.to_i, user_last_seen_at: conversation.user_last_seen_at.to_i, agent_last_seen_at: conversation.agent_last_seen_at.to_i,