From 789f84af9085969fb37c440336384fc25b1939c8 Mon Sep 17 00:00:00 2001 From: Harrison Healey Date: Fri, 2 Jun 2023 14:23:01 -0400 Subject: [PATCH] MM-52297 Fix reactions disappearing with search open and add testing utilities (#23510) * MM-52297 Fix reactions disappearing when search is open * Add unit tests and extra utilities * Fix typing issue --- .../external_link/external_link.test.tsx | 15 +- .../components/post/post_component.test.tsx | 131 ++++++++++ .../src/components/post/post_component.tsx | 2 +- .../src/components/post/user_profile.tsx | 4 +- .../__snapshots__/commented_on.test.tsx.snap | 7 - .../index.test.tsx | 15 +- .../components/user_profile/user_profile.tsx | 2 - webapp/channels/src/images/logo_compact.png | Bin 2431 -> 0 bytes .../src/tests/react_testing_utils.test.tsx | 244 ++++++++++++++++++ .../src/tests/react_testing_utils.tsx | 85 +++++- webapp/channels/src/utils/constants.tsx | 2 - 11 files changed, 472 insertions(+), 35 deletions(-) create mode 100644 webapp/channels/src/components/post/post_component.test.tsx delete mode 100644 webapp/channels/src/images/logo_compact.png create mode 100644 webapp/channels/src/tests/react_testing_utils.test.tsx diff --git a/webapp/channels/src/components/external_link/external_link.test.tsx b/webapp/channels/src/components/external_link/external_link.test.tsx index 67e237286d..753b48edb5 100644 --- a/webapp/channels/src/components/external_link/external_link.test.tsx +++ b/webapp/channels/src/components/external_link/external_link.test.tsx @@ -59,12 +59,11 @@ describe('components/external_link', () => { }, }, }; - const store: GlobalState = JSON.parse(JSON.stringify(state)); renderWithIntlAndStore( {'Click Me'} , - store, + state, ); expect(screen.queryByText('Click Me')).toHaveAttribute( @@ -86,12 +85,11 @@ describe('components/external_link', () => { }, }, }; - const store: GlobalState = JSON.parse(JSON.stringify(state)); renderWithIntlAndStore( {'Click Me'} , - store, + state, ); expect(screen.queryByText('Click Me')).toHaveAttribute( @@ -113,12 +111,11 @@ describe('components/external_link', () => { }, }, }; - const store: GlobalState = JSON.parse(JSON.stringify(state)); renderWithIntlAndStore( {'Click Me'} , - store, + state, ); expect(screen.queryByText('Click Me')).not.toHaveAttribute( @@ -140,14 +137,13 @@ describe('components/external_link', () => { }, }, }; - const store: GlobalState = JSON.parse(JSON.stringify(state)); renderWithIntlAndStore( {'Click Me'}, - store, + state, ); expect(screen.queryByText('Click Me')).toHaveAttribute( @@ -175,14 +171,13 @@ describe('components/external_link', () => { }, }, }; - const store: GlobalState = JSON.parse(JSON.stringify(state)); renderWithIntlAndStore( {'Click Me'} , - store, + state, ); expect(screen.queryByText('Click Me')).toHaveAttribute( diff --git a/webapp/channels/src/components/post/post_component.test.tsx b/webapp/channels/src/components/post/post_component.test.tsx new file mode 100644 index 0000000000..8bba229665 --- /dev/null +++ b/webapp/channels/src/components/post/post_component.test.tsx @@ -0,0 +1,131 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {screen} from '@testing-library/react'; +import React from 'react'; + +import {DeepPartial} from '@mattermost/types/utilities'; + +import {renderWithFullContext} from 'tests/react_testing_utils'; + +import {GlobalState} from 'types/store'; + +import {Locations} from 'utils/constants'; +import {TestHelper} from 'utils/test_helper'; + +import PostComponent from './post_component'; +import mergeObjects from 'packages/mattermost-redux/test/merge_objects'; + +describe('PostComponent', () => { + const baseProps = { + center: false, + currentTeam: TestHelper.getTeamMock(), + currentUserId: 'currentUserId', + displayName: '', + isBot: false, + isFlagged: false, + isMobileView: false, + isPostAcknowledgementsEnabled: false, + isPostPriorityEnabled: false, + location: Locations.CENTER, + post: TestHelper.getPostMock(), + recentEmojis: [], + actions: { + markPostAsUnread: jest.fn(), + emitShortcutReactToLastPostFrom: jest.fn(), + setActionsMenuInitialisationState: jest.fn(), + selectPost: jest.fn(), + selectPostFromRightHandSideSearch: jest.fn(), + removePost: jest.fn(), + closeRightHandSide: jest.fn(), + selectPostCard: jest.fn(), + setRhsExpanded: jest.fn(), + }, + }; + + describe('reactions', () => { + const baseState: DeepPartial = { + entities: { + posts: { + reactions: { + [baseProps.post.id]: { + [`${baseProps.currentUserId}-taco`]: TestHelper.getReactionMock({emoji_name: 'taco'}), + }, + }, + }, + }, + }; + + test('should show reactions in the center channel', () => { + renderWithFullContext( + , + baseState, + ); + + expect(screen.getByLabelText('reactions')).toBeInTheDocument(); + }); + + test('should show reactions in thread view', () => { + const state = mergeObjects(baseState, { + views: { + rhs: { + selectedPostId: baseProps.post.id, + }, + }, + }); + + const {rerender} = renderWithFullContext( + , + state, + ); + + expect(screen.getByLabelText('reactions')).toBeInTheDocument(); + + rerender( + , + ); + + expect(screen.getByLabelText('reactions')).toBeInTheDocument(); + }); + + test('should show only show reactions in search results with pinned/saved posts visible', () => { + const {rerender} = renderWithFullContext( + , + baseState, + ); + + expect(screen.queryByLabelText('reactions')).not.toBeInTheDocument(); + + rerender( + , + ); + + expect(screen.getByLabelText('reactions')).toBeInTheDocument(); + + rerender( + , + ); + + expect(screen.getByLabelText('reactions')).toBeInTheDocument(); + }); + }); +}); diff --git a/webapp/channels/src/components/post/post_component.tsx b/webapp/channels/src/components/post/post_component.tsx index 9fba63cdc4..6a63f95bb9 100644 --- a/webapp/channels/src/components/post/post_component.tsx +++ b/webapp/channels/src/components/post/post_component.tsx @@ -480,7 +480,7 @@ const PostComponent = (props: Props): JSX.Element => { ) : null; const currentPostDay = getDateForUnixTicks(post.create_at); const channelDisplayName = getChannelName(); - const showReactions = props.location !== Locations.SEARCH && !props.isPinnedPosts && !props.isFlaggedPosts; + const showReactions = props.location !== Locations.SEARCH || props.isPinnedPosts || props.isFlaggedPosts; const getTestId = () => { let idPrefix: string; diff --git a/webapp/channels/src/components/post/user_profile.tsx b/webapp/channels/src/components/post/user_profile.tsx index ca2d0ea41e..03f1280ef3 100644 --- a/webapp/channels/src/components/post/user_profile.tsx +++ b/webapp/channels/src/components/post/user_profile.tsx @@ -4,7 +4,7 @@ import React, {ReactNode} from 'react'; import {FormattedMessage} from 'react-intl'; -import Constants, {Locations} from 'utils/constants'; +import {Locations} from 'utils/constants'; import {fromAutoResponder, isFromWebhook} from 'utils/post_utils'; import Tag from 'components/widgets/tag/tag'; @@ -17,7 +17,6 @@ import {Post} from '@mattermost/types/posts'; type Props = { post: Post; compactDisplay?: boolean; - currentUserId: string; colorizeUsernames?: boolean; enablePostUsernameOverride?: boolean; isConsecutivePost?: boolean; @@ -142,7 +141,6 @@ const PostUserProfile = (props: Props): JSX.Element | null => { /> } userId={post.user_id} - overwriteImage={Constants.SYSTEM_MESSAGE_PROFILE_IMAGE} disablePopover={true} channelId={post.channel_id} colorize={colorize} diff --git a/webapp/channels/src/components/post_view/commented_on/__snapshots__/commented_on.test.tsx.snap b/webapp/channels/src/components/post_view/commented_on/__snapshots__/commented_on.test.tsx.snap index c34af41f1c..844456614d 100644 --- a/webapp/channels/src/components/post_view/commented_on/__snapshots__/commented_on.test.tsx.snap +++ b/webapp/channels/src/components/post_view/commented_on/__snapshots__/commented_on.test.tsx.snap @@ -21,7 +21,6 @@ exports[`components/post_view/CommentedOn should match snapshot 1`] = ` hasMention={true} hideStatus={false} isRHS={false} - overwriteImage="" overwriteName="" userId="" /> @@ -60,7 +59,6 @@ exports[`components/post_view/CommentedOn should match snapshot 2`] = ` hasMention={true} hideStatus={false} isRHS={false} - overwriteImage="" overwriteName="" userId="" /> @@ -99,7 +97,6 @@ exports[`components/post_view/CommentedOn should match snapshot 3`] = ` hasMention={true} hideStatus={false} isRHS={false} - overwriteImage="" overwriteName="" userId="" /> @@ -140,7 +137,6 @@ exports[`components/post_view/CommentedOn should match snapshots for post with p hasMention={true} hideStatus={false} isRHS={false} - overwriteImage="" overwriteName="" userId="" /> @@ -179,7 +175,6 @@ exports[`components/post_view/CommentedOn should match snapshots for post with p hasMention={true} hideStatus={false} isRHS={false} - overwriteImage="" overwriteName="" userId="" /> @@ -218,7 +213,6 @@ exports[`components/post_view/CommentedOn should match snapshots for post with p hasMention={true} hideStatus={false} isRHS={false} - overwriteImage="" overwriteName="" userId="" /> @@ -257,7 +251,6 @@ exports[`components/post_view/CommentedOn should match snapshots for post with p hasMention={true} hideStatus={false} isRHS={false} - overwriteImage="" overwriteName="" userId="" /> diff --git a/webapp/channels/src/components/self_hosted_purchases/self_hosted_expansion_modal/index.test.tsx b/webapp/channels/src/components/self_hosted_purchases/self_hosted_expansion_modal/index.test.tsx index 2915d932de..89642776ee 100644 --- a/webapp/channels/src/components/self_hosted_purchases/self_hosted_expansion_modal/index.test.tsx +++ b/webapp/channels/src/components/self_hosted_purchases/self_hosted_expansion_modal/index.test.tsx @@ -17,6 +17,7 @@ import {DeepPartial} from '@mattermost/types/utilities'; import SelfHostedExpansionModal, {makeInitialState, canSubmit, FormState} from './'; import moment from 'moment-timezone'; +import mergeObjects from 'packages/mattermost-redux/test/merge_objects'; interface MockCardInputProps { onCardInputChange: (event: {complete: boolean}) => void; @@ -345,13 +346,19 @@ describe('SelfHostedExpansionModal RHS Card', () => { }); it('New seats input cannot be less than 1', () => { - if (initialState.entities?.users?.filteredStats?.total_users_count) { - initialState.entities.users.filteredStats.total_users_count = 50; - } + const state = mergeObjects(initialState, { + entities: { + users: { + filteredStats: { + total_users_count: 50, + }, + }, + }, + }); const expectedAddNewSeats = '1'; - renderWithIntlAndStore(
, initialState); + renderWithIntlAndStore(
, state); fillForm(defaultSuccessForm); // Try to set a negative value. diff --git a/webapp/channels/src/components/user_profile/user_profile.tsx b/webapp/channels/src/components/user_profile/user_profile.tsx index 689557b2d1..770ca0c54d 100644 --- a/webapp/channels/src/components/user_profile/user_profile.tsx +++ b/webapp/channels/src/components/user_profile/user_profile.tsx @@ -35,7 +35,6 @@ export type UserProfileProps = { hasMention?: boolean; hideStatus?: boolean; isRHS?: boolean; - overwriteImage?: React.ReactNode; channelId?: string; theme?: Theme; } @@ -49,7 +48,6 @@ export default class UserProfile extends PureComponent { hasMention: false, hideStatus: false, isRHS: false, - overwriteImage: '', overwriteName: '', colorize: false, }; diff --git a/webapp/channels/src/images/logo_compact.png b/webapp/channels/src/images/logo_compact.png deleted file mode 100644 index e826e10f2f022c90e4a5c7c9ad3e9246019f08db..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2431 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 { + test('should be able to render anything', () => { + const TestComponent = () => { + return
{'Anything'}
; + }; + + renderWithFullContext( + , + {}, + ); + + expect(screen.getByText('Anything')).toBeInTheDocument(); + }); + + test('should be able to render react-intl components', () => { + const TestComponent = () => { + return ( + + ); + }; + + renderWithFullContext( + , + ); + + expect(screen.getByText('Build Number:')).toBeInTheDocument(); + }); + + test('should be able to render components using react-intl hooks', () => { + const TestComponent = () => { + const intl = useIntl(); + + return
{intl.formatMessage({id: 'about.hash', defaultMessage: 'Build Hash:'})}
; + }; + + renderWithFullContext( + , + ); + + expect(screen.getByText('Build Hash:')).toBeInTheDocument(); + }); + + test('should be able to render react-router components', () => { + const RouteComponent = () => { + return
{'this is the route component'}
; + }; + const TestComponent = () => { + return ( +
+ + {'Test Link'} +
+ ); + }; + + renderWithFullContext( + , + ); + + expect(screen.getByText('this is the route component')).toBeInTheDocument(); + expect(screen.getByRole('link', {name: 'Test Link'})).toBeInTheDocument(); + }); + + test('should be able to render components that use connect to access the Redux store', () => { + const UnconnectedTestComponent = (props: {numProfiles: number}) => { + return
{`There are ${props.numProfiles} users loaded`}
; + }; + const TestComponent = connect((state: GlobalState) => ({ + numProfiles: Object.keys(state.entities.users.profiles).length, + }))(UnconnectedTestComponent); + + renderWithFullContext( + , + ); + + expect(screen.getByText('There are 0 users loaded')).toBeInTheDocument(); + }); + + test('should be able to render components that use hooks to access the Redux store', () => { + const TestComponent = () => { + const numProfiles = useSelector((state: GlobalState) => Object.keys(state.entities.users.profiles).length); + return
{`There are ${numProfiles} users loaded`}
; + }; + + renderWithFullContext( + , + ); + + expect(screen.getByText('There are 0 users loaded')).toBeInTheDocument(); + }); + + test('should be able to rerender components without losing context', () => { + const TestComponent = (props: {appTitle: string}) => { + return ( + + ); + }; + + const {rerender} = renderWithFullContext( + , + ); + + expect(screen.getByText('About Mattermost')).toBeInTheDocument(); + + rerender( + , + ); + + expect(screen.getByText('About Mattermots')).toBeInTheDocument(); + }); + + test('should be able to inject store state and replace it later', () => { + const initialState = { + entities: { + users: { + profiles: { + user1: TestHelper.getUserMock({id: 'user1', username: 'Alpha'}), + user2: TestHelper.getUserMock({id: 'user2', username: 'Bravo'}), + }, + }, + }, + }; + + const TestComponent = () => { + const user1 = useSelector((state: GlobalState) => getUser(state, 'user1')); + const user2 = useSelector((state: GlobalState) => getUser(state, 'user2')); + + return
{`User1 is ${user1.username} and User2 is ${user2.username}!`}
; + }; + + const {replaceStoreState} = renderWithFullContext( + , + initialState, + ); + + expect(screen.getByText('User1 is Alpha and User2 is Bravo!')).toBeInTheDocument(); + + replaceStoreState(mergeObjects(initialState, { + entities: { + users: { + profiles: { + user1: {username: 'Charlie'}, + }, + }, + }, + })); + + expect(screen.getByText('User1 is Charlie and User2 is Bravo!')).toBeInTheDocument(); + + replaceStoreState(mergeObjects(initialState, { + entities: { + users: { + profiles: { + user2: {username: 'Delta'}, + }, + }, + }, + })); + + // Since this replaces the state, user1's username goes back to the initial value + expect(screen.getByText('User1 is Alpha and User2 is Delta!')).toBeInTheDocument(); + }); + + test('should be able to update store state', () => { + const initialState = { + entities: { + users: { + profiles: { + user1: TestHelper.getUserMock({id: 'user1', username: 'Echo'}), + user2: TestHelper.getUserMock({id: 'user2', username: 'Foxtrot'}), + }, + }, + }, + }; + + const TestComponent = () => { + const user1 = useSelector((state: GlobalState) => getUser(state, 'user1')); + const user2 = useSelector((state: GlobalState) => getUser(state, 'user2')); + + return
{`User1 is ${user1.username} and User2 is ${user2.username}!`}
; + }; + + const {updateStoreState} = renderWithFullContext( + , + initialState, + ); + + expect(screen.getByText('User1 is Echo and User2 is Foxtrot!')).toBeInTheDocument(); + + updateStoreState({ + entities: { + users: { + profiles: { + user1: {username: 'Golf'}, + }, + }, + }, + }); + + expect(screen.getByText('User1 is Golf and User2 is Foxtrot!')).toBeInTheDocument(); + + updateStoreState({ + entities: { + users: { + profiles: { + user2: {username: 'Hotel'}, + }, + }, + }, + }); + + expect(screen.getByText('User1 is Golf and User2 is Hotel!')).toBeInTheDocument(); + }); +}); diff --git a/webapp/channels/src/tests/react_testing_utils.tsx b/webapp/channels/src/tests/react_testing_utils.tsx index 25888652a2..08e39150d8 100644 --- a/webapp/channels/src/tests/react_testing_utils.tsx +++ b/webapp/channels/src/tests/react_testing_utils.tsx @@ -1,22 +1,32 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import React from 'react'; import {render} from '@testing-library/react'; -import {Provider} from 'react-redux'; - +import {createBrowserHistory} from 'history'; +import React from 'react'; import {IntlProvider} from 'react-intl'; +import {Provider} from 'react-redux'; +import {Router} from 'react-router-dom'; + +import {DeepPartial} from '@mattermost/types/utilities'; + +import configureStore from 'store'; import mockStore from 'tests/test_store'; -import {GlobalState} from '@mattermost/types/store'; -import {DeepPartial} from '@mattermost/types/utilities'; + +import {GlobalState} from 'types/store'; +import mergeObjects from 'packages/mattermost-redux/test/merge_objects'; export const renderWithIntl = (component: React.ReactNode | React.ReactNodeArray, locale = 'en') => { return render({component}); }; export const renderWithIntlAndStore = (component: React.ReactNode | React.ReactNodeArray, initialState: DeepPartial, locale = 'en') => { - const store = mockStore(initialState); + // We use a redux-mock-store store for testing, but we set up a real store to ensure the initial state is complete + const realStore = configureStore(initialState); + + const store = mockStore(realStore.getState()); + return render( @@ -25,3 +35,66 @@ export const renderWithIntlAndStore = (component: React.ReactNode | React.ReactN , ); }; + +export const renderWithFullContext = (component: React.ReactNode | React.ReactNodeArray, initialState: DeepPartial = {}, locale = 'en') => { + // We use a redux-mock-store store for testing, but we set up a real store to ensure the initial state is complete + const testState = configureStore(initialState).getState(); + + // Store these in an object so that they can be maintained through rerenders + const renderState = { + component, + history: createBrowserHistory(), + locale, + state: testState, + store: mockStore(testState), + }; + + // This should wrap the component in roughly the same providers used in App and RootProvider + function wrapComponent() { + // Every time this is called, these values should be updated from `renderState` + return ( + + + + {renderState.component} + + + + ); + } + + const results = render(wrapComponent()); + + return { + ...results, + rerender: (newComponent: React.ReactNode | React.ReactNodeArray) => { + renderState.component = newComponent; + + results.rerender(wrapComponent()); + }, + + /** + * Rerenders the component after replacing the entire store state with the provided one. + */ + replaceStoreState: (newInitialState: DeepPartial) => { + const newTestState = configureStore(newInitialState).getState(); + renderState.state = newTestState; + renderState.store = mockStore(newTestState); + + results.rerender(wrapComponent()); + }, + + /** + * Rerenders the component after merging the current store state with the provided one. + */ + updateStoreState: (stateDiff: DeepPartial) => { + const newTestState = mergeObjects(renderState.state, stateDiff); + renderState.state = newTestState; + renderState.store = mockStore(newTestState); + + results.rerender(wrapComponent()); + }, + }; +}; diff --git a/webapp/channels/src/utils/constants.tsx b/webapp/channels/src/utils/constants.tsx index 7c8a60340a..93a10c261d 100644 --- a/webapp/channels/src/utils/constants.tsx +++ b/webapp/channels/src/utils/constants.tsx @@ -18,7 +18,6 @@ import pdfIcon from 'images/icons/pdf.svg'; import pptIcon from 'images/icons/ppt.svg'; import videoIcon from 'images/icons/video.svg'; import wordIcon from 'images/icons/word.svg'; -import logoImage from 'images/logo_compact.png'; import githubIcon from 'images/themes/code_themes/github.png'; import monokaiIcon from 'images/themes/code_themes/monokai.png'; import solarizedDarkIcon from 'images/themes/code_themes/solarized-dark.png'; @@ -1508,7 +1507,6 @@ export const Constants = { MENTION_NAME_PADDING_LEFT: 2.4, AVATAR_WIDTH: 24, AUTO_RESPONDER: 'system_auto_responder', - SYSTEM_MESSAGE_PROFILE_IMAGE: logoImage, RESERVED_TEAM_NAMES: [ 'signup', 'login',