diff --git a/app/actions/views/channel.js b/app/actions/views/channel.js
index 122901c02..de59441e3 100644
--- a/app/actions/views/channel.js
+++ b/app/actions/views/channel.js
@@ -379,45 +379,23 @@ export function handleSelectChannel(channelId, fromPushNotification = false) {
dispatch(loadPostsIfNecessaryWithRetry(channelId));
}
+ let previousChannelId;
+ if (!fromPushNotification && !sameChannel) {
+ previousChannelId = currentChannelId;
+ }
+
const actions = [
selectChannel(channelId),
getChannelStats(channelId),
setChannelDisplayName(channel.display_name),
- {
- type: ViewTypes.SET_INITIAL_POST_VISIBILITY,
- data: channelId,
- },
+ setInitialPostVisibility(channelId),
setChannelLoading(false),
- {
- type: ViewTypes.SET_LAST_CHANNEL_FOR_TEAM,
- teamId: currentTeamId,
- channelId,
- },
+ setLastChannelForTeam(currentTeamId, channelId),
+ selectChannelWithMember(channelId, channel, member),
+ markChannelViewedAndRead(channelId, previousChannelId),
];
- let markPreviousChannelId;
- if (!fromPushNotification && !sameChannel) {
- markPreviousChannelId = currentChannelId;
- actions.push({
- type: ViewTypes.SELECT_CHANNEL_WITH_MEMBER,
- data: currentChannelId,
- channel: getChannel(state, currentChannelId),
- member: getMyChannelMember(state, currentChannelId),
- });
- }
-
- if (!fromPushNotification) {
- actions.push({
- type: ViewTypes.SELECT_CHANNEL_WITH_MEMBER,
- data: channelId,
- channel,
- member,
- });
- }
-
dispatch(batchActions(actions));
-
- dispatch(markChannelViewedAndRead(channelId, markPreviousChannelId));
};
}
@@ -686,3 +664,27 @@ function setLoadMorePostsVisible(visible) {
data: visible,
};
}
+
+function setInitialPostVisibility(channelId) {
+ return {
+ type: ViewTypes.SET_INITIAL_POST_VISIBILITY,
+ data: channelId,
+ };
+}
+
+function setLastChannelForTeam(teamId, channelId) {
+ return {
+ type: ViewTypes.SET_LAST_CHANNEL_FOR_TEAM,
+ teamId,
+ channelId,
+ };
+}
+
+function selectChannelWithMember(channelId, channel, member) {
+ return {
+ type: ViewTypes.SELECT_CHANNEL_WITH_MEMBER,
+ data: channelId,
+ channel,
+ member,
+ };
+}
diff --git a/app/actions/views/channel.test.js b/app/actions/views/channel.test.js
index 3af66604b..350e02b40 100644
--- a/app/actions/views/channel.test.js
+++ b/app/actions/views/channel.test.js
@@ -5,27 +5,24 @@ import configureStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import initialState from 'app/initial_state';
+import {ViewTypes} from 'app/constants';
import testHelper from 'test/test_helper';
-import {
+import * as ChannelActions from 'app/actions/views/channel';
+const {
+ handleSelectChannel,
handleSelectChannelByName,
loadPostsIfNecessaryWithRetry,
-} from 'app/actions/views/channel';
+} = ChannelActions;
import postReducer from 'mattermost-redux/reducers/entities/posts';
-jest.mock('mattermost-redux/selectors/entities/channels', () => ({
- getChannel: () => ({data: 'received-channel-id'}),
- getCurrentChannelId: () => 'current-channel-id',
- getMyChannelMember: () => ({data: {member: {}}}),
-}));
-
jest.mock('mattermost-redux/actions/channels', () => {
const channelActions = require.requireActual('mattermost-redux/actions/channels');
return {
...channelActions,
- markChannelAsRead: jest.fn(),
- markChannelAsViewed: jest.fn(),
+ markChannelAsRead: jest.fn().mockReturnValue({type: ''}),
+ markChannelAsViewed: jest.fn().mockReturnValue({type: ''}),
};
});
@@ -130,6 +127,11 @@ describe('Actions.Views.Channel', () => {
},
};
+ const channelSelectors = require('mattermost-redux/selectors/entities/channels');
+ channelSelectors.getChannel = jest.fn((state, channelId) => ({data: channelId}));
+ channelSelectors.getCurrentChannelId = jest.fn(() => currentChannelId);
+ channelSelectors.getMyChannelMember = jest.fn(() => ({data: {member: {}}}));
+
test('handleSelectChannelByName success', async () => {
store = mockStore(storeObj);
@@ -238,4 +240,33 @@ describe('Actions.Views.Channel', () => {
expect(postActions.getPostsSince).toHaveBeenCalledWith(currentChannelId, store.getState().views.channel.lastGetPosts[currentChannelId]);
expect(receivedPostsSince).not.toBe(null);
});
+
+ const handleSelectChannelCases = [
+ [currentChannelId, true],
+ [currentChannelId, false],
+ [`not-${currentChannelId}`, true],
+ [`not-${currentChannelId}`, false],
+ ];
+ test.each(handleSelectChannelCases)('handleSelectChannel dispatches selectChannelWithMember', async (channelId, fromPushNotification) => {
+ store = mockStore({...storeObj});
+
+ await store.dispatch(handleSelectChannel(channelId, fromPushNotification));
+ const storeBatchActions = store.getActions().find(({type}) => type === 'BATCHING_REDUCER.BATCH');
+ const selectChannelWithMember = storeBatchActions.payload.find(({type}) => type === ViewTypes.SELECT_CHANNEL_WITH_MEMBER);
+
+ const expectedSelectChannelWithMember = {
+ type: ViewTypes.SELECT_CHANNEL_WITH_MEMBER,
+ data: channelId,
+ channel: {
+ data: channelId,
+ },
+ member: {
+ data: {
+ member: {},
+ },
+ },
+
+ };
+ expect(selectChannelWithMember).toStrictEqual(expectedSelectChannelWithMember);
+ });
});
diff --git a/app/actions/views/root.js b/app/actions/views/root.js
index 8d3077c3c..6bed1877d 100644
--- a/app/actions/views/root.js
+++ b/app/actions/views/root.js
@@ -47,7 +47,7 @@ export function loadConfigAndLicense() {
};
}
-export function loadFromPushNotification(notification, startAppFromPushNotification) {
+export function loadFromPushNotification(notification) {
return async (dispatch, getState) => {
const state = getState();
const {data} = notification;
@@ -84,7 +84,7 @@ export function loadFromPushNotification(notification, startAppFromPushNotificat
dispatch(selectTeam({id: teamId}));
}
- dispatch(handleSelectChannel(channelId, startAppFromPushNotification));
+ dispatch(handleSelectChannel(channelId, true));
};
}
diff --git a/app/screens/notification/__snapshots__/notification.test.js.snap b/app/screens/notification/__snapshots__/notification.test.js.snap
new file mode 100644
index 000000000..87b26a683
--- /dev/null
+++ b/app/screens/notification/__snapshots__/notification.test.js.snap
@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Notification should match snapshot 1`] = `null`;
diff --git a/app/screens/notification/notification.test.js b/app/screens/notification/notification.test.js
new file mode 100644
index 000000000..002c2037d
--- /dev/null
+++ b/app/screens/notification/notification.test.js
@@ -0,0 +1,63 @@
+// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
+// See LICENSE.txt for license information.
+
+import React from 'react';
+import {shallow} from 'enzyme';
+import {InteractionManager} from 'react-native';
+
+import Preferences from 'mattermost-redux/constants/preferences';
+
+import Notification from './notification.js';
+
+jest.mock('react-native-navigation', () => ({
+ Navigation: {
+ events: jest.fn(() => ({
+ registerComponentDidDisappearListener: jest.fn(),
+ })),
+ },
+}));
+
+InteractionManager.runAfterInteractions = jest.fn((cb) => cb());
+
+describe('Notification', () => {
+ const baseProps = {
+ actions: {
+ loadFromPushNotification: jest.fn(),
+ },
+ componentId: 'component-id',
+ deviceWidth: 100,
+ notification: {},
+ theme: Preferences.THEMES.default,
+ };
+
+ test('should match snapshot', () => {
+ const wrapper = shallow(
+ ,
+ );
+
+ expect(wrapper.getElement()).toMatchSnapshot();
+ });
+
+ test('should call loadFromPushNotification on notification tap for non-local notification', () => {
+ const props = {
+ ...baseProps,
+ notification: {
+ localNotification: true,
+ },
+ };
+ const wrapper = shallow(
+ ,
+ );
+ const instance = wrapper.instance();
+
+ instance.notificationTapped();
+ expect(baseProps.actions.loadFromPushNotification).not.toHaveBeenCalled();
+
+ const notification = {
+ localNotification: false,
+ };
+ wrapper.setProps({notification});
+ instance.notificationTapped();
+ expect(baseProps.actions.loadFromPushNotification).toHaveBeenCalledWith(notification);
+ });
+});
diff --git a/app/utils/push_notifications.js b/app/utils/push_notifications.js
index 29e4dc274..f296c139c 100644
--- a/app/utils/push_notifications.js
+++ b/app/utils/push_notifications.js
@@ -47,7 +47,7 @@ class PushNotificationUtils {
loadFromNotification = async (notification) => {
// Set appStartedFromPushNotification to avoid channel screen to call selectInitialChannel
EphemeralStore.appStartedFromPushNotification = true;
- await this.store.dispatch(loadFromPushNotification(notification, true));
+ await this.store.dispatch(loadFromPushNotification(notification));
// if we have a componentId means that the app is already initialized
const componentId = EphemeralStore.getNavigationTopComponentId();