mirror of
				https://github.com/lingble/chatwoot.git
				synced 2025-10-30 18:47:51 +00:00 
			
		
		
		
	feat: add option for reply to in context menu (#8043)
Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
This commit is contained in:
		| @@ -124,6 +124,7 @@ | |||||||
|         :message="data" |         :message="data" | ||||||
|         @open="openContextMenu" |         @open="openContextMenu" | ||||||
|         @close="closeContextMenu" |         @close="closeContextMenu" | ||||||
|  |         @replyTo="handleReplyTo" | ||||||
|       /> |       /> | ||||||
|     </div> |     </div> | ||||||
|   </li> |   </li> | ||||||
| @@ -188,6 +189,10 @@ export default { | |||||||
|       type: Boolean, |       type: Boolean, | ||||||
|       default: false, |       default: false, | ||||||
|     }, |     }, | ||||||
|  |     inboxSupportsReplyTo: { | ||||||
|  |       type: Boolean, | ||||||
|  |       default: false, | ||||||
|  |     }, | ||||||
|   }, |   }, | ||||||
|   data() { |   data() { | ||||||
|     return { |     return { | ||||||
| @@ -269,6 +274,7 @@ export default { | |||||||
|         copy: this.hasText, |         copy: this.hasText, | ||||||
|         delete: this.hasText || this.hasAttachments, |         delete: this.hasText || this.hasAttachments, | ||||||
|         cannedResponse: this.isOutgoing && this.hasText, |         cannedResponse: this.isOutgoing && this.hasText, | ||||||
|  |         replyTo: !this.data.private && this.inboxSupportsReplyTo, | ||||||
|       }; |       }; | ||||||
|     }, |     }, | ||||||
|     contentAttributes() { |     contentAttributes() { | ||||||
| @@ -494,6 +500,7 @@ export default { | |||||||
|       this.showContextMenu = false; |       this.showContextMenu = false; | ||||||
|       this.contextMenuPosition = { x: null, y: null }; |       this.contextMenuPosition = { x: null, y: null }; | ||||||
|     }, |     }, | ||||||
|  |     handleReplyTo() {}, | ||||||
|     setupHighlightTimer() { |     setupHighlightTimer() { | ||||||
|       if (Number(this.$route.query.messageId) !== Number(this.data.id)) { |       if (Number(this.$route.query.messageId) !== Number(this.data.id)) { | ||||||
|         return; |         return; | ||||||
|   | |||||||
| @@ -42,6 +42,7 @@ | |||||||
|         :is-a-whatsapp-channel="isAWhatsAppChannel" |         :is-a-whatsapp-channel="isAWhatsAppChannel" | ||||||
|         :has-instagram-story="hasInstagramStory" |         :has-instagram-story="hasInstagramStory" | ||||||
|         :is-web-widget-inbox="isAWebWidgetInbox" |         :is-web-widget-inbox="isAWebWidgetInbox" | ||||||
|  |         :inbox-supports-reply-to="inboxSupportsReplyTo" | ||||||
|       /> |       /> | ||||||
|       <li v-show="unreadMessageCount != 0" class="unread--toast"> |       <li v-show="unreadMessageCount != 0" class="unread--toast"> | ||||||
|         <span> |         <span> | ||||||
| @@ -110,7 +111,7 @@ import { mapGetters } from 'vuex'; | |||||||
| import conversationMixin, { | import conversationMixin, { | ||||||
|   filterDuplicateSourceMessages, |   filterDuplicateSourceMessages, | ||||||
| } from '../../../mixins/conversations'; | } from '../../../mixins/conversations'; | ||||||
| import inboxMixin from 'shared/mixins/inboxMixin'; | import inboxMixin, { INBOX_FEATURES } from 'shared/mixins/inboxMixin'; | ||||||
| import configMixin from 'shared/mixins/configMixin'; | import configMixin from 'shared/mixins/configMixin'; | ||||||
| import eventListenerMixins from 'shared/mixins/eventListenerMixins'; | import eventListenerMixins from 'shared/mixins/eventListenerMixins'; | ||||||
| import aiMixin from 'dashboard/mixins/aiMixin'; | import aiMixin from 'dashboard/mixins/aiMixin'; | ||||||
| @@ -123,6 +124,7 @@ import { LocalStorage } from 'shared/helpers/localStorage'; | |||||||
|  |  | ||||||
| // constants | // constants | ||||||
| import { BUS_EVENTS } from 'shared/constants/busEvents'; | import { BUS_EVENTS } from 'shared/constants/busEvents'; | ||||||
|  | import { FEATURE_FLAGS } from 'dashboard/featureFlags'; | ||||||
| import { REPLY_POLICY } from 'shared/constants/links'; | import { REPLY_POLICY } from 'shared/constants/links'; | ||||||
| import wootConstants from 'dashboard/constants/globals'; | import wootConstants from 'dashboard/constants/globals'; | ||||||
| import { LOCAL_STORAGE_KEYS } from 'dashboard/constants/localStorage'; | import { LOCAL_STORAGE_KEYS } from 'dashboard/constants/localStorage'; | ||||||
| @@ -164,12 +166,14 @@ export default { | |||||||
|  |  | ||||||
|   computed: { |   computed: { | ||||||
|     ...mapGetters({ |     ...mapGetters({ | ||||||
|  |       accountId: 'getCurrentAccountId', | ||||||
|       currentChat: 'getSelectedChat', |       currentChat: 'getSelectedChat', | ||||||
|       allConversations: 'getAllConversations', |       allConversations: 'getAllConversations', | ||||||
|       inboxesList: 'inboxes/getInboxes', |       inboxesList: 'inboxes/getInboxes', | ||||||
|       listLoadingStatus: 'getAllMessagesLoaded', |       listLoadingStatus: 'getAllMessagesLoaded', | ||||||
|       loadingChatList: 'getChatListLoadingStatus', |       loadingChatList: 'getChatListLoadingStatus', | ||||||
|       appIntegrations: 'integrations/getAppIntegrations', |       appIntegrations: 'integrations/getAppIntegrations', | ||||||
|  |       isFeatureEnabledonAccount: 'accounts/isFeatureEnabledonAccount', | ||||||
|       currentAccountId: 'getCurrentAccountId', |       currentAccountId: 'getCurrentAccountId', | ||||||
|     }), |     }), | ||||||
|     isOpen() { |     isOpen() { | ||||||
| @@ -316,6 +320,15 @@ export default { | |||||||
|     unreadMessageCount() { |     unreadMessageCount() { | ||||||
|       return this.currentChat.unread_count || 0; |       return this.currentChat.unread_count || 0; | ||||||
|     }, |     }, | ||||||
|  |     inboxSupportsReplyTo() { | ||||||
|  |       return ( | ||||||
|  |         this.inboxHasFeature(INBOX_FEATURES.REPLY_TO) && | ||||||
|  |         this.isFeatureEnabledonAccount( | ||||||
|  |           this.accountId, | ||||||
|  |           FEATURE_FLAGS.MESSAGE_REPLY_TO | ||||||
|  |         ) | ||||||
|  |       ); | ||||||
|  |     }, | ||||||
|   }, |   }, | ||||||
|  |  | ||||||
|   watch: { |   watch: { | ||||||
|   | |||||||
| @@ -16,4 +16,5 @@ export const FEATURE_FLAGS = { | |||||||
|   TEAM_MANAGEMENT: 'team_management', |   TEAM_MANAGEMENT: 'team_management', | ||||||
|   VOICE_RECORDER: 'voice_recorder', |   VOICE_RECORDER: 'voice_recorder', | ||||||
|   AUDIT_LOGS: 'audit_logs', |   AUDIT_LOGS: 'audit_logs', | ||||||
|  |   MESSAGE_REPLY_TO: 'message_reply_to', | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -194,6 +194,7 @@ | |||||||
|     }, |     }, | ||||||
|     "CONTEXT_MENU": { |     "CONTEXT_MENU": { | ||||||
|       "COPY": "Copy", |       "COPY": "Copy", | ||||||
|  |       "REPLY_TO": "Reply to this message", | ||||||
|       "DELETE": "Delete", |       "DELETE": "Delete", | ||||||
|       "CREATE_A_CANNED_RESPONSE": "Add to canned responses", |       "CREATE_A_CANNED_RESPONSE": "Add to canned responses", | ||||||
|       "TRANSLATE": "Translate", |       "TRANSLATE": "Translate", | ||||||
|   | |||||||
| @@ -44,6 +44,15 @@ | |||||||
|       @close="handleClose" |       @close="handleClose" | ||||||
|     > |     > | ||||||
|       <div class="menu-container"> |       <div class="menu-container"> | ||||||
|  |         <menu-item | ||||||
|  |           v-if="enabledOptions['replyTo']" | ||||||
|  |           :option="{ | ||||||
|  |             icon: 'arrow-reply', | ||||||
|  |             label: $t('CONVERSATION.CONTEXT_MENU.REPLY_TO'), | ||||||
|  |           }" | ||||||
|  |           variant="icon" | ||||||
|  |           @click="handleReplyTo" | ||||||
|  |         /> | ||||||
|         <menu-item |         <menu-item | ||||||
|           v-if="enabledOptions['copy']" |           v-if="enabledOptions['copy']" | ||||||
|           :option="{ |           :option="{ | ||||||
| @@ -204,10 +213,13 @@ export default { | |||||||
|       this.handleClose(); |       this.handleClose(); | ||||||
|       this.showTranslateModal = true; |       this.showTranslateModal = true; | ||||||
|     }, |     }, | ||||||
|  |     handleReplyTo() { | ||||||
|  |       this.$emit('replyTo', this.message); | ||||||
|  |       this.handleClose(); | ||||||
|  |     }, | ||||||
|     onCloseTranslateModal() { |     onCloseTranslateModal() { | ||||||
|       this.showTranslateModal = false; |       this.showTranslateModal = false; | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     openDeleteModal() { |     openDeleteModal() { | ||||||
|       this.handleClose(); |       this.handleClose(); | ||||||
|       this.showDeleteModal = true; |       this.showDeleteModal = true; | ||||||
|   | |||||||
| @@ -11,6 +11,24 @@ export const INBOX_TYPES = { | |||||||
|   SMS: 'Channel::Sms', |   SMS: 'Channel::Sms', | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | export const INBOX_FEATURES = { | ||||||
|  |   REPLY_TO: 'replyTo', | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | // This is a single source of truth for inbox features | ||||||
|  | // This is used to check if a feature is available for a particular inbox or not | ||||||
|  | export const INBOX_FEATURE_MAP = { | ||||||
|  |   [INBOX_FEATURES.REPLY_TO]: [ | ||||||
|  |     INBOX_TYPES.WEB, | ||||||
|  |     INBOX_TYPES.FB, | ||||||
|  |     INBOX_TYPES.TWITTER, | ||||||
|  |     INBOX_TYPES.WHATSAPP, | ||||||
|  |     INBOX_TYPES.LINE, | ||||||
|  |     INBOX_TYPES.TELEGRAM, | ||||||
|  |     INBOX_TYPES.API, | ||||||
|  |   ], | ||||||
|  | }; | ||||||
|  |  | ||||||
| export default { | export default { | ||||||
|   computed: { |   computed: { | ||||||
|     channelType() { |     channelType() { | ||||||
| @@ -102,4 +120,9 @@ export default { | |||||||
|       ); |       ); | ||||||
|     }, |     }, | ||||||
|   }, |   }, | ||||||
|  |   methods: { | ||||||
|  |     inboxHasFeature(feature) { | ||||||
|  |       return INBOX_FEATURE_MAP[feature]?.includes(this.channelType) ?? false; | ||||||
|  |     }, | ||||||
|  |   }, | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -1,218 +1,286 @@ | |||||||
| import { shallowMount } from '@vue/test-utils'; | import { shallowMount } from '@vue/test-utils'; | ||||||
| import inboxMixin from '../inboxMixin'; | import inboxMixin from '../inboxMixin'; | ||||||
|  |  | ||||||
|  | function getComponentConfigForInbox(channelType, additionalConfig = {}) { | ||||||
|  |   return { | ||||||
|  |     render() {}, | ||||||
|  |     mixins: [inboxMixin], | ||||||
|  |     data() { | ||||||
|  |       return { | ||||||
|  |         inbox: { | ||||||
|  |           channel_type: channelType, | ||||||
|  |           ...additionalConfig, | ||||||
|  |         }, | ||||||
|  |       }; | ||||||
|  |     }, | ||||||
|  |   }; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function getComponentConfigForChat(chat) { | ||||||
|  |   return { | ||||||
|  |     render() {}, | ||||||
|  |     mixins: [inboxMixin], | ||||||
|  |     data() { | ||||||
|  |       return { | ||||||
|  |         chat, | ||||||
|  |       }; | ||||||
|  |     }, | ||||||
|  |   }; | ||||||
|  | } | ||||||
|  |  | ||||||
| describe('inboxMixin', () => { | describe('inboxMixin', () => { | ||||||
|   it('returns the correct channel type', () => { |   it('returns the correct channel type', () => { | ||||||
|     const Component = { |     const Component = getComponentConfigForInbox('Channel::WebWidget'); | ||||||
|       render() {}, |  | ||||||
|       mixins: [inboxMixin], |  | ||||||
|       data() { |  | ||||||
|         return { inbox: { channel_type: 'Channel::WebWidget' } }; |  | ||||||
|       }, |  | ||||||
|     }; |  | ||||||
|     const wrapper = shallowMount(Component); |     const wrapper = shallowMount(Component); | ||||||
|     expect(wrapper.vm.channelType).toBe('Channel::WebWidget'); |     expect(wrapper.vm.channelType).toBe('Channel::WebWidget'); | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
|   it('isAPIInbox returns true if channel type is API', () => { |   it('isAPIInbox returns true if channel type is API', () => { | ||||||
|     const Component = { |     const Component = getComponentConfigForInbox('Channel::Api'); | ||||||
|       render() {}, |  | ||||||
|       mixins: [inboxMixin], |  | ||||||
|       data() { |  | ||||||
|         return { inbox: { channel_type: 'Channel::Api' } }; |  | ||||||
|       }, |  | ||||||
|     }; |  | ||||||
|     const wrapper = shallowMount(Component); |     const wrapper = shallowMount(Component); | ||||||
|     expect(wrapper.vm.isAPIInbox).toBe(true); |     expect(wrapper.vm.isAPIInbox).toBe(true); | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
|   it('isATwitterInbox returns true if channel type is twitter', () => { |   it('isATwitterInbox returns true if channel type is twitter', () => { | ||||||
|     const Component = { |     const Component = getComponentConfigForInbox('Channel::TwitterProfile'); | ||||||
|       render() {}, |  | ||||||
|       mixins: [inboxMixin], |  | ||||||
|       data() { |  | ||||||
|         return { inbox: { channel_type: 'Channel::TwitterProfile' } }; |  | ||||||
|       }, |  | ||||||
|     }; |  | ||||||
|     const wrapper = shallowMount(Component); |     const wrapper = shallowMount(Component); | ||||||
|     expect(wrapper.vm.isATwitterInbox).toBe(true); |     expect(wrapper.vm.isATwitterInbox).toBe(true); | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
|   it('isAFacebookInbox returns true if channel type is Facebook', () => { |   it('isAFacebookInbox returns true if channel type is Facebook', () => { | ||||||
|     const Component = { |     const Component = getComponentConfigForInbox('Channel::FacebookPage'); | ||||||
|       render() {}, |  | ||||||
|       mixins: [inboxMixin], |  | ||||||
|       data() { |  | ||||||
|         return { inbox: { channel_type: 'Channel::FacebookPage' } }; |  | ||||||
|       }, |  | ||||||
|     }; |  | ||||||
|     const wrapper = shallowMount(Component); |     const wrapper = shallowMount(Component); | ||||||
|     expect(wrapper.vm.isAFacebookInbox).toBe(true); |     expect(wrapper.vm.isAFacebookInbox).toBe(true); | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
|   it('isAWebWidgetInbox returns true if channel type is Facebook', () => { |   it('isAWebWidgetInbox returns true if channel type is Facebook', () => { | ||||||
|     const Component = { |     const Component = getComponentConfigForInbox('Channel::WebWidget'); | ||||||
|       render() {}, |  | ||||||
|       mixins: [inboxMixin], |  | ||||||
|       data() { |  | ||||||
|         return { inbox: { channel_type: 'Channel::WebWidget' } }; |  | ||||||
|       }, |  | ||||||
|     }; |  | ||||||
|     const wrapper = shallowMount(Component); |     const wrapper = shallowMount(Component); | ||||||
|     expect(wrapper.vm.isAWebWidgetInbox).toBe(true); |     expect(wrapper.vm.isAWebWidgetInbox).toBe(true); | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
|   it('isASmsInbox returns true if channel type is sms', () => { |   it('isASmsInbox returns true if channel type is sms', () => { | ||||||
|     const Component = { |     const Component = getComponentConfigForInbox('Channel::Sms'); | ||||||
|       render() {}, |  | ||||||
|       mixins: [inboxMixin], |  | ||||||
|       data() { |  | ||||||
|         return { inbox: { channel_type: 'Channel::Sms' } }; |  | ||||||
|       }, |  | ||||||
|     }; |  | ||||||
|     const wrapper = shallowMount(Component); |     const wrapper = shallowMount(Component); | ||||||
|     expect(wrapper.vm.isASmsInbox).toBe(true); |     expect(wrapper.vm.isASmsInbox).toBe(true); | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
|  |   it('isASmsInbox returns true if channel type is twilio sms', () => { | ||||||
|  |     const Component = getComponentConfigForInbox('Channel::TwilioSms', { | ||||||
|  |       medium: 'sms', | ||||||
|  |     }); | ||||||
|  |     const wrapper = shallowMount(Component); | ||||||
|  |     expect(wrapper.vm.isASmsInbox).toBe(true); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   it('isALineChannel returns true if channel type is Line', () => { | ||||||
|  |     const Component = getComponentConfigForInbox('Channel::Line'); | ||||||
|  |     const wrapper = shallowMount(Component); | ||||||
|  |     expect(wrapper.vm.isALineChannel).toBe(true); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   it('isATelegramChannel returns true if channel type is Telegram', () => { | ||||||
|  |     const Component = getComponentConfigForInbox('Channel::Telegram'); | ||||||
|  |     const wrapper = shallowMount(Component); | ||||||
|  |     expect(wrapper.vm.isATelegramChannel).toBe(true); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|   it('isATwilioChannel returns true if channel type is Twilio', () => { |   it('isATwilioChannel returns true if channel type is Twilio', () => { | ||||||
|     const Component = { |     const Component = getComponentConfigForInbox('Channel::TwilioSms'); | ||||||
|       render() {}, |  | ||||||
|       mixins: [inboxMixin], |  | ||||||
|       data() { |  | ||||||
|         return { |  | ||||||
|           inbox: { |  | ||||||
|             channel_type: 'Channel::TwilioSms', |  | ||||||
|           }, |  | ||||||
|         }; |  | ||||||
|       }, |  | ||||||
|     }; |  | ||||||
|     const wrapper = shallowMount(Component); |     const wrapper = shallowMount(Component); | ||||||
|     expect(wrapper.vm.isATwilioChannel).toBe(true); |     expect(wrapper.vm.isATwilioChannel).toBe(true); | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
|   it('isATwilioSMSChannel returns true if channel type is Twilio and medium is SMS', () => { |   describe('isATwilioSMSChannel', () => { | ||||||
|     const Component = { |     it('returns true if channel type is Twilio and medium is SMS', () => { | ||||||
|       render() {}, |       const Component = getComponentConfigForInbox('Channel::TwilioSms', { | ||||||
|       mixins: [inboxMixin], |         medium: 'sms', | ||||||
|       data() { |       }); | ||||||
|         return { |       const wrapper = shallowMount(Component); | ||||||
|           inbox: { |       expect(wrapper.vm.isATwilioSMSChannel).toBe(true); | ||||||
|             channel_type: 'Channel::TwilioSms', |     }); | ||||||
|             medium: 'sms', |  | ||||||
|           }, |  | ||||||
|         }; |  | ||||||
|       }, |  | ||||||
|     }; |  | ||||||
|     const wrapper = shallowMount(Component); |  | ||||||
|     expect(wrapper.vm.isATwilioChannel).toBe(true); |  | ||||||
|     expect(wrapper.vm.isATwilioSMSChannel).toBe(true); |  | ||||||
|     expect(wrapper.vm.isASmsInbox).toBe(true); |  | ||||||
|   }); |  | ||||||
|  |  | ||||||
|   it('isATwilioWhatsAppChannel returns true if channel type is Twilio and medium is WhatsApp', () => { |     it('returns false if channel type is Twilio but medium is not SMS', () => { | ||||||
|     const Component = { |       const Component = getComponentConfigForInbox('Channel::TwilioSms', { | ||||||
|       render() {}, |         medium: 'whatsapp', | ||||||
|       mixins: [inboxMixin], |       }); | ||||||
|       data() { |       const wrapper = shallowMount(Component); | ||||||
|         return { |       expect(wrapper.vm.isATwilioSMSChannel).toBe(false); | ||||||
|           inbox: { |     }); | ||||||
|             channel_type: 'Channel::TwilioSms', |  | ||||||
|             medium: 'whatsapp', |     it('returns false if channel type is not Twilio but medium is SMS', () => { | ||||||
|           }, |       const Component = getComponentConfigForInbox('Channel::NotTwilio', { | ||||||
|         }; |         medium: 'sms', | ||||||
|       }, |       }); | ||||||
|     }; |       const wrapper = shallowMount(Component); | ||||||
|     const wrapper = shallowMount(Component); |       expect(wrapper.vm.isATwilioSMSChannel).toBe(false); | ||||||
|     expect(wrapper.vm.isATwilioChannel).toBe(true); |     }); | ||||||
|     expect(wrapper.vm.isATwilioWhatsAppChannel).toBe(true); |  | ||||||
|  |     it('returns false if neither channel type is Twilio nor medium is SMS', () => { | ||||||
|  |       const Component = getComponentConfigForInbox('Channel::NotTwilio', { | ||||||
|  |         medium: 'not_sms', | ||||||
|  |       }); | ||||||
|  |       const wrapper = shallowMount(Component); | ||||||
|  |       expect(wrapper.vm.isATwilioSMSChannel).toBe(false); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     it('returns false if channel type is Twilio but medium is empty', () => { | ||||||
|  |       const Component = getComponentConfigForInbox('Channel::TwilioSms', { | ||||||
|  |         medium: undefined, | ||||||
|  |       }); | ||||||
|  |       const wrapper = shallowMount(Component); | ||||||
|  |       expect(wrapper.vm.isATwilioSMSChannel).toBe(false); | ||||||
|  |     }); | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
|   it('isAnEmailChannel returns true if channel type is email', () => { |   it('isAnEmailChannel returns true if channel type is email', () => { | ||||||
|     const Component = { |     const Component = getComponentConfigForInbox('Channel::Email'); | ||||||
|       render() {}, |  | ||||||
|       mixins: [inboxMixin], |  | ||||||
|       data() { |  | ||||||
|         return { |  | ||||||
|           inbox: { channel_type: 'Channel::Email' }, |  | ||||||
|         }; |  | ||||||
|       }, |  | ||||||
|     }; |  | ||||||
|     const wrapper = shallowMount(Component); |     const wrapper = shallowMount(Component); | ||||||
|     expect(wrapper.vm.isAnEmailChannel).toBe(true); |     expect(wrapper.vm.isAnEmailChannel).toBe(true); | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
|   it('isTwitterInboxTweet returns true if Twitter channel type is tweet', () => { |   it('isTwitterInboxTweet returns true if Twitter channel type is tweet', () => { | ||||||
|     const Component = { |     const Component = getComponentConfigForChat({ | ||||||
|       render() {}, |       channel_type: 'Channel::TwitterProfile', | ||||||
|       mixins: [inboxMixin], |       additional_attributes: { | ||||||
|       data() { |         type: 'tweet', | ||||||
|         return { |  | ||||||
|           chat: { |  | ||||||
|             channel_type: 'Channel::TwitterProfile', |  | ||||||
|             additional_attributes: { |  | ||||||
|               type: 'tweet', |  | ||||||
|             }, |  | ||||||
|           }, |  | ||||||
|         }; |  | ||||||
|       }, |       }, | ||||||
|     }; |     }); | ||||||
|     const wrapper = shallowMount(Component); |     const wrapper = shallowMount(Component); | ||||||
|     expect(wrapper.vm.isTwitterInboxTweet).toBe(true); |     expect(wrapper.vm.isTwitterInboxTweet).toBe(true); | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
|   it('twilioBadge returns string sms if channel type is Twilio and medium is sms', () => { |   it('twilioBadge returns string sms if channel type is Twilio and medium is sms', () => { | ||||||
|     const Component = { |     const Component = getComponentConfigForInbox('Channel::TwilioSms', { | ||||||
|       render() {}, |       medium: 'sms', | ||||||
|       mixins: [inboxMixin], |     }); | ||||||
|       data() { |  | ||||||
|         return { |  | ||||||
|           inbox: { |  | ||||||
|             channel_type: 'Channel::TwilioSms', |  | ||||||
|             medium: 'sms', |  | ||||||
|           }, |  | ||||||
|         }; |  | ||||||
|       }, |  | ||||||
|     }; |  | ||||||
|     const wrapper = shallowMount(Component); |     const wrapper = shallowMount(Component); | ||||||
|     expect(wrapper.vm.isATwilioSMSChannel).toBe(true); |     expect(wrapper.vm.isATwilioSMSChannel).toBe(true); | ||||||
|     expect(wrapper.vm.twilioBadge).toBe('sms'); |     expect(wrapper.vm.twilioBadge).toBe('sms'); | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
|   it('twitterBadge returns string twitter-tweet if Twitter channel type is tweet', () => { |   it('twitterBadge returns string twitter-tweet if Twitter channel type is tweet', () => { | ||||||
|     const Component = { |     const Component = getComponentConfigForChat({ | ||||||
|       render() {}, |       id: 1, | ||||||
|       mixins: [inboxMixin], |       additional_attributes: { | ||||||
|       data() { |         type: 'tweet', | ||||||
|         return { |  | ||||||
|           chat: { |  | ||||||
|             id: 1, |  | ||||||
|             additional_attributes: { |  | ||||||
|               type: 'tweet', |  | ||||||
|             }, |  | ||||||
|           }, |  | ||||||
|         }; |  | ||||||
|       }, |       }, | ||||||
|     }; |     }); | ||||||
|  |  | ||||||
|     const wrapper = shallowMount(Component); |     const wrapper = shallowMount(Component); | ||||||
|     expect(wrapper.vm.isTwitterInboxTweet).toBe(true); |     expect(wrapper.vm.isTwitterInboxTweet).toBe(true); | ||||||
|     expect(wrapper.vm.twitterBadge).toBe('twitter-tweet'); |     expect(wrapper.vm.twitterBadge).toBe('twitter-tweet'); | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
|   it('inboxBadge returns string Channel::Telegram if isATwilioChannel and isATwitterInbox is false', () => { |   describe('Badges', () => { | ||||||
|     const Component = { |     it('inboxBadge returns string Channel::Telegram if isATwilioChannel and isATwitterInbox is false', () => { | ||||||
|       render() {}, |       const Component = getComponentConfigForInbox('Channel::Telegram'); | ||||||
|       mixins: [inboxMixin], |       const wrapper = shallowMount(Component); | ||||||
|       data() { |       expect(wrapper.vm.isATwilioChannel).toBe(false); | ||||||
|         return { |       expect(wrapper.vm.isATwitterInbox).toBe(false); | ||||||
|           inbox: { |       expect(wrapper.vm.channelType).toBe('Channel::Telegram'); | ||||||
|             channel_type: 'Channel::Telegram', |     }); | ||||||
|           }, |  | ||||||
|         }; |     it('inboxBadge returns correct badge for WhatsApp channel', () => { | ||||||
|       }, |       const Component = getComponentConfigForInbox('Channel::Whatsapp'); | ||||||
|     }; |       const wrapper = shallowMount(Component); | ||||||
|     const wrapper = shallowMount(Component); |       expect(wrapper.vm.inboxBadge).toBe('whatsapp'); | ||||||
|     expect(wrapper.vm.isATwilioChannel).toBe(false); |     }); | ||||||
|     expect(wrapper.vm.isATwitterInbox).toBe(false); |  | ||||||
|     expect(wrapper.vm.channelType).toBe('Channel::Telegram'); |     it('inboxBadge returns the twitterBadge when isATwitterInbox is true', () => { | ||||||
|  |       const Component = getComponentConfigForInbox('Channel::TwitterProfile'); | ||||||
|  |       const wrapper = shallowMount(Component); | ||||||
|  |       expect(wrapper.vm.inboxBadge).toBe('twitter-dm'); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     it('inboxBadge returns the facebookBadge when isAFacebookInbox is true', () => { | ||||||
|  |       const Component = getComponentConfigForInbox('Channel::FacebookPage'); | ||||||
|  |       const wrapper = shallowMount(Component); | ||||||
|  |       expect(wrapper.vm.inboxBadge).toBe('facebook'); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     it('inboxBadge returns the twilioBadge when isATwilioChannel is true', () => { | ||||||
|  |       const Component = getComponentConfigForInbox('Channel::TwilioSms', { | ||||||
|  |         medium: 'sms', | ||||||
|  |       }); | ||||||
|  |       const wrapper = shallowMount(Component); | ||||||
|  |       expect(wrapper.vm.inboxBadge).toBe('sms'); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     it('inboxBadge returns "whatsapp" when isAWhatsAppChannel is true', () => { | ||||||
|  |       const Component = getComponentConfigForInbox('Channel::Whatsapp'); | ||||||
|  |       const wrapper = shallowMount(Component); | ||||||
|  |       expect(wrapper.vm.inboxBadge).toBe('whatsapp'); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     it('inboxBadge returns the channelType when no specific condition is true', () => { | ||||||
|  |       const Component = getComponentConfigForInbox('Channel::Email'); | ||||||
|  |       const wrapper = shallowMount(Component); | ||||||
|  |       expect(wrapper.vm.inboxBadge).toBe('Channel::Email'); | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   describe('#inboxHasFeature', () => { | ||||||
|  |     it('detects the correct feature', () => { | ||||||
|  |       const Component = getComponentConfigForInbox('Channel::Telegram'); | ||||||
|  |       const wrapper = shallowMount(Component); | ||||||
|  |       expect(wrapper.vm.inboxHasFeature('replyTo')).toBe(true); | ||||||
|  |       expect(wrapper.vm.inboxHasFeature('feature-does-not-exist')).toBe(false); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     it('returns false for feature not included', () => { | ||||||
|  |       const Component = getComponentConfigForInbox('Channel::Sms'); | ||||||
|  |       const wrapper = shallowMount(Component); | ||||||
|  |       expect(wrapper.vm.inboxHasFeature('replyTo')).toBe(false); | ||||||
|  |       expect(wrapper.vm.inboxHasFeature('feature-does-not-exist')).toBe(false); | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   describe('WhatsApp channel', () => { | ||||||
|  |     it('returns correct whatsAppAPIProvider', () => { | ||||||
|  |       const Component = getComponentConfigForInbox('Channel::Whatsapp', { | ||||||
|  |         provider: 'whatsapp_cloud', | ||||||
|  |       }); | ||||||
|  |       const wrapper = shallowMount(Component); | ||||||
|  |       expect(wrapper.vm.whatsAppAPIProvider).toBe('whatsapp_cloud'); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     it('returns empty whatsAppAPIProvider if nothing is present', () => { | ||||||
|  |       const Component = getComponentConfigForInbox('Channel::Whatsapp', { | ||||||
|  |         provider: undefined, | ||||||
|  |       }); | ||||||
|  |       const wrapper = shallowMount(Component); | ||||||
|  |       expect(wrapper.vm.whatsAppAPIProvider).toBe(''); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     it('isAWhatsAppCloudChannel returns true if channel type is WhatsApp and provider is whatsapp_cloud', () => { | ||||||
|  |       const Component = getComponentConfigForInbox('Channel::Whatsapp', { | ||||||
|  |         provider: 'whatsapp_cloud', | ||||||
|  |       }); | ||||||
|  |       const wrapper = shallowMount(Component); | ||||||
|  |       expect(wrapper.vm.isAWhatsAppCloudChannel).toBe(true); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     it('is360DialogWhatsAppChannel returns true if channel type is WhatsApp and provider is default', () => { | ||||||
|  |       const Component = getComponentConfigForInbox('Channel::Whatsapp', { | ||||||
|  |         provider: 'default', | ||||||
|  |       }); | ||||||
|  |       const wrapper = shallowMount(Component); | ||||||
|  |       expect(wrapper.vm.is360DialogWhatsAppChannel).toBe(true); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     it('isAWhatsAppChannel returns true if channel type is WhatsApp', () => { | ||||||
|  |       const Component = getComponentConfigForInbox('Channel::Whatsapp'); | ||||||
|  |       const wrapper = shallowMount(Component); | ||||||
|  |       expect(wrapper.vm.isAWhatsAppChannel).toBe(true); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     it('isAWhatsAppChannel returns true if channel type is Twilio and medium is WhatsApp', () => { | ||||||
|  |       const Component = getComponentConfigForInbox('Channel::TwilioSms', { | ||||||
|  |         medium: 'whatsapp', | ||||||
|  |       }); | ||||||
|  |       const wrapper = shallowMount(Component); | ||||||
|  |       expect(wrapper.vm.isAWhatsAppChannel).toBe(true); | ||||||
|  |     }); | ||||||
|   }); |   }); | ||||||
| }); | }); | ||||||
|   | |||||||
| @@ -57,3 +57,5 @@ | |||||||
|   enabled: false |   enabled: false | ||||||
| - name: response_bot | - name: response_bot | ||||||
|   enabled: false |   enabled: false | ||||||
|  | - name: message_reply_to | ||||||
|  |   enabled: false | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Shivam Mishra
					Shivam Mishra