From 6dee486d4bbfa34823e3ac0ebd194fba1d5a2c19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Vay=C3=A1?= Date: Thu, 20 Feb 2020 15:16:28 +0100 Subject: [PATCH] [MM-21000] Fix using local storage to return to a DM/GM (#4791) Automatic Merge --- actions/global_actions.jsx | 16 +-- actions/global_actions.test.js | 196 ++++++++++++++++++++++++++++++++- 2 files changed, 204 insertions(+), 8 deletions(-) diff --git a/actions/global_actions.jsx b/actions/global_actions.jsx index 5bd056ad1ed1..d8ec42f4b2d9 100644 --- a/actions/global_actions.jsx +++ b/actions/global_actions.jsx @@ -14,7 +14,7 @@ import {logout, loadMe} from 'mattermost-redux/actions/users'; import {getConfig} from 'mattermost-redux/selectors/entities/general'; import {getCurrentTeamId, getMyTeams, getTeam, getMyTeamMember, getTeamMemberships} from 'mattermost-redux/selectors/entities/teams'; import {getCurrentUser, getCurrentUserId} from 'mattermost-redux/selectors/entities/users'; -import {getCurrentChannelStats, getCurrentChannelId, getMyChannelMember, getRedirectChannelNameForTeam, getChannelsNameMapInTeam} from 'mattermost-redux/selectors/entities/channels'; +import {getCurrentChannelStats, getCurrentChannelId, getMyChannelMember, getRedirectChannelNameForTeam, getChannelsNameMapInTeam, getAllDirectChannels} from 'mattermost-redux/selectors/entities/channels'; import {ChannelTypes} from 'mattermost-redux/action_types'; import {browserHistory} from 'utils/browser_history'; @@ -283,7 +283,7 @@ export function emitBrowserFocus(focus) { }); } -async function getTeamRedirectChannelIfIsAccesible(user, team) { +export async function getTeamRedirectChannelIfIsAccesible(user, team) { let state = getState(); let channel = null; @@ -299,11 +299,13 @@ async function getTeamRedirectChannelIfIsAccesible(user, team) { state = getState(); teamChannels = getChannelsNameMapInTeam(state, team.id); } - - let channelName = LocalStorageStore.getPreviousChannelName(user.id, team.id); + const channelName = LocalStorageStore.getPreviousChannelName(user.id, team.id); channel = teamChannels[channelName]; + if (typeof channel === 'undefined') { + const dmList = getAllDirectChannels(state); + channel = dmList.find((directChannel) => directChannel.name === channelName); + } let channelMember = getMyChannelMember(state, channel && channel.id); - if (!channel || !channelMember) { // This should be executed in pretty limited scenarios (when the last visited channel in the team has been removed) await dispatch(getChannelByNameAndTeamName(team.name, channelName)); // eslint-disable-line no-await-in-loop @@ -314,8 +316,8 @@ async function getTeamRedirectChannelIfIsAccesible(user, team) { } if (!channel || !channelMember) { - channelName = getRedirectChannelNameForTeam(state, team.id); - channel = teamChannels[channelName]; + const redirectedChannelName = getRedirectChannelNameForTeam(state, team.id); + channel = teamChannels[redirectedChannelName]; channelMember = getMyChannelMember(state, channel && channel.id); } diff --git a/actions/global_actions.test.js b/actions/global_actions.test.js index 6b2ac3599cdb..090084857f1c 100644 --- a/actions/global_actions.test.js +++ b/actions/global_actions.test.js @@ -9,7 +9,7 @@ import {close as closeLhs} from 'actions/views/lhs'; import LocalStorageStore from 'stores/local_storage_store'; import {getState} from 'stores/redux_store'; -import {redirectUserToDefaultTeam, toggleSideBarRightMenuAction} from 'actions/global_actions.jsx'; +import {redirectUserToDefaultTeam, toggleSideBarRightMenuAction, getTeamRedirectChannelIfIsAccesible} from 'actions/global_actions.jsx'; jest.mock('actions/views/rhs', () => ({ closeMenu: jest.fn(), @@ -326,6 +326,200 @@ describe('actions/global_actions', () => { expect(browserHistory.push).not.toHaveBeenCalled(); }); + it('should redirect to direct message if that\'s the most recently used', async () => { + const userId = 'user1'; + const teamId = 'team1'; + const user2 = 'user2'; + const directChannelId = `${userId}__${user2}`; + const mockStore = configureStore(); + const store = mockStore({ + entities: { + general: { + config: { + DefaultClientLocale: 'en', + TeammateNameDisplay: 'username', + }, + serverVersion: '5.16.0', + }, + preferences: { + myPreferences: {}, + }, + teams: { + teams: { + team1: {id: 'team1', display_name: 'Team 1', name: 'team1', delete_at: 0}, + team2: {id: 'team2', display_name: 'Team 2', name: 'team2', delete_at: 0}, + }, + myMembers: { + team1: {id: 'team1'}, + team2: {id: 'team2'}, + }, + }, + channels: { + myMembers: { + 'channel-in-team-1': {}, + 'channel-in-team-2': {}, + [directChannelId]: {}, + }, + channels: { + 'channel-in-team-1': { + id: 'channel-in-team-1', + team_id: 'team1', + name: 'channel-in-team-1', + type: 'O', + }, + 'channel-in-team-2': { + id: 'channel-in-team-2', + team_id: 'team2', + name: 'channel-in-team-2', + type: 'O', + }, + [directChannelId]: { + id: directChannelId, + team_id: '', + name: directChannelId, + type: 'D', + teammate_id: 'user2', + }, + 'group-channel': { + id: 'group-channel', + name: 'group-channel', + team_id: 'team1', + type: 'G', + }, + }, + channelsInTeam: { + team1: ['channel-in-team-1', directChannelId], + team2: ['channel-in-team-2'], + }, + }, + users: { + currentUserId: userId, + profiles: { + [userId]: {id: userId, username: userId, roles: 'system_guest'}, + [user2]: {id: user2, username: user2, roles: 'system_guest'}, + }, + }, + roles: { + roles: { + system_guest: { + permissions: [], + }, + team_guest: { + permissions: [], + }, + channel_guest: { + permissions: [], + }, + }, + }, + }, + }); + getState.mockImplementation(store.getState); + LocalStorageStore.setPreviousTeamId(userId, teamId); + LocalStorageStore.setPreviousChannelName(userId, teamId, directChannelId); + + const result = await getTeamRedirectChannelIfIsAccesible({id: userId}, {id: teamId}); + expect(result.id).toBe(directChannelId); + }); + + it('should redirect to group message if that\'s the most recently used', async () => { + const userId = 'user1'; + const teamId = 'team1'; + const user2 = 'user2'; + const directChannelId = `${userId}__${user2}`; + const groupChannelId = 'group-channel'; + const mockStore = configureStore(); + const store = mockStore({ + entities: { + general: { + config: { + DefaultClientLocale: 'en', + TeammateNameDisplay: 'username', + }, + serverVersion: '5.16.0', + }, + preferences: { + myPreferences: {}, + }, + teams: { + teams: { + team1: {id: 'team1', display_name: 'Team 1', name: 'team1', delete_at: 0}, + team2: {id: 'team2', display_name: 'Team 2', name: 'team2', delete_at: 0}, + }, + myMembers: { + team1: {id: 'team1'}, + team2: {id: 'team2'}, + }, + }, + channels: { + myMembers: { + 'channel-in-team-1': {}, + 'channel-in-team-2': {}, + [directChannelId]: {}, + [groupChannelId]: {}, + }, + channels: { + 'channel-in-team-1': { + id: 'channel-in-team-1', + team_id: 'team1', + name: 'channel-in-team-1', + type: 'O', + }, + 'channel-in-team-2': { + id: 'channel-in-team-2', + team_id: 'team2', + name: 'channel-in-team-2', + type: 'O', + }, + [directChannelId]: { + id: directChannelId, + team_id: '', + name: directChannelId, + type: 'D', + teammate_id: 'user2', + }, + [groupChannelId]: { + id: groupChannelId, + name: groupChannelId, + team_id: 'team1', + type: 'G', + }, + }, + channelsInTeam: { + team1: ['channel-in-team-1', directChannelId, groupChannelId], + team2: ['channel-in-team-2'], + }, + }, + users: { + currentUserId: userId, + profiles: { + [userId]: {id: userId, username: userId, roles: 'system_guest'}, + [user2]: {id: user2, username: user2, roles: 'system_guest'}, + }, + }, + roles: { + roles: { + system_guest: { + permissions: [], + }, + team_guest: { + permissions: [], + }, + channel_guest: { + permissions: [], + }, + }, + }, + }, + }); + getState.mockImplementation(store.getState); + LocalStorageStore.setPreviousTeamId(userId, teamId); + LocalStorageStore.setPreviousChannelName(userId, teamId, groupChannelId); + + const result = await getTeamRedirectChannelIfIsAccesible({id: userId}, {id: teamId}); + expect(result.id).toBe(groupChannelId); + }); + it('should redirect to last channel on first team when current team is no longer available', async () => { const userId = 'user1'; LocalStorageStore.setPreviousTeamId(userId, 'non-existent');