From aaba9fa472d34e338bf538926da4b23121d4bad7 Mon Sep 17 00:00:00 2001 From: Ashish Bhate Date: Tue, 12 Jan 2021 04:21:14 +0530 Subject: [PATCH] [MM-30976] fix viewing/joining archived channels using channel links (#5106) --- app/actions/views/channel.js | 2 +- app/actions/views/channel.test.js | 55 +++++++++++++++++++++++++++++++ app/selectors/channel.js | 14 +++++++- 3 files changed, 69 insertions(+), 2 deletions(-) diff --git a/app/actions/views/channel.js b/app/actions/views/channel.js index e795a009c..8f59e6587 100644 --- a/app/actions/views/channel.js +++ b/app/actions/views/channel.js @@ -224,7 +224,7 @@ export function handleSelectChannelByName(channelName, teamName, errorHandler) { const {teams: currentTeams, currentTeamId} = state.entities.teams; const currentTeam = currentTeams[currentTeamId]; const currentTeamName = currentTeam?.name; - const response = await dispatch(getChannelByNameAndTeamName(teamName || currentTeamName, channelName)); + const response = await dispatch(getChannelByNameAndTeamName(teamName || currentTeamName, channelName, true)); const {error, data: channel} = response; const currentChannelId = getCurrentChannelId(state); diff --git a/app/actions/views/channel.test.js b/app/actions/views/channel.test.js index e5b2a6373..199141dce 100644 --- a/app/actions/views/channel.test.js +++ b/app/actions/views/channel.test.js @@ -150,6 +150,7 @@ describe('Actions.Views.Channel', () => { channelSelectors.getMyChannelMember = jest.fn(() => ({data: {member: {}}})); const appChannelSelectors = require('app/selectors/channel'); + const getChannelReachableOriginal = appChannelSelectors.getChannelReachable; appChannelSelectors.getChannelReachable = jest.fn(() => true); test('handleSelectChannelByName success', async () => { @@ -232,6 +233,60 @@ describe('Actions.Views.Channel', () => { expect(joinedChannel).toBe(true); }); + test('handleSelectChannelByName select archived channel with ExperimentalViewArchivedChannels enabled', async () => { + const archivedChannelStoreObj = {...storeObj}; + archivedChannelStoreObj.entities.general.config.ExperimentalViewArchivedChannels = 'true'; + store = mockStore(archivedChannelStoreObj); + + appChannelSelectors.getChannelReachable = getChannelReachableOriginal; + actions.getChannelByNameAndTeamName = jest.fn(() => { + return { + type: MOCK_RECEIVE_CHANNEL_TYPE, + data: {id: 'channel-id-3', name: 'channel-id-3', display_name: 'Test Channel', type: General.OPEN_CHANNEL, delete_at: 100}, + }; + }); + channelSelectors.getChannelByName = jest.fn(() => { + return { + data: {id: 'channel-id-3', name: 'channel-id-3', display_name: 'Test Channel', type: General.OPEN_CHANNEL, delete_at: 100}, + }; + }); + const errorHandler = jest.fn(); + + await store.dispatch(handleSelectChannelByName('channel-id-3', currentTeamName, errorHandler)); + + const storeActions = store.getActions(); + const receivedChannel = storeActions.some((action) => action.type === MOCK_RECEIVE_CHANNEL_TYPE); + expect(receivedChannel).toBe(true); + expect(errorHandler).not.toBeCalled(); + }); + + test('handleSelectChannelByName select archived channel with ExperimentalViewArchivedChannels disabled', async () => { + const noArchivedChannelStoreObj = {...storeObj}; + noArchivedChannelStoreObj.entities.general.config.ExperimentalViewArchivedChannels = 'false'; + store = mockStore(noArchivedChannelStoreObj); + + appChannelSelectors.getChannelReachable = getChannelReachableOriginal; + actions.getChannelByNameAndTeamName = jest.fn(() => { + return { + type: MOCK_RECEIVE_CHANNEL_TYPE, + data: {id: 'channel-id-3', name: 'channel-id-3', display_name: 'Test Channel', type: General.OPEN_CHANNEL, delete_at: 100}, + }; + }); + channelSelectors.getChannelByName = jest.fn(() => { + return { + data: {id: 'channel-id-3', name: 'channel-id-3', display_name: 'Test Channel', type: General.OPEN_CHANNEL, delete_at: 100}, + }; + }); + const errorHandler = jest.fn(); + + await store.dispatch(handleSelectChannelByName('channel-id-3', currentTeamName, errorHandler)); + + const storeActions = store.getActions(); + const receivedChannel = storeActions.some((action) => action.type === MOCK_RECEIVE_CHANNEL_TYPE); + expect(receivedChannel).toBe(true); + expect(errorHandler).toBeCalled(); + }); + test('loadPostsIfNecessaryWithRetry for the first time', async () => { store = mockStore(storeObj); diff --git a/app/selectors/channel.js b/app/selectors/channel.js index b37697d50..1df59139f 100644 --- a/app/selectors/channel.js +++ b/app/selectors/channel.js @@ -6,6 +6,8 @@ import {createSelector} from 'reselect'; import {getCurrentUserId, getUser} from '@mm-redux/selectors/entities/users'; import {getChannelByName} from '@mm-redux/selectors/entities/channels'; import {getTeamByName} from '@mm-redux/selectors/entities/teams'; +import {getConfig} from '@mm-redux/selectors/entities/general'; +import {isArchivedChannel} from '@mm-redux/utils/channel_utils'; const getOtherUserIdForDm = createSelector( (state, channel) => channel, @@ -46,5 +48,15 @@ const getChannel = (state, channelName) => getChannelByName(state, channelName); export const getChannelReachable = createSelector( getTeam, getChannel, - (team, channel) => team && channel, + getConfig, + (team, channel, config) => { + if (!(team && channel)) { + return false; + } + const viewArchivedChannels = config.ExperimentalViewArchivedChannels === 'true'; + if (isArchivedChannel(channel) && !viewArchivedChannels) { + return false; + } + return true; + }, );