diff --git a/webapp/channels/src/components/post_view/floating_timestamp/__snapshots__/floating_timestamp.test.tsx.snap b/webapp/channels/src/components/post_view/floating_timestamp/__snapshots__/floating_timestamp.test.tsx.snap deleted file mode 100644 index 6e176ad306..0000000000 --- a/webapp/channels/src/components/post_view/floating_timestamp/__snapshots__/floating_timestamp.test.tsx.snap +++ /dev/null @@ -1,41 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`components/post_view/FloatingTimestamp should match snapshot 1`] = ` -
-
- - , - "equals": Array [ - "day", - 0, - ], - }, - Object { - "display": , - "equals": Array [ - "day", - -1, - ], - }, - ] - } - useTime={false} - value={1234} - /> - -
-
-`; diff --git a/webapp/channels/src/components/post_view/floating_timestamp/floating_timestamp.test.tsx b/webapp/channels/src/components/post_view/floating_timestamp/floating_timestamp.test.tsx index a864f9b72e..9de8776b86 100644 --- a/webapp/channels/src/components/post_view/floating_timestamp/floating_timestamp.test.tsx +++ b/webapp/channels/src/components/post_view/floating_timestamp/floating_timestamp.test.tsx @@ -2,9 +2,10 @@ // See LICENSE.txt for license information. import React from 'react'; -import {shallow} from 'enzyme'; import FloatingTimestamp from './floating_timestamp'; +import {screen} from '@testing-library/react'; +import {renderWithIntlAndStore} from 'tests/react_testing_utils'; describe('components/post_view/FloatingTimestamp', () => { const baseProps = { @@ -13,10 +14,27 @@ describe('components/post_view/FloatingTimestamp', () => { toastPresent: true, isRhsPost: false, }; + const initialState = { + entities: { + general: { + config: {}, + }, + preferences: { + myPreferences: {}, + }, + }, + }; - test('should match snapshot', () => { - const wrapper = shallow(); - expect(wrapper).toMatchSnapshot(); - expect(wrapper.hasClass('toastAdjustment')).toBe(true); + test('should match component state with given props', () => { + renderWithIntlAndStore(, initialState); + + const floatingTimeStamp = screen.getByTestId('floatingTimestamp'); + const time = screen.getByText('January 01, 1970'); + + expect(floatingTimeStamp).toBeInTheDocument(); + expect(floatingTimeStamp).toHaveClass('post-list__timestamp scrolling toastAdjustment'); + + expect(time).toBeInTheDocument(); + expect(time).toHaveAttribute('datetime', '1970-01-01T00:00:01.234'); }); }); diff --git a/webapp/channels/src/components/post_view/message_attachments/action_button/__snapshots__/action_button.test.tsx.snap b/webapp/channels/src/components/post_view/message_attachments/action_button/__snapshots__/action_button.test.tsx.snap deleted file mode 100644 index f73dc5ab36..0000000000 --- a/webapp/channels/src/components/post_view/message_attachments/action_button/__snapshots__/action_button.test.tsx.snap +++ /dev/null @@ -1,26 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`components/post_view/message_attachments/action_button.jsx should match snapshot 1`] = ` - -`; diff --git a/webapp/channels/src/components/post_view/message_attachments/action_button/action_button.test.tsx b/webapp/channels/src/components/post_view/message_attachments/action_button/action_button.test.tsx index 9c468806f3..48e8e26f89 100644 --- a/webapp/channels/src/components/post_view/message_attachments/action_button/action_button.test.tsx +++ b/webapp/channels/src/components/post_view/message_attachments/action_button/action_button.test.tsx @@ -2,13 +2,14 @@ // See LICENSE.txt for license information. import React from 'react'; -import {shallow} from 'enzyme'; import {Theme} from 'mattermost-redux/selectors/entities/preferences'; import {changeOpacity} from 'mattermost-redux/utils/theme_utils'; import {Preferences} from 'mattermost-redux/constants'; import ActionButton from 'components/post_view/message_attachments/action_button/action_button'; +import {render, screen} from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; describe('components/post_view/message_attachments/action_button.jsx', () => { const baseProps = { @@ -17,15 +18,23 @@ describe('components/post_view/message_attachments/action_button.jsx', () => { theme: Preferences.THEMES.denim as unknown as Theme, }; - test('should match snapshot', () => { - const wrapper = shallow(); - expect(wrapper).toMatchSnapshot(); + test('should match default component state with given props', () => { + render(); + + const button = screen.getByRole('button'); + expect(button).toHaveAttribute('data-action-cookie', 'cookie-contents'); + expect(button).toHaveAttribute('data-action-id', 'action_id_1'); + + const loadingIcon = screen.getByTitle('Loading Icon'); + expect(loadingIcon).toHaveClass('fa fa-spinner fa-fw fa-pulse spinner'); }); test('should call handleAction on click', () => { - const wrapper = shallow(); + render(); - wrapper.find('button').simulate('click'); + const button = screen.getByRole('button'); + + userEvent.click(button); expect(baseProps.handleAction).toHaveBeenCalledTimes(1); }); @@ -36,12 +45,13 @@ describe('components/post_view/message_attachments/action_button.jsx', () => { action: {...baseProps.action, style: 'onlineIndicator'}, }; - const wrapper = shallow(); - const buttonStyles = wrapper.find('button').prop('style'); + render(); - expect(buttonStyles).toHaveProperty('borderColor', changeOpacity(Preferences.THEMES.denim.onlineIndicator, 0.25)); - expect(buttonStyles).toHaveProperty('borderWidth', 2); - expect(buttonStyles).toHaveProperty('color', Preferences.THEMES.denim.onlineIndicator); + const button = screen.getByRole('button'); + + expect(button).toHaveStyle(`borderColor: ${changeOpacity(Preferences.THEMES.denim.onlineIndicator, 0.25)}`); + expect(button).toHaveStyle('borderWidth: 2'); + expect(button).toHaveStyle(`color: ${Preferences.THEMES.denim.onlineIndicator}`); }); test('should have correct styles when provided color from not default theme', () => { @@ -51,12 +61,13 @@ describe('components/post_view/message_attachments/action_button.jsx', () => { action: {...baseProps.action, style: 'danger'}, }; - const wrapper = shallow(); - const buttonStyles = wrapper.find('button').prop('style'); + render(); - expect(buttonStyles).toHaveProperty('borderColor', changeOpacity(Preferences.THEMES.indigo.errorTextColor, 0.25)); - expect(buttonStyles).toHaveProperty('borderWidth', 2); - expect(buttonStyles).toHaveProperty('color', Preferences.THEMES.indigo.errorTextColor); + const button = screen.getByRole('button'); + + expect(button).toHaveStyle(`borderColor: ${changeOpacity(Preferences.THEMES.indigo.errorTextColor, 0.25)}`); + expect(button).toHaveStyle('borderWidth: 2'); + expect(button).toHaveStyle(`color: ${Preferences.THEMES.indigo.errorTextColor}`); }); test('should have correct styles when provided status color', () => { @@ -65,12 +76,12 @@ describe('components/post_view/message_attachments/action_button.jsx', () => { action: {...baseProps.action, style: 'success'}, }; - const wrapper = shallow(); - const buttonStyles = wrapper.find('button').prop('style'); + render(); + const button = screen.getByRole('button'); - expect(buttonStyles).toHaveProperty('borderColor', changeOpacity(Preferences.THEMES.denim.onlineIndicator, 0.25)); - expect(buttonStyles).toHaveProperty('borderWidth', 2); - expect(buttonStyles).toHaveProperty('color', Preferences.THEMES.denim.onlineIndicator); + expect(button).toHaveStyle(`borderColor: ${changeOpacity(Preferences.THEMES.denim.onlineIndicator, 0.25)}`); + expect(button).toHaveStyle('borderWidth: 2'); + expect(button).toHaveStyle(`color: ${Preferences.THEMES.denim.onlineIndicator}`); }); test('should have correct styles when provided hex color', () => { @@ -79,12 +90,12 @@ describe('components/post_view/message_attachments/action_button.jsx', () => { action: {...baseProps.action, style: '#28a745'}, }; - const wrapper = shallow(); - const buttonStyles = wrapper.find('button').prop('style'); + render(); + const button = screen.getByRole('button'); - expect(buttonStyles).toHaveProperty('borderColor', changeOpacity(props.action.style, 0.25)); - expect(buttonStyles).toHaveProperty('borderWidth', 2); - expect(buttonStyles).toHaveProperty('color', props.action.style); + expect(button).toHaveStyle(`borderColor: ${changeOpacity(props.action.style, 0.25)}`); + expect(button).toHaveStyle('borderWidth: 2'); + expect(button).toHaveStyle(`color: ${props.action.style}`); }); test('should have no styles when provided invalid hex color', () => { @@ -93,10 +104,10 @@ describe('components/post_view/message_attachments/action_button.jsx', () => { action: {...baseProps.action, style: '#wrong'}, }; - const wrapper = shallow(); - const buttonStyles = wrapper.find('button').prop('style'); + render(); + const button = screen.getByRole('button'); - expect(buttonStyles).toBeUndefined(); + expect(button.style.length).toBe(0); }); test('should have no styles when provided undefined', () => { @@ -105,9 +116,9 @@ describe('components/post_view/message_attachments/action_button.jsx', () => { action: {...baseProps.action, style: undefined}, }; - const wrapper = shallow(); - const buttonStyles = wrapper.find('button').prop('style'); + render(); + const button = screen.getByRole('button'); - expect(buttonStyles).toBeUndefined(); + expect(button.style.length).toBe(0); }); }); diff --git a/webapp/channels/src/components/post_view/message_attachments/action_menu/action_menu.test.tsx b/webapp/channels/src/components/post_view/message_attachments/action_menu/action_menu.test.tsx index d041dda7db..62c5ab3212 100644 --- a/webapp/channels/src/components/post_view/message_attachments/action_menu/action_menu.test.tsx +++ b/webapp/channels/src/components/post_view/message_attachments/action_menu/action_menu.test.tsx @@ -1,10 +1,11 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import {shallow} from 'enzyme'; import React from 'react'; import ActionMenu from './action_menu'; +import {screen} from '@testing-library/react'; +import {renderWithIntlAndStore} from 'tests/react_testing_utils'; describe('components/post_view/message_attachments/ActionMenu', () => { const baseProps = { @@ -30,13 +31,20 @@ describe('components/post_view/message_attachments/ActionMenu', () => { selectAttachmentMenuAction: jest.fn(), }; - test('should start with nothing selected', () => { - const wrapper = shallow(); + test('should start with nothing selected', async () => { + renderWithIntlAndStore(, {}); - expect(wrapper.state()).toMatchObject({ - selected: undefined, - value: '', - }); + const autoCompleteSelector = screen.getByTestId('autoCompleteSelector'); + const input = screen.getByPlaceholderText('action'); + + expect(autoCompleteSelector).toBeInTheDocument(); + expect(autoCompleteSelector).toHaveClass('form-group'); + + //if nothing is selected or selected is undefined, baseProps.selectAttachmentMenuAction should not be called + expect(baseProps.selectAttachmentMenuAction).not.toHaveBeenCalled(); + + expect(input).toHaveClass('form-control'); + expect(input).toHaveAttribute('value', ''); }); test('should set selected based on default option', () => { @@ -47,14 +55,11 @@ describe('components/post_view/message_attachments/ActionMenu', () => { default_option: '2', }, }; - const wrapper = shallow(); + renderWithIntlAndStore(, {}); - expect(wrapper.state()).toMatchObject({ - selected: { - text: 'Two', - value: '2', - }, - value: 'Two', - }); + const input = screen.getByPlaceholderText('action'); + + //default_option is given in props + expect(input).toHaveAttribute('value', 'Two'); }); }); diff --git a/webapp/channels/src/components/post_view/new_message_separator/__snapshots__/new_message_separator.test.tsx.snap b/webapp/channels/src/components/post_view/new_message_separator/__snapshots__/new_message_separator.test.tsx.snap deleted file mode 100644 index b07c8ecf43..0000000000 --- a/webapp/channels/src/components/post_view/new_message_separator/__snapshots__/new_message_separator.test.tsx.snap +++ /dev/null @@ -1,16 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`components/post_view/new_message_separator should render new_message_separator 1`] = ` -
- - - -
-`; diff --git a/webapp/channels/src/components/post_view/new_message_separator/new_message_separator.test.tsx b/webapp/channels/src/components/post_view/new_message_separator/new_message_separator.test.tsx index 06c9922dc1..18ba8320a4 100644 --- a/webapp/channels/src/components/post_view/new_message_separator/new_message_separator.test.tsx +++ b/webapp/channels/src/components/post_view/new_message_separator/new_message_separator.test.tsx @@ -1,16 +1,25 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import {shallow} from 'enzyme'; import React from 'react'; import NewMessageSeparator from './new_message_separator'; +import {screen} from '@testing-library/react'; +import {renderWithIntl} from 'tests/react_testing_utils'; describe('components/post_view/new_message_separator', () => { test('should render new_message_separator', () => { - const wrapper = shallow( + renderWithIntl( , ); - expect(wrapper).toMatchSnapshot(); + + const newMessage = screen.getByText('New Messages'); + const separator = screen.getByTestId('NotificationSeparator'); + + expect(newMessage).toBeInTheDocument(); + expect(newMessage).toHaveClass('separator__text'); + + expect(separator).toBeInTheDocument(); + expect(separator).toHaveClass('Separator NotificationSeparator'); }); }); diff --git a/webapp/channels/src/components/post_view/post_attachment_container/__snapshots__/post_attachment_container.test.tsx.snap b/webapp/channels/src/components/post_view/post_attachment_container/__snapshots__/post_attachment_container.test.tsx.snap deleted file mode 100644 index aa796606af..0000000000 --- a/webapp/channels/src/components/post_view/post_attachment_container/__snapshots__/post_attachment_container.test.tsx.snap +++ /dev/null @@ -1,44 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`PostAttachmentContainer should render correctly 1`] = ` - - -

- some children -

-
-
-`; diff --git a/webapp/channels/src/components/post_view/post_attachment_container/post_attachment_container.test.tsx b/webapp/channels/src/components/post_view/post_attachment_container/post_attachment_container.test.tsx index 4cb8e1a64b..49661a126c 100644 --- a/webapp/channels/src/components/post_view/post_attachment_container/post_attachment_container.test.tsx +++ b/webapp/channels/src/components/post_view/post_attachment_container/post_attachment_container.test.tsx @@ -1,14 +1,13 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import {shallow} from 'enzyme'; - import React from 'react'; -import {Provider} from 'react-redux'; - -import {mockStore} from 'tests/test_store'; import PostAttachmentContainer, {Props} from './post_attachment_container'; +import {screen} from '@testing-library/react'; +import {renderWithIntlAndStore} from 'tests/react_testing_utils'; +import {DeepPartial} from '@mattermost/types/utilities'; +import {GlobalState} from '@mattermost/types/store'; describe('PostAttachmentContainer', () => { const baseProps: Props = { @@ -17,24 +16,34 @@ describe('PostAttachmentContainer', () => { link: '/test/pl/1', }; - const initialState = { + const initialState: DeepPartial = { entities: { + general: {config: {}}, users: { currentUserId: 'user1', profiles: {}, }, + teams: { + currentTeamId: 'current_team_id', + teams: {}, + }, + posts: {posts: {}}, + preferences: {myPreferences: {}}, + }, + }; - test('should render correctly', async () => { - const store = await mockStore(initialState); - - const wrapper = shallow( - - - , + test('should render correctly', () => { + renderWithIntlAndStore( + , initialState, ); - expect(wrapper).toMatchSnapshot(); + const button = screen.getByRole('button'); + expect(button).toBeInTheDocument(); + expect(button).toHaveClass('attachment attachment--permalink'); + expect(button.children[0]).toHaveClass('attachment__content attachment__content--permalink'); + + expect(screen.getByText('some children')).toBeInTheDocument(); }); }); diff --git a/webapp/channels/src/components/post_view/post_list_virtualized/latest_post_reader.test.tsx b/webapp/channels/src/components/post_view/post_list_virtualized/latest_post_reader.test.tsx index 25a07c738c..0f56f20a86 100644 --- a/webapp/channels/src/components/post_view/post_list_virtualized/latest_post_reader.test.tsx +++ b/webapp/channels/src/components/post_view/post_list_virtualized/latest_post_reader.test.tsx @@ -1,7 +1,6 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import {mount} from 'enzyme'; import React from 'react'; import {createIntl, useIntl} from 'react-intl'; @@ -13,6 +12,9 @@ import {mockStore} from 'tests/test_store'; import {TestHelper} from 'utils/test_helper'; import LatestPostReader from './latest_post_reader'; +import {render, screen} from '@testing-library/react'; +import {renderWithIntlAndStore} from 'tests/react_testing_utils'; +import {Provider} from 'react-redux'; jest.mock('react-intl', () => ({ ...jest.requireActual('react-intl'), @@ -59,36 +61,40 @@ describe('LatestPostReader', () => { }; test('should render aria-label as a child in the given locale', () => { - const {mountOptions} = mockStore(baseState); + const store = mockStore(baseState); (useIntl as jest.Mock).mockImplementation(() => createIntl({locale: 'en', messages: enMessages, defaultLocale: 'en'})); - let wrapper = mount(, mountOptions); - let span = wrapper.childAt(0); + const {rerender} = render( + + + , + ); - expect(span.prop('children')).toContain(author.username); - expect(span.prop('children')).toContain('January'); + const prevMessage = screen.getByText(`January 1, ${author.username} wrote, This is a test`, {exact: false}); + expect(prevMessage).toBeInTheDocument(); + expect(prevMessage).toHaveClass('sr-only'); (useIntl as jest.Mock).mockImplementation(() => createIntl({locale: 'es', messages: esMessages, defaultLocale: 'es'})); - wrapper = mount(, mountOptions); - span = wrapper.childAt(0); + rerender( ); + const januaryInSpanish = 'enero'; + const message = screen.getByText(`${januaryInSpanish}, ${author.username} wrote, This is a test`, {exact: false}); - expect(span.prop('children')).toContain(author.username); - expect(span.prop('children')).toContain('enero'); + expect(message).toBeInTheDocument(); + expect(message).toHaveClass('sr-only'); }); test('should be able to handle an empty post array', () => { - const {mountOptions} = mockStore(baseState); - const props = { ...baseProps, postIds: [], }; - const wrapper = mount(, mountOptions); - const span = wrapper.childAt(0); + renderWithIntlAndStore(, baseState); - expect(span.prop('children')).toEqual(''); + // body should be empty + const message = screen.queryByText('This is a test'); + expect(message).not.toBeInTheDocument(); }); });