diff --git a/src/message/__tests__/__snapshots__/messageActions-test.js.snap b/src/message/__tests__/__snapshots__/messageActions-test.js.snap index 0acfe41242a..9f5243812f7 100644 --- a/src/message/__tests__/__snapshots__/messageActions-test.js.snap +++ b/src/message/__tests__/__snapshots__/messageActions-test.js.snap @@ -1,5 +1,9 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`messageActions doNarrow if newNarrow stream is not valid, do nothing 1`] = `Array []`; + +exports[`messageActions doNarrow if newNarrow user is deactivated, do nothing 1`] = `Array []`; + exports[`messageActions doNarrow when messages in new narrow, only action to switch narrow is dispatched 1`] = ` Array [ Object { diff --git a/src/message/__tests__/messageActions-test.js b/src/message/__tests__/messageActions-test.js index 520202e96bd..133a48833f9 100644 --- a/src/message/__tests__/messageActions-test.js +++ b/src/message/__tests__/messageActions-test.js @@ -1,7 +1,7 @@ import mockStore from 'redux-mock-store'; // eslint-disable-line import { doNarrow } from '../messagesActions'; -import { streamNarrow, homeNarrow } from '../../utils/narrow'; +import { streamNarrow, homeNarrow, privateNarrow } from '../../utils/narrow'; const narrow = streamNarrow('some stream'); const streamNarrowStr = JSON.stringify(narrow); @@ -20,6 +20,11 @@ describe('messageActions', () => { narrow: homeNarrow, messages: {}, }, + streams: [ + { + name: 'some stream', + }, + ], }); store.dispatch(doNarrow(narrow)); @@ -38,6 +43,11 @@ describe('messageActions', () => { narrow: homeNarrow, messages: {}, }, + streams: [ + { + name: 'some stream', + }, + ], }); store.dispatch(doNarrow(narrow)); @@ -53,10 +63,55 @@ describe('messageActions', () => { [streamNarrowStr]: [{ id: 1 }], }, }, + streams: [ + { + name: 'some stream', + }, + ], + }); + + store.dispatch(doNarrow(narrow)); + expect(store.getActions()).toMatchSnapshot(); + }); + + test('if newNarrow stream is not valid, do nothing', () => { + const store = mockStore({ + caughtUp: {}, + chat: { + narrow: homeNarrow, + messages: { + [streamNarrowStr]: [{ id: 1 }], + }, + }, + streams: [ + { + name: 'some updated stream', + }, + ], }); store.dispatch(doNarrow(narrow)); expect(store.getActions()).toMatchSnapshot(); }); + + test('if newNarrow user is deactivated, do nothing', () => { + const store = mockStore({ + caughtUp: {}, + chat: { + narrow: homeNarrow, + messages: { + [streamNarrowStr]: [{ id: 1 }], + }, + }, + users: [ + { + email: 'ab@a.com', + }, + ], + }); + + store.dispatch(doNarrow(privateNarrow('a@a.com'))); + expect(store.getActions()).toMatchSnapshot(); + }); }); }); diff --git a/src/message/messagesActions.js b/src/message/messagesActions.js index 2a8843e1c67..50c00433529 100644 --- a/src/message/messagesActions.js +++ b/src/message/messagesActions.js @@ -1,11 +1,13 @@ /* @flow */ import type { Action, Narrow, Dispatch, GetState } from '../types'; import { NULL_CAUGHTUP } from '../nullObjects'; -import { getAuth, getUsers, getAllMessages } from '../selectors'; +import { getAuth, getUsers, getAllMessages, getStreams } from '../selectors'; import { SWITCH_NARROW } from '../actionConstants'; import { getMessageIdFromLink, getNarrowFromLink, isUrlInAppLink, getFullUrl } from '../utils/url'; import openLink from '../utils/openLink'; import { fetchMessagesAtFirstUnread } from './fetchActions'; +import { validateNarrow } from '../utils/narrow'; +// import showToast from '../utils/showToast'; export const switchNarrow = (narrow: Narrow): Action => ({ type: SWITCH_NARROW, @@ -16,6 +18,13 @@ export const doNarrow = (newNarrow: Narrow, anchor: number = Number.MAX_SAFE_INT dispatch: Dispatch, getState: GetState, ) => { + const isValidNarrow = validateNarrow(newNarrow, getStreams(getState()), getUsers(getState())); + + if (!isValidNarrow) { + // show message to user that narrow is outdated now + // showToast('Invalid narrow'); + return; + } dispatch(switchNarrow(newNarrow)); const anyMessagesInNewNarrow = JSON.stringify(newNarrow) in getAllMessages(getState()); diff --git a/src/utils/narrow.js b/src/utils/narrow.js index 6a166196c19..eea7240891a 100644 --- a/src/utils/narrow.js +++ b/src/utils/narrow.js @@ -1,5 +1,5 @@ /* @flow */ -import type { Narrow, Message } from '../types'; +import type { Narrow, Message, Stream, User } from '../types'; import { normalizeRecipients } from './message'; export const homeNarrow: Narrow = []; @@ -137,3 +137,14 @@ export const getNarrowFromMessage = (message: Message, email: string) => { return streamNarrow(message.display_recipient); }; + +export const validateNarrow = (narrow: Narrow, streams: Stream[], users: User[]): boolean => { + if (isStreamOrTopicNarrow(narrow)) { + // check if stream is not outdated + return streams && streams.find(s => s.name === narrow[0].operand) !== undefined; + } else if (isPrivateNarrow(narrow)) { + // check user account is not deactivited + return users && users.find(u => u.email === narrow[0].operand) !== undefined; + } + return isSpecialNarrow(narrow) || isHomeNarrow(narrow); +};