[WebApp][MM-52125]: Migrate multiple enzyme unit test to testing library (#23245)

* Migrate multiple enzyme unit test to testing library
Этот коммит содержится в:
Ashish Dhama
2023-05-04 11:55:01 +05:30
коммит произвёл GitHub
родитель 60234d0880
Коммит 96b537167c
11 изменённых файлов: 489 добавлений и 1630 удалений

Просмотреть файл

@@ -1,137 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`components/feature_discovery FeatureDiscovery should match snapshot 1`] = `
<div
className="FeatureDiscovery"
>
<div
className="FeatureDiscovery_copyWrapper"
>
<div
className="FeatureDiscovery_title"
data-testid="featureDiscovery_title"
>
<MemoizedFormattedMessage
defaultMessage="Foo"
id="translation.test.title"
/>
</div>
<div
className="FeatureDiscovery_copy"
>
<MemoizedFormattedMessage
defaultMessage="Bar"
id="translation.test.copy"
/>
</div>
<StartTrialBtn
btnClass="btn btn-primary"
message="Start trial"
renderAsButton={true}
telemetryId="start_self_hosted_trial_from_test"
trackingPage="test"
/>
<ExternalLink
className="btn btn-secondary"
data-testid="featureDiscovery_secondaryCallToAction"
href="https://test.mattermost.com/secondary/"
location="feature_discovery"
>
<MemoizedFormattedMessage
defaultMessage="Learn more"
id="admin.ldap_feature_discovery.call_to_action.secondary"
/>
</ExternalLink>
<p
className="trial-legal-terms"
>
<MemoizedFormattedMessage
defaultMessage="By clicking <highlight>Start trial</highlight>, I agree to the <linkEvaluation>Mattermost Software and Services License Agreement</linkEvaluation>, <linkPrivacy>Privacy Policy</linkPrivacy> and receiving product emails."
id="admin.feature_discovery.trial-request.accept-terms"
values={
Object {
"highlight": [Function],
"linkEvaluation": [Function],
"linkPrivacy": [Function],
}
}
/>
</p>
</div>
<div
className="FeatureDiscovery_imageWrapper"
>
<SamlSVG />
</div>
</div>
`;
exports[`components/feature_discovery FeatureDiscovery should match snapshot when is cloud environment 1`] = `
<div
className="FeatureDiscovery"
>
<div
className="FeatureDiscovery_copyWrapper"
>
<div
className="FeatureDiscovery_title"
data-testid="featureDiscovery_title"
>
<MemoizedFormattedMessage
defaultMessage="Foo"
id="translation.test.title"
/>
</div>
<div
className="FeatureDiscovery_copy"
>
<MemoizedFormattedMessage
defaultMessage="Bar"
id="translation.test.copy"
/>
</div>
<FeatureDiscoveryCloudStartTrialButton
extraClass="btn btn-primary"
telemetryId="start_cloud_trial_from_test"
/>
<ExternalLink
className="btn btn-secondary"
data-testid="featureDiscovery_secondaryCallToAction"
href="https://test.mattermost.com/secondary/"
location="feature_discovery"
>
<MemoizedFormattedMessage
defaultMessage="Learn more"
id="admin.ldap_feature_discovery.call_to_action.secondary"
/>
</ExternalLink>
<p
className="trial-legal-terms"
>
<MemoizedFormattedMessage
defaultMessage="By selecting <highlight>Try free for {trialLength} days</highlight>, I agree to the <linkEvaluation>Mattermost Software and Services License Agreement</linkEvaluation>, <linkPrivacy>Privacy Policy</linkPrivacy>, and receiving product emails."
id="admin.feature_discovery.trial-request.accept-terms.cloudFree"
values={
Object {
"highlight": [Function],
"linkEvaluation": [Function],
"linkPrivacy": [Function],
"trialLength": 30,
}
}
/>
</p>
</div>
<div
className="FeatureDiscovery_imageWrapper"
>
<SamlSVG />
</div>
</div>
`;
exports[`components/feature_discovery FeatureDiscovery should match snapshot when is cloud environment and subscription is not loaded yet in redux store 1`] = `
<LoadingSpinner
text={null}
/>
`;

Просмотреть файл

@@ -2,103 +2,189 @@
// See LICENSE.txt for license information.
import React from 'react';
import {shallow} from 'enzyme';
import FeatureDiscovery from 'components/admin_console/feature_discovery/feature_discovery';
import {LicenseSkus} from 'utils/constants';
import SamlSVG from './features/images/saml_svg';
import {renderWithIntl} from 'tests/react_testing_utils';
import {screen, waitFor} from '@testing-library/react';
import {Provider as ReduxProvider} from 'react-redux';
import store from 'stores/redux_store';
import userEvent from '@testing-library/user-event';
describe('components/feature_discovery', () => {
describe('FeatureDiscovery', () => {
test('should match snapshot', () => {
const wrapper = shallow(
<FeatureDiscovery
featureName='test'
minimumSKURequiredForFeature={LicenseSkus.Professional}
titleID='translation.test.title'
titleDefault='Foo'
copyID='translation.test.copy'
copyDefault={'Bar'}
learnMoreURL='https://test.mattermost.com/secondary/'
featureDiscoveryImage={<SamlSVG/>}
// eslint-disable-next-line @typescript-eslint/naming-convention
stats={{TOTAL_USERS: 20}}
prevTrialLicense={{IsLicensed: 'false'}}
isCloud={false}
isCloudTrial={false}
hadPrevCloudTrial={false}
isSubscriptionLoaded={true}
isPaidSubscription={false}
cloudFreeDeprecated={false}
actions={{
getPrevTrialLicense: jest.fn(),
getCloudSubscription: jest.fn(),
openModal: jest.fn(),
}}
/>,
test('should match the default state of the component when is not cloud environment', async () => {
const getPrevTrialLicense = jest.fn();
const getCloudSubscription = jest.fn();
const openModal = jest.fn();
renderWithIntl(
<ReduxProvider store={store}>
<FeatureDiscovery
featureName='test'
minimumSKURequiredForFeature={LicenseSkus.Professional}
titleID='translation.test.title'
titleDefault='Foo'
copyID='translation.test.copy'
copyDefault={'Bar'}
learnMoreURL='https://test.mattermost.com/secondary/'
featureDiscoveryImage={<SamlSVG/>}
// eslint-disable-next-line @typescript-eslint/naming-convention
stats={{TOTAL_USERS: 20}}
prevTrialLicense={{IsLicensed: 'false'}}
isCloud={false}
isCloudTrial={false}
hadPrevCloudTrial={false}
isSubscriptionLoaded={true}
isPaidSubscription={false}
cloudFreeDeprecated={false}
actions={{
getPrevTrialLicense,
getCloudSubscription,
openModal,
}}
/>
</ReduxProvider>,
);
expect(wrapper).toMatchSnapshot();
expect(screen.queryByText('Bar')).toBeInTheDocument();
expect(screen.queryByText('Foo')).toBeInTheDocument();
expect(screen.getByRole('button', {name: 'Start trial'})).toBeInTheDocument();
await userEvent.click(screen.getByRole('button', {name: 'Start trial'}));
await userEvent.click(screen.getByText('Mattermost Software and Services License Agreement'));
//cloud option
expect(screen.queryByRole('button', {name: 'Try free for 30 days'})).not.toBeInTheDocument();
const featureLink = screen.getByTestId('featureDiscovery_secondaryCallToAction');
expect(featureLink).toBeInTheDocument();
expect(featureLink).toHaveAttribute('href', 'https://test.mattermost.com/secondary/?utm_source=mattermost&utm_medium=in-product&utm_content=feature_discovery&uid=&sid=');
expect(featureLink).toHaveTextContent('Learn more');
expect(screen.getByText('Mattermost Software and Services License Agreement')).toHaveAttribute('href', 'https://mattermost.com/pl/software-and-services-license-agreement?utm_source=mattermost&utm_medium=in-product&utm_content=feature_discovery&uid=&sid=');
expect(screen.getByText('Privacy Policy')).toHaveAttribute('href', 'https://mattermost.com/privacy-policy/?utm_source=mattermost&utm_medium=in-product&utm_content=feature_discovery&uid=&sid=');
expect(getPrevTrialLicense).toHaveBeenCalled();
expect(getCloudSubscription).not.toHaveBeenCalled();
expect(openModal).not.toHaveBeenCalled();
});
test('should match snapshot when is cloud environment', () => {
const wrapper = shallow(
<FeatureDiscovery
featureName='test'
minimumSKURequiredForFeature={LicenseSkus.Professional}
titleID='translation.test.title'
titleDefault='Foo'
copyID='translation.test.copy'
copyDefault={'Bar'}
learnMoreURL='https://test.mattermost.com/secondary/'
featureDiscoveryImage={<SamlSVG/>}
// eslint-disable-next-line @typescript-eslint/naming-convention
stats={{TOTAL_USERS: 20}}
prevTrialLicense={{IsLicensed: 'false'}}
isCloud={true}
isCloudTrial={false}
hadPrevCloudTrial={false}
isPaidSubscription={false}
cloudFreeDeprecated={false}
isSubscriptionLoaded={true}
actions={{
getPrevTrialLicense: jest.fn(),
openModal: jest.fn(),
getCloudSubscription: jest.fn(),
}}
/>,
);
expect(wrapper).toMatchSnapshot();
test('should match component state when is cloud environment', async () => {
const getPrevTrialLicense = jest.fn();
const getCloudSubscription = jest.fn();
const openModal = jest.fn();
await waitFor(() => {
renderWithIntl(
<ReduxProvider store={store}>
<FeatureDiscovery
featureName='test'
minimumSKURequiredForFeature={LicenseSkus.Professional}
titleID='translation.test.title'
titleDefault='Foo'
copyID='translation.test.copy'
copyDefault={'Bar'}
learnMoreURL='https://test.mattermost.com/secondary/'
featureDiscoveryImage={<SamlSVG/>}
// eslint-disable-next-line @typescript-eslint/naming-convention
stats={{TOTAL_USERS: 20}}
prevTrialLicense={{IsLicensed: 'false'}}
isCloud={true}
isCloudTrial={false}
hadPrevCloudTrial={false}
isPaidSubscription={false}
isSubscriptionLoaded={true}
cloudFreeDeprecated={false}
actions={{
getPrevTrialLicense,
getCloudSubscription,
openModal,
}}
/>
</ReduxProvider>,
);
});
// subscription is loaded, so loadingSpinner should not be visible
expect(screen.queryByTestId('loadingSpinner')).not.toBeInTheDocument();
expect(screen.queryByText('Bar')).toBeInTheDocument();
expect(screen.queryByText('Foo')).toBeInTheDocument();
//this option is visible only when it is cloud environment
expect(screen.getByRole('button', {name: 'Try free for 30 days'})).toBeInTheDocument();
expect(screen.getAllByText('Try free for 30 days')).toHaveLength(2);
expect(screen.getByTestId('featureDiscovery_secondaryCallToAction')).toHaveAttribute('href', 'https://test.mattermost.com/secondary/?utm_source=mattermost&utm_medium=in-product&utm_content=feature_discovery&uid=&sid=');
expect(screen.getByText('Privacy Policy')).toHaveAttribute('href', 'https://mattermost.com/privacy-policy/?utm_source=mattermost&utm_medium=in-product&utm_content=feature_discovery&uid=&sid=');
const featureLink = screen.getByTestId('featureDiscovery_secondaryCallToAction');
expect(featureLink).toBeInTheDocument();
expect(featureLink).toHaveAttribute('href', 'https://test.mattermost.com/secondary/?utm_source=mattermost&utm_medium=in-product&utm_content=feature_discovery&uid=&sid=');
expect(featureLink).toHaveTextContent('Learn more');
expect(getPrevTrialLicense).toHaveBeenCalled();
expect(getCloudSubscription).not.toHaveBeenCalled();
expect(openModal).not.toHaveBeenCalled();
expect(screen.queryByRole('button', {name: 'Start trial'})).not.toBeInTheDocument();
});
test('should match snapshot when is cloud environment and subscription is not loaded yet in redux store', () => {
const wrapper = shallow(
<FeatureDiscovery
featureName='test'
minimumSKURequiredForFeature={LicenseSkus.Professional}
titleID='translation.test.title'
titleDefault='Foo'
copyID='translation.test.copy'
copyDefault={'Bar'}
learnMoreURL='https://test.mattermost.com/secondary/'
featureDiscoveryImage={<SamlSVG/>}
// eslint-disable-next-line @typescript-eslint/naming-convention
stats={{TOTAL_USERS: 20}}
prevTrialLicense={{IsLicensed: 'false'}}
isCloud={true}
isCloudTrial={false}
hadPrevCloudTrial={false}
isSubscriptionLoaded={false}
cloudFreeDeprecated={false}
isPaidSubscription={false}
actions={{
getPrevTrialLicense: jest.fn(),
openModal: jest.fn(),
getCloudSubscription: jest.fn(),
}}
/>,
test('should match component state when is cloud environment and subscription is not loaded yet in redux store', () => {
const getPrevTrialLicense = jest.fn();
const getCloudSubscription = jest.fn();
const openModal = jest.fn();
renderWithIntl(
<ReduxProvider store={store}>
<FeatureDiscovery
featureName='test'
minimumSKURequiredForFeature={LicenseSkus.Professional}
titleID='translation.test.title'
titleDefault='Foo'
copyID='translation.test.copy'
copyDefault={'Bar'}
learnMoreURL='https://test.mattermost.com/secondary/'
featureDiscoveryImage={<SamlSVG/>}
// eslint-disable-next-line @typescript-eslint/naming-convention
stats={{TOTAL_USERS: 20}}
prevTrialLicense={{IsLicensed: 'false'}}
isCloud={true}
isCloudTrial={false}
hadPrevCloudTrial={false}
isSubscriptionLoaded={false}
isPaidSubscription={false}
cloudFreeDeprecated={false}
actions={{
getPrevTrialLicense,
getCloudSubscription,
openModal,
}}
/>
</ReduxProvider>,
);
expect(wrapper).toMatchSnapshot();
// when is cloud and subscription is not loaded yet, then only loading spinner is visible
expect(screen.getByTestId('loadingSpinner')).toBeInTheDocument();
expect(screen.queryByText('Bar')).not.toBeInTheDocument();
expect(screen.queryByText('Foo')).not.toBeInTheDocument();
//this option is visible only when subscription is loaded and is cloud environment
expect(screen.queryByRole('button', {name: 'Try free for 30 days'})).not.toBeInTheDocument();
expect(screen.queryByTestId('featureDiscovery_secondaryCallToAction')).not.toBeInTheDocument();
expect(getPrevTrialLicense).toHaveBeenCalled();
expect(getCloudSubscription).not.toHaveBeenCalled();
expect(openModal).not.toHaveBeenCalled();
expect(screen.queryByRole('button', {name: 'Start trial'})).not.toBeInTheDocument();
});
});
});

Просмотреть файл

@@ -2,9 +2,9 @@
// See LICENSE.txt for license information.
import React from 'react';
import {shallow} from 'enzyme';
import PostEmoji from './post_emoji';
import {render, screen} from '@testing-library/react';
describe('PostEmoji', () => {
const baseProps = {
@@ -13,17 +13,16 @@ describe('PostEmoji', () => {
};
test('should render image when imageUrl is provided', () => {
const wrapper = shallow(<PostEmoji {...baseProps}/>);
render(<PostEmoji {...baseProps}/>);
expect(wrapper.find('span').prop('style')).toMatchObject({
backgroundImage: `url(${baseProps.imageUrl})`,
});
expect(screen.getByTitle(':' + baseProps.name + ':')).toBeInTheDocument();
expect(screen.getByTitle(':' + baseProps.name + ':')).toHaveStyle(`backgroundImage: url(${baseProps.imageUrl})}`);
});
test('should render shortcode text within span when imageUrl is provided', () => {
const wrapper = shallow(<PostEmoji {...baseProps}/>);
render(<PostEmoji {...baseProps}/>);
expect(wrapper.find('span').text()).toBe(`:${baseProps.name}:`);
expect(screen.getByTitle(':' + baseProps.name + ':')).toHaveTextContent(`:${baseProps.name}:`);
});
test('should render original text when imageUrl is empty', () => {
@@ -32,9 +31,9 @@ describe('PostEmoji', () => {
imageUrl: '',
};
const wrapper = shallow(<PostEmoji {...props}/>);
render(<PostEmoji {...props}/>);
expect(wrapper.find('span')).toHaveLength(0);
expect(wrapper.text()).toBe(`:${props.name}:`);
expect(screen.queryByTitle(':' + baseProps.name + ':')).not.toBeInTheDocument();
expect(screen.getByText(`:${props.name}:`)).toBeInTheDocument();
});
});

Просмотреть файл

@@ -1,301 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`components/PostMarkdown plugin hooks can build upon other hook message updates 1`] = `
<Connect(Markdown)
channelNamesMap={
Object {
"test": Object {
"display_name": "Test",
},
}
}
editedAt={0}
imageProps={Object {}}
imagesMetadata={Object {}}
isRHS={false}
mentionKeys={
Array [
Object {
"key": "a",
},
Object {
"key": "b",
},
Object {
"key": "c",
},
]
}
message="hello world!"
options={
Object {
"disableGroupHighlight": false,
"editedAt": 0,
"mentionHighlight": true,
}
}
postId="id"
proxyImages={true}
/>
`;
exports[`components/PostMarkdown plugin hooks can overwrite other hooks messages 1`] = `
<Connect(Markdown)
channelNamesMap={
Object {
"test": Object {
"display_name": "Test",
},
}
}
editedAt={0}
imageProps={Object {}}
imagesMetadata={Object {}}
isRHS={false}
mentionKeys={
Array [
Object {
"key": "a",
},
Object {
"key": "b",
},
Object {
"key": "c",
},
]
}
message="world!"
options={
Object {
"disableGroupHighlight": false,
"editedAt": 0,
"mentionHighlight": true,
}
}
postId="id"
proxyImages={true}
/>
`;
exports[`components/PostMarkdown should correctly pass postId down 1`] = `
<Connect(Markdown)
editedAt={0}
imageProps={Object {}}
imagesMetadata={Object {}}
isRHS={false}
mentionKeys={
Array [
Object {
"key": "a",
},
Object {
"key": "b",
},
Object {
"key": "c",
},
]
}
message="message"
options={
Object {
"disableGroupHighlight": false,
"editedAt": 0,
"mentionHighlight": true,
}
}
postId="post_id"
proxyImages={true}
/>
`;
exports[`components/PostMarkdown should render header change properly 1`] = `
<div>
<MemoizedFormattedMessage
defaultMessage="{username} updated the channel header <br></br><strong>From:</strong> {old} <br></br><strong>To:</strong> {new}"
id="api.channel.post_update_channel_header_message_and_forget.updated_from"
values={
Object {
"br": [Function],
"new": <Memo(Connect(Markdown))
message="now ~test"
options={
Object {
"channelNamesMap": Object {
"test": Object {
"display_name": "Test",
},
},
"mentionHighlight": true,
"singleline": true,
}
}
postId="post_id"
postType="system_header_change"
/>,
"old": <Memo(Connect(Markdown))
message="see ~test"
options={
Object {
"channelNamesMap": Object {
"test": Object {
"display_name": "Test",
},
},
"mentionHighlight": true,
"singleline": true,
}
}
postId="post_id"
postType="system_header_change"
/>,
"strong": [Function],
"username": <Memo(Connect(Markdown))
message="@user"
options={
Object {
"markdown": false,
}
}
/>,
}
}
/>
</div>
`;
exports[`components/PostMarkdown should render properly with a post 1`] = `
<Connect(Markdown)
channelNamesMap={
Object {
"test": Object {
"display_name": "Test",
},
}
}
editedAt={0}
imageProps={Object {}}
imagesMetadata={Object {}}
isRHS={false}
mentionKeys={
Array [
Object {
"key": "a",
},
Object {
"key": "b",
},
Object {
"key": "c",
},
]
}
message="See ~test"
options={
Object {
"disableGroupHighlight": false,
"editedAt": 0,
"mentionHighlight": true,
}
}
postId="id"
proxyImages={true}
/>
`;
exports[`components/PostMarkdown should render properly with an empty post 1`] = `
<Connect(Markdown)
editedAt={0}
imageProps={Object {}}
imagesMetadata={Object {}}
isRHS={false}
mentionKeys={
Array [
Object {
"key": "a",
},
Object {
"key": "b",
},
Object {
"key": "c",
},
]
}
message="message"
options={
Object {
"disableGroupHighlight": false,
"editedAt": 0,
"mentionHighlight": true,
}
}
postId="id"
proxyImages={true}
/>
`;
exports[`components/PostMarkdown should render properly without group highlight on a post 1`] = `
<Connect(Markdown)
editedAt={0}
imageProps={Object {}}
imagesMetadata={Object {}}
isRHS={false}
mentionKeys={
Array [
Object {
"key": "a",
},
Object {
"key": "b",
},
Object {
"key": "c",
},
]
}
message="No @group highlight"
options={
Object {
"disableGroupHighlight": true,
"editedAt": 0,
"mentionHighlight": true,
}
}
postId="id"
proxyImages={true}
/>
`;
exports[`components/PostMarkdown should render properly without highlight a post 1`] = `
<Connect(Markdown)
editedAt={0}
imageProps={Object {}}
imagesMetadata={Object {}}
isRHS={false}
mentionKeys={
Array [
Object {
"key": "a",
},
Object {
"key": "b",
},
Object {
"key": "c",
},
]
}
message="No highlight"
options={
Object {
"disableGroupHighlight": false,
"editedAt": 0,
"mentionHighlight": true,
}
}
postId="id"
proxyImages={true}
/>
`;

Просмотреть файл

@@ -2,15 +2,15 @@
// See LICENSE.txt for license information.
import React from 'react';
import {shallow} from 'enzyme';
import {Posts} from 'mattermost-redux/constants';
import PostMarkdown from 'components/post_markdown/post_markdown';
import Markdown from 'components/markdown';
import {TestHelper} from 'utils/test_helper';
import {Post, PostType} from '@mattermost/types/posts';
import {screen} from '@testing-library/react';
import {renderWithIntlAndStore} from 'tests/react_testing_utils';
describe('components/PostMarkdown', () => {
const baseProps = {
@@ -24,16 +24,51 @@ describe('components/PostMarkdown', () => {
currentTeam: TestHelper.getTeamMock(),
};
const state = {entities: {
posts: {
posts: {},
postsInThread: {},
},
channels: {},
teams: {
teams: {
currentTeamId: {},
},
},
preferences: {
myPreferences: {
},
},
groups: {
groups: {},
myGroups: [],
},
users: {
currentUserId: '',
profiles: {},
},
emojis: {customEmoji: {}},
general: {config: {}, license: {}},
},
};
test('should not error when rendering without a post', () => {
const props = {...baseProps};
Reflect.deleteProperty(props, 'post');
shallow(<PostMarkdown {...props}/>);
Reflect.deleteProperty(props, 'post');
renderWithIntlAndStore(<PostMarkdown {...props}/>, state);
expect(screen.getByText('message')).toBeInTheDocument();
});
test('should render properly with an empty post', () => {
const wrapper = shallow(<PostMarkdown {...baseProps}/>);
expect(wrapper).toMatchSnapshot();
renderWithIntlAndStore(
<PostMarkdown
{...baseProps}
post={{} as any}
/>, state);
expect(screen.getByText('message')).toBeInTheDocument();
});
test('should render properly with a post', () => {
@@ -45,13 +80,21 @@ describe('components/PostMarkdown', () => {
channel_mentions: {
test: {
display_name: 'Test',
team_name: 'test',
},
},
},
}),
};
const wrapper = shallow(<PostMarkdown {...props}/>);
expect(wrapper).toMatchSnapshot();
renderWithIntlAndStore(<PostMarkdown {...props}/>, state);
const link = screen.getByRole('link');
expect(screen.getByText('See')).toBeInTheDocument();
expect(link).toHaveAttribute('data-channel-mention', 'test');
expect(link).toHaveAttribute('data-channel-mention-team', 'test');
expect(link).toHaveAttribute('href', '/test/channels/test');
expect(link).toHaveClass('mention-link');
});
test('should render properly without highlight a post', () => {
@@ -61,10 +104,21 @@ describe('components/PostMarkdown', () => {
options: {
mentionHighlight: false,
},
post: TestHelper.getPostMock(),
post: TestHelper.getPostMock({
props: {
channel_mentions: {
test: {
display_name: 'Test',
team_name: 'test',
},
},
},
}),
};
const wrapper = shallow(<PostMarkdown {...props}/>);
expect(wrapper).toMatchSnapshot();
renderWithIntlAndStore(<PostMarkdown {...props}/>, state);
expect(screen.getByText('No highlight')).toBeInTheDocument();
expect(screen.queryByRole('link')).not.toBeInTheDocument();
});
test('should render properly without group highlight on a post', () => {
@@ -78,8 +132,17 @@ describe('components/PostMarkdown', () => {
},
}),
};
const wrapper = shallow(<PostMarkdown {...props}/>);
expect(wrapper).toMatchSnapshot();
renderWithIntlAndStore(<PostMarkdown {...props}/>, state);
const groupMention = screen.getByText('@group');
expect(screen.getByText('No', {exact: false})).toBeInTheDocument();
expect(groupMention).toBeInTheDocument();
expect(groupMention).toHaveAttribute('data-mention', 'group');
expect(groupMention).not.toHaveClass('mention-link');
expect(screen.getByText('highlight', {exact: false})).toBeInTheDocument();
});
test('should correctly pass postId down', () => {
@@ -89,9 +152,8 @@ describe('components/PostMarkdown', () => {
id: 'post_id',
}),
};
const wrapper = shallow(<PostMarkdown {...props}/>);
expect(wrapper.find(Markdown).prop('postId')).toEqual(props.post.id);
expect(wrapper).toMatchSnapshot();
renderWithIntlAndStore(<PostMarkdown {...props}/>, state);
expect(screen.getByText('message')).toBeInTheDocument();
});
test('should render header change properly', () => {
@@ -107,13 +169,34 @@ describe('components/PostMarkdown', () => {
channel_mentions: {
test: {
display_name: 'Test',
team_name: 'test',
},
},
},
}),
};
const wrapper = shallow(<PostMarkdown {...props}/>);
expect(wrapper).toMatchSnapshot();
renderWithIntlAndStore(<PostMarkdown {...props}/>, state);
expect(screen.getByText('@user')).toBeInTheDocument();
expect(screen.getByText('updated the channel header')).toBeInTheDocument();
expect(screen.getByText('From:')).toBeInTheDocument();
expect(screen.getByText('see')).toBeInTheDocument();
expect(screen.getByText('To:')).toBeInTheDocument();
expect(screen.getByText('now')).toBeInTheDocument();
const testLink = screen.getAllByRole('link', {name: '~Test'});
expect(testLink).toHaveLength(2);
expect(testLink[0]).toHaveAttribute('data-channel-mention', 'test');
expect(testLink[0]).toHaveAttribute('data-channel-mention-team', 'test');
expect(testLink[0]).toHaveAttribute('href', '/test/channels/test');
expect(screen.getAllByRole('link')[0]).toHaveClass('mention-link');
expect(testLink[1]).toHaveAttribute('data-channel-mention', 'test');
expect(testLink[1]).toHaveAttribute('data-channel-mention-team', 'test');
expect(testLink[1]).toHaveAttribute('href', '/test/channels/test');
expect(screen.getAllByRole('link')[1]).toHaveClass('mention-link');
});
test('plugin hooks can build upon other hook message updates', () => {
@@ -143,8 +226,11 @@ describe('components/PostMarkdown', () => {
},
],
};
const wrapper = shallow(<PostMarkdown {...props}/>);
expect(wrapper).toMatchSnapshot();
renderWithIntlAndStore(<PostMarkdown {...props}/>, state);
expect(screen.queryByText('world', {exact: true})).not.toBeInTheDocument();
// hook message
expect(screen.getByText('hello world!')).toBeInTheDocument();
});
test('plugin hooks can overwrite other hooks messages', () => {
@@ -174,7 +260,8 @@ describe('components/PostMarkdown', () => {
},
],
};
const wrapper = shallow(<PostMarkdown {...props}/>);
expect(wrapper).toMatchSnapshot();
renderWithIntlAndStore(<PostMarkdown {...props}/>, state);
expect(screen.queryByText('world', {exact: true})).not.toBeInTheDocument();
expect(screen.queryByText('world!', {exact: true})).toBeInTheDocument();
});
});

Просмотреть файл

@@ -1,43 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`components/PostProfilePicture should match snapshot, no status and post icon override specified, default props 1`] = `
<ProfilePicture
channelId=""
fromAutoResponder={false}
fromWebhook={false}
hasMention={true}
isBot={false}
isBusy={true}
isEmoji={false}
isRHS={false}
popoverPlacement="right"
profileSrc="/api/v4/users/defaultuser/image?_=0"
size="md"
src=""
status="offline"
userId="defaultuser"
username="some-user"
wrapperClass=""
/>
`;
exports[`components/PostProfilePicture should match snapshot, status and post icon override specified, default props 1`] = `
<ProfilePicture
channelId=""
fromAutoResponder={false}
fromWebhook={false}
hasMention={true}
isBot={false}
isBusy={true}
isEmoji={false}
isRHS={false}
popoverPlacement="right"
profileSrc="/api/v4/users/defaultuser/image?_=0"
size="md"
src=""
status="away"
userId="defaultuser"
username="some-user"
wrapperClass=""
/>
`;

Просмотреть файл

@@ -2,11 +2,11 @@
// See LICENSE.txt for license information.
import React, {ComponentProps} from 'react';
import {shallow} from 'enzyme';
import {TestHelper} from 'utils/test_helper';
import PostProfilePicture from './post_profile_picture';
import {render, screen} from '@testing-library/react';
type Props = ComponentProps<typeof PostProfilePicture>;
@@ -29,25 +29,35 @@ describe('components/PostProfilePicture', () => {
isBot: Boolean(user.is_bot),
};
test('should match snapshot, no status and post icon override specified, default props', () => {
test('no status and post icon override specified, default props', () => {
const props: Props = baseProps;
const wrapper = shallow(
render(
<PostProfilePicture {...props}/>,
);
expect(wrapper).toMatchSnapshot();
expect(screen.queryByLabelText('Online Icon')).not.toBeInTheDocument();
// no status is given, 'Offline Icon' should be in the dom as a fallback
expect(screen.getByLabelText('Offline Icon')).toBeInTheDocument();
});
test('should match snapshot, status and post icon override specified, default props', () => {
test('status and post icon override specified, default props', () => {
const props: Props = {
...baseProps,
status: 'away',
postIconOverrideURL: 'http://example.com/image.png',
};
const wrapper = shallow(
render(
<PostProfilePicture {...props}/>,
);
expect(wrapper).toMatchSnapshot();
// status is given, 'Away Icon' should be in the dom
expect(screen.getByLabelText('Away Icon')).toBeInTheDocument();
expect(screen.queryByLabelText('Online Icon')).not.toBeInTheDocument();
expect(screen.queryByLabelText('Offline Icon')).not.toBeInTheDocument();
expect(screen.getAllByRole('img')).toHaveLength(2);
});
});

Просмотреть файл

@@ -1,941 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`components/post_view/ChannelIntroMessages test DEFAULT Channel should match snapshot 1`] = `
<div
className="channel-intro "
id="channelIntro"
>
<h2
className="channel-intro__title"
>
<MemoizedFormattedMessage
defaultMessage="Beginning of {name}"
id="intro_messages.beginning"
values={
Object {
"name": "test channel",
}
}
/>
</h2>
<p
className="channel-intro__content"
>
<FormattedMarkdownMessage
defaultMessage="**Welcome to {display_name}!**\\\\n \\\\nPost messages here that you want everyone to see. Everyone automatically becomes a permanent member of this channel when they join the team."
id="intro_messages.default"
values={
Object {
"display_name": "test channel",
}
}
/>
</p>
<Connect(PluggableIntroButtons)
channel={
Object {
"create_at": 1508265709607,
"creator_id": "creator_id",
"delete_at": 0,
"display_name": "test channel",
"header": "test",
"id": "channel_id",
"last_post_at": 1508265709635,
"name": "town-square",
"purpose": "test",
"team_id": "team-id",
"type": "O",
"update_at": 1508265709607,
}
}
/>
<Connect(ChannelPermissionGate)
channelId="channel_id"
permissions={
Array [
"manage_public_channel_properties",
]
}
teamId="team-id"
>
<Connect(ToggleModalButton)
ariaLabel="Set a Header"
className="intro-links color--link channelIntroButton"
dialogProps={
Object {
"channel": Object {
"create_at": 1508265709607,
"creator_id": "creator_id",
"delete_at": 0,
"display_name": "test channel",
"header": "test",
"id": "channel_id",
"last_post_at": 1508265709635,
"name": "town-square",
"purpose": "test",
"team_id": "team-id",
"type": "O",
"update_at": 1508265709607,
},
}
}
dialogType={
Object {
"$$typeof": Symbol(react.memo),
"WrappedComponent": [Function],
"compare": null,
"type": [Function],
}
}
modalId="edit_channel_header"
>
<EditIcon />
<MemoizedFormattedMessage
defaultMessage="Set a Header"
id="intro_messages.setHeader"
/>
</Connect(ToggleModalButton)>
</Connect(ChannelPermissionGate)>
<br />
</div>
`;
exports[`components/post_view/ChannelIntroMessages test DEFAULT Channel should match snapshot, readonly 1`] = `
<div
className="channel-intro "
id="channelIntro"
>
<h2
className="channel-intro__title"
>
<MemoizedFormattedMessage
defaultMessage="Beginning of {name}"
id="intro_messages.beginning"
values={
Object {
"name": "test channel",
}
}
/>
</h2>
<p
className="channel-intro__content"
>
<FormattedMarkdownMessage
defaultMessage="**Welcome to {display_name}!**\\\\n \\\\nMessages can only be posted by system admins. Everyone automatically becomes a permanent member of this channel when they join the team."
id="intro_messages.readonly.default"
values={
Object {
"display_name": "test channel",
}
}
/>
</p>
<br />
</div>
`;
exports[`components/post_view/ChannelIntroMessages test DEFAULT Channel should match snapshot, with enable, group constrained 1`] = `
<div
className="channel-intro "
id="channelIntro"
>
<h2
className="channel-intro__title"
>
<MemoizedFormattedMessage
defaultMessage="Beginning of {name}"
id="intro_messages.beginning"
values={
Object {
"name": "test channel",
}
}
/>
</h2>
<p
className="channel-intro__content"
>
<FormattedMarkdownMessage
defaultMessage="**Welcome to {display_name}!**\\\\n \\\\nPost messages here that you want everyone to see. Everyone automatically becomes a permanent member of this channel when they join the team."
id="intro_messages.default"
values={
Object {
"display_name": "test channel",
}
}
/>
</p>
<Connect(TeamPermissionGate)
permissions={
Array [
"invite_user",
]
}
teamId="team-id"
>
<Connect(TeamPermissionGate)
permissions={
Array [
"add_user_to_team",
]
}
teamId="team-id"
>
<Connect(ToggleModalButton)
className="intro-links color--link"
dialogProps={
Object {
"channel": Object {
"create_at": 1508265709607,
"creator_id": "creator_id",
"delete_at": 0,
"display_name": "test channel",
"header": "test",
"id": "channel_id",
"last_post_at": 1508265709635,
"name": "town-square",
"purpose": "test",
"team_id": "team-id",
"type": "O",
"update_at": 1508265709607,
},
}
}
dialogType={
Object {
"$$typeof": Symbol(react.memo),
"WrappedComponent": [Function],
"compare": null,
"type": [Function],
}
}
modalId="add_groups_to_team"
>
<LocalizedIcon
className="fa fa-user-plus"
title={
Object {
"defaultMessage": "Add Icon",
"id": "generic_icons.add",
}
}
/>
<MemoizedFormattedMessage
defaultMessage="Add other groups to this team"
id="intro_messages.addGroupsToTeam"
/>
</Connect(ToggleModalButton)>
</Connect(TeamPermissionGate)>
</Connect(TeamPermissionGate)>
<Connect(PluggableIntroButtons)
channel={
Object {
"create_at": 1508265709607,
"creator_id": "creator_id",
"delete_at": 0,
"display_name": "test channel",
"header": "test",
"id": "channel_id",
"last_post_at": 1508265709635,
"name": "town-square",
"purpose": "test",
"team_id": "team-id",
"type": "O",
"update_at": 1508265709607,
}
}
/>
<Connect(ChannelPermissionGate)
channelId="channel_id"
permissions={
Array [
"manage_public_channel_properties",
]
}
teamId="team-id"
>
<Connect(ToggleModalButton)
ariaLabel="Set a Header"
className="intro-links color--link channelIntroButton"
dialogProps={
Object {
"channel": Object {
"create_at": 1508265709607,
"creator_id": "creator_id",
"delete_at": 0,
"display_name": "test channel",
"header": "test",
"id": "channel_id",
"last_post_at": 1508265709635,
"name": "town-square",
"purpose": "test",
"team_id": "team-id",
"type": "O",
"update_at": 1508265709607,
},
}
}
dialogType={
Object {
"$$typeof": Symbol(react.memo),
"WrappedComponent": [Function],
"compare": null,
"type": [Function],
}
}
modalId="edit_channel_header"
>
<EditIcon />
<MemoizedFormattedMessage
defaultMessage="Set a Header"
id="intro_messages.setHeader"
/>
</Connect(ToggleModalButton)>
</Connect(ChannelPermissionGate)>
<br />
</div>
`;
exports[`components/post_view/ChannelIntroMessages test DEFAULT Channel should match snapshot, with enableUserCreation 1`] = `
<div
className="channel-intro "
id="channelIntro"
>
<h2
className="channel-intro__title"
>
<MemoizedFormattedMessage
defaultMessage="Beginning of {name}"
id="intro_messages.beginning"
values={
Object {
"name": "test channel",
}
}
/>
</h2>
<p
className="channel-intro__content"
>
<FormattedMarkdownMessage
defaultMessage="**Welcome to {display_name}!**\\\\n \\\\nPost messages here that you want everyone to see. Everyone automatically becomes a permanent member of this channel when they join the team."
id="intro_messages.default"
values={
Object {
"display_name": "test channel",
}
}
/>
</p>
<Connect(TeamPermissionGate)
permissions={
Array [
"invite_user",
]
}
teamId="team-id"
>
<Connect(TeamPermissionGate)
permissions={
Array [
"add_user_to_team",
]
}
teamId="team-id"
>
<Memo(AddMembersButton)
channel={
Object {
"create_at": 1508265709607,
"creator_id": "creator_id",
"delete_at": 0,
"display_name": "test channel",
"header": "test",
"id": "channel_id",
"last_post_at": 1508265709635,
"name": "town-square",
"purpose": "test",
"team_id": "team-id",
"type": "O",
"update_at": 1508265709607,
}
}
pluginButtons={
<Memo(Connect(PluggableIntroButtons))
channel={
Object {
"create_at": 1508265709607,
"creator_id": "creator_id",
"delete_at": 0,
"display_name": "test channel",
"header": "test",
"id": "channel_id",
"last_post_at": 1508265709635,
"name": "town-square",
"purpose": "test",
"team_id": "team-id",
"type": "O",
"update_at": 1508265709607,
}
}
/>
}
setHeader={
<Memo(Connect(ChannelPermissionGate))
channelId="channel_id"
permissions={
Array [
"manage_public_channel_properties",
]
}
teamId="team-id"
>
<Memo(Connect(ToggleModalButton))
ariaLabel="Set a Header"
className="intro-links color--link channelIntroButton"
dialogProps={
Object {
"channel": Object {
"create_at": 1508265709607,
"creator_id": "creator_id",
"delete_at": 0,
"display_name": "test channel",
"header": "test",
"id": "channel_id",
"last_post_at": 1508265709635,
"name": "town-square",
"purpose": "test",
"team_id": "team-id",
"type": "O",
"update_at": 1508265709607,
},
}
}
dialogType={
Object {
"$$typeof": Symbol(react.memo),
"WrappedComponent": [Function],
"compare": null,
"type": [Function],
}
}
modalId="edit_channel_header"
>
<EditIcon />
<Memo(MemoizedFormattedMessage)
defaultMessage="Set a Header"
id="intro_messages.setHeader"
/>
</Memo(Connect(ToggleModalButton))>
</Memo(Connect(ChannelPermissionGate))>
}
usersLimit={10}
/>
</Connect(TeamPermissionGate)>
</Connect(TeamPermissionGate)>
<br />
</div>
`;
exports[`components/post_view/ChannelIntroMessages test DIRECT Channel should match snapshot, with teammate 1`] = `
<div
className="channel-intro "
id="channelIntro"
>
<div
className="post-profile-img__container channel-intro-img"
>
<ProfilePicture
hasMention={true}
isEmoji={false}
isRHS={false}
popoverPlacement="right"
size="xl"
src="/api/v4/users/user1/image?_=0"
userId="user1"
wrapperClass=""
/>
</div>
<div
className="channel-intro-profile d-flex"
>
<Connect(UserProfile)
disablePopover={false}
hasMention={true}
userId="user1"
/>
</div>
<p
className="channel-intro-text"
>
<FormattedMarkdownMessage
defaultMessage="This is the start of your direct message history with {teammate}.\\\\nDirect messages and files shared here are not shown to people outside this area."
id="intro_messages.DM"
values={
Object {
"teammate": "my teammate",
}
}
/>
</p>
<Connect(PluggableIntroButtons)
channel={
Object {
"create_at": 1508265709607,
"creator_id": "creator_id",
"delete_at": 0,
"display_name": "test channel",
"header": "test",
"id": "channel_id",
"last_post_at": 1508265709635,
"name": "testing",
"purpose": "test",
"team_id": "team-id",
"type": "D",
"update_at": 1508265709607,
}
}
/>
<Connect(ToggleModalButton)
ariaLabel="Set a Header"
className="intro-links color--link channelIntroButton"
dialogProps={
Object {
"channel": Object {
"create_at": 1508265709607,
"creator_id": "creator_id",
"delete_at": 0,
"display_name": "test channel",
"header": "test",
"id": "channel_id",
"last_post_at": 1508265709635,
"name": "testing",
"purpose": "test",
"team_id": "team-id",
"type": "D",
"update_at": 1508265709607,
},
}
}
dialogType={
Object {
"$$typeof": Symbol(react.memo),
"WrappedComponent": [Function],
"compare": null,
"type": [Function],
}
}
modalId="edit_channel_header"
>
<EditIcon />
<MemoizedFormattedMessage
defaultMessage="Set a Header"
id="intro_messages.setHeader"
/>
</Connect(ToggleModalButton)>
</div>
`;
exports[`components/post_view/ChannelIntroMessages test DIRECT Channel should match snapshot, without teammate 1`] = `
<div
className="channel-intro "
id="channelIntro"
>
<p
className="channel-intro-text"
>
<MemoizedFormattedMessage
defaultMessage="This is the start of your direct message history with this teammate. Direct messages and files shared here are not shown to people outside this area."
id="intro_messages.teammate"
/>
</p>
</div>
`;
exports[`components/post_view/ChannelIntroMessages test Group Channel should match snapshot, no profiles 1`] = `
<div
className="channel-intro "
id="channelIntro"
>
<p
className="channel-intro-text"
>
<MemoizedFormattedMessage
defaultMessage="This is the start of your group message history with these teammates. Messages and files shared here are not shown to people outside this area."
id="intro_messages.group_message"
/>
</p>
</div>
`;
exports[`components/post_view/ChannelIntroMessages test Group Channel should match snapshot, with profiles 1`] = `
<div
className="channel-intro "
id="channelIntro"
>
<div
className="post-profile-img__container channel-intro-img"
>
<ProfilePicture
hasMention={false}
isEmoji={false}
isRHS={false}
key="introprofilepictureuser1"
popoverPlacement="right"
size="xl"
src="/api/v4/users/user1/image?_=0"
userId="user1"
wrapperClass=""
/>
<ProfilePicture
hasMention={false}
isEmoji={false}
isRHS={false}
key="introprofilepictureguest1"
popoverPlacement="right"
size="xl"
src="/api/v4/users/guest1/image?_=0"
userId="guest1"
wrapperClass=""
/>
</div>
<p
className="channel-intro-text"
>
<FormattedMarkdownMessage
defaultMessage="This is the start of your group message history with {names}.\\\\nMessages and files shared here are not shown to people outside this area."
id="intro_messages.GM"
values={
Object {
"names": "test channel",
}
}
/>
</p>
<Connect(PluggableIntroButtons)
channel={
Object {
"create_at": 1508265709607,
"creator_id": "creator_id",
"delete_at": 0,
"display_name": "test channel",
"header": "test",
"id": "channel_id",
"last_post_at": 1508265709635,
"name": "testing",
"purpose": "test",
"team_id": "team-id",
"type": "G",
"update_at": 1508265709607,
}
}
/>
<Connect(ToggleModalButton)
ariaLabel="Set a Header"
className="intro-links color--link channelIntroButton"
dialogProps={
Object {
"channel": Object {
"create_at": 1508265709607,
"creator_id": "creator_id",
"delete_at": 0,
"display_name": "test channel",
"header": "test",
"id": "channel_id",
"last_post_at": 1508265709635,
"name": "testing",
"purpose": "test",
"team_id": "team-id",
"type": "G",
"update_at": 1508265709607,
},
}
}
dialogType={
Object {
"$$typeof": Symbol(react.memo),
"WrappedComponent": [Function],
"compare": null,
"type": [Function],
}
}
modalId="edit_channel_header"
>
<EditIcon />
<MemoizedFormattedMessage
defaultMessage="Set a Header"
id="intro_messages.setHeader"
/>
</Connect(ToggleModalButton)>
</div>
`;
exports[`components/post_view/ChannelIntroMessages test OFFTOPIC Channel should match snapshot 1`] = `
<div
className="channel-intro "
id="channelIntro"
>
<h2
className="channel-intro__title"
>
<MemoizedFormattedMessage
defaultMessage="Beginning of {name}"
id="intro_messages.beginning"
values={
Object {
"name": "test channel",
}
}
/>
</h2>
<p
className="channel-intro__content"
>
<MemoizedFormattedMessage
defaultMessage="This is the start of {display_name}, a channel for non-work-related conversations."
id="intro_messages.offTopic"
values={
Object {
"display_name": "test channel",
}
}
/>
</p>
<Memo(AddMembersButton)
channel={
Object {
"create_at": 1508265709607,
"creator_id": "creator_id",
"delete_at": 0,
"display_name": "test channel",
"header": "test",
"id": "channel_id",
"last_post_at": 1508265709635,
"name": "off-topic",
"purpose": "test",
"team_id": "team-id",
"type": "O",
"update_at": 1508265709607,
}
}
pluginButtons={
<Memo(Connect(PluggableIntroButtons))
channel={
Object {
"create_at": 1508265709607,
"creator_id": "creator_id",
"delete_at": 0,
"display_name": "test channel",
"header": "test",
"id": "channel_id",
"last_post_at": 1508265709635,
"name": "off-topic",
"purpose": "test",
"team_id": "team-id",
"type": "O",
"update_at": 1508265709607,
}
}
/>
}
setHeader={
<Memo(Connect(ChannelPermissionGate))
channelId="channel_id"
permissions={
Array [
"manage_public_channel_properties",
]
}
teamId="team-id"
>
<Memo(Connect(ToggleModalButton))
ariaLabel="Set a Header"
className="intro-links color--link channelIntroButton"
dialogProps={
Object {
"channel": Object {
"create_at": 1508265709607,
"creator_id": "creator_id",
"delete_at": 0,
"display_name": "test channel",
"header": "test",
"id": "channel_id",
"last_post_at": 1508265709635,
"name": "off-topic",
"purpose": "test",
"team_id": "team-id",
"type": "O",
"update_at": 1508265709607,
},
}
}
dialogType={
Object {
"$$typeof": Symbol(react.memo),
"WrappedComponent": [Function],
"compare": null,
"type": [Function],
}
}
modalId="edit_channel_header"
>
<EditIcon />
<Memo(MemoizedFormattedMessage)
defaultMessage="Set a Header"
id="intro_messages.setHeader"
/>
</Memo(Connect(ToggleModalButton))>
</Memo(Connect(ChannelPermissionGate))>
}
usersLimit={10}
/>
</div>
`;
exports[`components/post_view/ChannelIntroMessages test Open Channel should match snapshot, without boards 1`] = `
<div
className="channel-intro "
id="channelIntro"
>
<h2
className="channel-intro__title"
>
<MemoizedFormattedMessage
defaultMessage="Beginning of {name}"
id="intro_messages.beginning"
values={
Object {
"name": "test channel",
}
}
/>
</h2>
<p
className="channel-intro__content"
>
<span>
<MemoizedFormattedMessage
defaultMessage="This is the start of the {name} channel, created by {creator} on {date}."
id="intro_messages.creator"
values={
Object {
"creator": "creatorName",
"date": <FormattedDate
day="2-digit"
month="long"
value={1508265709607}
year="numeric"
/>,
"name": "test channel",
}
}
/>
</span>
<MemoizedFormattedMessage
defaultMessage=" Any member can join and read this channel."
id="intro_messages.anyMember"
/>
<span>
<MemoizedFormattedMessage
defaultMessage=" This channel's purpose is: {purpose}"
id="intro_messages.purpose"
values={
Object {
"purpose": "test",
}
}
/>
</span>
<br />
</p>
<Memo(AddMembersButton)
channel={
Object {
"create_at": 1508265709607,
"creator_id": "creator_id",
"delete_at": 0,
"display_name": "test channel",
"header": "test",
"id": "channel_id",
"last_post_at": 1508265709635,
"name": "testing",
"purpose": "test",
"team_id": "team-id",
"type": "O",
"update_at": 1508265709607,
}
}
pluginButtons={
<Memo(Connect(PluggableIntroButtons))
channel={
Object {
"create_at": 1508265709607,
"creator_id": "creator_id",
"delete_at": 0,
"display_name": "test channel",
"header": "test",
"id": "channel_id",
"last_post_at": 1508265709635,
"name": "testing",
"purpose": "test",
"team_id": "team-id",
"type": "O",
"update_at": 1508265709607,
}
}
/>
}
setHeader={
<Memo(Connect(ChannelPermissionGate))
channelId="channel_id"
permissions={
Array [
"manage_public_channel_properties",
]
}
teamId="team-id"
>
<Memo(Connect(ToggleModalButton))
ariaLabel="Set a Header"
className="intro-links color--link channelIntroButton"
dialogProps={
Object {
"channel": Object {
"create_at": 1508265709607,
"creator_id": "creator_id",
"delete_at": 0,
"display_name": "test channel",
"header": "test",
"id": "channel_id",
"last_post_at": 1508265709635,
"name": "testing",
"purpose": "test",
"team_id": "team-id",
"type": "O",
"update_at": 1508265709607,
},
}
}
dialogType={
Object {
"$$typeof": Symbol(react.memo),
"WrappedComponent": [Function],
"compare": null,
"type": [Function],
}
}
modalId="edit_channel_header"
>
<EditIcon />
<Memo(MemoizedFormattedMessage)
defaultMessage="Set a Header"
id="intro_messages.setHeader"
/>
</Memo(Connect(ToggleModalButton))>
</Memo(Connect(ChannelPermissionGate))>
}
usersLimit={10}
/>
</div>
`;

Просмотреть файл

@@ -2,7 +2,6 @@
// See LICENSE.txt for license information.
import React from 'react';
import {shallow} from 'enzyme';
import {Constants} from 'utils/constants';
import {UserProfile} from '@mattermost/types/users';
@@ -10,6 +9,9 @@ import {UserProfile} from '@mattermost/types/users';
import {Channel, ChannelType} from '@mattermost/types/channels';
import ChannelIntroMessage from './channel_intro_message';
import {screen} from '@testing-library/react';
import {renderWithIntlAndStore} from 'tests/react_testing_utils';
import {TestHelper} from 'utils/test_helper';
describe('components/post_view/ChannelIntroMessages', () => {
const channel = {
@@ -49,12 +51,51 @@ describe('components/post_view/ChannelIntroMessages', () => {
},
};
const initialState = {
entities: {
general: {config: {}},
users: {
profiles: {
user1: TestHelper.getUserMock({
id: 'user1',
username: 'my teammate',
}),
},
},
roles: {
roles: {},
},
channels: {roles: {channel_id: ['system_user']},
currentChannelId: 'channel_id',
myMembers: {},
},
teams: {
teams: {},
},
preferences: {
myPreferences: {},
},
},
plugins: {
components: {},
},
} as any;
describe('test Open Channel', () => {
test('should match snapshot, without boards', () => {
const wrapper = shallow(
<ChannelIntroMessage{...baseProps}/>,
test('should match component state, without boards', () => {
renderWithIntlAndStore(
<ChannelIntroMessage{...baseProps}/>, initialState,
);
expect(wrapper).toMatchSnapshot();
const beginningHeading = screen.getByText('Beginning of test channel');
expect(beginningHeading).toBeInTheDocument();
expect(beginningHeading).toHaveClass('channel-intro__title');
expect(screen.getByText(`This is the start of the test channel channel, created by ${baseProps.creatorName} on October 17, 2017.`));
expect(screen.getByText('Any member can join and read this channel.')).toBeInTheDocument();
});
});
@@ -68,23 +109,51 @@ describe('components/post_view/ChannelIntroMessages', () => {
channel: groupChannel,
};
test('should match snapshot, no profiles', () => {
const wrapper = shallow(
test('should match component state, no profiles', () => {
renderWithIntlAndStore(
<ChannelIntroMessage
{...props}
/>,
/>, initialState,
);
expect(wrapper).toMatchSnapshot();
expect(screen.queryByText('Beginning of test channel')).not.toBeInTheDocument();
expect(screen.queryByText('Any member can join and read this channel.')).not.toBeInTheDocument();
// there are no profiles in the dom, channel type is GM_CHANNEL, teammate text should be displayed
expect(screen.getByText('This is the start of your group message history with these teammates. Messages and files shared here are not shown to people outside this area.')).toBeInTheDocument();
expect(screen.getByText('This is the start of your', {exact: false})).toHaveClass('channel-intro-text');
});
test('should match snapshot, with profiles', () => {
const wrapper = shallow(
test('should match component state, with profiles', () => {
renderWithIntlAndStore(
<ChannelIntroMessage
{...props}
channelProfiles={users}
/>,
/>, initialState,
);
expect(wrapper).toMatchSnapshot();
expect(screen.getByText('This is the start of your group message history with test channel', {exact: false})).toBeInTheDocument();
const headerDialog = screen.getByLabelText('Set a Header dialog');
expect(headerDialog).toBeInTheDocument();
expect(headerDialog).toHaveTextContent('Set a Header');
expect(headerDialog).toHaveClass('style--none intro-links color--link channelIntroButton');
// one for user1 and one for guest
const image = screen.getAllByAltText('user profile image');
expect(image).toHaveLength(2);
expect(image[0]).toHaveAttribute('src', '/api/v4/users/user1/image?_=0');
expect(image[0]).toHaveAttribute('loading', 'lazy');
expect(image[1]).toHaveAttribute('src', '/api/v4/users/guest1/image?_=0');
expect(image[1]).toHaveAttribute('loading', 'lazy');
const editIcon = screen.getByTitle('Edit Icon');
expect(editIcon).toBeInTheDocument();
expect(editIcon).toHaveClass('icon-pencil-outline');
});
});
@@ -98,24 +167,50 @@ describe('components/post_view/ChannelIntroMessages', () => {
channel: directChannel,
};
test('should match snapshot, without teammate', () => {
const wrapper = shallow(
test('should match component state, without teammate', () => {
renderWithIntlAndStore(
<ChannelIntroMessage
{...props}
/>,
/>, initialState,
);
expect(wrapper).toMatchSnapshot();
const message = screen.getByText('This is the start of your direct message history with this teammate', {exact: false});
expect(message).toBeInTheDocument();
expect(message).toHaveClass('channel-intro-text');
});
test('should match snapshot, with teammate', () => {
const wrapper = shallow(
test('should match component state, with teammate', () => {
renderWithIntlAndStore(
<ChannelIntroMessage
{...props}
teammate={user1 as UserProfile}
teammateName='my teammate'
/>,
/>, initialState,
);
expect(wrapper).toMatchSnapshot();
expect(screen.getByText('This is the start of your direct message history with my teammate', {exact: false})).toBeInTheDocument();
const teammate = screen.getByLabelText('my teammate');
expect(teammate).toBeInTheDocument();
expect(teammate).toHaveTextContent('my teammate');
expect(teammate).toHaveClass('user-popover style--none');
const image = screen.getByRole('img');
expect(image).toBeInTheDocument();
expect(image).toHaveAttribute('src', '/api/v4/users/user1/image?_=0');
expect(image).toHaveAttribute('loading', 'lazy');
const headerDialog = screen.getByLabelText('Set a Header dialog');
expect(headerDialog).toBeInTheDocument();
expect(headerDialog).toHaveTextContent('Set a Header');
expect(headerDialog).toHaveClass('style--none intro-links color--link channelIntroButton');
const editIcon = screen.getByTitle('Edit Icon');
expect(editIcon).toBeInTheDocument();
expect(editIcon).toHaveClass('icon-pencil-outline');
});
});
@@ -130,66 +225,67 @@ describe('components/post_view/ChannelIntroMessages', () => {
channel: directChannel,
};
test('should match snapshot, readonly', () => {
const wrapper = shallow(
test('should match component state, readonly', () => {
renderWithIntlAndStore(
<ChannelIntroMessage
{...props}
isReadOnly={true}
/>,
/>, initialState,
);
expect(wrapper).toMatchSnapshot();
const beginningHeading = screen.getByText('Beginning of test channel');
expect(beginningHeading).toBeInTheDocument();
expect(beginningHeading).toHaveClass('channel-intro__title');
expect(screen.getByText('Welcome to test channel!')).toBeInTheDocument();
expect(screen.getByText('Messages can only be posted by system admins. Everyone automatically becomes a permanent member of this channel when they join the team.', {exact: false})).toBeInTheDocument();
});
test('should match snapshot', () => {
const wrapper = shallow(
test('should match component state without any permission', () => {
renderWithIntlAndStore(
<ChannelIntroMessage
{...props}
teamIsGroupConstrained={true}
/>,
/>, initialState,
);
expect(wrapper).toMatchSnapshot();
});
test('should match snapshot, with enableUserCreation', () => {
const wrapper = shallow(
<ChannelIntroMessage
{...props}
enableUserCreation={true}
/>,
);
expect(wrapper).toMatchSnapshot();
});
//no permission is given, invite link should not be in the dom
expect(screen.queryByText('Add other groups to this team')).not.toBeInTheDocument();
test('should match snapshot, with enable, group constrained', () => {
const wrapper = shallow(
<ChannelIntroMessage
{...props}
enableUserCreation={true}
teamIsGroupConstrained={true}
/>,
);
expect(wrapper).toMatchSnapshot();
const beginningHeading = screen.getByText('Beginning of test channel');
expect(beginningHeading).toBeInTheDocument();
expect(beginningHeading).toHaveClass('channel-intro__title');
expect(screen.getByText('Welcome to test channel!')).toBeInTheDocument();
expect(screen.getByText('Post messages here that you want everyone to see. Everyone automatically becomes a permanent member of this channel when they join the team.', {exact: false})).toBeInTheDocument();
});
});
describe('test OFFTOPIC Channel', () => {
describe('test OFF TOPIC Channel', () => {
const directChannel = {
...channel,
type: Constants.OPEN_CHANNEL as ChannelType,
name: Constants.OFFTOPIC_CHANNEL,
display_name: Constants.OFFTOPIC_CHANNEL,
};
const props = {
...baseProps,
channel: directChannel,
};
test('should match snapshot', () => {
const wrapper = shallow(
test('should match component state', () => {
renderWithIntlAndStore(
<ChannelIntroMessage
{...props}
/>,
/>, initialState,
);
expect(wrapper).toMatchSnapshot();
expect(screen.getByText('Beginning of off-topic')).toBeInTheDocument();
screen.getByText('This is the start of off-topic, a channel for non-work-related conversations.');
expect(screen.getByText('This is the start of off-topic, a channel for non-work-related conversations.')).toHaveClass('channel-intro__content');
// stats.total_users_count is not specified, loading icon should be in the dom
screen.getByTitle('Loading Icon');
});
});
});

Просмотреть файл

@@ -10,42 +10,44 @@ describe('components/widgets/loadingLoadingSpinner', () => {
test('showing spinner with text', () => {
const wrapper = shallow(<LoadingSpinner text='test'/>);
expect(wrapper).toMatchInlineSnapshot(`
<span
className="LoadingSpinner with-text"
id="loadingSpinner"
>
<LocalizedIcon
className="fa fa-spinner fa-fw fa-pulse spinner"
component="span"
title={
Object {
"defaultMessage": "Loading Icon",
"id": "generic_icons.loading",
}
}
/>
test
</span>
`);
<span
className="LoadingSpinner with-text"
data-testid="loadingSpinner"
id="loadingSpinner"
>
<LocalizedIcon
className="fa fa-spinner fa-fw fa-pulse spinner"
component="span"
title={
Object {
"defaultMessage": "Loading Icon",
"id": "generic_icons.loading",
}
}
/>
test
</span>
`);
});
test('showing spinner without text', () => {
const wrapper = shallow(<LoadingSpinner/>);
expect(wrapper).toMatchInlineSnapshot(`
<span
className="LoadingSpinner"
id="loadingSpinner"
>
<LocalizedIcon
className="fa fa-spinner fa-fw fa-pulse spinner"
component="span"
title={
Object {
"defaultMessage": "Loading Icon",
"id": "generic_icons.loading",
}
}
/>
</span>
`);
<span
className="LoadingSpinner"
data-testid="loadingSpinner"
id="loadingSpinner"
>
<LocalizedIcon
className="fa fa-spinner fa-fw fa-pulse spinner"
component="span"
title={
Object {
"defaultMessage": "Loading Icon",
"id": "generic_icons.loading",
}
}
/>
</span>
`);
});
});

Просмотреть файл

@@ -23,6 +23,7 @@ export default class LoadingSpinner extends React.PureComponent<Props> {
id='loadingSpinner'
className={'LoadingSpinner' + (this.props.text ? ' with-text' : '')}
style={this.props.style}
data-testid='loadingSpinner'
>
<LocalizedIcon
className='fa fa-spinner fa-fw fa-pulse spinner'