From 96b537167c72aeb212b6a347b0f84d3e0a4e834e Mon Sep 17 00:00:00 2001
From: Ashish Dhama <16203333+AshishDhama@users.noreply.github.com>
Date: Thu, 4 May 2023 11:55:01 +0530
Subject: [PATCH] [WebApp][MM-52125]: Migrate multiple enzyme unit test to
testing library (#23245)
* Migrate multiple enzyme unit test to testing library
---
.../feature_discovery.test.tsx.snap | 137 ---
.../feature_discovery.test.tsx | 252 +++--
.../components/post_emoji/post_emoji.test.tsx | 19 +-
.../__snapshots__/post_markdown.test.tsx.snap | 301 ------
.../post_markdown/post_markdown.test.tsx | 131 ++-
.../post_profile_picture.test.tsx.snap | 43 -
.../post_profile_picture.test.tsx | 24 +-
.../channel_intro_message.test.tsx.snap | 941 ------------------
.../channel_intro_message.test.tsx | 202 +++-
.../widgets/loading/loading_spinner.test.tsx | 68 +-
.../widgets/loading/loading_spinner.tsx | 1 +
11 files changed, 489 insertions(+), 1630 deletions(-)
delete mode 100644 webapp/channels/src/components/admin_console/feature_discovery/__snapshots__/feature_discovery.test.tsx.snap
delete mode 100644 webapp/channels/src/components/post_markdown/__snapshots__/post_markdown.test.tsx.snap
delete mode 100644 webapp/channels/src/components/post_profile_picture/__snapshots__/post_profile_picture.test.tsx.snap
delete mode 100644 webapp/channels/src/components/post_view/channel_intro_message/__snapshots__/channel_intro_message.test.tsx.snap
diff --git a/webapp/channels/src/components/admin_console/feature_discovery/__snapshots__/feature_discovery.test.tsx.snap b/webapp/channels/src/components/admin_console/feature_discovery/__snapshots__/feature_discovery.test.tsx.snap
deleted file mode 100644
index 024bb3b9e5..0000000000
--- a/webapp/channels/src/components/admin_console/feature_discovery/__snapshots__/feature_discovery.test.tsx.snap
+++ /dev/null
@@ -1,137 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`components/feature_discovery FeatureDiscovery should match snapshot 1`] = `
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-`;
-
-exports[`components/feature_discovery FeatureDiscovery should match snapshot when is cloud environment 1`] = `
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-`;
-
-exports[`components/feature_discovery FeatureDiscovery should match snapshot when is cloud environment and subscription is not loaded yet in redux store 1`] = `
-
-`;
diff --git a/webapp/channels/src/components/admin_console/feature_discovery/feature_discovery.test.tsx b/webapp/channels/src/components/admin_console/feature_discovery/feature_discovery.test.tsx
index b59e778bd6..e0cd671bb3 100644
--- a/webapp/channels/src/components/admin_console/feature_discovery/feature_discovery.test.tsx
+++ b/webapp/channels/src/components/admin_console/feature_discovery/feature_discovery.test.tsx
@@ -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(
- }
- // 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(
+
+ }
+ // 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,
+ }}
+ />
+ ,
);
- 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(
- }
- // 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(
+
+ }
+ // 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,
+ }}
+ />
+ ,
+ );
+ });
+
+ // 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(
- }
- // 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(
+
+ }
+ // 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,
+ }}
+ />
+ ,
);
- 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();
});
});
});
diff --git a/webapp/channels/src/components/post_emoji/post_emoji.test.tsx b/webapp/channels/src/components/post_emoji/post_emoji.test.tsx
index 5937766d6f..cb4028d693 100644
--- a/webapp/channels/src/components/post_emoji/post_emoji.test.tsx
+++ b/webapp/channels/src/components/post_emoji/post_emoji.test.tsx
@@ -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();
+ render();
- 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();
+ render();
- 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();
+ render();
- 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();
});
});
diff --git a/webapp/channels/src/components/post_markdown/__snapshots__/post_markdown.test.tsx.snap b/webapp/channels/src/components/post_markdown/__snapshots__/post_markdown.test.tsx.snap
deleted file mode 100644
index d6ee7dfd6a..0000000000
--- a/webapp/channels/src/components/post_markdown/__snapshots__/post_markdown.test.tsx.snap
+++ /dev/null
@@ -1,301 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`components/PostMarkdown plugin hooks can build upon other hook message updates 1`] = `
-
-`;
-
-exports[`components/PostMarkdown plugin hooks can overwrite other hooks messages 1`] = `
-
-`;
-
-exports[`components/PostMarkdown should correctly pass postId down 1`] = `
-
-`;
-
-exports[`components/PostMarkdown should render header change properly 1`] = `
-
- ,
- "old": ,
- "strong": [Function],
- "username": ,
- }
- }
- />
-
-`;
-
-exports[`components/PostMarkdown should render properly with a post 1`] = `
-
-`;
-
-exports[`components/PostMarkdown should render properly with an empty post 1`] = `
-
-`;
-
-exports[`components/PostMarkdown should render properly without group highlight on a post 1`] = `
-
-`;
-
-exports[`components/PostMarkdown should render properly without highlight a post 1`] = `
-
-`;
diff --git a/webapp/channels/src/components/post_markdown/post_markdown.test.tsx b/webapp/channels/src/components/post_markdown/post_markdown.test.tsx
index bb30478615..1f938cb71a 100644
--- a/webapp/channels/src/components/post_markdown/post_markdown.test.tsx
+++ b/webapp/channels/src/components/post_markdown/post_markdown.test.tsx
@@ -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();
+ Reflect.deleteProperty(props, 'post');
+ renderWithIntlAndStore(, state);
+
+ expect(screen.getByText('message')).toBeInTheDocument();
});
test('should render properly with an empty post', () => {
- const wrapper = shallow();
- expect(wrapper).toMatchSnapshot();
+ renderWithIntlAndStore(
+ , 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();
- expect(wrapper).toMatchSnapshot();
+ renderWithIntlAndStore(, 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();
- expect(wrapper).toMatchSnapshot();
+ renderWithIntlAndStore(, 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();
- expect(wrapper).toMatchSnapshot();
+ renderWithIntlAndStore(, 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();
- expect(wrapper.find(Markdown).prop('postId')).toEqual(props.post.id);
- expect(wrapper).toMatchSnapshot();
+ renderWithIntlAndStore(, 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();
- expect(wrapper).toMatchSnapshot();
+
+ renderWithIntlAndStore(, 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();
- expect(wrapper).toMatchSnapshot();
+ renderWithIntlAndStore(, 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();
- expect(wrapper).toMatchSnapshot();
+ renderWithIntlAndStore(, state);
+ expect(screen.queryByText('world', {exact: true})).not.toBeInTheDocument();
+ expect(screen.queryByText('world!', {exact: true})).toBeInTheDocument();
});
});
diff --git a/webapp/channels/src/components/post_profile_picture/__snapshots__/post_profile_picture.test.tsx.snap b/webapp/channels/src/components/post_profile_picture/__snapshots__/post_profile_picture.test.tsx.snap
deleted file mode 100644
index 0b772c4681..0000000000
--- a/webapp/channels/src/components/post_profile_picture/__snapshots__/post_profile_picture.test.tsx.snap
+++ /dev/null
@@ -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`] = `
-
-`;
-
-exports[`components/PostProfilePicture should match snapshot, status and post icon override specified, default props 1`] = `
-
-`;
diff --git a/webapp/channels/src/components/post_profile_picture/post_profile_picture.test.tsx b/webapp/channels/src/components/post_profile_picture/post_profile_picture.test.tsx
index f967770aee..9101717254 100644
--- a/webapp/channels/src/components/post_profile_picture/post_profile_picture.test.tsx
+++ b/webapp/channels/src/components/post_profile_picture/post_profile_picture.test.tsx
@@ -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;
@@ -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(
,
);
- 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(
,
);
- 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);
});
});
diff --git a/webapp/channels/src/components/post_view/channel_intro_message/__snapshots__/channel_intro_message.test.tsx.snap b/webapp/channels/src/components/post_view/channel_intro_message/__snapshots__/channel_intro_message.test.tsx.snap
deleted file mode 100644
index 0b3326fc1b..0000000000
--- a/webapp/channels/src/components/post_view/channel_intro_message/__snapshots__/channel_intro_message.test.tsx.snap
+++ /dev/null
@@ -1,941 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`components/post_view/ChannelIntroMessages test DEFAULT Channel should match snapshot 1`] = `
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-`;
-
-exports[`components/post_view/ChannelIntroMessages test DEFAULT Channel should match snapshot, readonly 1`] = `
-
-`;
-
-exports[`components/post_view/ChannelIntroMessages test DEFAULT Channel should match snapshot, with enable, group constrained 1`] = `
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-`;
-
-exports[`components/post_view/ChannelIntroMessages test DEFAULT Channel should match snapshot, with enableUserCreation 1`] = `
-
-
-
-
-
-
-
-
-
-
- }
- setHeader={
-
-
-
-
-
-
- }
- usersLimit={10}
- />
-
-
-
-
-`;
-
-exports[`components/post_view/ChannelIntroMessages test DIRECT Channel should match snapshot, with teammate 1`] = `
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-`;
-
-exports[`components/post_view/ChannelIntroMessages test DIRECT Channel should match snapshot, without teammate 1`] = `
-
-`;
-
-exports[`components/post_view/ChannelIntroMessages test Group Channel should match snapshot, no profiles 1`] = `
-
-`;
-
-exports[`components/post_view/ChannelIntroMessages test Group Channel should match snapshot, with profiles 1`] = `
-
-`;
-
-exports[`components/post_view/ChannelIntroMessages test OFFTOPIC Channel should match snapshot 1`] = `
-
-
-
-
-
-
-
-
- }
- setHeader={
-
-
-
-
-
-
- }
- usersLimit={10}
- />
-
-`;
-
-exports[`components/post_view/ChannelIntroMessages test Open Channel should match snapshot, without boards 1`] = `
-
-
-
-
-
-
- ,
- "name": "test channel",
- }
- }
- />
-
-
-
-
-
-
-
-
- }
- setHeader={
-
-
-
-
-
-
- }
- usersLimit={10}
- />
-
-`;
diff --git a/webapp/channels/src/components/post_view/channel_intro_message/channel_intro_message.test.tsx b/webapp/channels/src/components/post_view/channel_intro_message/channel_intro_message.test.tsx
index c961fe10ee..23778fc4d1 100644
--- a/webapp/channels/src/components/post_view/channel_intro_message/channel_intro_message.test.tsx
+++ b/webapp/channels/src/components/post_view/channel_intro_message/channel_intro_message.test.tsx
@@ -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(
- ,
+ test('should match component state, without boards', () => {
+ renderWithIntlAndStore(
+ , 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(
,
+ />, 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(
,
+ />, 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(
,
+ />, 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(
,
+ />, 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(
,
+ />, 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(
,
+ />, initialState,
);
- expect(wrapper).toMatchSnapshot();
- });
- test('should match snapshot, with enableUserCreation', () => {
- const wrapper = shallow(
- ,
- );
- 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(
- ,
- );
- 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(
,
+ />, 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');
});
});
});
diff --git a/webapp/channels/src/components/widgets/loading/loading_spinner.test.tsx b/webapp/channels/src/components/widgets/loading/loading_spinner.test.tsx
index 3fe761cd5c..e0f6213a2b 100644
--- a/webapp/channels/src/components/widgets/loading/loading_spinner.test.tsx
+++ b/webapp/channels/src/components/widgets/loading/loading_spinner.test.tsx
@@ -10,42 +10,44 @@ describe('components/widgets/loadingLoadingSpinner', () => {
test('showing spinner with text', () => {
const wrapper = shallow();
expect(wrapper).toMatchInlineSnapshot(`
-
-
- test
-
-`);
+
+
+ test
+
+ `);
});
test('showing spinner without text', () => {
const wrapper = shallow();
expect(wrapper).toMatchInlineSnapshot(`
-
-
-
-`);
+
+
+
+ `);
});
});
diff --git a/webapp/channels/src/components/widgets/loading/loading_spinner.tsx b/webapp/channels/src/components/widgets/loading/loading_spinner.tsx
index 8280fb7dda..f9089f8fa4 100644
--- a/webapp/channels/src/components/widgets/loading/loading_spinner.tsx
+++ b/webapp/channels/src/components/widgets/loading/loading_spinner.tsx
@@ -23,6 +23,7 @@ export default class LoadingSpinner extends React.PureComponent {
id='loadingSpinner'
className={'LoadingSpinner' + (this.props.text ? ' with-text' : '')}
style={this.props.style}
+ data-testid='loadingSpinner'
>