From 7b15c24e151b2046e86196939fe10b149b4960ee Mon Sep 17 00:00:00 2001 From: Sudheer Date: Wed, 22 Jul 2020 00:33:59 +0530 Subject: [PATCH] MM-25525 Sidebar: Event for tracking number of visible GMs and DMs in LHS (#5794) * MM-25525 Sidebar: Event for tracking number of visible GMs and DMs in sidebar * Fix types * Fix test * Use getDirectChannels * Update rudder key for testing * Fix Actions type * Remove Rudder keys for testing Co-authored-by: Harrison Healey --- actions/user_actions.jsx | 12 +++++++ actions/user_actions.test.js | 31 +++++++++++++++++-- .../data_prefetch/data_prefetch.test.tsx | 3 ++ components/data_prefetch/data_prefetch.tsx | 2 ++ components/data_prefetch/index.ts | 3 ++ 5 files changed, 49 insertions(+), 2 deletions(-) diff --git a/actions/user_actions.jsx b/actions/user_actions.jsx index 197affcce0ff..d167d6e2a716 100644 --- a/actions/user_actions.jsx +++ b/actions/user_actions.jsx @@ -13,6 +13,7 @@ import { getMyChannels, getMyChannelMember, getChannelMembersInChannels, + getDirectChannels, } from 'mattermost-redux/selectors/entities/channels'; import {getBool} from 'mattermost-redux/selectors/entities/preferences'; import {getCurrentTeamId, getTeamMember} from 'mattermost-redux/selectors/entities/teams'; @@ -21,6 +22,7 @@ import {makeFilterAutoclosedDMs, makeFilterManuallyClosedDMs} from 'mattermost-r import {CategoryTypes} from 'mattermost-redux/constants/channel_categories'; import {loadStatusesForProfilesList, loadStatusesForProfilesMap} from 'actions/status_actions.jsx'; +import {trackEvent} from 'actions/diagnostics_actions.jsx'; import store from 'stores/redux_store.jsx'; import * as Utils from 'utils/utils.jsx'; import {Constants, Preferences, UserStatuses} from 'utils/constants'; @@ -419,3 +421,13 @@ export function autoResetStatus() { return userStatus; }; } + +export function trackDMGMOpenChannels() { + return (doDispatch, doGetState) => { + const state = doGetState(); + const channels = getDirectChannels(state); + trackEvent('ui', 'LHS_DM_GM_Count', {count: channels.length}); + + return {data: true}; + }; +} diff --git a/actions/user_actions.test.js b/actions/user_actions.test.js index 85aee19ca6f3..c24d2a962172 100644 --- a/actions/user_actions.test.js +++ b/actions/user_actions.test.js @@ -11,6 +11,7 @@ import {CategoryTypes} from 'mattermost-redux/constants/channel_categories'; import * as UserActions from 'actions/user_actions'; import {getState} from 'stores/redux_store'; import TestHelper from 'tests/helpers/client-test-helper'; +import {trackEvent} from 'actions/diagnostics_actions.jsx'; const mockStore = configureStore([thunk]); @@ -29,12 +30,24 @@ jest.mock('mattermost-redux/actions/users', () => { }; }); +jest.mock('mattermost-redux/selectors/entities/channels', () => { + const GeneralTypes = require.requireActual('mattermost-redux/constants').General; + const original = jest.requireActual('mattermost-redux/selectors/entities/channels'); + const mockDmGmUsersInLhs = [{id: 'gmChannel', type: GeneralTypes.GM_CHANNEL}, {id: 'dmChannel', type: GeneralTypes.DM_CHANNEL}]; + + return { + ...original, + getDirectChannels: jest.fn().mockReturnValue(mockDmGmUsersInLhs), + }; +}); + jest.mock('mattermost-redux/selectors/entities/channel_categories', () => { - const GeneralTypes = jest.requireActual('mattermost-redux/constants').General; - const original = jest.requireActual('mattermost-redux/selectors/entities/channel_categories'); + const GeneralTypes = require.requireActual('mattermost-redux/constants').General; + const original = require.requireActual('mattermost-redux/selectors/entities/channel_categories'); const mockChannelsObj = [{id: 'gmChannel', type: GeneralTypes.GM_CHANNEL}]; const mockFunc = jest.fn(); + return { ...original, makeFilterAutoclosedDMs: jest.fn().mockReturnValue(mockFunc), @@ -74,6 +87,14 @@ jest.mock('stores/redux_store', () => { }; }); +jest.mock('actions/diagnostics_actions.jsx', () => { + const original = require.requireActual('actions/diagnostics_actions.jsx'); + return { + ...original, + trackEvent: jest.fn(), + }; +}); + describe('Actions.User', () => { const initialState = { entities: { @@ -349,4 +370,10 @@ describe('Actions.User', () => { expect(UserActions.queue.onEmpty).toHaveBeenCalled(); expect(UserActions.queue.add).toHaveBeenCalled(); }); + + test('trackDMGMOpenChannels', async () => { + const testStore = await mockStore(initialState); + await testStore.dispatch(UserActions.trackDMGMOpenChannels()); + expect(trackEvent).toHaveBeenCalledWith('ui', 'LHS_DM_GM_Count', {count: 2}); + }); }); diff --git a/components/data_prefetch/data_prefetch.test.tsx b/components/data_prefetch/data_prefetch.test.tsx index a213fa9cc8e7..1ef212d1d301 100644 --- a/components/data_prefetch/data_prefetch.test.tsx +++ b/components/data_prefetch/data_prefetch.test.tsx @@ -19,6 +19,7 @@ describe('/components/create_team', () => { currentChannelId: '', actions: { prefetchChannelPosts: jest.fn(() => Promise.resolve({})), + trackDMGMOpenChannels: jest.fn(() => Promise.resolve()), }, prefetchQueueObj: { 1: ['mentionChannel'], @@ -71,6 +72,8 @@ describe('/components/create_team', () => { instance.prefetchPosts = jest.fn(); wrapper.setProps({currentChannelId: 'currentChannelId'}); expect(instance.prefetchPosts).toHaveBeenCalledWith('currentChannelId'); + await loadProfilesForSidebar(); + expect(defaultProps.actions.trackDMGMOpenChannels).toHaveBeenCalled(); }); test('should call for LHS profiles and also call for posts based on prefetchQueueObj', async () => { diff --git a/components/data_prefetch/data_prefetch.tsx b/components/data_prefetch/data_prefetch.tsx index 25db3c809ce8..81c8a84c7ebd 100644 --- a/components/data_prefetch/data_prefetch.tsx +++ b/components/data_prefetch/data_prefetch.tsx @@ -18,6 +18,7 @@ type Props = { unreadChannels: Channel[]; actions: { prefetchChannelPosts: (channelId: string, delay?: number) => Promise; + trackDMGMOpenChannels: () => Promise; }; } @@ -52,6 +53,7 @@ export default class DataPrefetch extends React.PureComponent { queue.add(async () => this.prefetchPosts(currentChannelId)); await loadProfilesForSidebar(); this.prefetchData(); + this.props.actions.trackDMGMOpenChannels(); } else if (prevProps.prefetchQueueObj !== prefetchQueueObj) { clearTimeout(this.prefetchTimeout); await queue.clear(); diff --git a/components/data_prefetch/index.ts b/components/data_prefetch/index.ts index ec6d2fe48264..326819ec8108 100644 --- a/components/data_prefetch/index.ts +++ b/components/data_prefetch/index.ts @@ -17,11 +17,13 @@ import {RelationOneToOne} from 'mattermost-redux/types/utilities'; import {GlobalState} from 'types/store'; import {prefetchChannelPosts} from 'actions/views/channel'; +import {trackDMGMOpenChannels} from 'actions/user_actions'; import DataPrefetch from './data_prefetch'; type Actions = { prefetchChannelPosts: (channelId: string, delay?: number) => Promise<{data: {}}>; + trackDMGMOpenChannels: () => Promise; }; enum Priority { @@ -77,6 +79,7 @@ function mapDispatchToProps(dispatch: Dispatch) { return { actions: bindActionCreators, Actions>({ prefetchChannelPosts, + trackDMGMOpenChannels, }, dispatch), }; }