Migrate multiple enzyme unit test to testing library (#23236)
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
0e371b010e
Коммит
444bbd56f1
@@ -1,41 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`components/post_view/FloatingTimestamp should match snapshot 1`] = `
|
||||
<div
|
||||
className="post-list__timestamp scrolling toastAdjustment"
|
||||
data-testid="floatingTimestamp"
|
||||
>
|
||||
<div>
|
||||
<span>
|
||||
<Connect(injectIntl(Timestamp))
|
||||
ranges={
|
||||
Array [
|
||||
Object {
|
||||
"display": <Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Today"
|
||||
id="date_separator.today"
|
||||
/>,
|
||||
"equals": Array [
|
||||
"day",
|
||||
0,
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"display": <Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Yesterday"
|
||||
id="date_separator.yesterday"
|
||||
/>,
|
||||
"equals": Array [
|
||||
"day",
|
||||
-1,
|
||||
],
|
||||
},
|
||||
]
|
||||
}
|
||||
useTime={false}
|
||||
value={1234}
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -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(<FloatingTimestamp {...baseProps}/>);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(wrapper.hasClass('toastAdjustment')).toBe(true);
|
||||
test('should match component state with given props', () => {
|
||||
renderWithIntlAndStore(<FloatingTimestamp {...baseProps}/>, 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');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`components/post_view/message_attachments/action_button.jsx should match snapshot 1`] = `
|
||||
<button
|
||||
data-action-cookie="cookie-contents"
|
||||
data-action-id="action_id_1"
|
||||
key="action_id_1"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<LoadingWrapper
|
||||
loading={true}
|
||||
text={null}
|
||||
>
|
||||
<Connect(Markdown)
|
||||
message="action_name_1"
|
||||
options={
|
||||
Object {
|
||||
"autolinkedUrlSchemes": Array [],
|
||||
"markdown": false,
|
||||
"mentionHighlight": false,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</LoadingWrapper>
|
||||
</button>
|
||||
`;
|
||||
@@ -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(<ActionButton {...baseProps}/>);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
test('should match default component state with given props', () => {
|
||||
render(<ActionButton {...baseProps}/>);
|
||||
|
||||
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(<ActionButton {...baseProps}/>);
|
||||
render(<ActionButton {...baseProps}/>);
|
||||
|
||||
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(<ActionButton {...props}/>);
|
||||
const buttonStyles = wrapper.find('button').prop('style');
|
||||
render(<ActionButton {...props}/>);
|
||||
|
||||
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(<ActionButton {...props}/>);
|
||||
const buttonStyles = wrapper.find('button').prop('style');
|
||||
render(<ActionButton {...props}/>);
|
||||
|
||||
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(<ActionButton {...props}/>);
|
||||
const buttonStyles = wrapper.find('button').prop('style');
|
||||
render(<ActionButton {...props}/>);
|
||||
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(<ActionButton {...props}/>);
|
||||
const buttonStyles = wrapper.find('button').prop('style');
|
||||
render(<ActionButton {...props}/>);
|
||||
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(<ActionButton {...props}/>);
|
||||
const buttonStyles = wrapper.find('button').prop('style');
|
||||
render(<ActionButton {...props}/>);
|
||||
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(<ActionButton {...props}/>);
|
||||
const buttonStyles = wrapper.find('button').prop('style');
|
||||
render(<ActionButton {...props}/>);
|
||||
const button = screen.getByRole('button');
|
||||
|
||||
expect(buttonStyles).toBeUndefined();
|
||||
expect(button.style.length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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(<ActionMenu {...baseProps}/>);
|
||||
test('should start with nothing selected', async () => {
|
||||
renderWithIntlAndStore(<ActionMenu {...baseProps}/>, {});
|
||||
|
||||
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(<ActionMenu {...props}/>);
|
||||
renderWithIntlAndStore(<ActionMenu {...props}/>, {});
|
||||
|
||||
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');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`components/post_view/new_message_separator should render new_message_separator 1`] = `
|
||||
<div
|
||||
className="new-separator"
|
||||
>
|
||||
<NotificationSeparator
|
||||
id="1234"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="New Messages"
|
||||
id="posts_view.newMsg"
|
||||
/>
|
||||
</NotificationSeparator>
|
||||
</div>
|
||||
`;
|
||||
@@ -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(
|
||||
<NewMessageSeparator separatorId='1234'/>,
|
||||
);
|
||||
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');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`PostAttachmentContainer should render correctly 1`] = `
|
||||
<ContextProvider
|
||||
value={
|
||||
Object {
|
||||
"store": Object {
|
||||
"clearActions": [Function],
|
||||
"dispatch": [Function],
|
||||
"getActions": [Function],
|
||||
"getState": [Function],
|
||||
"replaceReducer": [Function],
|
||||
"subscribe": [Function],
|
||||
},
|
||||
"subscription": Subscription {
|
||||
"handleChangeWrapper": [Function],
|
||||
"listeners": Object {
|
||||
"notify": [Function],
|
||||
},
|
||||
"onStateChange": [Function],
|
||||
"parentSub": undefined,
|
||||
"store": Object {
|
||||
"clearActions": [Function],
|
||||
"dispatch": [Function],
|
||||
"getActions": [Function],
|
||||
"getState": [Function],
|
||||
"replaceReducer": [Function],
|
||||
"subscribe": [Function],
|
||||
},
|
||||
"unsubscribe": null,
|
||||
},
|
||||
}
|
||||
}
|
||||
>
|
||||
<PostAttachmentContainer
|
||||
className="permalink"
|
||||
link="/test/pl/1"
|
||||
>
|
||||
<p>
|
||||
some children
|
||||
</p>
|
||||
</PostAttachmentContainer>
|
||||
</ContextProvider>
|
||||
`;
|
||||
@@ -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<GlobalState> = {
|
||||
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(
|
||||
<Provider store={store.store}>
|
||||
<PostAttachmentContainer {...baseProps}/>
|
||||
</Provider>,
|
||||
test('should render correctly', () => {
|
||||
renderWithIntlAndStore(
|
||||
<PostAttachmentContainer {...baseProps}/>, 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();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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(<LatestPostReader {...baseProps}/>, mountOptions);
|
||||
let span = wrapper.childAt(0);
|
||||
const {rerender} = render(
|
||||
<Provider store={store.store}>
|
||||
<LatestPostReader {...baseProps}/>
|
||||
</Provider>,
|
||||
);
|
||||
|
||||
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(<LatestPostReader {...baseProps}/>, mountOptions);
|
||||
span = wrapper.childAt(0);
|
||||
rerender(<Provider store={store.store}> <LatestPostReader {...baseProps}/></Provider>);
|
||||
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(<LatestPostReader {...props}/>, mountOptions);
|
||||
const span = wrapper.childAt(0);
|
||||
renderWithIntlAndStore(<LatestPostReader {...props}/>, baseState);
|
||||
|
||||
expect(span.prop('children')).toEqual('');
|
||||
// body should be empty
|
||||
const message = screen.queryByText('This is a test');
|
||||
expect(message).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
Ссылка в новой задаче
Block a user