Run component tests with a real store and use renderWithContext everywhere (#25217)
* Change renderWithFullContext to not mock Redux store * Remove renderWithIntl and renderWithIntlAndStore * Rename renderWithFullContext to renderWithContext * Use renderWithContext for WS context
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
ab349946db
Коммит
be34a5d2df
@@ -7,7 +7,7 @@ import type {ClientConfig, ClientLicense} from '@mattermost/types/config';
|
||||
|
||||
import AboutBuildModal from 'components/about_build_modal/about_build_modal';
|
||||
|
||||
import {renderWithFullContext, screen, userEvent} from 'tests/react_testing_utils';
|
||||
import {renderWithContext, screen, userEvent} from 'tests/react_testing_utils';
|
||||
import {AboutLinks} from 'utils/constants';
|
||||
|
||||
import AboutBuildModalCloud from './about_build_modal_cloud/about_build_modal_cloud';
|
||||
@@ -94,7 +94,7 @@ describe('components/AboutBuildModal', () => {
|
||||
license.Cloud = 'true';
|
||||
}
|
||||
|
||||
renderWithFullContext(
|
||||
renderWithContext(
|
||||
<AboutBuildModalCloud
|
||||
config={config}
|
||||
license={license}
|
||||
@@ -154,7 +154,7 @@ describe('components/AboutBuildModal', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderWithFullContext(
|
||||
renderWithContext(
|
||||
<AboutBuildModal
|
||||
config={config}
|
||||
license={license}
|
||||
@@ -181,7 +181,7 @@ describe('components/AboutBuildModal', () => {
|
||||
},
|
||||
},
|
||||
};
|
||||
renderWithFullContext(
|
||||
renderWithContext(
|
||||
<AboutBuildModal
|
||||
config={config}
|
||||
license={license}
|
||||
@@ -210,6 +210,6 @@ describe('components/AboutBuildModal', () => {
|
||||
...props,
|
||||
};
|
||||
|
||||
return renderWithFullContext(<AboutBuildModal {...allProps}/>);
|
||||
return renderWithContext(<AboutBuildModal {...allProps}/>);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import {renderWithFullContext, screen} from 'tests/react_testing_utils';
|
||||
import {renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
|
||||
import {MenuItemBlockableLinkImpl} from './menu_item_blockable_link';
|
||||
|
||||
describe('components/MenuItemBlockableLink', () => {
|
||||
test('should render my link', () => {
|
||||
renderWithFullContext(
|
||||
renderWithContext(
|
||||
<MenuItemBlockableLinkImpl
|
||||
to='/wherever'
|
||||
text='Whatever'
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import {renderWithIntl, screen} from 'tests/react_testing_utils';
|
||||
import {renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
import {TestHelper} from 'utils/test_helper';
|
||||
|
||||
import AdminUserCard from './admin_user_card';
|
||||
@@ -22,7 +22,7 @@ describe('components/admin_console/admin_user_card/admin_user_card', () => {
|
||||
|
||||
test('should match default snapshot', () => {
|
||||
const props = defaultProps;
|
||||
const {container} = renderWithIntl(<AdminUserCard {...props}/>);
|
||||
const {container} = renderWithContext(<AdminUserCard {...props}/>);
|
||||
screen.getByText(props.user.first_name, {exact: false});
|
||||
screen.getByText(props.user.last_name, {exact: false});
|
||||
screen.getByText(props.user.nickname, {exact: false});
|
||||
@@ -38,7 +38,7 @@ describe('components/admin_console/admin_user_card/admin_user_card', () => {
|
||||
nickname: null,
|
||||
},
|
||||
};
|
||||
const {container} = renderWithIntl(<AdminUserCard {...props}/>);
|
||||
const {container} = renderWithContext(<AdminUserCard {...props}/>);
|
||||
screen.getByText(props.user.first_name, {exact: false});
|
||||
screen.getByText(props.user.last_name, {exact: false});
|
||||
expect(screen.queryByText(defaultProps.user.nickname)).not.toBeInTheDocument();
|
||||
@@ -55,7 +55,7 @@ describe('components/admin_console/admin_user_card/admin_user_card', () => {
|
||||
last_name: null,
|
||||
},
|
||||
};
|
||||
const {container} = renderWithIntl(<AdminUserCard {...props}/>);
|
||||
const {container} = renderWithContext(<AdminUserCard {...props}/>);
|
||||
expect(screen.queryByText(defaultProps.user.first_name)).not.toBeInTheDocument();
|
||||
expect(screen.queryByText(defaultProps.user.last_name)).not.toBeInTheDocument();
|
||||
screen.getByText(props.user.nickname, {exact: false});
|
||||
@@ -73,7 +73,7 @@ describe('components/admin_console/admin_user_card/admin_user_card', () => {
|
||||
nickname: null,
|
||||
},
|
||||
};
|
||||
const {container} = renderWithIntl(<AdminUserCard {...props}/>);
|
||||
const {container} = renderWithContext(<AdminUserCard {...props}/>);
|
||||
expect(screen.queryByText(defaultProps.user.first_name)).not.toBeInTheDocument();
|
||||
expect(screen.queryByText(defaultProps.user.last_name)).not.toBeInTheDocument();
|
||||
expect(screen.queryByText(defaultProps.user.nickname)).not.toBeInTheDocument();
|
||||
|
||||
@@ -2,17 +2,16 @@
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import {Provider} from 'react-redux';
|
||||
|
||||
import {renderWithIntl, renderWithIntlAndStore, screen} from 'tests/react_testing_utils';
|
||||
import mockStore from 'tests/test_store';
|
||||
import {renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
import {CloudLinks, HostedCustomerLinks} from 'utils/constants';
|
||||
import {TestHelper} from 'utils/test_helper';
|
||||
|
||||
import BillingHistory, {NoBillingHistorySection} from './billing_history';
|
||||
|
||||
const NO_INVOICES_LEGEND = 'All of your invoices will be shown here';
|
||||
|
||||
const invoiceA = {
|
||||
const invoiceA = TestHelper.getInvoiceMock({
|
||||
id: 'in_1KNb3DI67GP2qpb4ueaJYBt8',
|
||||
number: '87030375-0015',
|
||||
create_at: 1643540071000,
|
||||
@@ -35,8 +34,8 @@ const invoiceA = {
|
||||
metadata: {},
|
||||
},
|
||||
],
|
||||
};
|
||||
const invoiceB = {
|
||||
});
|
||||
const invoiceB = TestHelper.getInvoiceMock({
|
||||
id: 'in_1KIWNTI67GP2qpb4KjGj1KAy',
|
||||
number: '87030375-0013',
|
||||
create_at: 1642330467000,
|
||||
@@ -59,7 +58,7 @@ const invoiceB = {
|
||||
metadata: {},
|
||||
},
|
||||
],
|
||||
};
|
||||
});
|
||||
|
||||
describe('components/admin_console/billing/billing_history', () => {
|
||||
// required state to mount using the provider
|
||||
@@ -91,13 +90,10 @@ describe('components/admin_console/billing/billing_history', () => {
|
||||
views: {},
|
||||
};
|
||||
|
||||
const store = mockStore(state);
|
||||
|
||||
test('should match the default state of the component with given props', () => {
|
||||
renderWithIntl(
|
||||
<Provider store={store}>
|
||||
<BillingHistory/>
|
||||
</Provider>,
|
||||
renderWithContext(
|
||||
<BillingHistory/>,
|
||||
state,
|
||||
);
|
||||
|
||||
expect(screen.queryByText('Billing History')).toBeInTheDocument();
|
||||
@@ -115,11 +111,9 @@ describe('components/admin_console/billing/billing_history', () => {
|
||||
...state,
|
||||
entities: {...state.entities, cloud: {invoices: {}, errors: {}}},
|
||||
};
|
||||
const storeNoBillingHistory = mockStore(noBillingHistoryState);
|
||||
renderWithIntl(
|
||||
<Provider store={storeNoBillingHistory}>
|
||||
<BillingHistory/>
|
||||
</Provider>,
|
||||
renderWithContext(
|
||||
<BillingHistory/>,
|
||||
noBillingHistoryState,
|
||||
);
|
||||
|
||||
expect(screen.queryByText('Date')).not.toBeInTheDocument();
|
||||
@@ -139,10 +133,9 @@ describe('components/admin_console/billing/billing_history', () => {
|
||||
});
|
||||
|
||||
test('Billing history section shows two invoices to download', () => {
|
||||
renderWithIntl(
|
||||
<Provider store={store}>
|
||||
<BillingHistory/>
|
||||
</Provider>,
|
||||
renderWithContext(
|
||||
<BillingHistory/>,
|
||||
state,
|
||||
);
|
||||
|
||||
expect(screen.queryByText('Date')).toBeInTheDocument();
|
||||
@@ -154,10 +147,9 @@ describe('components/admin_console/billing/billing_history', () => {
|
||||
});
|
||||
|
||||
test('Billing history section download button has the target property set as _self so it works well in desktop app', () => {
|
||||
renderWithIntl(
|
||||
<Provider store={store}>
|
||||
<BillingHistory/>
|
||||
</Provider>,
|
||||
renderWithContext(
|
||||
<BillingHistory/>,
|
||||
state,
|
||||
);
|
||||
|
||||
expect(screen.getByTestId(`billingHistoryLink-${invoiceA.id}`)).toHaveAttribute('target', '_self');
|
||||
@@ -205,11 +197,9 @@ describe('BillingHistory -- self-hosted', () => {
|
||||
...state,
|
||||
entities: {...state.entities, hostedCustomer: {invoices: {invoices: {}, invoicesLoaded: true}, errors: {}}},
|
||||
};
|
||||
const storeNoBillingHistory = mockStore(noBillingHistoryState);
|
||||
renderWithIntl(
|
||||
<Provider store={storeNoBillingHistory}>
|
||||
<BillingHistory/>
|
||||
</Provider>,
|
||||
renderWithContext(
|
||||
<BillingHistory/>,
|
||||
noBillingHistoryState,
|
||||
);
|
||||
|
||||
expect(screen.queryByText('Date')).not.toBeInTheDocument();
|
||||
@@ -229,12 +219,9 @@ describe('BillingHistory -- self-hosted', () => {
|
||||
});
|
||||
|
||||
test('Billing history section shows two invoices to download', () => {
|
||||
const store = mockStore(state);
|
||||
|
||||
renderWithIntl(
|
||||
<Provider store={store}>
|
||||
<BillingHistory/>
|
||||
</Provider>,
|
||||
renderWithContext(
|
||||
<BillingHistory/>,
|
||||
state,
|
||||
);
|
||||
|
||||
expect(screen.queryByText('Date')).toBeInTheDocument();
|
||||
@@ -248,12 +235,18 @@ describe('BillingHistory -- self-hosted', () => {
|
||||
describe('NoBillingHistorySection', () => {
|
||||
const state = {entities: {users: {}, general: {config: {}, license: {}}}} as any;
|
||||
test('goes to cloud docs on cloud', () => {
|
||||
renderWithIntlAndStore(<NoBillingHistorySection selfHosted={false}/>, state);
|
||||
renderWithContext(
|
||||
<NoBillingHistorySection selfHosted={false}/>,
|
||||
state,
|
||||
);
|
||||
expect((screen.getByRole('link') as HTMLAnchorElement).href).toContain(CloudLinks.BILLING_DOCS);
|
||||
});
|
||||
|
||||
test('goes to self-hosted docs on self-hosted', () => {
|
||||
renderWithIntlAndStore(<NoBillingHistorySection selfHosted={true}/>, state);
|
||||
renderWithContext(
|
||||
<NoBillingHistorySection selfHosted={true}/>,
|
||||
state,
|
||||
);
|
||||
expect((screen.getByRole('link') as HTMLAnchorElement).href).toContain(HostedCustomerLinks.SELF_HOSTED_BILLING);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -15,7 +15,7 @@ import * as useOpenPricingModal from 'components/common/hooks/useOpenPricingModa
|
||||
import * as useOpenSalesLink from 'components/common/hooks/useOpenSalesLink';
|
||||
import * as useSaveBool from 'components/common/hooks/useSavePreferences';
|
||||
|
||||
import {fireEvent, renderWithFullContext, screen} from 'tests/react_testing_utils';
|
||||
import {fireEvent, renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
import {CloudProducts} from 'utils/constants';
|
||||
|
||||
import LimitReachedBanner from './limit_reached_banner';
|
||||
@@ -119,7 +119,7 @@ describe('limits_reached_banner', () => {
|
||||
const spies = makeSpies();
|
||||
spies.useGetUsageDeltas.mockReturnValue(someLimitReached);
|
||||
|
||||
renderWithFullContext(<LimitReachedBanner product={enterprise}/>, state);
|
||||
renderWithContext(<LimitReachedBanner product={enterprise}/>, state);
|
||||
|
||||
expect(screen.queryByText(titleFree)).not.toBeInTheDocument();
|
||||
expect(screen.queryByText(titleProfessional)).not.toBeInTheDocument();
|
||||
@@ -143,7 +143,7 @@ describe('limits_reached_banner', () => {
|
||||
const spies = makeSpies();
|
||||
spies.useGetUsageDeltas.mockReturnValue(someLimitReached);
|
||||
|
||||
renderWithFullContext(<LimitReachedBanner product={enterprise}/>, myState);
|
||||
renderWithContext(<LimitReachedBanner product={enterprise}/>, myState);
|
||||
|
||||
expect(screen.queryByText(titleFree)).not.toBeInTheDocument();
|
||||
expect(screen.queryByText(titleProfessional)).not.toBeInTheDocument();
|
||||
@@ -153,7 +153,7 @@ describe('limits_reached_banner', () => {
|
||||
const spies = makeSpies();
|
||||
spies.useGetUsageDeltas.mockReturnValue(noLimitReached);
|
||||
|
||||
renderWithFullContext(<LimitReachedBanner product={free}/>, state);
|
||||
renderWithContext(<LimitReachedBanner product={free}/>, state);
|
||||
|
||||
expect(screen.queryByText(titleFree)).not.toBeInTheDocument();
|
||||
expect(screen.queryByText(titleProfessional)).not.toBeInTheDocument();
|
||||
@@ -165,7 +165,7 @@ describe('limits_reached_banner', () => {
|
||||
spies.useOpenPricingModal.mockReturnValue(mockOpenPricingModal);
|
||||
spies.useGetUsageDeltas.mockReturnValue(someLimitReached);
|
||||
|
||||
renderWithFullContext(<LimitReachedBanner product={free}/>, state);
|
||||
renderWithContext(<LimitReachedBanner product={free}/>, state);
|
||||
|
||||
screen.getByText(titleFree);
|
||||
expect(screen.queryByText(titleProfessional)).not.toBeInTheDocument();
|
||||
@@ -181,7 +181,7 @@ describe('limits_reached_banner', () => {
|
||||
spies.useOpenSalesLink.mockReturnValue([mockOpenSalesLink, '']);
|
||||
spies.useGetUsageDeltas.mockReturnValue(someLimitReached);
|
||||
|
||||
renderWithFullContext(<LimitReachedBanner product={free}/>, state);
|
||||
renderWithContext(<LimitReachedBanner product={free}/>, state);
|
||||
|
||||
screen.getByText(titleFree);
|
||||
expect(screen.queryByText(titleProfessional)).not.toBeInTheDocument();
|
||||
|
||||
@@ -3,16 +3,15 @@
|
||||
|
||||
import React from 'react';
|
||||
import * as redux from 'react-redux';
|
||||
import {Provider} from 'react-redux';
|
||||
|
||||
import type {Subscription, Product} from '@mattermost/types/cloud';
|
||||
import type {GlobalState} from '@mattermost/types/store';
|
||||
import type {UserProfile, UsersState} from '@mattermost/types/users';
|
||||
import type {DeepPartial} from '@mattermost/types/utilities';
|
||||
|
||||
import * as cloudActions from 'actions/cloud';
|
||||
|
||||
import {renderWithIntl, screen} from 'tests/react_testing_utils';
|
||||
import mockStore from 'tests/test_store';
|
||||
import {renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
import {Constants, CloudProducts} from 'utils/constants';
|
||||
import {FileSizes} from 'utils/file_utils';
|
||||
|
||||
@@ -37,7 +36,7 @@ const freeLimits = {
|
||||
interface SetupOptions {
|
||||
isEnterprise?: boolean;
|
||||
}
|
||||
function setupStore(setupOptions: SetupOptions) {
|
||||
function setupState(setupOptions: SetupOptions): DeepPartial<GlobalState> {
|
||||
const state = {
|
||||
entities: {
|
||||
cloud: {
|
||||
@@ -92,29 +91,28 @@ function setupStore(setupOptions: SetupOptions) {
|
||||
config: {},
|
||||
},
|
||||
},
|
||||
} as GlobalState;
|
||||
};
|
||||
if (setupOptions.isEnterprise) {
|
||||
state.entities.cloud.subscription!.is_free_trial = 'true';
|
||||
}
|
||||
const store = mockStore(state);
|
||||
|
||||
return store;
|
||||
return state;
|
||||
}
|
||||
|
||||
describe('Limits', () => {
|
||||
const defaultOptions = {};
|
||||
test('message limit rendered in K', () => {
|
||||
const store = setupStore(defaultOptions);
|
||||
const state = setupState(defaultOptions);
|
||||
|
||||
renderWithIntl(<Provider store={store}><Limits/></Provider>);
|
||||
renderWithContext(<Limits/>, state);
|
||||
screen.getByText('Message History');
|
||||
screen.getByText(/of 10K/);
|
||||
});
|
||||
|
||||
test('storage limit rendered in GB', () => {
|
||||
const store = setupStore(defaultOptions);
|
||||
const state = setupState(defaultOptions);
|
||||
|
||||
renderWithIntl(<Provider store={store}><Limits/></Provider>);
|
||||
renderWithContext(<Limits/>, state);
|
||||
screen.getByText('File Storage');
|
||||
screen.getByText(/of 1GB/);
|
||||
});
|
||||
@@ -123,9 +121,9 @@ describe('Limits', () => {
|
||||
const mockGetLimits = jest.fn();
|
||||
jest.spyOn(cloudActions, 'getCloudLimits').mockImplementation(mockGetLimits);
|
||||
jest.spyOn(redux, 'useDispatch').mockImplementation(jest.fn(() => jest.fn()));
|
||||
const store = setupStore({isEnterprise: true});
|
||||
const state = setupState({isEnterprise: true});
|
||||
|
||||
renderWithIntl(<Provider store={store}><Limits/></Provider>);
|
||||
renderWithContext(<Limits/>, state);
|
||||
expect(screen.queryByTestId('limits-panel-title')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -133,9 +131,9 @@ describe('Limits', () => {
|
||||
const mockGetLimits = jest.fn();
|
||||
jest.spyOn(cloudActions, 'getCloudLimits').mockImplementation(mockGetLimits);
|
||||
jest.spyOn(redux, 'useDispatch').mockImplementation(jest.fn(() => jest.fn()));
|
||||
const store = setupStore(defaultOptions);
|
||||
const state = setupState(defaultOptions);
|
||||
|
||||
renderWithIntl(<Provider store={store}><Limits/></Provider>);
|
||||
renderWithContext(<Limits/>, state);
|
||||
screen.getByTestId('limits-panel-title');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import {renderWithIntlAndStore, screen} from 'tests/react_testing_utils';
|
||||
import {renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
import {CloudProducts} from 'utils/constants';
|
||||
|
||||
import {ToPaidNudgeBanner, ToPaidPlanBannerDismissable} from './to_paid_plan_nudge_banner';
|
||||
@@ -60,7 +60,7 @@ describe('ToPaidPlanBannerDismissable', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderWithIntlAndStore(<ToPaidPlanBannerDismissable/>, state);
|
||||
renderWithContext(<ToPaidPlanBannerDismissable/>, state, {useMockedStore: true});
|
||||
|
||||
screen.getByTestId('cloud-free-deprecation-announcement-bar');
|
||||
});
|
||||
@@ -84,7 +84,7 @@ describe('ToPaidPlanBannerDismissable', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderWithIntlAndStore(<ToPaidPlanBannerDismissable/>, state);
|
||||
renderWithContext(<ToPaidPlanBannerDismissable/>, state, {useMockedStore: true});
|
||||
|
||||
expect(() => screen.getByTestId('cloud-free-deprecation-announcement-bar')).toThrow();
|
||||
});
|
||||
@@ -108,7 +108,7 @@ describe('ToPaidPlanBannerDismissable', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderWithIntlAndStore(<ToPaidPlanBannerDismissable/>, state);
|
||||
renderWithContext(<ToPaidPlanBannerDismissable/>, state, {useMockedStore: true});
|
||||
|
||||
expect(() => screen.getByTestId('cloud-free-deprecation-announcement-bar')).toThrow();
|
||||
});
|
||||
@@ -132,7 +132,7 @@ describe('ToPaidPlanBannerDismissable', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderWithIntlAndStore(<ToPaidPlanBannerDismissable/>, state);
|
||||
renderWithContext(<ToPaidPlanBannerDismissable/>, state, {useMockedStore: true});
|
||||
|
||||
expect(() => screen.getByTestId('cloud-free-deprecation-announcement-bar')).toThrow();
|
||||
});
|
||||
@@ -166,7 +166,7 @@ describe('ToPaidPlanBannerDismissable', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderWithIntlAndStore(<ToPaidPlanBannerDismissable/>, state);
|
||||
renderWithContext(<ToPaidPlanBannerDismissable/>, state, {useMockedStore: true});
|
||||
|
||||
expect(() => screen.getByTestId('cloud-free-deprecation-announcement-bar')).toThrow();
|
||||
});
|
||||
@@ -189,7 +189,7 @@ describe('ToPaidNudgeBanner', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderWithIntlAndStore(<ToPaidNudgeBanner/>, state);
|
||||
renderWithContext(<ToPaidNudgeBanner/>, state, {useMockedStore: true});
|
||||
|
||||
screen.getByTestId('cloud-free-deprecation-alert-banner');
|
||||
});
|
||||
@@ -210,7 +210,7 @@ describe('ToPaidNudgeBanner', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderWithIntlAndStore(<ToPaidNudgeBanner/>, state);
|
||||
renderWithContext(<ToPaidNudgeBanner/>, state, {useMockedStore: true});
|
||||
|
||||
expect(() => screen.getByTestId('cloud-free-deprecation-alert-banner')).toThrow();
|
||||
});
|
||||
@@ -231,7 +231,7 @@ describe('ToPaidNudgeBanner', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderWithIntlAndStore(<ToPaidNudgeBanner/>, state);
|
||||
renderWithContext(<ToPaidNudgeBanner/>, state, {useMockedStore: true});
|
||||
|
||||
expect(() => screen.getByTestId('cloud-free-deprecation-alert-banner')).toThrow();
|
||||
});
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import {renderWithIntlAndStore, screen} from 'tests/react_testing_utils';
|
||||
import {renderWithContext, screen, waitFor} from 'tests/react_testing_utils';
|
||||
import {CloudProducts, RecurringIntervals} from 'utils/constants';
|
||||
|
||||
import {ToYearlyNudgeBanner, ToYearlyNudgeBannerDismissable} from './to_yearly_nudge_banner';
|
||||
@@ -60,7 +60,7 @@ describe('ToYearlyNudgeBannerDismissable', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderWithIntlAndStore(<ToYearlyNudgeBannerDismissable/>, state);
|
||||
renderWithContext(<ToYearlyNudgeBannerDismissable/>, state, {useMockedStore: true});
|
||||
|
||||
screen.getByTestId('cloud-pro-monthly-deprecation-announcement-bar');
|
||||
});
|
||||
@@ -85,7 +85,7 @@ describe('ToYearlyNudgeBannerDismissable', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderWithIntlAndStore(<ToYearlyNudgeBannerDismissable/>, state);
|
||||
renderWithContext(<ToYearlyNudgeBannerDismissable/>, state, {useMockedStore: true});
|
||||
|
||||
expect(() => screen.getByTestId('cloud-pro-monthly-deprecation-announcement-bar')).toThrow();
|
||||
});
|
||||
@@ -110,7 +110,7 @@ describe('ToYearlyNudgeBannerDismissable', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderWithIntlAndStore(<ToYearlyNudgeBannerDismissable/>, state);
|
||||
renderWithContext(<ToYearlyNudgeBannerDismissable/>, state, {useMockedStore: true});
|
||||
|
||||
expect(() => screen.getByTestId('cloud-pro-monthly-deprecation-announcement-bar')).toThrow();
|
||||
});
|
||||
@@ -135,7 +135,7 @@ describe('ToYearlyNudgeBannerDismissable', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderWithIntlAndStore(<ToYearlyNudgeBannerDismissable/>, state);
|
||||
renderWithContext(<ToYearlyNudgeBannerDismissable/>, state, {useMockedStore: true});
|
||||
|
||||
expect(() => screen.getByTestId('cloud-pro-monthly-deprecation-announcement-bar')).toThrow();
|
||||
});
|
||||
@@ -159,12 +159,12 @@ describe('ToYearlyNudgeBannerDismissable', () => {
|
||||
},
|
||||
},
|
||||
};
|
||||
renderWithIntlAndStore(<ToYearlyNudgeBannerDismissable/>, state);
|
||||
renderWithContext(<ToYearlyNudgeBannerDismissable/>, state, {useMockedStore: true});
|
||||
|
||||
expect(() => screen.getByTestId('cloud-pro-monthly-deprecation-announcement-bar')).toThrow();
|
||||
});
|
||||
|
||||
test('should NOT show for admins when banner was dismissed in preferences', () => {
|
||||
test('should NOT show for admins when banner was dismissed in preferences', async () => {
|
||||
const state = JSON.parse(JSON.stringify(initialState));
|
||||
state.entities.users.profiles = {
|
||||
current_user_id: {roles: 'system_admin'},
|
||||
@@ -192,7 +192,9 @@ describe('ToYearlyNudgeBannerDismissable', () => {
|
||||
},
|
||||
},
|
||||
};
|
||||
renderWithIntlAndStore(<ToYearlyNudgeBannerDismissable/>, state);
|
||||
await waitFor(() => {
|
||||
renderWithContext(<ToYearlyNudgeBannerDismissable/>, state, {useMockedStore: true});
|
||||
});
|
||||
|
||||
expect(() => screen.getByTestId('cloud-pro-monthly-deprecation-announcement-bar')).toThrow();
|
||||
});
|
||||
@@ -218,7 +220,7 @@ describe('ToYearlyNudgeBannerDismissable', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderWithIntlAndStore(<ToYearlyNudgeBannerDismissable/>, state);
|
||||
renderWithContext(<ToYearlyNudgeBannerDismissable/>, state, {useMockedStore: true});
|
||||
|
||||
expect(() => screen.getByTestId('cloud-pro-monthly-deprecation-announcement-bar')).toThrow();
|
||||
});
|
||||
@@ -244,7 +246,7 @@ describe('ToYearlyNudgeBannerDismissable', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderWithIntlAndStore(<ToYearlyNudgeBannerDismissable/>, state);
|
||||
renderWithContext(<ToYearlyNudgeBannerDismissable/>, state, {useMockedStore: true});
|
||||
|
||||
expect(() => screen.getByTestId('cloud-pro-monthly-deprecation-announcement-bar')).toThrow();
|
||||
});
|
||||
@@ -268,7 +270,7 @@ describe('ToYearlyNudgeBanner', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderWithIntlAndStore(<ToYearlyNudgeBanner/>, state);
|
||||
renderWithContext(<ToYearlyNudgeBanner/>, state, {useMockedStore: true});
|
||||
|
||||
screen.getByTestId('cloud-pro-monthly-deprecation-alert-banner');
|
||||
});
|
||||
@@ -290,7 +292,7 @@ describe('ToYearlyNudgeBanner', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderWithIntlAndStore(<ToYearlyNudgeBanner/>, state);
|
||||
renderWithContext(<ToYearlyNudgeBanner/>, state, {useMockedStore: true});
|
||||
|
||||
expect(() => screen.getByTestId('cloud-pro-monthly-deprecation-alert-banner')).toThrow();
|
||||
});
|
||||
@@ -312,7 +314,7 @@ describe('ToYearlyNudgeBanner', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderWithIntlAndStore(<ToYearlyNudgeBanner/>, state);
|
||||
renderWithContext(<ToYearlyNudgeBanner/>, state, {useMockedStore: true});
|
||||
|
||||
expect(() => screen.getByTestId('cloud-pro-monthly-deprecation-alert-banner')).toThrow();
|
||||
});
|
||||
@@ -335,7 +337,7 @@ describe('ToYearlyNudgeBanner', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderWithIntlAndStore(<ToYearlyNudgeBanner/>, state);
|
||||
renderWithContext(<ToYearlyNudgeBanner/>, state, {useMockedStore: true});
|
||||
|
||||
expect(() => screen.getByTestId('cloud-pro-monthly-deprecation-alert-banner')).toThrow();
|
||||
});
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import {renderWithIntl, screen} from 'tests/react_testing_utils';
|
||||
import {renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
|
||||
import ColorSetting from './color_setting';
|
||||
|
||||
@@ -11,7 +11,7 @@ describe('components/ColorSetting', () => {
|
||||
test('should match snapshot, all', () => {
|
||||
function emptyFunction() {} //eslint-disable-line no-empty-function
|
||||
|
||||
const {container} = renderWithIntl(
|
||||
const {container} = renderWithContext(
|
||||
<ColorSetting
|
||||
id='id'
|
||||
label='label'
|
||||
@@ -30,7 +30,7 @@ describe('components/ColorSetting', () => {
|
||||
test('should match snapshot, no help text', () => {
|
||||
function emptyFunction() {} //eslint-disable-line no-empty-function
|
||||
|
||||
const {container} = renderWithIntl(
|
||||
const {container} = renderWithContext(
|
||||
<ColorSetting
|
||||
id='id'
|
||||
label='label'
|
||||
@@ -47,7 +47,7 @@ describe('components/ColorSetting', () => {
|
||||
test('should match snapshot, disabled', () => {
|
||||
function emptyFunction() {} //eslint-disable-line no-empty-function
|
||||
|
||||
const {container} = renderWithIntl(
|
||||
const {container} = renderWithContext(
|
||||
<ColorSetting
|
||||
id='id'
|
||||
label='label'
|
||||
@@ -65,7 +65,7 @@ describe('components/ColorSetting', () => {
|
||||
test('should match snapshot, clicked on color setting', () => {
|
||||
function emptyFunction() {} //eslint-disable-line no-empty-function
|
||||
|
||||
const {container} = renderWithIntl(
|
||||
const {container} = renderWithContext(
|
||||
<ColorSetting
|
||||
id='id'
|
||||
label='label'
|
||||
|
||||
@@ -2,14 +2,11 @@
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import {Provider as ReduxProvider} from 'react-redux';
|
||||
|
||||
import store from 'stores/redux_store';
|
||||
|
||||
import FeatureDiscovery from 'components/admin_console/feature_discovery/feature_discovery';
|
||||
|
||||
import {
|
||||
renderWithIntl,
|
||||
renderWithContext,
|
||||
screen,
|
||||
userEvent,
|
||||
waitFor,
|
||||
@@ -25,33 +22,31 @@ describe('components/feature_discovery', () => {
|
||||
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>,
|
||||
renderWithContext(
|
||||
<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,
|
||||
}}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(screen.queryByText('Bar')).toBeInTheDocument();
|
||||
@@ -76,39 +71,38 @@ describe('components/feature_discovery', () => {
|
||||
expect(getCloudSubscription).not.toHaveBeenCalled();
|
||||
expect(openModal).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
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>,
|
||||
renderWithContext(
|
||||
<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,
|
||||
}}
|
||||
/>,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -144,33 +138,31 @@ describe('components/feature_discovery', () => {
|
||||
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>,
|
||||
renderWithContext(
|
||||
<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,
|
||||
}}
|
||||
/>,
|
||||
);
|
||||
|
||||
// when is cloud and subscription is not loaded yet, then only loading spinner is visible
|
||||
|
||||
@@ -12,8 +12,9 @@ import {General} from 'mattermost-redux/constants';
|
||||
|
||||
import * as useCanSelfHostedExpand from 'components/common/hooks/useCanSelfHostedExpand';
|
||||
|
||||
import mergeObjects from 'packages/mattermost-redux/test/merge_objects';
|
||||
import {mountWithIntl} from 'tests/helpers/intl-test-helper';
|
||||
import {renderWithIntl, screen} from 'tests/react_testing_utils';
|
||||
import {renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
import mockStore from 'tests/test_store';
|
||||
import {OverActiveUserLimits, SelfHostedProducts} from 'utils/constants';
|
||||
import {TestHelper} from 'utils/test_helper';
|
||||
@@ -91,28 +92,25 @@ describe('components/admin_console/license_settings/enterprise_edition/enterpris
|
||||
},
|
||||
};
|
||||
|
||||
const props = {
|
||||
const baseProps: EnterpriseEditionProps = {
|
||||
license,
|
||||
openEELicenseModal: jest.fn(),
|
||||
upgradedFromTE: false,
|
||||
isTrialLicense: false,
|
||||
issued: <></>,
|
||||
startsAt: <></>,
|
||||
expiresAt: <></>,
|
||||
handleRemove: jest.fn(),
|
||||
isDisabled: false,
|
||||
removing: false,
|
||||
handleChange: jest.fn(),
|
||||
fileInputRef: React.createRef(),
|
||||
statsActiveUsers: 1,
|
||||
} as EnterpriseEditionProps;
|
||||
};
|
||||
|
||||
test('should format the Users field', async () => {
|
||||
const store = await mockStore(initialState);
|
||||
test('should format the Users field', () => {
|
||||
const store = mockStore(initialState);
|
||||
const wrapper = mountWithIntl(
|
||||
<Provider store={store}>
|
||||
<EnterpriseEditionLeftPanel
|
||||
{...props}
|
||||
{...baseProps}
|
||||
/>
|
||||
</Provider>,
|
||||
);
|
||||
@@ -127,35 +125,34 @@ describe('components/admin_console/license_settings/enterprise_edition/enterpris
|
||||
expect(item.text()).toContain('1,000');
|
||||
});
|
||||
|
||||
test('should not add any class if active users is lower than the minimal', async () => {
|
||||
const store = await mockStore(initialState);
|
||||
renderWithIntl(
|
||||
<Provider store={store}>
|
||||
<EnterpriseEditionLeftPanel
|
||||
{...props}
|
||||
/>
|
||||
</Provider>,
|
||||
test('should not add any class if active users is lower than the minimal', () => {
|
||||
renderWithContext(
|
||||
<EnterpriseEditionLeftPanel
|
||||
{...baseProps}
|
||||
/>,
|
||||
initialState,
|
||||
);
|
||||
|
||||
expect(screen.getByText(Intl.NumberFormat('en').format(props.statsActiveUsers))).toHaveClass('value');
|
||||
expect(screen.getByText(Intl.NumberFormat('en').format(props.statsActiveUsers))).not.toHaveClass('value--warning-over-seats-purchased');
|
||||
expect(screen.getByText(Intl.NumberFormat('en').format(props.statsActiveUsers))).not.toHaveClass('value--over-seats-purchased');
|
||||
expect(screen.getByText(Intl.NumberFormat('en').format(baseProps.statsActiveUsers))).toHaveClass('value');
|
||||
expect(screen.getByText(Intl.NumberFormat('en').format(baseProps.statsActiveUsers))).not.toHaveClass('value--warning-over-seats-purchased');
|
||||
expect(screen.getByText(Intl.NumberFormat('en').format(baseProps.statsActiveUsers))).not.toHaveClass('value--over-seats-purchased');
|
||||
expect(screen.getByText('ACTIVE USERS:')).toHaveClass('legend');
|
||||
expect(screen.getByText('ACTIVE USERS:')).not.toHaveClass('legend--warning-over-seats-purchased');
|
||||
expect(screen.getByText('ACTIVE USERS:')).not.toHaveClass('legend--over-seats-purchased');
|
||||
});
|
||||
|
||||
test('should add warning class to active users', async () => {
|
||||
test('should add warning class to active users', () => {
|
||||
const minWarning = Math.ceil(parseInt(license.Users, 10) * OverActiveUserLimits.MIN) + parseInt(license.Users, 10);
|
||||
const store = await mockStore(initialState);
|
||||
props.statsActiveUsers = minWarning;
|
||||
const props = {
|
||||
...baseProps,
|
||||
statsActiveUsers: minWarning,
|
||||
};
|
||||
|
||||
renderWithIntl(
|
||||
<Provider store={store}>
|
||||
<EnterpriseEditionLeftPanel
|
||||
{...props}
|
||||
/>
|
||||
</Provider>,
|
||||
renderWithContext(
|
||||
<EnterpriseEditionLeftPanel
|
||||
{...props}
|
||||
/>,
|
||||
initialState,
|
||||
);
|
||||
|
||||
expect(screen.getByText(Intl.NumberFormat('en').format(minWarning))).toHaveClass('value');
|
||||
@@ -166,16 +163,18 @@ describe('components/admin_console/license_settings/enterprise_edition/enterpris
|
||||
expect(screen.getByText('ACTIVE USERS:')).not.toHaveClass('legend--over-seats-purchased');
|
||||
});
|
||||
|
||||
test('should add over-seats-purchased class to active users', async () => {
|
||||
test('should add over-seats-purchased class to active users', () => {
|
||||
const exceedHighLimitExtraUsersError = Math.ceil(parseInt(license.Users, 10) * OverActiveUserLimits.MAX) + parseInt(license.Users, 10);
|
||||
props.statsActiveUsers = exceedHighLimitExtraUsersError;
|
||||
const store = await mockStore(initialState);
|
||||
renderWithIntl(
|
||||
<Provider store={store}>
|
||||
<EnterpriseEditionLeftPanel
|
||||
{...props}
|
||||
/>
|
||||
</Provider>,
|
||||
const props = {
|
||||
...baseProps,
|
||||
statsActiveUsers: exceedHighLimitExtraUsersError,
|
||||
};
|
||||
|
||||
renderWithContext(
|
||||
<EnterpriseEditionLeftPanel
|
||||
{...props}
|
||||
/>,
|
||||
initialState,
|
||||
);
|
||||
|
||||
expect(screen.getByText(Intl.NumberFormat('en').format(exceedHighLimitExtraUsersError))).toHaveClass('value');
|
||||
@@ -186,44 +185,87 @@ describe('components/admin_console/license_settings/enterprise_edition/enterpris
|
||||
expect(screen.getByText('ACTIVE USERS:')).toHaveClass('legend--over-seats-purchased');
|
||||
});
|
||||
|
||||
test('should add warning class to days expired indicator when there are more than 5 days until expiry', async () => {
|
||||
license.ExpiresAt = moment().add(6, 'days').valueOf().toString();
|
||||
const store = await mockStore(initialState);
|
||||
renderWithIntl(
|
||||
<Provider store={store}>
|
||||
<EnterpriseEditionLeftPanel
|
||||
{...props}
|
||||
/>
|
||||
</Provider>,
|
||||
test('should add warning class to days expired indicator when there are more than 5 days until expiry', () => {
|
||||
const testLicense = {
|
||||
...license,
|
||||
ExpiresAt: moment().add(6, 'days').valueOf().toString(),
|
||||
};
|
||||
|
||||
const testState = mergeObjects(initialState, {
|
||||
entities: {
|
||||
general: {
|
||||
license: testLicense,
|
||||
},
|
||||
},
|
||||
});
|
||||
const props = {
|
||||
...baseProps,
|
||||
license: testLicense,
|
||||
};
|
||||
|
||||
renderWithContext(
|
||||
<EnterpriseEditionLeftPanel
|
||||
{...props}
|
||||
/>,
|
||||
testState,
|
||||
);
|
||||
|
||||
expect(screen.getByText('Expires in 6 days')).toHaveClass('expiration-days-warning');
|
||||
});
|
||||
|
||||
test('should add danger class to days expired indicator when there are at least 5 days until expiry', async () => {
|
||||
license.ExpiresAt = moment().add(5, 'days').valueOf().toString();
|
||||
const store = await mockStore(initialState);
|
||||
renderWithIntl(
|
||||
<Provider store={store}>
|
||||
<EnterpriseEditionLeftPanel
|
||||
{...props}
|
||||
/>
|
||||
</Provider>,
|
||||
test('should add danger class to days expired indicator when there are at least 5 days until expiry', () => {
|
||||
const testLicense = {
|
||||
...license,
|
||||
ExpiresAt: moment().add(5, 'days').valueOf().toString(),
|
||||
};
|
||||
|
||||
const testState = mergeObjects(initialState, {
|
||||
entities: {
|
||||
general: {
|
||||
license: testLicense,
|
||||
},
|
||||
},
|
||||
});
|
||||
const props = {
|
||||
...baseProps,
|
||||
license: testLicense,
|
||||
};
|
||||
|
||||
renderWithContext(
|
||||
<EnterpriseEditionLeftPanel
|
||||
{...props}
|
||||
/>,
|
||||
testState,
|
||||
);
|
||||
|
||||
expect(screen.getByText('Expires in 5 days')).toHaveClass('expiration-days-danger');
|
||||
});
|
||||
|
||||
test('should display add seats button when there are more than 60 days until expiry and self hosted expansion is available', async () => {
|
||||
license.ExpiresAt = moment().add(61, 'days').valueOf().toString();
|
||||
const store = await mockStore(initialState);
|
||||
test('should display add seats button when there are more than 60 days until expiry and self hosted expansion is available', () => {
|
||||
const testLicense = {
|
||||
...license,
|
||||
ExpiresAt: moment().add(61, 'days').valueOf().toString(),
|
||||
};
|
||||
|
||||
const testState = mergeObjects(initialState, {
|
||||
entities: {
|
||||
general: {
|
||||
license: testLicense,
|
||||
},
|
||||
},
|
||||
});
|
||||
const props = {
|
||||
...baseProps,
|
||||
license: testLicense,
|
||||
};
|
||||
|
||||
jest.spyOn(useCanSelfHostedExpand, 'default').mockImplementation(() => true);
|
||||
renderWithIntl(
|
||||
<Provider store={store}>
|
||||
<EnterpriseEditionLeftPanel
|
||||
{...props}
|
||||
/>
|
||||
</Provider>,
|
||||
|
||||
renderWithContext(
|
||||
<EnterpriseEditionLeftPanel
|
||||
{...props}
|
||||
/>,
|
||||
testState,
|
||||
);
|
||||
|
||||
expect(screen.getByText('+ Add seats')).toBeVisible();
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import {renderWithIntl, screen} from 'tests/react_testing_utils';
|
||||
import {renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
|
||||
import AdminTextSetting from './text_setting';
|
||||
|
||||
describe('components/admin_console/TextSetting', () => {
|
||||
test('render component with required props', () => {
|
||||
renderWithIntl(
|
||||
renderWithContext(
|
||||
<AdminTextSetting
|
||||
id='some.id'
|
||||
label='some label'
|
||||
|
||||
@@ -11,11 +11,9 @@ import Permissions from 'mattermost-redux/constants/permissions';
|
||||
import type {FileUpload} from 'components/file_upload/file_upload';
|
||||
import type Textbox from 'components/textbox/textbox';
|
||||
|
||||
import WebSocketClient from 'client/web_websocket_client';
|
||||
import mergeObjects from 'packages/mattermost-redux/test/merge_objects';
|
||||
import {renderWithFullContext, userEvent} from 'tests/react_testing_utils';
|
||||
import {renderWithContext, userEvent} from 'tests/react_testing_utils';
|
||||
import {TestHelper} from 'utils/test_helper';
|
||||
import {WebSocketContext} from 'utils/use_websocket';
|
||||
|
||||
import type {PostDraft} from 'types/store/draft';
|
||||
|
||||
@@ -152,14 +150,13 @@ describe('components/avanced_text_editor/advanced_text_editor', () => {
|
||||
describe('keyDown behavior', () => {
|
||||
it('Enter should call postMsgKeyPress', () => {
|
||||
const postMsgKeyPress = jest.fn();
|
||||
renderWithFullContext(
|
||||
<WebSocketContext.Provider value={WebSocketClient}>
|
||||
<AdavancedTextEditor
|
||||
{...baseProps}
|
||||
postMsgKeyPress={postMsgKeyPress}
|
||||
message={'test'}
|
||||
/>
|
||||
</WebSocketContext.Provider>, mergeObjects(initialState, {
|
||||
renderWithContext(
|
||||
<AdavancedTextEditor
|
||||
{...baseProps}
|
||||
postMsgKeyPress={postMsgKeyPress}
|
||||
message={'test'}
|
||||
/>,
|
||||
mergeObjects(initialState, {
|
||||
entities: {
|
||||
roles: {
|
||||
roles: {
|
||||
@@ -167,7 +164,8 @@ describe('components/avanced_text_editor/advanced_text_editor', () => {
|
||||
},
|
||||
},
|
||||
},
|
||||
}));
|
||||
}),
|
||||
);
|
||||
|
||||
userEvent.type(screen.getByTestId('post_textbox'), '{enter}');
|
||||
expect(postMsgKeyPress).toHaveBeenCalledTimes(1);
|
||||
@@ -175,13 +173,12 @@ describe('components/avanced_text_editor/advanced_text_editor', () => {
|
||||
|
||||
it('Ctrl+up should call loadPrevMessage', () => {
|
||||
const loadPrevMessage = jest.fn();
|
||||
renderWithFullContext(
|
||||
<WebSocketContext.Provider value={WebSocketClient}>
|
||||
<AdavancedTextEditor
|
||||
{...baseProps}
|
||||
loadPrevMessage={loadPrevMessage}
|
||||
/>
|
||||
</WebSocketContext.Provider>, mergeObjects(initialState, {
|
||||
renderWithContext(
|
||||
<AdavancedTextEditor
|
||||
{...baseProps}
|
||||
loadPrevMessage={loadPrevMessage}
|
||||
/>,
|
||||
mergeObjects(initialState, {
|
||||
entities: {
|
||||
roles: {
|
||||
roles: {
|
||||
@@ -189,20 +186,20 @@ describe('components/avanced_text_editor/advanced_text_editor', () => {
|
||||
},
|
||||
},
|
||||
},
|
||||
}));
|
||||
}),
|
||||
);
|
||||
userEvent.type(screen.getByTestId('post_textbox'), '{ctrl}{arrowup}');
|
||||
expect(loadPrevMessage).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('up should call onEditLatestPost', () => {
|
||||
const onEditLatestPost = jest.fn();
|
||||
renderWithFullContext(
|
||||
<WebSocketContext.Provider value={WebSocketClient}>
|
||||
<AdavancedTextEditor
|
||||
{...baseProps}
|
||||
onEditLatestPost={onEditLatestPost}
|
||||
/>
|
||||
</WebSocketContext.Provider>, mergeObjects(initialState, {
|
||||
renderWithContext(
|
||||
<AdavancedTextEditor
|
||||
{...baseProps}
|
||||
onEditLatestPost={onEditLatestPost}
|
||||
/>,
|
||||
mergeObjects(initialState, {
|
||||
entities: {
|
||||
roles: {
|
||||
roles: {
|
||||
@@ -210,18 +207,18 @@ describe('components/avanced_text_editor/advanced_text_editor', () => {
|
||||
},
|
||||
},
|
||||
},
|
||||
}));
|
||||
}),
|
||||
);
|
||||
userEvent.type(screen.getByTestId('post_textbox'), '{arrowup}');
|
||||
expect(onEditLatestPost).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('ESC should blur the input', () => {
|
||||
renderWithFullContext(
|
||||
<WebSocketContext.Provider value={WebSocketClient}>
|
||||
<AdavancedTextEditor
|
||||
{...baseProps}
|
||||
/>
|
||||
</WebSocketContext.Provider>, mergeObjects(initialState, {
|
||||
renderWithContext(
|
||||
<AdavancedTextEditor
|
||||
{...baseProps}
|
||||
/>,
|
||||
mergeObjects(initialState, {
|
||||
entities: {
|
||||
roles: {
|
||||
roles: {
|
||||
@@ -229,7 +226,8 @@ describe('components/avanced_text_editor/advanced_text_editor', () => {
|
||||
},
|
||||
},
|
||||
},
|
||||
}));
|
||||
}),
|
||||
);
|
||||
const textbox = screen.getByTestId('post_textbox');
|
||||
userEvent.type(textbox, 'something{esc}');
|
||||
expect(textbox).not.toHaveFocus();
|
||||
@@ -261,14 +259,13 @@ describe('components/avanced_text_editor/advanced_text_editor', () => {
|
||||
const selectionStart = 5;
|
||||
const selectionEnd = 10;
|
||||
|
||||
renderWithFullContext(
|
||||
<WebSocketContext.Provider value={WebSocketClient}>
|
||||
<AdavancedTextEditor
|
||||
{...baseProps}
|
||||
applyMarkdown={applyMarkdown}
|
||||
message={'Some markdown text'}
|
||||
/>
|
||||
</WebSocketContext.Provider>, mergeObjects(initialState, {
|
||||
renderWithContext(
|
||||
<AdavancedTextEditor
|
||||
{...baseProps}
|
||||
applyMarkdown={applyMarkdown}
|
||||
message={'Some markdown text'}
|
||||
/>,
|
||||
mergeObjects(initialState, {
|
||||
entities: {
|
||||
roles: {
|
||||
roles: {
|
||||
@@ -276,7 +273,8 @@ describe('components/avanced_text_editor/advanced_text_editor', () => {
|
||||
},
|
||||
},
|
||||
},
|
||||
}));
|
||||
}),
|
||||
);
|
||||
const textbox = screen.getByTestId('post_textbox');
|
||||
userEvent.type(textbox, tc.input, {initialSelectionStart: selectionStart, initialSelectionEnd: selectionEnd});
|
||||
expect(applyMarkdown).toHaveBeenCalledWith({
|
||||
|
||||
@@ -8,14 +8,14 @@ import type {DeepPartial} from '@mattermost/types/utilities';
|
||||
|
||||
import * as useCWSAvailabilityCheckAll from 'components/common/hooks/useCWSAvailabilityCheck';
|
||||
|
||||
import {renderWithIntlAndStore, screen} from 'tests/react_testing_utils';
|
||||
import {renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
import {LicenseSkus} from 'utils/constants';
|
||||
import {TestHelper as TH} from 'utils/test_helper';
|
||||
|
||||
import TrueUpReview from './true_up_review';
|
||||
|
||||
describe('TrueUpReview', () => {
|
||||
const showsTrueUpReviewStore: DeepPartial<GlobalState> = {
|
||||
const showsTrueUpReviewState: DeepPartial<GlobalState> = {
|
||||
entities: {
|
||||
general: {
|
||||
license: TH.getLicenseMock({
|
||||
@@ -58,16 +58,16 @@ describe('TrueUpReview', () => {
|
||||
it('regular self hosted license in the true up window sees content', () => {
|
||||
jest.spyOn(useCWSAvailabilityCheckAll, 'default').mockImplementation(() => true);
|
||||
|
||||
renderWithIntlAndStore(<TrueUpReview/>, showsTrueUpReviewStore);
|
||||
renderWithContext(<TrueUpReview/>, showsTrueUpReviewState);
|
||||
screen.getByText('Share to Mattermost');
|
||||
});
|
||||
|
||||
it('gov sku self-hosted license does not see true up content', () => {
|
||||
const store = JSON.parse(JSON.stringify(showsTrueUpReviewStore));
|
||||
const store = JSON.parse(JSON.stringify(showsTrueUpReviewState));
|
||||
store.entities.general.license.IsGovSku = 'true';
|
||||
jest.spyOn(useCWSAvailabilityCheckAll, 'default').mockImplementation(() => true);
|
||||
|
||||
renderWithIntlAndStore(<TrueUpReview/>, store);
|
||||
renderWithContext(<TrueUpReview/>, store);
|
||||
expect(screen.queryByText('Share to Mattermost')).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,18 +2,15 @@
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import type {ComponentProps} from 'react';
|
||||
import * as reactRedux from 'react-redux';
|
||||
|
||||
import {savePreferences} from 'mattermost-redux/actions/preferences';
|
||||
import {Client4} from 'mattermost-redux/client';
|
||||
|
||||
import {trackEvent} from 'actions/telemetry_actions';
|
||||
import configureStore from 'store';
|
||||
|
||||
import {
|
||||
fireEvent,
|
||||
renderWithIntl,
|
||||
renderWithContext,
|
||||
screen,
|
||||
waitFor,
|
||||
} from 'tests/react_testing_utils';
|
||||
@@ -22,11 +19,6 @@ import {TestHelper} from 'utils/test_helper';
|
||||
|
||||
import NotifyAdminDowngradeDeliquencyBar, {BannerPreferenceName} from './index';
|
||||
|
||||
type RenderComponentArgs = {
|
||||
props?: Partial<ComponentProps<typeof NotifyAdminDowngradeDeliquencyBar>>;
|
||||
store?: any;
|
||||
}
|
||||
|
||||
jest.mock('actions/telemetry_actions', () => ({
|
||||
trackEvent: jest.fn(),
|
||||
}));
|
||||
@@ -93,14 +85,6 @@ describe('components/announcement_bar/notify_admin_downgrade_delinquency_bar', (
|
||||
},
|
||||
};
|
||||
|
||||
const renderComponent = ({store = initialState}: RenderComponentArgs) => {
|
||||
return renderWithIntl(
|
||||
<reactRedux.Provider store={configureStore(store)}>
|
||||
<NotifyAdminDowngradeDeliquencyBar/>
|
||||
</reactRedux.Provider>,
|
||||
);
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
@@ -113,7 +97,7 @@ describe('components/announcement_bar/notify_admin_downgrade_delinquency_bar', (
|
||||
is_free_trial: 'false',
|
||||
};
|
||||
|
||||
renderComponent({store: state});
|
||||
renderWithContext(<NotifyAdminDowngradeDeliquencyBar/>, state);
|
||||
|
||||
expect(screen.queryByText('Your workspace has been downgraded. Notify your admin to fix billing issues')).not.toBeInTheDocument();
|
||||
});
|
||||
@@ -121,7 +105,7 @@ describe('components/announcement_bar/notify_admin_downgrade_delinquency_bar', (
|
||||
it('Should not show banner when deliquency is less than 90 days', () => {
|
||||
jest.useFakeTimers().setSystemTime(new Date('2022-06-20'));
|
||||
|
||||
renderComponent({});
|
||||
renderWithContext(<NotifyAdminDowngradeDeliquencyBar/>, initialState);
|
||||
|
||||
expect(screen.queryByText('Your workspace has been downgraded. Notify your admin to fix billing issues')).not.toBeInTheDocument();
|
||||
});
|
||||
@@ -138,7 +122,7 @@ describe('components/announcement_bar/notify_admin_downgrade_delinquency_bar', (
|
||||
],
|
||||
);
|
||||
|
||||
renderComponent({store: state});
|
||||
renderWithContext(<NotifyAdminDowngradeDeliquencyBar/>, state);
|
||||
|
||||
expect(screen.queryByText('Your workspace has been downgraded. Notify your admin to fix billing issues')).not.toBeInTheDocument();
|
||||
});
|
||||
@@ -155,7 +139,7 @@ describe('components/announcement_bar/notify_admin_downgrade_delinquency_bar', (
|
||||
],
|
||||
);
|
||||
|
||||
renderComponent({store: state});
|
||||
renderWithContext(<NotifyAdminDowngradeDeliquencyBar/>, state);
|
||||
|
||||
expect(screen.queryByText('Your workspace has been downgraded. Notify your admin to fix billing issues')).not.toBeInTheDocument();
|
||||
});
|
||||
@@ -165,7 +149,7 @@ describe('components/announcement_bar/notify_admin_downgrade_delinquency_bar', (
|
||||
const state = JSON.parse(JSON.stringify(initialState));
|
||||
state.entities.users.profiles.current_user_id = {roles: 'system_admin'};
|
||||
|
||||
renderComponent({store: state});
|
||||
renderWithContext(<NotifyAdminDowngradeDeliquencyBar/>, state);
|
||||
|
||||
expect(screen.queryByText('Your workspace has been downgraded. Notify your admin to fix billing issues')).not.toBeInTheDocument();
|
||||
});
|
||||
@@ -174,7 +158,7 @@ describe('components/announcement_bar/notify_admin_downgrade_delinquency_bar', (
|
||||
jest.useFakeTimers().setSystemTime(new Date('2022-08-17'));
|
||||
Client4.notifyAdmin = jest.fn();
|
||||
|
||||
renderComponent({});
|
||||
renderWithContext(<NotifyAdminDowngradeDeliquencyBar/>, initialState);
|
||||
|
||||
expect(savePreferences).not.toBeCalled();
|
||||
});
|
||||
@@ -182,7 +166,7 @@ describe('components/announcement_bar/notify_admin_downgrade_delinquency_bar', (
|
||||
it('Should show banner when deliquency is higher than 90 days', () => {
|
||||
jest.useFakeTimers().setSystemTime(new Date('2022-08-17'));
|
||||
|
||||
renderComponent({});
|
||||
renderWithContext(<NotifyAdminDowngradeDeliquencyBar/>, initialState);
|
||||
|
||||
expect(screen.getByText('Your workspace has been downgraded. Notify your admin to fix billing issues')).toBeInTheDocument();
|
||||
});
|
||||
@@ -190,7 +174,7 @@ describe('components/announcement_bar/notify_admin_downgrade_delinquency_bar', (
|
||||
it('Should save the preferences if the user close the banner', async () => {
|
||||
jest.useFakeTimers().setSystemTime(new Date('2022-08-17'));
|
||||
|
||||
renderComponent({});
|
||||
renderWithContext(<NotifyAdminDowngradeDeliquencyBar/>, initialState);
|
||||
|
||||
fireEvent.click(screen.getByRole('link'));
|
||||
|
||||
@@ -207,7 +191,7 @@ describe('components/announcement_bar/notify_admin_downgrade_delinquency_bar', (
|
||||
jest.useFakeTimers().setSystemTime(new Date('2022-08-17'));
|
||||
Client4.notifyAdmin = jest.fn();
|
||||
|
||||
renderComponent({});
|
||||
renderWithContext(<NotifyAdminDowngradeDeliquencyBar/>, initialState);
|
||||
|
||||
fireEvent.click(screen.getByText('Notify admin'));
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import {General} from 'mattermost-redux/constants';
|
||||
|
||||
import {trackEvent} from 'actions/telemetry_actions';
|
||||
|
||||
import {fireEvent, renderWithIntlAndStore, screen} from 'tests/react_testing_utils';
|
||||
import {fireEvent, renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
import {OverActiveUserLimits, Preferences, SelfHostedProducts, StatTypes} from 'utils/constants';
|
||||
import {TestHelper} from 'utils/test_helper';
|
||||
import {generateId} from 'utils/utils';
|
||||
@@ -20,13 +20,6 @@ import type {GlobalState} from 'types/store';
|
||||
|
||||
import OverageUsersBanner from './index';
|
||||
|
||||
type ComponentProps = React.ComponentProps<typeof OverageUsersBanner>;
|
||||
|
||||
type RenderComponentArgs = {
|
||||
props?: Partial<ComponentProps>;
|
||||
store?: any;
|
||||
}
|
||||
|
||||
jest.mock('react-redux', () => ({
|
||||
...jest.requireActual('react-redux'),
|
||||
useDispatch: jest.fn().mockReturnValue(() => {}),
|
||||
@@ -137,20 +130,15 @@ describe('components/overage_users_banner', () => {
|
||||
windowSpy.mockRestore();
|
||||
});
|
||||
|
||||
const renderComponent = ({store}: RenderComponentArgs = {props: {}, store: initialState}) => {
|
||||
return renderWithIntlAndStore(
|
||||
<OverageUsersBanner/>, store);
|
||||
};
|
||||
|
||||
it('should not render the banner because we are not on overage state', () => {
|
||||
renderComponent();
|
||||
renderWithContext(<OverageUsersBanner/>);
|
||||
|
||||
expect(screen.queryByText('(Only visible to admins) Your workspace user count has exceeded your paid license seat count by', {exact: false})).not.toBeInTheDocument();
|
||||
expect(getLicenseSelfServeStatus).not.toBeCalled();
|
||||
});
|
||||
|
||||
it('should not render the banner because we are not admins', () => {
|
||||
const store: GlobalState = JSON.parse(JSON.stringify(initialState));
|
||||
const store = JSON.parse(JSON.stringify(initialState));
|
||||
|
||||
store.entities.users = {
|
||||
...store.entities.users,
|
||||
@@ -163,32 +151,28 @@ describe('components/overage_users_banner', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderComponent({
|
||||
store,
|
||||
});
|
||||
renderWithContext(<OverageUsersBanner/>, store);
|
||||
|
||||
expect(screen.queryByText('Your workspace user count has exceeded your paid license seat count by', {exact: false})).not.toBeInTheDocument();
|
||||
expect(getLicenseSelfServeStatus).not.toBeCalled();
|
||||
});
|
||||
|
||||
it('should not render the banner because it\'s cloud licenese', () => {
|
||||
const store: GlobalState = JSON.parse(JSON.stringify(initialState));
|
||||
const store = JSON.parse(JSON.stringify(initialState));
|
||||
|
||||
store.entities.general.license = {
|
||||
...store.entities.general.license,
|
||||
Cloud: 'true',
|
||||
};
|
||||
|
||||
renderComponent({
|
||||
store,
|
||||
});
|
||||
renderWithContext(<OverageUsersBanner/>, store);
|
||||
|
||||
expect(screen.queryByText('Your workspace user count has exceeded your paid license seat count by', {exact: false})).not.toBeInTheDocument();
|
||||
expect(getLicenseSelfServeStatus).not.toBeCalled();
|
||||
});
|
||||
|
||||
it('should not render the 5% banner because we have dissmised it', () => {
|
||||
const store: GlobalState = JSON.parse(JSON.stringify(initialState));
|
||||
const store = JSON.parse(JSON.stringify(initialState));
|
||||
|
||||
store.entities.preferences.myPreferences = TestHelper.getPreferencesMock(
|
||||
[
|
||||
@@ -207,16 +191,14 @@ describe('components/overage_users_banner', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderComponent({
|
||||
store,
|
||||
});
|
||||
renderWithContext(<OverageUsersBanner/>, store);
|
||||
|
||||
expect(screen.queryByText(text5PercentageState)).not.toBeInTheDocument();
|
||||
expect(getLicenseSelfServeStatus).not.toBeCalled();
|
||||
});
|
||||
|
||||
it('should render the banner because we are over 5% and we don\'t have any preferences', () => {
|
||||
const store: GlobalState = JSON.parse(JSON.stringify(initialState));
|
||||
const store = JSON.parse(JSON.stringify(initialState));
|
||||
|
||||
store.entities.cloud = {
|
||||
...store.entities.cloud,
|
||||
@@ -233,16 +215,14 @@ describe('components/overage_users_banner', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderComponent({
|
||||
store,
|
||||
});
|
||||
renderWithContext(<OverageUsersBanner/>, store);
|
||||
|
||||
expect(screen.getByText(text5PercentageState)).toBeInTheDocument();
|
||||
expect(screen.getByText(contactSalesTextLink)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should track if the admin click Contact Sales CTA in a 10% overage state', () => {
|
||||
const store: GlobalState = JSON.parse(JSON.stringify(initialState));
|
||||
const store = JSON.parse(JSON.stringify(initialState));
|
||||
|
||||
store.entities.cloud = {
|
||||
...store.entities.cloud,
|
||||
@@ -259,9 +239,7 @@ describe('components/overage_users_banner', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderComponent({
|
||||
store,
|
||||
});
|
||||
renderWithContext(<OverageUsersBanner/>, store);
|
||||
|
||||
fireEvent.click(screen.getByText(contactSalesTextLink));
|
||||
expect(windowSpy).toBeCalledTimes(1);
|
||||
@@ -277,7 +255,7 @@ describe('components/overage_users_banner', () => {
|
||||
});
|
||||
|
||||
it('should render the banner because we are over 5% and we have preferences from one old banner', () => {
|
||||
const store: GlobalState = JSON.parse(JSON.stringify(initialState));
|
||||
const store = JSON.parse(JSON.stringify(initialState));
|
||||
|
||||
store.entities.cloud = {
|
||||
...store.entities.cloud,
|
||||
@@ -304,16 +282,14 @@ describe('components/overage_users_banner', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderComponent({
|
||||
store,
|
||||
});
|
||||
renderWithContext(<OverageUsersBanner/>, store);
|
||||
|
||||
expect(screen.getByText(text5PercentageState)).toBeInTheDocument();
|
||||
expect(screen.getByText(contactSalesTextLink)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should save the preferences for 5% banner if admin click on close', () => {
|
||||
const store: GlobalState = JSON.parse(JSON.stringify(initialState));
|
||||
const store = JSON.parse(JSON.stringify(initialState));
|
||||
|
||||
store.entities.admin = {
|
||||
...store.entities.admin,
|
||||
@@ -322,9 +298,7 @@ describe('components/overage_users_banner', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderComponent({
|
||||
store,
|
||||
});
|
||||
renderWithContext(<OverageUsersBanner/>, store);
|
||||
|
||||
fireEvent.click(screen.getByRole('link'));
|
||||
|
||||
@@ -338,7 +312,7 @@ describe('components/overage_users_banner', () => {
|
||||
});
|
||||
|
||||
it('should render the banner because we are over 10%', () => {
|
||||
const store: GlobalState = JSON.parse(JSON.stringify(initialState));
|
||||
const store = JSON.parse(JSON.stringify(initialState));
|
||||
|
||||
store.entities.cloud = {
|
||||
...store.entities.cloud,
|
||||
@@ -355,16 +329,14 @@ describe('components/overage_users_banner', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderComponent({
|
||||
store,
|
||||
});
|
||||
renderWithContext(<OverageUsersBanner/>, store);
|
||||
|
||||
expect(screen.getByText(text10PercentageState)).toBeInTheDocument();
|
||||
expect(screen.getByText(contactSalesTextLink)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should track if the admin click Contact Sales CTA in a 10% overage state', () => {
|
||||
const store: GlobalState = JSON.parse(JSON.stringify(initialState));
|
||||
const store = JSON.parse(JSON.stringify(initialState));
|
||||
|
||||
store.entities.cloud = {
|
||||
...store.entities.cloud,
|
||||
@@ -381,9 +353,7 @@ describe('components/overage_users_banner', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderComponent({
|
||||
store,
|
||||
});
|
||||
renderWithContext(<OverageUsersBanner/>, store);
|
||||
|
||||
fireEvent.click(screen.getByText(contactSalesTextLink));
|
||||
expect(windowSpy).toBeCalledTimes(1);
|
||||
@@ -399,7 +369,7 @@ describe('components/overage_users_banner', () => {
|
||||
});
|
||||
|
||||
it('should render the warning banner with expansion seats CTA if the license is expandable', () => {
|
||||
const store: GlobalState = JSON.parse(JSON.stringify(initialState));
|
||||
const store = JSON.parse(JSON.stringify(initialState));
|
||||
|
||||
store.entities.cloud = {
|
||||
...store.entities.cloud,
|
||||
@@ -417,15 +387,13 @@ describe('components/overage_users_banner', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderComponent({
|
||||
store,
|
||||
});
|
||||
renderWithContext(<OverageUsersBanner/>, store);
|
||||
|
||||
expect(screen.getByText(expandSeatsTextLink)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should track if the admin click expansion seats CTA in a 5% overage state', () => {
|
||||
const store: GlobalState = JSON.parse(JSON.stringify(initialState));
|
||||
const store = JSON.parse(JSON.stringify(initialState));
|
||||
|
||||
store.entities.cloud = {
|
||||
...store.entities.cloud,
|
||||
@@ -443,9 +411,7 @@ describe('components/overage_users_banner', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderComponent({
|
||||
store,
|
||||
});
|
||||
renderWithContext(<OverageUsersBanner/>, store);
|
||||
|
||||
fireEvent.click(screen.getByText(expandSeatsTextLink));
|
||||
expect(windowSpy).toBeCalledTimes(1);
|
||||
@@ -458,7 +424,7 @@ describe('components/overage_users_banner', () => {
|
||||
});
|
||||
|
||||
it('should render the error banner with expansion seats CTA if the license is be expandable', () => {
|
||||
const store: GlobalState = JSON.parse(JSON.stringify(initialState));
|
||||
const store = JSON.parse(JSON.stringify(initialState));
|
||||
|
||||
store.entities.cloud = {
|
||||
...store.entities.cloud,
|
||||
@@ -476,15 +442,13 @@ describe('components/overage_users_banner', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderComponent({
|
||||
store,
|
||||
});
|
||||
renderWithContext(<OverageUsersBanner/>, store);
|
||||
|
||||
expect(screen.getByText(expandSeatsTextLink)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should track if the admin click expansion seats CTA in a 10% overage state', () => {
|
||||
const store: GlobalState = JSON.parse(JSON.stringify(initialState));
|
||||
const store = JSON.parse(JSON.stringify(initialState));
|
||||
|
||||
store.entities.cloud = {
|
||||
...store.entities.cloud,
|
||||
@@ -502,9 +466,7 @@ describe('components/overage_users_banner', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderComponent({
|
||||
store,
|
||||
});
|
||||
renderWithContext(<OverageUsersBanner/>, store);
|
||||
|
||||
fireEvent.click(screen.getByText(expandSeatsTextLink));
|
||||
expect(windowSpy).toBeCalledTimes(1);
|
||||
|
||||
@@ -5,7 +5,7 @@ import React from 'react';
|
||||
|
||||
import * as cloudActions from 'mattermost-redux/actions/cloud';
|
||||
|
||||
import {renderWithIntlAndStore, screen} from 'tests/react_testing_utils';
|
||||
import {renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
import {CloudProducts} from 'utils/constants';
|
||||
|
||||
import PaymentAnnouncementBar from './';
|
||||
@@ -68,7 +68,7 @@ describe('PaymentAnnouncementBar', () => {
|
||||
};
|
||||
|
||||
it('when most recent payment failed, shows that', () => {
|
||||
renderWithIntlAndStore(<PaymentAnnouncementBar/>, happyPathStore);
|
||||
renderWithContext(<PaymentAnnouncementBar/>, happyPathStore);
|
||||
screen.getByText('Your most recent payment failed');
|
||||
});
|
||||
|
||||
@@ -76,7 +76,7 @@ describe('PaymentAnnouncementBar', () => {
|
||||
const store = JSON.parse(JSON.stringify(happyPathStore));
|
||||
store.entities.cloud.customer.payment_method.exp_year = (new Date()).getFullYear() - 1;
|
||||
store.entities.cloud.subscription.last_invoice.status = 'success';
|
||||
renderWithIntlAndStore(<PaymentAnnouncementBar/>, store);
|
||||
renderWithContext(<PaymentAnnouncementBar/>, store);
|
||||
screen.getByText('Your credit card has expired', {exact: false});
|
||||
});
|
||||
|
||||
@@ -84,14 +84,14 @@ describe('PaymentAnnouncementBar', () => {
|
||||
const store = JSON.parse(JSON.stringify(happyPathStore));
|
||||
store.entities.cloud.customer = null;
|
||||
store.entities.cloud.subscription.last_invoice.status = 'success';
|
||||
renderWithIntlAndStore(<PaymentAnnouncementBar/>, store);
|
||||
renderWithContext(<PaymentAnnouncementBar/>, store);
|
||||
expect(cloudActions.getCloudCustomer).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('when not an admin, does not fetch customer', () => {
|
||||
const store = JSON.parse(JSON.stringify(happyPathStore));
|
||||
store.entities.users.profiles.me.roles = '';
|
||||
renderWithIntlAndStore(<PaymentAnnouncementBar/>, store);
|
||||
renderWithContext(<PaymentAnnouncementBar/>, store);
|
||||
expect(cloudActions.getCloudCustomer).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,13 +2,11 @@
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import {Provider} from 'react-redux';
|
||||
|
||||
import {emptyLimits} from 'tests/constants/cloud';
|
||||
import {emptyTeams} from 'tests/constants/teams';
|
||||
import {adminUsersState, endUsersState} from 'tests/constants/users';
|
||||
import {renderWithIntl, screen} from 'tests/react_testing_utils';
|
||||
import testConfigureStore from 'tests/test_store';
|
||||
import {screen, renderWithContext} from 'tests/react_testing_utils';
|
||||
import {makeEmptyUsage} from 'utils/limits_test';
|
||||
import {TestHelper} from 'utils/test_helper';
|
||||
|
||||
@@ -102,38 +100,34 @@ const endUserLimitExceeded = {
|
||||
|
||||
describe('CenterMessageLock', () => {
|
||||
it('returns null if limits not loaded', () => {
|
||||
renderWithIntl(
|
||||
<Provider store={testConfigureStore(initialState)}>
|
||||
<CenterMessageLock channelId={'channelId'}/>
|
||||
</Provider>,
|
||||
renderWithContext(
|
||||
<CenterMessageLock channelId={'channelId'}/>,
|
||||
initialState,
|
||||
);
|
||||
expect(screen.queryByText('Notify Admin')).not.toBeInTheDocument();
|
||||
expect(screen.queryByText('Upgrade now')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('Admins have a call to upgrade', () => {
|
||||
renderWithIntl(
|
||||
<Provider store={testConfigureStore(exceededLimitsState)}>
|
||||
<CenterMessageLock channelId={'channelId'}/>
|
||||
</Provider>,
|
||||
renderWithContext(
|
||||
<CenterMessageLock channelId={'channelId'}/>,
|
||||
exceededLimitsState,
|
||||
);
|
||||
screen.getByText('Upgrade now');
|
||||
});
|
||||
|
||||
it('End users have a call to notify admin', () => {
|
||||
renderWithIntl(
|
||||
<Provider store={testConfigureStore(endUserLimitExceeded)}>
|
||||
<CenterMessageLock channelId={'channelId'}/>
|
||||
</Provider>,
|
||||
renderWithContext(
|
||||
<CenterMessageLock channelId={'channelId'}/>,
|
||||
endUserLimitExceeded,
|
||||
);
|
||||
screen.getByText('Notify Admin');
|
||||
});
|
||||
|
||||
it('Filtered messages over one year old display year', () => {
|
||||
renderWithIntl(
|
||||
<Provider store={testConfigureStore(exceededLimitsState)}>
|
||||
<CenterMessageLock channelId={'channelId'}/>
|
||||
</Provider>,
|
||||
renderWithContext(
|
||||
<CenterMessageLock channelId={'channelId'}/>,
|
||||
exceededLimitsState,
|
||||
);
|
||||
screen.getByText('January 1, 1970', {exact: false});
|
||||
});
|
||||
@@ -145,10 +139,9 @@ describe('CenterMessageLock', () => {
|
||||
const expectedDate = firstOfMonth.toLocaleString('en', {month: 'long', day: 'numeric'});
|
||||
|
||||
state.entities.posts.posts.c.create_at = Date.parse(firstOfMonth.toUTCString());
|
||||
renderWithIntl(
|
||||
<Provider store={testConfigureStore(state)}>
|
||||
<CenterMessageLock channelId={'channelId'}/>
|
||||
</Provider>,
|
||||
renderWithContext(
|
||||
<CenterMessageLock channelId={'channelId'}/>,
|
||||
state,
|
||||
);
|
||||
screen.getByText(expectedDate, {exact: false});
|
||||
});
|
||||
@@ -158,13 +151,12 @@ describe('CenterMessageLock', () => {
|
||||
const secondOfMonth = new Date(now + (1000 * 60 * 60 * 24));
|
||||
const expectedDate = secondOfMonth.toLocaleString('en', {month: 'long', day: 'numeric'});
|
||||
|
||||
renderWithIntl(
|
||||
<Provider store={testConfigureStore(exceededLimitsStateNoAccessiblePosts)}>
|
||||
<CenterMessageLock
|
||||
channelId={'channelId'}
|
||||
firstInaccessiblePostTime={now}
|
||||
/>
|
||||
</Provider>,
|
||||
renderWithContext(
|
||||
<CenterMessageLock
|
||||
channelId={'channelId'}
|
||||
firstInaccessiblePostTime={now}
|
||||
/>,
|
||||
exceededLimitsStateNoAccessiblePosts,
|
||||
);
|
||||
screen.getByText(expectedDate, {exact: false});
|
||||
});
|
||||
|
||||
@@ -2,16 +2,17 @@
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import {Provider} from 'react-redux';
|
||||
|
||||
import type {Channel} from '@mattermost/types/channels';
|
||||
import type {DeepPartial} from '@mattermost/types/utilities';
|
||||
|
||||
import {renderWithIntl, screen} from 'tests/react_testing_utils';
|
||||
import mockStore from 'tests/test_store';
|
||||
import {renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
|
||||
import type {GlobalState} from 'types/store';
|
||||
|
||||
import AboutAreaChannel from './about_area_channel';
|
||||
|
||||
const initialState = {
|
||||
const initialState: DeepPartial<GlobalState> = {
|
||||
entities: {
|
||||
channels: {
|
||||
currentChannelId: 'current_channel_id',
|
||||
@@ -38,7 +39,7 @@ const initialState = {
|
||||
name: 'current_user_id__existingId',
|
||||
display_name: 'Default',
|
||||
delete_at: 0,
|
||||
type: '0',
|
||||
type: 'D',
|
||||
team_id: 'team_id',
|
||||
},
|
||||
},
|
||||
@@ -56,7 +57,7 @@ const initialState = {
|
||||
'team-id': {
|
||||
id: 'team_id',
|
||||
name: 'team-1',
|
||||
displayName: 'Team 1',
|
||||
display_name: 'Team 1',
|
||||
},
|
||||
},
|
||||
myMembers: {
|
||||
@@ -102,7 +103,7 @@ const initialState = {
|
||||
general: {
|
||||
license: {IsLicensed: 'false'},
|
||||
serverVersion: '5.4.0',
|
||||
config: {PostEditTimeLimit: -1},
|
||||
config: {PostEditTimeLimit: '-1'},
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -122,28 +123,23 @@ describe('channel_info_rhs/about_area_channel', () => {
|
||||
},
|
||||
};
|
||||
|
||||
test('should display channel purpose', async () => {
|
||||
const store = await mockStore(initialState);
|
||||
|
||||
renderWithIntl(
|
||||
<Provider store={store}>
|
||||
<AboutAreaChannel
|
||||
{...defaultProps}
|
||||
/>
|
||||
</Provider>,
|
||||
test('should display channel purpose', () => {
|
||||
renderWithContext(
|
||||
<AboutAreaChannel
|
||||
{...defaultProps}
|
||||
/>,
|
||||
initialState,
|
||||
);
|
||||
|
||||
expect(screen.getByText('my channel purpose')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should display channel header', async () => {
|
||||
const store = await mockStore(initialState);
|
||||
renderWithIntl(
|
||||
<Provider store={store}>
|
||||
<AboutAreaChannel
|
||||
{...defaultProps}
|
||||
/>
|
||||
</Provider>,
|
||||
test('should display channel header', () => {
|
||||
renderWithContext(
|
||||
<AboutAreaChannel
|
||||
{...defaultProps}
|
||||
/>,
|
||||
initialState,
|
||||
);
|
||||
|
||||
expect(screen.getByText('my channel header')).toBeInTheDocument();
|
||||
|
||||
@@ -2,18 +2,19 @@
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import {Provider} from 'react-redux';
|
||||
|
||||
import type {Channel} from '@mattermost/types/channels';
|
||||
import type {UserProfile} from '@mattermost/types/users';
|
||||
import type {DeepPartial} from '@mattermost/types/utilities';
|
||||
|
||||
import {renderWithIntl, screen} from 'tests/react_testing_utils';
|
||||
import mockStore from 'tests/test_store';
|
||||
import {renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
import Constants from 'utils/constants';
|
||||
|
||||
import type {GlobalState} from 'types/store';
|
||||
|
||||
import AboutAreaDM from './about_area_dm';
|
||||
|
||||
const initialState = {
|
||||
const initialState: DeepPartial<GlobalState> = {
|
||||
entities: {
|
||||
channels: {
|
||||
currentChannelId: 'current_channel_id',
|
||||
@@ -40,7 +41,7 @@ const initialState = {
|
||||
name: 'current_user_id__existingId',
|
||||
display_name: 'Default',
|
||||
delete_at: 0,
|
||||
type: '0',
|
||||
type: 'D',
|
||||
team_id: 'team_id',
|
||||
},
|
||||
},
|
||||
@@ -58,7 +59,7 @@ const initialState = {
|
||||
'team-id': {
|
||||
id: 'team_id',
|
||||
name: 'team-1',
|
||||
displayName: 'Team 1',
|
||||
display_name: 'Team 1',
|
||||
},
|
||||
},
|
||||
myMembers: {
|
||||
@@ -104,7 +105,7 @@ const initialState = {
|
||||
general: {
|
||||
license: {IsLicensed: 'false'},
|
||||
serverVersion: '5.4.0',
|
||||
config: {PostEditTimeLimit: -1},
|
||||
config: {PostEditTimeLimit: '-1'},
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -133,50 +134,40 @@ describe('channel_info_rhs/about_area_dm', () => {
|
||||
},
|
||||
};
|
||||
|
||||
test('should display user avatar', async () => {
|
||||
const store = await mockStore(initialState);
|
||||
|
||||
renderWithIntl(
|
||||
<Provider store={store}>
|
||||
<AboutAreaDM
|
||||
{...defaultProps}
|
||||
/>
|
||||
</Provider>,
|
||||
test('should display user avatar', () => {
|
||||
renderWithContext(
|
||||
<AboutAreaDM
|
||||
{...defaultProps}
|
||||
/>,
|
||||
initialState,
|
||||
);
|
||||
|
||||
expect(screen.getByAltText('my_username profile image')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should display user name', async () => {
|
||||
const store = await mockStore(initialState);
|
||||
|
||||
renderWithIntl(
|
||||
<Provider store={store}>
|
||||
<AboutAreaDM
|
||||
{...defaultProps}
|
||||
/>
|
||||
</Provider>,
|
||||
test('should display user name', () => {
|
||||
renderWithContext(
|
||||
<AboutAreaDM
|
||||
{...defaultProps}
|
||||
/>,
|
||||
initialState,
|
||||
);
|
||||
|
||||
expect(screen.getByText('my_username')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should display user position', async () => {
|
||||
const store = await mockStore(initialState);
|
||||
|
||||
renderWithIntl(
|
||||
<Provider store={store}>
|
||||
<AboutAreaDM
|
||||
{...defaultProps}
|
||||
/>
|
||||
</Provider>,
|
||||
test('should display user position', () => {
|
||||
renderWithContext(
|
||||
<AboutAreaDM
|
||||
{...defaultProps}
|
||||
/>,
|
||||
initialState,
|
||||
);
|
||||
|
||||
expect(screen.getByText('my position')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should display bot tag', async () => {
|
||||
const store = await mockStore(initialState);
|
||||
test('should display bot tag', () => {
|
||||
const props = {
|
||||
...defaultProps,
|
||||
dmUser: {
|
||||
@@ -187,19 +178,17 @@ describe('channel_info_rhs/about_area_dm', () => {
|
||||
},
|
||||
},
|
||||
};
|
||||
const {container} = renderWithIntl(
|
||||
<Provider store={store}>
|
||||
<AboutAreaDM
|
||||
{...props}
|
||||
/>
|
||||
</Provider>,
|
||||
const {container} = renderWithContext(
|
||||
<AboutAreaDM
|
||||
{...props}
|
||||
/>,
|
||||
initialState,
|
||||
);
|
||||
expect(container.querySelector('.Tag')).toBeInTheDocument();
|
||||
expect(container.querySelector('.Tag')).toHaveTextContent('BOT');
|
||||
});
|
||||
|
||||
test('should display guest tag', async () => {
|
||||
const store = await mockStore(initialState);
|
||||
test('should display guest tag', () => {
|
||||
const props = {
|
||||
...defaultProps,
|
||||
dmUser: {
|
||||
@@ -207,19 +196,17 @@ describe('channel_info_rhs/about_area_dm', () => {
|
||||
is_guest: true,
|
||||
},
|
||||
};
|
||||
const {container} = renderWithIntl(
|
||||
<Provider store={store}>
|
||||
<AboutAreaDM
|
||||
{...props}
|
||||
/>
|
||||
</Provider>,
|
||||
const {container} = renderWithContext(
|
||||
<AboutAreaDM
|
||||
{...props}
|
||||
/>,
|
||||
initialState,
|
||||
);
|
||||
expect(container.querySelector('.Tag')).toBeInTheDocument();
|
||||
expect(container.querySelector('.Tag')).toHaveTextContent('GUEST');
|
||||
});
|
||||
|
||||
test('should display bot description', async () => {
|
||||
const store = await mockStore(initialState);
|
||||
test('should display bot description', () => {
|
||||
const props = {
|
||||
...defaultProps,
|
||||
dmUser: {
|
||||
@@ -230,32 +217,28 @@ describe('channel_info_rhs/about_area_dm', () => {
|
||||
},
|
||||
},
|
||||
};
|
||||
renderWithIntl(
|
||||
<Provider store={store}>
|
||||
<AboutAreaDM
|
||||
{...props}
|
||||
/>
|
||||
</Provider>,
|
||||
renderWithContext(
|
||||
<AboutAreaDM
|
||||
{...props}
|
||||
/>,
|
||||
initialState,
|
||||
);
|
||||
|
||||
expect(screen.getByText('my bot description')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should display channel header', async () => {
|
||||
const store = await mockStore(initialState);
|
||||
renderWithIntl(
|
||||
<Provider store={store}>
|
||||
<AboutAreaDM
|
||||
{...defaultProps}
|
||||
/>
|
||||
</Provider>,
|
||||
test('should display channel header', () => {
|
||||
renderWithContext(
|
||||
<AboutAreaDM
|
||||
{...defaultProps}
|
||||
/>,
|
||||
initialState,
|
||||
);
|
||||
|
||||
expect(screen.getByText('my channel header')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should not display channel header for bots', async () => {
|
||||
const store = await mockStore(initialState);
|
||||
test('should not display channel header for bots', () => {
|
||||
const props = {
|
||||
...defaultProps,
|
||||
dmUser: {
|
||||
@@ -266,12 +249,11 @@ describe('channel_info_rhs/about_area_dm', () => {
|
||||
},
|
||||
},
|
||||
};
|
||||
renderWithIntl(
|
||||
<Provider store={store}>
|
||||
<AboutAreaDM
|
||||
{...props}
|
||||
/>
|
||||
</Provider>,
|
||||
renderWithContext(
|
||||
<AboutAreaDM
|
||||
{...props}
|
||||
/>,
|
||||
initialState,
|
||||
);
|
||||
|
||||
expect(screen.queryByText('my channel header')).not.toBeInTheDocument();
|
||||
|
||||
@@ -2,17 +2,18 @@
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import {Provider} from 'react-redux';
|
||||
|
||||
import type {Channel} from '@mattermost/types/channels';
|
||||
import type {UserProfile} from '@mattermost/types/users';
|
||||
import type {DeepPartial} from '@mattermost/types/utilities';
|
||||
|
||||
import {renderWithIntl, screen} from 'tests/react_testing_utils';
|
||||
import mockStore from 'tests/test_store';
|
||||
import {renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
|
||||
import type {GlobalState} from 'types/store';
|
||||
|
||||
import AboutAreaGM from './about_area_gm';
|
||||
|
||||
const initialState = {
|
||||
const initialState: DeepPartial<GlobalState> = {
|
||||
entities: {
|
||||
channels: {
|
||||
currentChannelId: 'current_channel_id',
|
||||
@@ -39,7 +40,7 @@ const initialState = {
|
||||
name: 'current_user_id__existingId',
|
||||
display_name: 'Default',
|
||||
delete_at: 0,
|
||||
type: '0',
|
||||
type: 'D',
|
||||
team_id: 'team_id',
|
||||
},
|
||||
},
|
||||
@@ -57,7 +58,7 @@ const initialState = {
|
||||
'team-id': {
|
||||
id: 'team_id',
|
||||
name: 'team-1',
|
||||
displayName: 'Team 1',
|
||||
display_name: 'Team 1',
|
||||
},
|
||||
},
|
||||
myMembers: {
|
||||
@@ -105,7 +106,7 @@ const initialState = {
|
||||
general: {
|
||||
license: {IsLicensed: 'false'},
|
||||
serverVersion: '5.4.0',
|
||||
config: {PostEditTimeLimit: -1},
|
||||
config: {PostEditTimeLimit: '-1'},
|
||||
},
|
||||
},
|
||||
views: {
|
||||
@@ -138,43 +139,35 @@ describe('channel_info_rhs/about_area_gm', () => {
|
||||
},
|
||||
};
|
||||
|
||||
test('should display users avatar', async () => {
|
||||
const store = await mockStore(initialState);
|
||||
|
||||
renderWithIntl(
|
||||
<Provider store={store}>
|
||||
<AboutAreaGM
|
||||
{...defaultProps}
|
||||
/>
|
||||
</Provider>,
|
||||
test('should display users avatar', () => {
|
||||
renderWithContext(
|
||||
<AboutAreaGM
|
||||
{...defaultProps}
|
||||
/>,
|
||||
initialState,
|
||||
);
|
||||
|
||||
expect(screen.getByAltText('my username profile image')).toBeInTheDocument();
|
||||
expect(screen.getByAltText('my username2 profile image')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should display user names', async () => {
|
||||
const store = await mockStore(initialState);
|
||||
|
||||
renderWithIntl(
|
||||
<Provider store={store}>
|
||||
<AboutAreaGM
|
||||
{...defaultProps}
|
||||
/>
|
||||
</Provider>,
|
||||
test('should display user names', () => {
|
||||
renderWithContext(
|
||||
<AboutAreaGM
|
||||
{...defaultProps}
|
||||
/>,
|
||||
initialState,
|
||||
);
|
||||
|
||||
expect(screen.getByLabelText('my username')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should display channel header', async () => {
|
||||
const store = await mockStore(initialState);
|
||||
renderWithIntl(
|
||||
<Provider store={store}>
|
||||
<AboutAreaGM
|
||||
{...defaultProps}
|
||||
/>
|
||||
</Provider>,
|
||||
test('should display channel header', () => {
|
||||
renderWithContext(
|
||||
<AboutAreaGM
|
||||
{...defaultProps}
|
||||
/>,
|
||||
initialState,
|
||||
);
|
||||
|
||||
expect(screen.getByText('my channel header')).toBeInTheDocument();
|
||||
|
||||
@@ -7,7 +7,7 @@ import type {Channel, ChannelStats} from '@mattermost/types/channels';
|
||||
import type {Team} from '@mattermost/types/teams';
|
||||
import type {UserProfile} from '@mattermost/types/users';
|
||||
|
||||
import {act, renderWithIntl} from 'tests/react_testing_utils';
|
||||
import {act, renderWithContext} from 'tests/react_testing_utils';
|
||||
|
||||
import ChannelInfoRHS from './channel_info_rhs';
|
||||
|
||||
@@ -52,7 +52,7 @@ describe('channel_info_rhs', () => {
|
||||
|
||||
describe('about area', () => {
|
||||
test('should be editable', async () => {
|
||||
renderWithIntl(
|
||||
renderWithContext(
|
||||
<ChannelInfoRHS
|
||||
{...props}
|
||||
/>,
|
||||
@@ -71,7 +71,7 @@ describe('channel_info_rhs', () => {
|
||||
test('should not be editable in archived channel', async () => {
|
||||
props.isArchived = true;
|
||||
|
||||
renderWithIntl(
|
||||
renderWithContext(
|
||||
<ChannelInfoRHS
|
||||
{...props}
|
||||
/>,
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import {fireEvent, renderWithIntl, screen} from 'tests/react_testing_utils';
|
||||
import {fireEvent, renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
|
||||
import EditableArea from './editable_area';
|
||||
|
||||
describe('channel_info_rhs/components/editable_area', () => {
|
||||
test('should be able to see content', async () => {
|
||||
renderWithIntl(
|
||||
renderWithContext(
|
||||
<EditableArea
|
||||
content='test content'
|
||||
editable={true}
|
||||
@@ -23,7 +23,7 @@ describe('channel_info_rhs/components/editable_area', () => {
|
||||
|
||||
test('should be able to edit content', async () => {
|
||||
const mockOnEdit = jest.fn();
|
||||
renderWithIntl(
|
||||
renderWithContext(
|
||||
<EditableArea
|
||||
content='test content'
|
||||
editable={true}
|
||||
@@ -38,7 +38,7 @@ describe('channel_info_rhs/components/editable_area', () => {
|
||||
});
|
||||
|
||||
test('should be able prevent edition', async () => {
|
||||
renderWithIntl(
|
||||
renderWithContext(
|
||||
<EditableArea
|
||||
content='test content'
|
||||
editable={false}
|
||||
@@ -52,7 +52,7 @@ describe('channel_info_rhs/components/editable_area', () => {
|
||||
|
||||
test('should show the empty label when there\'s no content', async () => {
|
||||
const mockOnEdit = jest.fn();
|
||||
renderWithIntl(
|
||||
renderWithContext(
|
||||
<EditableArea
|
||||
content=''
|
||||
editable={true}
|
||||
|
||||
@@ -5,13 +5,13 @@ import React from 'react';
|
||||
|
||||
import type {Channel} from '@mattermost/types/channels';
|
||||
|
||||
import {fireEvent, renderWithIntl, screen} from 'tests/react_testing_utils';
|
||||
import {fireEvent, renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
|
||||
import Header from './header';
|
||||
|
||||
describe('channel_info_rhs/header', () => {
|
||||
test('should the current channel name', () => {
|
||||
renderWithIntl(
|
||||
renderWithContext(
|
||||
<Header
|
||||
channel={{display_name: 'my channel title'} as Channel}
|
||||
isMobile={false}
|
||||
@@ -25,7 +25,7 @@ describe('channel_info_rhs/header', () => {
|
||||
test('should call onClose when clicking on the close icon', () => {
|
||||
const onClose = jest.fn();
|
||||
|
||||
renderWithIntl(
|
||||
renderWithContext(
|
||||
<Header
|
||||
channel={{display_name: 'my channel title'} as Channel}
|
||||
isMobile={false}
|
||||
@@ -41,7 +41,7 @@ describe('channel_info_rhs/header', () => {
|
||||
test('should call onClose when clicking on the back icon', () => {
|
||||
const onClose = jest.fn();
|
||||
|
||||
renderWithIntl(
|
||||
renderWithContext(
|
||||
<Header
|
||||
channel={{display_name: 'my channel title'} as Channel}
|
||||
isMobile={true}
|
||||
@@ -55,7 +55,7 @@ describe('channel_info_rhs/header', () => {
|
||||
expect(onClose).toHaveBeenCalled();
|
||||
});
|
||||
test('should have archived icon when channel is archived', () => {
|
||||
const {container} = renderWithIntl(
|
||||
const {container} = renderWithContext(
|
||||
<Header
|
||||
channel={{display_name: 'my channel title'} as Channel}
|
||||
isMobile={false}
|
||||
@@ -67,7 +67,7 @@ describe('channel_info_rhs/header', () => {
|
||||
expect(container.querySelector('i.icon-archive-outline')).toBeInTheDocument();
|
||||
});
|
||||
test('should not have archived icon when channel is archived', () => {
|
||||
const {container} = renderWithIntl(
|
||||
const {container} = renderWithContext(
|
||||
<Header
|
||||
channel={{display_name: 'my channel title'} as Channel}
|
||||
isMobile={false}
|
||||
|
||||
@@ -8,7 +8,7 @@ import type {Channel, ChannelStats} from '@mattermost/types/channels';
|
||||
import {
|
||||
act,
|
||||
fireEvent,
|
||||
renderWithIntl,
|
||||
renderWithContext,
|
||||
screen,
|
||||
} from 'tests/react_testing_utils';
|
||||
import Constants from 'utils/constants';
|
||||
@@ -43,7 +43,7 @@ describe('channel_info_rhs/menu', () => {
|
||||
const props = {...defaultProps};
|
||||
props.actions.openNotificationSettings = jest.fn();
|
||||
|
||||
renderWithIntl(
|
||||
renderWithContext(
|
||||
<Menu
|
||||
{...props}
|
||||
/>,
|
||||
@@ -65,7 +65,7 @@ describe('channel_info_rhs/menu', () => {
|
||||
channel: {type: Constants.DM_CHANNEL} as Channel,
|
||||
};
|
||||
|
||||
renderWithIntl(
|
||||
renderWithContext(
|
||||
<Menu
|
||||
{...props}
|
||||
/>,
|
||||
@@ -84,7 +84,7 @@ describe('channel_info_rhs/menu', () => {
|
||||
isArchived: true,
|
||||
};
|
||||
|
||||
renderWithIntl(
|
||||
renderWithContext(
|
||||
<Menu
|
||||
{...props}
|
||||
/>,
|
||||
@@ -101,7 +101,7 @@ describe('channel_info_rhs/menu', () => {
|
||||
const props = {...defaultProps};
|
||||
props.actions.showChannelFiles = jest.fn();
|
||||
|
||||
renderWithIntl(
|
||||
renderWithContext(
|
||||
<Menu
|
||||
{...props}
|
||||
/>,
|
||||
@@ -123,7 +123,7 @@ describe('channel_info_rhs/menu', () => {
|
||||
const props = {...defaultProps};
|
||||
props.actions.showPinnedPosts = jest.fn();
|
||||
|
||||
renderWithIntl(
|
||||
renderWithContext(
|
||||
<Menu
|
||||
{...props}
|
||||
/>,
|
||||
@@ -145,7 +145,7 @@ describe('channel_info_rhs/menu', () => {
|
||||
const props = {...defaultProps};
|
||||
props.actions.showChannelMembers = jest.fn();
|
||||
|
||||
renderWithIntl(
|
||||
renderWithContext(
|
||||
<Menu
|
||||
{...props}
|
||||
/>,
|
||||
@@ -169,7 +169,7 @@ describe('channel_info_rhs/menu', () => {
|
||||
channel: {type: Constants.DM_CHANNEL} as Channel,
|
||||
};
|
||||
|
||||
renderWithIntl(
|
||||
renderWithContext(
|
||||
<Menu
|
||||
{...props}
|
||||
/>,
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import {fireEvent, renderWithIntl, screen} from 'tests/react_testing_utils';
|
||||
import {fireEvent, renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
import Constants from 'utils/constants';
|
||||
|
||||
import TopButtons from './top_buttons';
|
||||
@@ -47,7 +47,7 @@ describe('channel_info_rhs/top_buttons', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderWithIntl(
|
||||
renderWithContext(
|
||||
<TopButtons
|
||||
{...testProps}
|
||||
/>,
|
||||
@@ -60,7 +60,7 @@ describe('channel_info_rhs/top_buttons', () => {
|
||||
// Favorited to Favorite
|
||||
toggleFavorite.mockReset();
|
||||
testProps.isFavorite = true;
|
||||
renderWithIntl(
|
||||
renderWithContext(
|
||||
<TopButtons
|
||||
{...testProps}
|
||||
/>,
|
||||
@@ -83,7 +83,7 @@ describe('channel_info_rhs/top_buttons', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderWithIntl(
|
||||
renderWithContext(
|
||||
<TopButtons
|
||||
{...testProps}
|
||||
/>,
|
||||
@@ -96,7 +96,7 @@ describe('channel_info_rhs/top_buttons', () => {
|
||||
// Muted to Mute
|
||||
toggleMute.mockReset();
|
||||
testProps.isMuted = true;
|
||||
renderWithIntl(
|
||||
renderWithContext(
|
||||
<TopButtons
|
||||
{...testProps}
|
||||
/>,
|
||||
@@ -118,7 +118,7 @@ describe('channel_info_rhs/top_buttons', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderWithIntl(
|
||||
renderWithContext(
|
||||
<TopButtons
|
||||
{...testProps}
|
||||
/>,
|
||||
@@ -134,7 +134,7 @@ describe('channel_info_rhs/top_buttons', () => {
|
||||
channelType: Constants.DM_CHANNEL,
|
||||
};
|
||||
|
||||
renderWithIntl(
|
||||
renderWithContext(
|
||||
<TopButtons
|
||||
{...testProps}
|
||||
/>,
|
||||
@@ -149,7 +149,7 @@ describe('channel_info_rhs/top_buttons', () => {
|
||||
canAddPeople: false,
|
||||
};
|
||||
|
||||
renderWithIntl(
|
||||
renderWithContext(
|
||||
<TopButtons
|
||||
{...testProps}
|
||||
/>,
|
||||
@@ -159,7 +159,7 @@ describe('channel_info_rhs/top_buttons', () => {
|
||||
});
|
||||
|
||||
test('can copy link', () => {
|
||||
renderWithIntl(
|
||||
renderWithContext(
|
||||
<TopButtons
|
||||
{...topButtonDefaultProps}
|
||||
/>,
|
||||
@@ -179,7 +179,7 @@ describe('channel_info_rhs/top_buttons', () => {
|
||||
...topButtonDefaultProps,
|
||||
channelType,
|
||||
};
|
||||
renderWithIntl(
|
||||
renderWithContext(
|
||||
<TopButtons
|
||||
{...localProps}
|
||||
/>,
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import {fireEvent, renderWithIntl, screen} from 'tests/react_testing_utils';
|
||||
import {fireEvent, renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
import Constants from 'utils/constants';
|
||||
|
||||
import ActionBar from './action_bar';
|
||||
@@ -33,7 +33,7 @@ describe('channel_members_rhs/action_bar', () => {
|
||||
test('should display the members count', () => {
|
||||
const testProps: Props = {...actionBarDefaultProps};
|
||||
|
||||
renderWithIntl(
|
||||
renderWithContext(
|
||||
<ActionBar
|
||||
{...testProps}
|
||||
/>,
|
||||
@@ -45,7 +45,7 @@ describe('channel_members_rhs/action_bar', () => {
|
||||
test('should display Add button', () => {
|
||||
const testProps: Props = {...actionBarDefaultProps};
|
||||
|
||||
renderWithIntl(
|
||||
renderWithContext(
|
||||
<ActionBar
|
||||
{...testProps}
|
||||
/>,
|
||||
@@ -59,7 +59,7 @@ describe('channel_members_rhs/action_bar', () => {
|
||||
test('should not display Add button to members', () => {
|
||||
const testProps: Props = {...actionBarDefaultProps, canManageMembers: false};
|
||||
|
||||
renderWithIntl(
|
||||
renderWithContext(
|
||||
<ActionBar
|
||||
{...testProps}
|
||||
/>,
|
||||
@@ -71,7 +71,7 @@ describe('channel_members_rhs/action_bar', () => {
|
||||
test('should display Manage', () => {
|
||||
const testProps: Props = {...actionBarDefaultProps};
|
||||
|
||||
renderWithIntl(
|
||||
renderWithContext(
|
||||
<ActionBar
|
||||
{...testProps}
|
||||
/>,
|
||||
@@ -88,7 +88,7 @@ describe('channel_members_rhs/action_bar', () => {
|
||||
editing: true,
|
||||
};
|
||||
|
||||
renderWithIntl(
|
||||
renderWithContext(
|
||||
<ActionBar
|
||||
{...testProps}
|
||||
/>,
|
||||
@@ -102,7 +102,7 @@ describe('channel_members_rhs/action_bar', () => {
|
||||
test('should not display manage button to members', () => {
|
||||
const testProps: Props = {...actionBarDefaultProps, canManageMembers: false};
|
||||
|
||||
renderWithIntl(
|
||||
renderWithContext(
|
||||
<ActionBar
|
||||
{...testProps}
|
||||
/>,
|
||||
|
||||
@@ -3,13 +3,12 @@
|
||||
|
||||
import React from 'react';
|
||||
import * as redux from 'react-redux';
|
||||
import {Provider} from 'react-redux';
|
||||
|
||||
import type {Subscription} from '@mattermost/types/cloud';
|
||||
import type {GlobalState} from '@mattermost/types/store';
|
||||
import type {DeepPartial} from '@mattermost/types/utilities';
|
||||
|
||||
import {renderWithIntl, screen} from 'tests/react_testing_utils';
|
||||
import mockStore from 'tests/test_store';
|
||||
import {renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
import {Constants} from 'utils/constants';
|
||||
import {FileSizes} from 'utils/file_utils';
|
||||
|
||||
@@ -29,8 +28,8 @@ const freeLimits = {
|
||||
},
|
||||
};
|
||||
|
||||
function setupStore(hasLimits: boolean) {
|
||||
const state = {
|
||||
function setupState(hasLimits: boolean) {
|
||||
const state: DeepPartial<GlobalState> = {
|
||||
entities: {
|
||||
cloud: {
|
||||
limits: {
|
||||
@@ -77,10 +76,9 @@ function setupStore(hasLimits: boolean) {
|
||||
},
|
||||
} as unknown as GlobalState['entities']['users'],
|
||||
},
|
||||
} as GlobalState;
|
||||
const store = mockStore(state);
|
||||
};
|
||||
|
||||
return store;
|
||||
return state;
|
||||
}
|
||||
|
||||
let props: Props = {
|
||||
@@ -98,36 +96,34 @@ describe('CloudUsageModal', () => {
|
||||
});
|
||||
|
||||
test('renders text elements', () => {
|
||||
const store = setupStore(true);
|
||||
const state = setupState(true);
|
||||
|
||||
props.title = 'very important title';
|
||||
props.description = 'very important description';
|
||||
|
||||
renderWithIntl(
|
||||
<Provider store={store}>
|
||||
<CloudUsageModal
|
||||
{...props}
|
||||
/>
|
||||
</Provider>,
|
||||
renderWithContext(
|
||||
<CloudUsageModal
|
||||
{...props}
|
||||
/>,
|
||||
state,
|
||||
);
|
||||
screen.getByText(props.title as string);
|
||||
screen.getByText(props.description as string);
|
||||
});
|
||||
|
||||
test('renders primary modal action', () => {
|
||||
const store = setupStore(true);
|
||||
const state = setupState(true);
|
||||
|
||||
props.primaryAction = {
|
||||
message: 'primary action',
|
||||
onClick: jest.fn(),
|
||||
};
|
||||
|
||||
renderWithIntl(
|
||||
<Provider store={store}>
|
||||
<CloudUsageModal
|
||||
{...props}
|
||||
/>
|
||||
</Provider>,
|
||||
renderWithContext(
|
||||
<CloudUsageModal
|
||||
{...props}
|
||||
/>,
|
||||
state,
|
||||
);
|
||||
expect(props.primaryAction.onClick).not.toHaveBeenCalled();
|
||||
screen.getByText(props.primaryAction.message as string).click();
|
||||
@@ -135,18 +131,17 @@ describe('CloudUsageModal', () => {
|
||||
});
|
||||
|
||||
test('renders secondary modal action', () => {
|
||||
const store = setupStore(true);
|
||||
const state = setupState(true);
|
||||
|
||||
props.secondaryAction = {
|
||||
message: 'secondary action',
|
||||
};
|
||||
|
||||
renderWithIntl(
|
||||
<Provider store={store}>
|
||||
<CloudUsageModal
|
||||
{...props}
|
||||
/>
|
||||
</Provider>,
|
||||
renderWithContext(
|
||||
<CloudUsageModal
|
||||
{...props}
|
||||
/>,
|
||||
state,
|
||||
);
|
||||
expect(props.onClose).not.toHaveBeenCalled();
|
||||
screen.getByText(props.secondaryAction.message as string).click();
|
||||
@@ -154,14 +149,13 @@ describe('CloudUsageModal', () => {
|
||||
});
|
||||
|
||||
test('hides footer when there are no actions', () => {
|
||||
const store = setupStore(true);
|
||||
const state = setupState(true);
|
||||
|
||||
renderWithIntl(
|
||||
<Provider store={store}>
|
||||
<CloudUsageModal
|
||||
{...props}
|
||||
/>
|
||||
</Provider>,
|
||||
renderWithContext(
|
||||
<CloudUsageModal
|
||||
{...props}
|
||||
/>,
|
||||
state,
|
||||
);
|
||||
expect(screen.queryByTestId('limits-modal-footer')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -3,15 +3,12 @@
|
||||
|
||||
import React from 'react';
|
||||
import type {ReactPortal} from 'react';
|
||||
import {Provider} from 'react-redux';
|
||||
|
||||
import configureStore from 'store';
|
||||
|
||||
import * as useGetLimitsHook from 'components/common/hooks/useGetLimits';
|
||||
import * as useGetUsageHook from 'components/common/hooks/useGetUsage';
|
||||
import ModalController from 'components/modal_controller';
|
||||
|
||||
import {renderWithIntl, screen} from 'tests/react_testing_utils';
|
||||
import {renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
import {Preferences} from 'utils/constants';
|
||||
import {TestHelper} from 'utils/test_helper';
|
||||
|
||||
@@ -102,13 +99,13 @@ jest.mock('react-dom', () => ({
|
||||
describe('useShowAdminLimitReached', () => {
|
||||
it('opens cloud usage modal if admin has just logged in on a cloud instance, the instance has exceeded its message history limit, and the admin has not been shown the modal on log in before.', () => {
|
||||
const state = JSON.parse(JSON.stringify(openModalState));
|
||||
const store = configureStore(state);
|
||||
renderWithIntl(
|
||||
<Provider store={store}>
|
||||
renderWithContext(
|
||||
<>
|
||||
<div id='root-portal'/>
|
||||
<ModalController/>
|
||||
<TestComponent/>
|
||||
</Provider>,
|
||||
</>,
|
||||
state,
|
||||
);
|
||||
screen.getByText(modalRegex);
|
||||
});
|
||||
@@ -125,13 +122,13 @@ describe('useShowAdminLimitReached', () => {
|
||||
],
|
||||
'admin',
|
||||
);
|
||||
const store = configureStore(state);
|
||||
renderWithIntl(
|
||||
<Provider store={store}>
|
||||
renderWithContext(
|
||||
<>
|
||||
<div id='root-portal'/>
|
||||
<ModalController/>
|
||||
<TestComponent/>
|
||||
</Provider>,
|
||||
</>,
|
||||
state,
|
||||
);
|
||||
expect(screen.queryByText(modalRegex)).not.toBeInTheDocument();
|
||||
});
|
||||
@@ -139,13 +136,13 @@ describe('useShowAdminLimitReached', () => {
|
||||
it('does not open cloud usage modal if workspace has not exceeded limit', () => {
|
||||
const state = JSON.parse(JSON.stringify(openModalState));
|
||||
state.entities.usage.messages.history = 10000;
|
||||
const store = configureStore(state);
|
||||
renderWithIntl(
|
||||
<Provider store={store}>
|
||||
renderWithContext(
|
||||
<>
|
||||
<div id='root-portal'/>
|
||||
<ModalController/>
|
||||
<TestComponent/>
|
||||
</Provider>,
|
||||
</>,
|
||||
state,
|
||||
);
|
||||
expect(screen.queryByText(modalRegex)).not.toBeInTheDocument();
|
||||
});
|
||||
@@ -153,13 +150,13 @@ describe('useShowAdminLimitReached', () => {
|
||||
it('does not open cloud usage modal if there is no message limit', () => {
|
||||
const state = JSON.parse(JSON.stringify(openModalState));
|
||||
state.entities.cloud.limits = {};
|
||||
const store = configureStore(state);
|
||||
renderWithIntl(
|
||||
<Provider store={store}>
|
||||
renderWithContext(
|
||||
<>
|
||||
<div id='root-portal'/>
|
||||
<ModalController/>
|
||||
<TestComponent/>
|
||||
</Provider>,
|
||||
</>,
|
||||
state,
|
||||
);
|
||||
expect(screen.queryByText(modalRegex)).not.toBeInTheDocument();
|
||||
});
|
||||
@@ -167,13 +164,13 @@ describe('useShowAdminLimitReached', () => {
|
||||
it('does not open cloud usage modal if there is no message limit', () => {
|
||||
const state = JSON.parse(JSON.stringify(openModalState));
|
||||
state.entities.cloud.limits = {};
|
||||
const store = configureStore(state);
|
||||
renderWithIntl(
|
||||
<Provider store={store}>
|
||||
renderWithContext(
|
||||
<>
|
||||
<div id='root-portal'/>
|
||||
<ModalController/>
|
||||
<TestComponent/>
|
||||
</Provider>,
|
||||
</>,
|
||||
state,
|
||||
);
|
||||
expect(screen.queryByText(modalRegex)).not.toBeInTheDocument();
|
||||
});
|
||||
@@ -181,13 +178,13 @@ describe('useShowAdminLimitReached', () => {
|
||||
it('does not open cloud usage modal if admin was already logged in', () => {
|
||||
const state = JSON.parse(JSON.stringify(openModalState));
|
||||
state.views.admin.needsLoggedInLimitReachedCheck = false;
|
||||
const store = configureStore(state);
|
||||
renderWithIntl(
|
||||
<Provider store={store}>
|
||||
renderWithContext(
|
||||
<>
|
||||
<div id='root-portal'/>
|
||||
<ModalController/>
|
||||
<TestComponent/>
|
||||
</Provider>,
|
||||
</>,
|
||||
state,
|
||||
);
|
||||
expect(screen.queryByText(modalRegex)).not.toBeInTheDocument();
|
||||
});
|
||||
@@ -195,17 +192,17 @@ describe('useShowAdminLimitReached', () => {
|
||||
it('does not open cloud usage modal if limits are not yet loaded', () => {
|
||||
const state = JSON.parse(JSON.stringify(openModalState));
|
||||
state.entities.cloud.limits.limitsLoaded = false;
|
||||
const store = configureStore(state);
|
||||
jest.spyOn(useGetLimitsHook, 'default').mockImplementation(() => ([
|
||||
state.entities.cloud.limits.limits,
|
||||
false,
|
||||
]));
|
||||
renderWithIntl(
|
||||
<Provider store={store}>
|
||||
renderWithContext(
|
||||
<>
|
||||
<div id='root-portal'/>
|
||||
<ModalController/>
|
||||
<TestComponent/>
|
||||
</Provider>,
|
||||
</>,
|
||||
state,
|
||||
);
|
||||
expect(screen.queryByText(modalRegex)).not.toBeInTheDocument();
|
||||
});
|
||||
@@ -216,14 +213,14 @@ describe('useShowAdminLimitReached', () => {
|
||||
history: 0,
|
||||
historyLoaded: false,
|
||||
};
|
||||
const store = configureStore(state);
|
||||
jest.spyOn(useGetUsageHook, 'default').mockImplementation(() => state.entities.usage);
|
||||
renderWithIntl(
|
||||
<Provider store={store}>
|
||||
renderWithContext(
|
||||
<>
|
||||
<div id='root-portal'/>
|
||||
<ModalController/>
|
||||
<TestComponent/>
|
||||
</Provider>,
|
||||
</>,
|
||||
state,
|
||||
);
|
||||
expect(screen.queryByText(modalRegex)).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -17,7 +17,7 @@ import {Preferences} from 'mattermost-redux/constants';
|
||||
import ConvertGmToChannelModal from 'components/convert_gm_to_channel_modal/convert_gm_to_channel_modal';
|
||||
|
||||
import TestHelper from 'packages/mattermost-redux/test/test_helper';
|
||||
import {renderWithFullContext, screen} from 'tests/react_testing_utils';
|
||||
import {renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
|
||||
import type {GlobalState} from 'types/store';
|
||||
|
||||
@@ -61,7 +61,7 @@ describe('component/ConvertGmToChannelModal', () => {
|
||||
{id: 'team_id_2', display_name: 'Team 2', name: 'team_2'},
|
||||
]);
|
||||
|
||||
renderWithFullContext(
|
||||
renderWithContext(
|
||||
<ConvertGmToChannelModal {...baseProps}/>,
|
||||
baseState,
|
||||
);
|
||||
@@ -87,7 +87,7 @@ describe('component/ConvertGmToChannelModal', () => {
|
||||
{id: 'team_id_1', display_name: 'Team 1', name: 'team_1'},
|
||||
]);
|
||||
|
||||
renderWithFullContext(
|
||||
renderWithContext(
|
||||
<ConvertGmToChannelModal {...baseProps}/>,
|
||||
baseState,
|
||||
);
|
||||
@@ -110,7 +110,7 @@ describe('component/ConvertGmToChannelModal', () => {
|
||||
get('/channels/channel_id_1/common_teams').
|
||||
reply(200, []);
|
||||
|
||||
renderWithFullContext(
|
||||
renderWithContext(
|
||||
<ConvertGmToChannelModal {...baseProps}/>,
|
||||
baseState,
|
||||
);
|
||||
@@ -138,7 +138,7 @@ describe('component/ConvertGmToChannelModal', () => {
|
||||
|
||||
baseProps.actions.convertGroupMessageToPrivateChannel.mockResolvedValueOnce({});
|
||||
|
||||
renderWithFullContext(
|
||||
renderWithContext(
|
||||
<ConvertGmToChannelModal {...baseProps}/>,
|
||||
baseState,
|
||||
);
|
||||
@@ -191,7 +191,7 @@ describe('component/ConvertGmToChannelModal', () => {
|
||||
},
|
||||
});
|
||||
|
||||
renderWithFullContext(
|
||||
renderWithContext(
|
||||
<ConvertGmToChannelModal {...baseProps}/>,
|
||||
baseState,
|
||||
);
|
||||
|
||||
@@ -3,22 +3,15 @@
|
||||
|
||||
import React from 'react';
|
||||
import type {ComponentProps} from 'react';
|
||||
import * as reactRedux from 'react-redux';
|
||||
|
||||
import {savePreferences} from 'mattermost-redux/actions/preferences';
|
||||
|
||||
import {trackEvent} from 'actions/telemetry_actions';
|
||||
import configureStore from 'store';
|
||||
|
||||
import {fireEvent, renderWithIntl, screen} from 'tests/react_testing_utils';
|
||||
import {fireEvent, renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
import {ModalIdentifiers, Preferences, TELEMETRY_CATEGORIES} from 'utils/constants';
|
||||
|
||||
import DeliquencyModal from './delinquency_modal';
|
||||
|
||||
type RenderComponentArgs = {
|
||||
props?: Partial<ComponentProps<typeof DeliquencyModal>>;
|
||||
store?: any;
|
||||
}
|
||||
import DelinquencyModal from './delinquency_modal';
|
||||
|
||||
jest.mock('mattermost-redux/actions/preferences', () => ({
|
||||
savePreferences: jest.fn(),
|
||||
@@ -38,7 +31,7 @@ jest.mock('react-redux', () => ({
|
||||
}));
|
||||
|
||||
describe('components/deliquency_modal/deliquency_modal', () => {
|
||||
const initialStates = {
|
||||
const initialState = {
|
||||
views: {
|
||||
modals: {
|
||||
modalState: {
|
||||
@@ -50,7 +43,7 @@ describe('components/deliquency_modal/deliquency_modal', () => {
|
||||
closeModal: () => {},
|
||||
isAdminConsole: false,
|
||||
},
|
||||
dialogType: React.Fragment,
|
||||
dialogType: React.Fragment as any,
|
||||
},
|
||||
},
|
||||
showLaunchingWorkspace: false,
|
||||
@@ -66,38 +59,23 @@ describe('components/deliquency_modal/deliquency_modal', () => {
|
||||
},
|
||||
};
|
||||
|
||||
const renderComponent = ({props = {}, store = configureStore(initialStates)}: RenderComponentArgs) => {
|
||||
const defaultProps: ComponentProps<typeof DeliquencyModal> = {
|
||||
closeModal: jest.fn(),
|
||||
onExited: jest.fn(),
|
||||
planName: 'planName',
|
||||
isAdminConsole: false,
|
||||
};
|
||||
|
||||
return renderWithIntl(
|
||||
<reactRedux.Provider store={store}>
|
||||
<DeliquencyModal
|
||||
{...defaultProps}
|
||||
{...props}
|
||||
/>
|
||||
</reactRedux.Provider>,
|
||||
);
|
||||
const baseProps: ComponentProps<typeof DelinquencyModal> = {
|
||||
closeModal: jest.fn(),
|
||||
onExited: jest.fn(),
|
||||
planName: 'planName',
|
||||
isAdminConsole: false,
|
||||
};
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should save preferences and track stayOnFremium if admin click Stay on Free', () => {
|
||||
renderComponent({});
|
||||
renderWithContext(<DelinquencyModal {...baseProps}/>, initialState);
|
||||
|
||||
fireEvent.click(screen.getByText('Stay on Free'));
|
||||
|
||||
expect(savePreferences).toBeCalledTimes(1);
|
||||
expect(savePreferences).toBeCalledWith(initialStates.entities.users.profiles.current_user_id.id, [{
|
||||
expect(savePreferences).toBeCalledWith(initialState.entities.users.profiles.current_user_id.id, [{
|
||||
category: Preferences.DELINQUENCY_MODAL_CONFIRMED,
|
||||
name: ModalIdentifiers.DELINQUENCY_MODAL_DOWNGRADE,
|
||||
user_id: initialStates.entities.users.profiles.current_user_id.id,
|
||||
user_id: initialState.entities.users.profiles.current_user_id.id,
|
||||
value: 'stayOnFremium',
|
||||
}]);
|
||||
|
||||
@@ -106,15 +84,15 @@ describe('components/deliquency_modal/deliquency_modal', () => {
|
||||
});
|
||||
|
||||
it('should save preferences and track update Billing if admin click Update Billing', () => {
|
||||
renderComponent({});
|
||||
renderWithContext(<DelinquencyModal {...baseProps}/>, initialState);
|
||||
|
||||
fireEvent.click(screen.getByText('Update Billing'));
|
||||
|
||||
expect(savePreferences).toBeCalledTimes(1);
|
||||
expect(savePreferences).toBeCalledWith(initialStates.entities.users.profiles.current_user_id.id, [{
|
||||
expect(savePreferences).toBeCalledWith(initialState.entities.users.profiles.current_user_id.id, [{
|
||||
category: Preferences.DELINQUENCY_MODAL_CONFIRMED,
|
||||
name: ModalIdentifiers.DELINQUENCY_MODAL_DOWNGRADE,
|
||||
user_id: initialStates.entities.users.profiles.current_user_id.id,
|
||||
user_id: initialState.entities.users.profiles.current_user_id.id,
|
||||
value: 'updateBilling',
|
||||
}]);
|
||||
|
||||
|
||||
@@ -2,32 +2,29 @@
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import * as reactRedux from 'react-redux';
|
||||
|
||||
import type {DeepPartial} from '@mattermost/types/utilities';
|
||||
|
||||
import * as cloudActions from 'mattermost-redux/actions/cloud';
|
||||
|
||||
import * as StorageSelectors from 'selectors/storage';
|
||||
import configureStore from 'store';
|
||||
|
||||
import ModalController from 'components/modal_controller';
|
||||
|
||||
import {renderWithIntl, screen} from 'tests/react_testing_utils';
|
||||
import {renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
import {CloudProducts, ModalIdentifiers, Preferences} from 'utils/constants';
|
||||
import {TestHelper} from 'utils/test_helper';
|
||||
|
||||
import type {GlobalState} from 'types/store';
|
||||
|
||||
import DelinquencyModalController from './index';
|
||||
|
||||
jest.mock('selectors/storage');
|
||||
|
||||
(StorageSelectors.makeGetItem as jest.Mock).mockReturnValue(() => false);
|
||||
|
||||
jest.mock('react-dom', () => ({
|
||||
...jest.requireActual('react-dom'),
|
||||
createPortal: (node: any) => node,
|
||||
}));
|
||||
|
||||
describe('components/delinquency_modal/delinquency_modal_controller', () => {
|
||||
const initialState = {
|
||||
const initialState: DeepPartial<GlobalState> = {
|
||||
views: {
|
||||
modals: {
|
||||
modalState: {},
|
||||
@@ -50,31 +47,31 @@ describe('components/delinquency_modal/delinquency_modal_controller', () => {
|
||||
},
|
||||
},
|
||||
cloud: {
|
||||
subscription: {
|
||||
subscription: TestHelper.getSubscriptionMock({
|
||||
product_id: 'test_prod_1',
|
||||
trial_end_at: 1652807380,
|
||||
is_free_trial: 'false',
|
||||
delinquent_since: 1652807380, // may 17 2022
|
||||
},
|
||||
}),
|
||||
products: {
|
||||
test_prod_1: {
|
||||
test_prod_1: TestHelper.getProductMock({
|
||||
id: 'test_prod_1',
|
||||
sku: CloudProducts.STARTER,
|
||||
price_per_seat: 0,
|
||||
name: 'testProd1',
|
||||
},
|
||||
test_prod_2: {
|
||||
}),
|
||||
test_prod_2: TestHelper.getProductMock({
|
||||
id: 'test_prod_2',
|
||||
sku: CloudProducts.ENTERPRISE,
|
||||
price_per_seat: 0,
|
||||
name: 'testProd2',
|
||||
},
|
||||
test_prod_3: {
|
||||
}),
|
||||
test_prod_3: TestHelper.getProductMock({
|
||||
id: 'test_prod_3',
|
||||
sku: CloudProducts.PROFESSIONAL,
|
||||
price_per_seat: 0,
|
||||
name: 'testProd3',
|
||||
},
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -83,14 +80,13 @@ describe('components/delinquency_modal/delinquency_modal_controller', () => {
|
||||
it('Should show the modal if the admin hasn\'t a preference', () => {
|
||||
jest.useFakeTimers().setSystemTime(new Date('2022-12-20'));
|
||||
|
||||
const store = configureStore(initialState);
|
||||
|
||||
renderWithIntl(
|
||||
<reactRedux.Provider store={store}>
|
||||
renderWithContext(
|
||||
<>
|
||||
<div id='root-portal'/>
|
||||
<ModalController/>
|
||||
<DelinquencyModalController/>
|
||||
</reactRedux.Provider>,
|
||||
</>,
|
||||
initialState,
|
||||
);
|
||||
|
||||
expect(screen.queryByText('Your workspace has been downgraded')).toBeInTheDocument();
|
||||
@@ -110,14 +106,13 @@ describe('components/delinquency_modal/delinquency_modal_controller', () => {
|
||||
|
||||
jest.useFakeTimers().setSystemTime(new Date('2022-12-20'));
|
||||
|
||||
const store = configureStore(state);
|
||||
|
||||
renderWithIntl(
|
||||
<reactRedux.Provider store={store}>
|
||||
renderWithContext(
|
||||
<>
|
||||
<div id='root-portal'/>
|
||||
<ModalController/>
|
||||
<DelinquencyModalController/>
|
||||
</reactRedux.Provider>,
|
||||
</>,
|
||||
state,
|
||||
);
|
||||
|
||||
expect(screen.queryByText('Your workspace has been downgraded')).not.toBeInTheDocument();
|
||||
@@ -126,14 +121,13 @@ describe('components/delinquency_modal/delinquency_modal_controller', () => {
|
||||
it('Should show the modal if the deliquency_since is equal 90 days', () => {
|
||||
jest.useFakeTimers().setSystemTime(new Date('2022-08-16'));
|
||||
|
||||
const store = configureStore(initialState);
|
||||
|
||||
renderWithIntl(
|
||||
<reactRedux.Provider store={store}>
|
||||
renderWithContext(
|
||||
<>
|
||||
<div id='root-portal'/>
|
||||
<ModalController/>
|
||||
<DelinquencyModalController/>
|
||||
</reactRedux.Provider>,
|
||||
</>,
|
||||
initialState,
|
||||
);
|
||||
|
||||
expect(screen.queryByText('Your workspace has been downgraded')).toBeInTheDocument();
|
||||
@@ -142,14 +136,13 @@ describe('components/delinquency_modal/delinquency_modal_controller', () => {
|
||||
it('Should show the modal if the deliquency_since is more than 90 days', () => {
|
||||
jest.useFakeTimers().setSystemTime(new Date('2022-08-17'));
|
||||
|
||||
const store = configureStore(initialState);
|
||||
|
||||
renderWithIntl(
|
||||
<reactRedux.Provider store={store}>
|
||||
renderWithContext(
|
||||
<>
|
||||
<div id='root-portal'/>
|
||||
<ModalController/>
|
||||
<DelinquencyModalController/>
|
||||
</reactRedux.Provider>,
|
||||
</>,
|
||||
initialState,
|
||||
);
|
||||
|
||||
expect(screen.queryByText('Your workspace has been downgraded')).toBeInTheDocument();
|
||||
@@ -158,14 +151,13 @@ describe('components/delinquency_modal/delinquency_modal_controller', () => {
|
||||
it('Shouldn\'t show the modal if the deliqeuncy_since is less than 90 days', () => {
|
||||
jest.useFakeTimers().setSystemTime(new Date('2022-08-15'));
|
||||
|
||||
const store = configureStore(initialState);
|
||||
|
||||
renderWithIntl(
|
||||
<reactRedux.Provider store={store}>
|
||||
renderWithContext(
|
||||
<>
|
||||
<div id='root-portal'/>
|
||||
<ModalController/>
|
||||
<DelinquencyModalController/>
|
||||
</reactRedux.Provider>,
|
||||
</>,
|
||||
initialState,
|
||||
);
|
||||
|
||||
expect(screen.queryByText('Your workspace has been downgraded')).not.toBeInTheDocument();
|
||||
@@ -174,14 +166,13 @@ describe('components/delinquency_modal/delinquency_modal_controller', () => {
|
||||
it('Should show the modal if the license is cloud', () => {
|
||||
jest.useFakeTimers().setSystemTime(new Date('2022-08-17'));
|
||||
|
||||
const store = configureStore(initialState);
|
||||
|
||||
renderWithIntl(
|
||||
<reactRedux.Provider store={store}>
|
||||
renderWithContext(
|
||||
<>
|
||||
<div id='root-portal'/>
|
||||
<ModalController/>
|
||||
<DelinquencyModalController/>
|
||||
</reactRedux.Provider>,
|
||||
</>,
|
||||
initialState,
|
||||
);
|
||||
|
||||
expect(screen.queryByText('Your workspace has been downgraded')).toBeInTheDocument();
|
||||
@@ -196,14 +187,13 @@ describe('components/delinquency_modal/delinquency_modal_controller', () => {
|
||||
|
||||
jest.useFakeTimers().setSystemTime(new Date('2022-12-20'));
|
||||
|
||||
const store = configureStore(state);
|
||||
|
||||
renderWithIntl(
|
||||
<reactRedux.Provider store={store}>
|
||||
renderWithContext(
|
||||
<>
|
||||
<div id='root-portal'/>
|
||||
<ModalController/>
|
||||
<DelinquencyModalController/>
|
||||
</reactRedux.Provider>,
|
||||
</>,
|
||||
state,
|
||||
);
|
||||
|
||||
expect(screen.queryByText('Your workspace has been downgraded')).not.toBeInTheDocument();
|
||||
@@ -218,14 +208,13 @@ describe('components/delinquency_modal/delinquency_modal_controller', () => {
|
||||
|
||||
jest.useFakeTimers().setSystemTime(new Date('2022-12-20'));
|
||||
|
||||
const store = configureStore(state);
|
||||
|
||||
renderWithIntl(
|
||||
<reactRedux.Provider store={store}>
|
||||
renderWithContext(
|
||||
<>
|
||||
<div id='root-portal'/>
|
||||
<ModalController/>
|
||||
<DelinquencyModalController/>
|
||||
</reactRedux.Provider>,
|
||||
</>,
|
||||
state,
|
||||
);
|
||||
|
||||
expect(screen.queryByText('Your workspace has been downgraded')).not.toBeInTheDocument();
|
||||
@@ -234,14 +223,13 @@ describe('components/delinquency_modal/delinquency_modal_controller', () => {
|
||||
it('Should show the modal if the user is an admin', () => {
|
||||
jest.useFakeTimers().setSystemTime(new Date('2022-08-17'));
|
||||
|
||||
const store = configureStore(initialState);
|
||||
|
||||
renderWithIntl(
|
||||
<reactRedux.Provider store={store}>
|
||||
renderWithContext(
|
||||
<>
|
||||
<div id='root-portal'/>
|
||||
<ModalController/>
|
||||
<DelinquencyModalController/>
|
||||
</reactRedux.Provider>,
|
||||
</>,
|
||||
initialState,
|
||||
);
|
||||
|
||||
expect(screen.queryByText('Your workspace has been downgraded')).toBeInTheDocument();
|
||||
@@ -257,14 +245,13 @@ describe('components/delinquency_modal/delinquency_modal_controller', () => {
|
||||
};
|
||||
jest.useFakeTimers().setSystemTime(new Date('2022-12-20'));
|
||||
|
||||
const store = configureStore(state);
|
||||
|
||||
renderWithIntl(
|
||||
<reactRedux.Provider store={store}>
|
||||
renderWithContext(
|
||||
<>
|
||||
<div id='root-portal'/>
|
||||
<ModalController/>
|
||||
<DelinquencyModalController/>
|
||||
</reactRedux.Provider>,
|
||||
</>,
|
||||
state,
|
||||
);
|
||||
|
||||
expect(screen.queryByText('Your workspace has been downgraded')).not.toBeInTheDocument();
|
||||
@@ -273,14 +260,13 @@ describe('components/delinquency_modal/delinquency_modal_controller', () => {
|
||||
it('Should show the modal if the user just logged in', () => {
|
||||
jest.useFakeTimers().setSystemTime(new Date('2022-08-17'));
|
||||
|
||||
const store = configureStore(initialState);
|
||||
|
||||
renderWithIntl(
|
||||
<reactRedux.Provider store={store}>
|
||||
renderWithContext(
|
||||
<>
|
||||
<div id='root-portal'/>
|
||||
<ModalController/>
|
||||
<DelinquencyModalController/>
|
||||
</reactRedux.Provider>,
|
||||
</>,
|
||||
initialState,
|
||||
);
|
||||
|
||||
expect(screen.queryByText('Your workspace has been downgraded')).toBeInTheDocument();
|
||||
@@ -289,14 +275,13 @@ describe('components/delinquency_modal/delinquency_modal_controller', () => {
|
||||
(StorageSelectors.makeGetItem as jest.Mock).mockReturnValue(() => true);
|
||||
jest.useFakeTimers().setSystemTime(new Date('2022-08-17'));
|
||||
|
||||
const store = configureStore(initialState);
|
||||
|
||||
renderWithIntl(
|
||||
<reactRedux.Provider store={store}>
|
||||
renderWithContext(
|
||||
<>
|
||||
<div id='root-portal'/>
|
||||
<ModalController/>
|
||||
<DelinquencyModalController/>
|
||||
</reactRedux.Provider>,
|
||||
</>,
|
||||
initialState,
|
||||
);
|
||||
|
||||
expect(screen.queryByText('Your workspace has been downgraded')).not.toBeInTheDocument();
|
||||
@@ -308,15 +293,15 @@ describe('components/delinquency_modal/delinquency_modal_controller', () => {
|
||||
const newState = JSON.parse(JSON.stringify(initialState));
|
||||
newState.entities.cloud.products = {};
|
||||
|
||||
const store = configureStore(newState);
|
||||
const getCloudProds = jest.spyOn(cloudActions, 'getCloudProducts').mockImplementationOnce(jest.fn().mockReturnValue({type: 'mock_impl'}));
|
||||
|
||||
renderWithIntl(
|
||||
<reactRedux.Provider store={store}>
|
||||
renderWithContext(
|
||||
<>
|
||||
<div id='root-portal'/>
|
||||
<ModalController/>
|
||||
<DelinquencyModalController/>
|
||||
</reactRedux.Provider>,
|
||||
</>,
|
||||
newState,
|
||||
);
|
||||
|
||||
expect(getCloudProds).toHaveBeenCalledTimes(1);
|
||||
@@ -332,15 +317,15 @@ describe('components/delinquency_modal/delinquency_modal_controller', () => {
|
||||
Cloud: 'false',
|
||||
};
|
||||
|
||||
const store = configureStore(newState);
|
||||
const getCloudProds = jest.spyOn(cloudActions, 'getCloudProducts').mockImplementationOnce(jest.fn().mockReturnValue({type: 'mock_impl'}));
|
||||
|
||||
renderWithIntl(
|
||||
<reactRedux.Provider store={store}>
|
||||
renderWithContext(
|
||||
<>
|
||||
<div id='root-portal'/>
|
||||
<ModalController/>
|
||||
<DelinquencyModalController/>
|
||||
</reactRedux.Provider>,
|
||||
</>,
|
||||
newState,
|
||||
);
|
||||
|
||||
expect(getCloudProds).toHaveBeenCalledTimes(0);
|
||||
|
||||
@@ -3,23 +3,20 @@
|
||||
|
||||
import React from 'react';
|
||||
import type {ComponentProps} from 'react';
|
||||
import * as reactRedux from 'react-redux';
|
||||
|
||||
import type {DeepPartial} from '@mattermost/types/utilities';
|
||||
|
||||
import {trackEvent} from 'actions/telemetry_actions';
|
||||
import configureStore from 'store';
|
||||
|
||||
import useGetMultiplesExceededCloudLimit from 'components/common/hooks/useGetMultiplesExceededCloudLimit';
|
||||
|
||||
import {fireEvent, renderWithIntl, screen} from 'tests/react_testing_utils';
|
||||
import {fireEvent, renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
import {ModalIdentifiers, TELEMETRY_CATEGORIES} from 'utils/constants';
|
||||
import {LimitTypes} from 'utils/limits';
|
||||
|
||||
import {FreemiumModal} from './freemium_modal';
|
||||
import type {GlobalState} from 'types/store';
|
||||
|
||||
type RenderComponentArgs = {
|
||||
props?: Partial<ComponentProps<typeof FreemiumModal>>;
|
||||
store?: any;
|
||||
}
|
||||
import {FreemiumModal} from './freemium_modal';
|
||||
|
||||
jest.mock('actions/telemetry_actions', () => ({
|
||||
trackEvent: jest.fn(),
|
||||
@@ -33,7 +30,7 @@ jest.mock('react-redux', () => ({
|
||||
jest.mock('components/common/hooks/useGetMultiplesExceededCloudLimit');
|
||||
|
||||
describe('components/delinquency_modal/freemium_modal', () => {
|
||||
const initialStates = {
|
||||
const initialState: DeepPartial<GlobalState> = {
|
||||
views: {
|
||||
modals: {
|
||||
modalState: {
|
||||
@@ -45,7 +42,7 @@ describe('components/delinquency_modal/freemium_modal', () => {
|
||||
closeModal: () => {},
|
||||
isAdminConsole: false,
|
||||
},
|
||||
dialogType: React.Fragment,
|
||||
dialogType: React.Fragment as any,
|
||||
},
|
||||
},
|
||||
showLaunchingWorkspace: false,
|
||||
@@ -61,36 +58,20 @@ describe('components/delinquency_modal/freemium_modal', () => {
|
||||
},
|
||||
};
|
||||
|
||||
const renderComponent = ({props = {}, store = configureStore(initialStates)}: RenderComponentArgs) => {
|
||||
const defaultProps: ComponentProps<typeof FreemiumModal> = {
|
||||
onClose: jest.fn(),
|
||||
planName: 'planName',
|
||||
isAdminConsole: false,
|
||||
onExited: jest.fn(),
|
||||
};
|
||||
|
||||
return renderWithIntl(
|
||||
<reactRedux.Provider store={store}>
|
||||
<FreemiumModal
|
||||
{...defaultProps}
|
||||
{...props}
|
||||
/>
|
||||
</reactRedux.Provider>,
|
||||
);
|
||||
const planName = 'Testing';
|
||||
const baseProps: ComponentProps<typeof FreemiumModal> = {
|
||||
onClose: jest.fn(),
|
||||
planName,
|
||||
isAdminConsole: false,
|
||||
onExited: jest.fn(),
|
||||
};
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should track reactivate plan if admin click Re activate plan', () => {
|
||||
const planName = 'Testing';
|
||||
(useGetMultiplesExceededCloudLimit as jest.Mock).mockReturnValue([LimitTypes.fileStorage]);
|
||||
renderComponent({
|
||||
props: {
|
||||
planName,
|
||||
},
|
||||
});
|
||||
renderWithContext(
|
||||
<FreemiumModal {...baseProps}/>,
|
||||
initialState,
|
||||
);
|
||||
|
||||
fireEvent.click(screen.getByText(`Re-activate ${planName}`));
|
||||
|
||||
@@ -102,13 +83,11 @@ describe('components/delinquency_modal/freemium_modal', () => {
|
||||
});
|
||||
|
||||
it('should not show reactivate plan if admin limits isn\'t surpassed', () => {
|
||||
const planName = 'Testing';
|
||||
(useGetMultiplesExceededCloudLimit as jest.Mock).mockReturnValue([]);
|
||||
renderComponent({
|
||||
props: {
|
||||
planName,
|
||||
},
|
||||
});
|
||||
renderWithContext(
|
||||
<FreemiumModal {...baseProps}/>,
|
||||
initialState,
|
||||
);
|
||||
|
||||
expect(screen.queryByText(`Re-activate ${planName}`)).not.toBeInTheDocument();
|
||||
|
||||
@@ -116,42 +95,33 @@ describe('components/delinquency_modal/freemium_modal', () => {
|
||||
});
|
||||
|
||||
it('should display message history text when only message limit is surpassed', () => {
|
||||
const planName = 'Testing';
|
||||
|
||||
(useGetMultiplesExceededCloudLimit as jest.Mock).mockReturnValue([LimitTypes.messageHistory]);
|
||||
renderComponent({
|
||||
props: {
|
||||
planName,
|
||||
},
|
||||
});
|
||||
renderWithContext(
|
||||
<FreemiumModal {...baseProps}/>,
|
||||
initialState,
|
||||
);
|
||||
|
||||
expect(screen.queryByText(`Re-activate ${planName}`)).toBeInTheDocument();
|
||||
expect(screen.getByText('Some of your workspace\'s message history are no longer accessible. Upgrade to a paid plan and get unlimited access to your message history.')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should display storage text when only storage is surpassed', () => {
|
||||
const planName = 'Testing';
|
||||
|
||||
(useGetMultiplesExceededCloudLimit as jest.Mock).mockReturnValue([LimitTypes.fileStorage]);
|
||||
renderComponent({
|
||||
props: {
|
||||
planName,
|
||||
},
|
||||
});
|
||||
renderWithContext(
|
||||
<FreemiumModal {...baseProps}/>,
|
||||
initialState,
|
||||
);
|
||||
|
||||
expect(screen.queryByText(`Re-activate ${planName}`)).toBeInTheDocument();
|
||||
expect(screen.getByText('Some of your workspace\'s files are no longer accessible. Upgrade to a paid plan and get unlimited access to your files.')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should display update to paid plan text when only multiples limits is surpassed', () => {
|
||||
const planName = 'Testing';
|
||||
|
||||
(useGetMultiplesExceededCloudLimit as jest.Mock).mockReturnValue([LimitTypes.messageHistory, LimitTypes.fileStorage]);
|
||||
renderComponent({
|
||||
props: {
|
||||
planName,
|
||||
},
|
||||
});
|
||||
renderWithContext(
|
||||
<FreemiumModal {...baseProps}/>,
|
||||
initialState,
|
||||
);
|
||||
|
||||
expect(screen.queryByText(`Re-activate ${planName}`)).toBeInTheDocument();
|
||||
expect(screen.getByText('Your workspace has reached free plan limits. Upgrade to a paid plan.')).toBeInTheDocument();
|
||||
|
||||
@@ -102,8 +102,10 @@ Object {
|
||||
"queryByTestId": [Function],
|
||||
"queryByText": [Function],
|
||||
"queryByTitle": [Function],
|
||||
"replaceStoreState": [Function],
|
||||
"rerender": [Function],
|
||||
"unmount": [Function],
|
||||
"updateStoreState": [Function],
|
||||
}
|
||||
`;
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import type {PostType} from '@mattermost/types/posts';
|
||||
import type {DeepPartial} from '@mattermost/types/utilities';
|
||||
|
||||
import {shallowWithIntl} from 'tests/helpers/intl-test-helper';
|
||||
import {fireEvent, renderWithIntlAndStore, screen} from 'tests/react_testing_utils';
|
||||
import {fireEvent, renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
import {Locations} from 'utils/constants';
|
||||
import {TestHelper} from 'utils/test_helper';
|
||||
|
||||
@@ -172,7 +172,7 @@ describe('components/dot_menu/DotMenu', () => {
|
||||
canEdit: true,
|
||||
canDelete: true,
|
||||
};
|
||||
const wrapper = renderWithIntlAndStore(
|
||||
const wrapper = renderWithContext(
|
||||
<DotMenu {...props}/>,
|
||||
initialState,
|
||||
);
|
||||
@@ -185,7 +185,7 @@ describe('components/dot_menu/DotMenu', () => {
|
||||
...baseProps,
|
||||
location: Locations.CENTER,
|
||||
};
|
||||
renderWithIntlAndStore(
|
||||
renderWithContext(
|
||||
<DotMenu {...props}/>,
|
||||
initialState,
|
||||
);
|
||||
@@ -200,7 +200,7 @@ describe('components/dot_menu/DotMenu', () => {
|
||||
...baseProps,
|
||||
channelIsArchived: true,
|
||||
};
|
||||
renderWithIntlAndStore(
|
||||
renderWithContext(
|
||||
<DotMenu {...props}/>,
|
||||
initialState,
|
||||
);
|
||||
@@ -215,7 +215,7 @@ describe('components/dot_menu/DotMenu', () => {
|
||||
...baseProps,
|
||||
location: Locations.SEARCH,
|
||||
};
|
||||
renderWithIntlAndStore(
|
||||
renderWithContext(
|
||||
<DotMenu {...props}/>,
|
||||
initialState,
|
||||
);
|
||||
@@ -235,7 +235,7 @@ describe('components/dot_menu/DotMenu', () => {
|
||||
...baseProps,
|
||||
...caseProps,
|
||||
};
|
||||
renderWithIntlAndStore(
|
||||
renderWithContext(
|
||||
<DotMenu {...props}/>,
|
||||
initialState,
|
||||
);
|
||||
@@ -256,7 +256,7 @@ describe('components/dot_menu/DotMenu', () => {
|
||||
...baseProps,
|
||||
...caseProps,
|
||||
};
|
||||
renderWithIntlAndStore(
|
||||
renderWithContext(
|
||||
<DotMenu {...props}/>,
|
||||
initialState,
|
||||
);
|
||||
@@ -277,7 +277,7 @@ describe('components/dot_menu/DotMenu', () => {
|
||||
...caseProps,
|
||||
location: Locations.RHS_ROOT,
|
||||
};
|
||||
renderWithIntlAndStore(
|
||||
renderWithContext(
|
||||
<DotMenu {...props}/>,
|
||||
initialState,
|
||||
);
|
||||
|
||||
@@ -2,11 +2,10 @@
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import {BrowserRouter} from 'react-router-dom';
|
||||
|
||||
import type {GlobalState} from '@mattermost/types/store';
|
||||
|
||||
import {renderWithIntlAndStore, screen} from 'tests/react_testing_utils';
|
||||
import {renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
import {ErrorPageTypes} from 'utils/constants';
|
||||
import {TestHelper} from 'utils/test_helper';
|
||||
|
||||
@@ -14,15 +13,13 @@ import ErrorPage from './error_page';
|
||||
|
||||
describe('ErrorPage', () => {
|
||||
it('displays cloud archived page correctly', () => {
|
||||
renderWithIntlAndStore(
|
||||
renderWithContext(
|
||||
(
|
||||
<BrowserRouter>
|
||||
<ErrorPage
|
||||
location={{
|
||||
search: `?type=${ErrorPageTypes.CLOUD_ARCHIVED}`,
|
||||
}}
|
||||
/>
|
||||
</BrowserRouter>
|
||||
<ErrorPage
|
||||
location={{
|
||||
search: `?type=${ErrorPageTypes.CLOUD_ARCHIVED}`,
|
||||
}}
|
||||
/>
|
||||
),
|
||||
{
|
||||
entities: {
|
||||
|
||||
@@ -6,7 +6,7 @@ import React from 'react';
|
||||
import {Provider} from 'react-redux';
|
||||
import type {DeepPartial} from 'redux';
|
||||
|
||||
import {renderWithIntlAndStore, screen} from 'tests/react_testing_utils';
|
||||
import {renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
import mockStore from 'tests/test_store';
|
||||
|
||||
import type {GlobalState} from 'types/store';
|
||||
@@ -55,7 +55,7 @@ describe('components/external_link', () => {
|
||||
},
|
||||
},
|
||||
};
|
||||
renderWithIntlAndStore(
|
||||
renderWithContext(
|
||||
<ExternalLink href='https://mattermost.com'>
|
||||
{'Click Me'}
|
||||
</ExternalLink>,
|
||||
@@ -81,7 +81,7 @@ describe('components/external_link', () => {
|
||||
},
|
||||
},
|
||||
};
|
||||
renderWithIntlAndStore(
|
||||
renderWithContext(
|
||||
<ExternalLink href='https://mattermost.com?test=true'>
|
||||
{'Click Me'}
|
||||
</ExternalLink>,
|
||||
@@ -107,7 +107,7 @@ describe('components/external_link', () => {
|
||||
},
|
||||
},
|
||||
};
|
||||
renderWithIntlAndStore(
|
||||
renderWithContext(
|
||||
<ExternalLink href='https://google.com'>
|
||||
{'Click Me'}
|
||||
</ExternalLink>,
|
||||
@@ -133,7 +133,7 @@ describe('components/external_link', () => {
|
||||
},
|
||||
},
|
||||
};
|
||||
renderWithIntlAndStore(
|
||||
renderWithContext(
|
||||
<ExternalLink
|
||||
target='test'
|
||||
rel='test'
|
||||
@@ -167,7 +167,7 @@ describe('components/external_link', () => {
|
||||
},
|
||||
},
|
||||
};
|
||||
renderWithIntlAndStore(
|
||||
renderWithContext(
|
||||
<ExternalLink
|
||||
href='https://mattermost.com#desktop'
|
||||
>
|
||||
|
||||
@@ -5,9 +5,10 @@ import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import type {GlobalState} from '@mattermost/types/store';
|
||||
import type {DeepPartial} from '@mattermost/types/utilities';
|
||||
|
||||
import {mountWithIntl} from 'tests/helpers/intl-test-helper';
|
||||
import {renderWithIntl, renderWithIntlAndStore, screen} from 'tests/react_testing_utils';
|
||||
import {renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
|
||||
import FileAttachment from './file_attachment';
|
||||
|
||||
@@ -69,7 +70,7 @@ describe('FileAttachment', () => {
|
||||
});
|
||||
|
||||
test('non archived file does not show archived elements', () => {
|
||||
const reduxState = {
|
||||
const reduxState: DeepPartial<GlobalState> = {
|
||||
entities: {
|
||||
general: {
|
||||
config: {},
|
||||
@@ -78,15 +79,15 @@ describe('FileAttachment', () => {
|
||||
currentUserId: 'currentUserId',
|
||||
},
|
||||
},
|
||||
} as GlobalState;
|
||||
renderWithIntlAndStore(<FileAttachment {...baseProps}/>, reduxState);
|
||||
};
|
||||
renderWithContext(<FileAttachment {...baseProps}/>, reduxState);
|
||||
|
||||
expect(screen.queryByTestId('archived-file-icon')).not.toBeInTheDocument();
|
||||
expect(screen.queryByText(/This file is archived/)).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('non archived file does not show archived elements in compact display mode', () => {
|
||||
renderWithIntl(<FileAttachment {...{...baseProps, compactDisplay: true}}/>);
|
||||
renderWithContext(<FileAttachment {...{...baseProps, compactDisplay: true}}/>);
|
||||
|
||||
expect(screen.queryByTestId('archived-file-icon')).not.toBeInTheDocument();
|
||||
expect(screen.queryByText(/archived/)).not.toBeInTheDocument();
|
||||
@@ -188,7 +189,7 @@ describe('FileAttachment', () => {
|
||||
},
|
||||
compactDisplay: true,
|
||||
};
|
||||
renderWithIntl(<FileAttachment {...props}/>);
|
||||
renderWithContext(<FileAttachment {...props}/>);
|
||||
screen.getByTestId('archived-file-icon');
|
||||
screen.getByText(baseProps.fileInfo.name);
|
||||
screen.getByText(/archived/);
|
||||
@@ -203,7 +204,7 @@ describe('FileAttachment', () => {
|
||||
},
|
||||
compactDisplay: false,
|
||||
};
|
||||
renderWithIntl(<FileAttachment {...props}/>);
|
||||
renderWithContext(<FileAttachment {...props}/>);
|
||||
screen.getByTestId('archived-file-icon');
|
||||
screen.getByText(baseProps.fileInfo.name);
|
||||
screen.getByText(/This file is archived/);
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`components/HeaderFooterTemplate should match snapshot with about link 1`] = `
|
||||
<div
|
||||
data-testid="root-testid"
|
||||
id="root"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="inner-wrap"
|
||||
>
|
||||
@@ -59,10 +56,7 @@ exports[`components/HeaderFooterTemplate should match snapshot with about link 1
|
||||
`;
|
||||
|
||||
exports[`components/HeaderFooterTemplate should match snapshot with all links 1`] = `
|
||||
<div
|
||||
data-testid="root-testid"
|
||||
id="root"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="inner-wrap"
|
||||
>
|
||||
@@ -147,10 +141,7 @@ exports[`components/HeaderFooterTemplate should match snapshot with all links 1`
|
||||
`;
|
||||
|
||||
exports[`components/HeaderFooterTemplate should match snapshot with children 1`] = `
|
||||
<div
|
||||
data-testid="root-testid"
|
||||
id="root"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="inner-wrap"
|
||||
>
|
||||
@@ -198,10 +189,7 @@ exports[`components/HeaderFooterTemplate should match snapshot with children 1`]
|
||||
`;
|
||||
|
||||
exports[`components/HeaderFooterTemplate should match snapshot with help link 1`] = `
|
||||
<div
|
||||
data-testid="root-testid"
|
||||
id="root"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="inner-wrap"
|
||||
>
|
||||
@@ -256,10 +244,7 @@ exports[`components/HeaderFooterTemplate should match snapshot with help link 1`
|
||||
`;
|
||||
|
||||
exports[`components/HeaderFooterTemplate should match snapshot with privacy policy link 1`] = `
|
||||
<div
|
||||
data-testid="root-testid"
|
||||
id="root"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="inner-wrap"
|
||||
>
|
||||
@@ -314,10 +299,7 @@ exports[`components/HeaderFooterTemplate should match snapshot with privacy poli
|
||||
`;
|
||||
|
||||
exports[`components/HeaderFooterTemplate should match snapshot with term of service link 1`] = `
|
||||
<div
|
||||
data-testid="root-testid"
|
||||
id="root"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="inner-wrap"
|
||||
>
|
||||
@@ -372,10 +354,7 @@ exports[`components/HeaderFooterTemplate should match snapshot with term of serv
|
||||
`;
|
||||
|
||||
exports[`components/HeaderFooterTemplate should match snapshot without children 1`] = `
|
||||
<div
|
||||
data-testid="root-testid"
|
||||
id="root"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="inner-wrap"
|
||||
>
|
||||
@@ -419,10 +398,7 @@ exports[`components/HeaderFooterTemplate should match snapshot without children
|
||||
`;
|
||||
|
||||
exports[`components/HeaderFooterTemplate should set classes on body and #root on mount and unset on unmount 1`] = `
|
||||
<div
|
||||
data-testid="root-testid"
|
||||
id="root"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="inner-wrap"
|
||||
>
|
||||
@@ -506,9 +482,4 @@ exports[`components/HeaderFooterTemplate should set classes on body and #root on
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/HeaderFooterTemplate should set classes on body and #root on mount and unset on unmount 2`] = `
|
||||
<div
|
||||
data-testid="root-testid"
|
||||
id="root"
|
||||
/>
|
||||
`;
|
||||
exports[`components/HeaderFooterTemplate should set classes on body and #root on mount and unset on unmount 2`] = `<div />`;
|
||||
|
||||
@@ -5,7 +5,8 @@ import React from 'react';
|
||||
|
||||
import type {DeepPartial} from '@mattermost/types/utilities';
|
||||
|
||||
import {renderWithIntlAndStore} from 'tests/react_testing_utils';
|
||||
import mergeObjects from 'packages/mattermost-redux/test/merge_objects';
|
||||
import {renderWithContext} from 'tests/react_testing_utils';
|
||||
|
||||
import type {GlobalState} from 'types/store';
|
||||
|
||||
@@ -22,7 +23,7 @@ describe('components/HeaderFooterTemplate', () => {
|
||||
global.Date = mock as any;
|
||||
}
|
||||
|
||||
const state = {
|
||||
const initialState: DeepPartial<GlobalState> = {
|
||||
entities: {
|
||||
general: {
|
||||
config: {},
|
||||
@@ -42,7 +43,7 @@ describe('components/HeaderFooterTemplate', () => {
|
||||
team1: {
|
||||
id: 'team1',
|
||||
name: 'team-1',
|
||||
displayName: 'Team 1',
|
||||
display_name: 'Team 1',
|
||||
},
|
||||
},
|
||||
myMembers: {
|
||||
@@ -53,19 +54,6 @@ describe('components/HeaderFooterTemplate', () => {
|
||||
storage: {
|
||||
initialized: true,
|
||||
},
|
||||
} as unknown as GlobalState;
|
||||
|
||||
const renderComponent = (component: React.ReactNode, state: DeepPartial<GlobalState>) => {
|
||||
const rootDiv = document.createElement('div');
|
||||
rootDiv.id = 'root';
|
||||
rootDiv.setAttribute('data-testid', 'root-testid');
|
||||
|
||||
return renderWithIntlAndStore(
|
||||
component,
|
||||
state,
|
||||
'en',
|
||||
rootDiv,
|
||||
);
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -77,69 +65,113 @@ describe('components/HeaderFooterTemplate', () => {
|
||||
});
|
||||
|
||||
test('should match snapshot without children', () => {
|
||||
const {container} = renderComponent(<HeaderFooterNotLoggedIn/>, state as DeepPartial<GlobalState>);
|
||||
const {container} = renderWithContext(<HeaderFooterNotLoggedIn/>, initialState);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot with children', () => {
|
||||
const {container} = renderComponent(
|
||||
const {container} = renderWithContext(
|
||||
<HeaderFooterNotLoggedIn>
|
||||
<p>{'test'}</p>
|
||||
</HeaderFooterNotLoggedIn>,
|
||||
state as DeepPartial<GlobalState>,
|
||||
initialState,
|
||||
);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot with help link', () => {
|
||||
state.entities.general.config = {HelpLink: 'http://testhelplink'};
|
||||
const state = mergeObjects(initialState, {
|
||||
entities: {
|
||||
general: {
|
||||
config: {
|
||||
HelpLink: 'http://testhelplink',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const {container} = renderComponent(<HeaderFooterNotLoggedIn/>, state as DeepPartial<GlobalState>);
|
||||
const {container} = renderWithContext(<HeaderFooterNotLoggedIn/>, state);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot with term of service link', () => {
|
||||
state.entities.general.config = {TermsOfServiceLink: 'http://testtermsofservicelink'};
|
||||
const state = mergeObjects(initialState, {
|
||||
entities: {
|
||||
general: {
|
||||
config: {
|
||||
TermsOfServiceLink: 'http://testtermsofservicelink',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const {container} = renderComponent(<HeaderFooterNotLoggedIn/>, state as DeepPartial<GlobalState>);
|
||||
const {container} = renderWithContext(<HeaderFooterNotLoggedIn/>, state);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot with privacy policy link', () => {
|
||||
state.entities.general.config = {PrivacyPolicyLink: 'http://testprivacypolicylink'};
|
||||
const state = mergeObjects(initialState, {
|
||||
entities: {
|
||||
general: {
|
||||
config: {
|
||||
PrivacyPolicyLink: 'http://testprivacypolicylink',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const {container} = renderComponent(<HeaderFooterNotLoggedIn/>, state as DeepPartial<GlobalState>);
|
||||
const {container} = renderWithContext(<HeaderFooterNotLoggedIn/>, state);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot with about link', () => {
|
||||
state.entities.general.config = {AboutLink: 'http://testaboutlink'};
|
||||
const state = mergeObjects(initialState, {
|
||||
entities: {
|
||||
general: {
|
||||
config: {
|
||||
AboutLink: 'http://testaboutlink',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const {container} = renderComponent(<HeaderFooterNotLoggedIn/>, state as DeepPartial<GlobalState>);
|
||||
const {container} = renderWithContext(<HeaderFooterNotLoggedIn/>, state);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot with all links', () => {
|
||||
state.entities.general.config = {
|
||||
HelpLink: 'http://testhelplink',
|
||||
TermsOfServiceLink: 'http://testtermsofservicelink',
|
||||
PrivacyPolicyLink: 'http://testprivacypolicylink',
|
||||
AboutLink: 'http://testaboutlink',
|
||||
};
|
||||
const state = mergeObjects(initialState, {
|
||||
entities: {
|
||||
general: {
|
||||
config: {
|
||||
HelpLink: 'http://testhelplink',
|
||||
TermsOfServiceLink: 'http://testtermsofservicelink',
|
||||
PrivacyPolicyLink: 'http://testprivacypolicylink',
|
||||
AboutLink: 'http://testaboutlink',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const {container} = renderComponent(<HeaderFooterNotLoggedIn/>, state as DeepPartial<GlobalState>);
|
||||
const {container} = renderWithContext(<HeaderFooterNotLoggedIn/>, state);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should set classes on body and #root on mount and unset on unmount', () => {
|
||||
state.entities.general.config = {
|
||||
HelpLink: 'http://testhelplink',
|
||||
TermsOfServiceLink: 'http://testtermsofservicelink',
|
||||
PrivacyPolicyLink: 'http://testprivacypolicylink',
|
||||
AboutLink: 'http://testaboutlink',
|
||||
};
|
||||
const state = mergeObjects(initialState, {
|
||||
entities: {
|
||||
general: {
|
||||
config: {
|
||||
HelpLink: 'http://testhelplink',
|
||||
TermsOfServiceLink: 'http://testtermsofservicelink',
|
||||
PrivacyPolicyLink: 'http://testprivacypolicylink',
|
||||
AboutLink: 'http://testaboutlink',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(document.body.classList.contains('sticky')).toBe(false);
|
||||
const {container, unmount} = renderComponent(<HeaderFooterNotLoggedIn/>, state as DeepPartial<GlobalState>);
|
||||
const {container, unmount} = renderWithContext(<HeaderFooterNotLoggedIn/>, state);
|
||||
expect(container).toMatchSnapshot();
|
||||
expect(document.body.classList.contains('sticky')).toBe(true);
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
import {Router} from 'react-router-dom';
|
||||
|
||||
import type {Bot} from '@mattermost/types/bots';
|
||||
import type {IncomingWebhook, OAuthApp, OutgoingWebhook} from '@mattermost/types/integrations';
|
||||
@@ -11,8 +10,7 @@ import type {IDMappedObjects} from '@mattermost/types/utilities';
|
||||
|
||||
import ConfirmIntegration from 'components/integrations/confirm_integration/confirm_integration';
|
||||
|
||||
import {renderWithIntlAndStore} from 'tests/react_testing_utils';
|
||||
import {getHistory} from 'utils/browser_history';
|
||||
import {renderWithContext} from 'tests/react_testing_utils';
|
||||
import {TestHelper} from 'utils/test_helper';
|
||||
|
||||
describe('components/integrations/ConfirmIntegration', () => {
|
||||
@@ -76,10 +74,8 @@ describe('components/integrations/ConfirmIntegration', () => {
|
||||
|
||||
test('should match callback URLs of OAuth Apps', () => {
|
||||
props.location.search = getSearchString('oauth2-apps');
|
||||
const {container} = renderWithIntlAndStore(
|
||||
<Router history={getHistory()}>
|
||||
<ConfirmIntegration {...props}/>
|
||||
</Router>,
|
||||
const {container} = renderWithContext(
|
||||
<ConfirmIntegration {...props}/>,
|
||||
initialState,
|
||||
);
|
||||
|
||||
|
||||
@@ -10,12 +10,12 @@ import deepFreeze from 'mattermost-redux/utils/deep_freeze';
|
||||
import CloseCircleIcon from 'components/widgets/icons/close_circle_icon';
|
||||
|
||||
import {mountWithIntl} from 'tests/helpers/intl-test-helper';
|
||||
import {renderWithIntl, screen} from 'tests/react_testing_utils';
|
||||
import {renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
|
||||
import AddToChannels from './add_to_channels';
|
||||
import type {Props} from './add_to_channels';
|
||||
|
||||
const defaultProps: Props = deepFreeze({
|
||||
const baseProps: Props = deepFreeze({
|
||||
customMessage: {
|
||||
message: '',
|
||||
open: false,
|
||||
@@ -35,35 +35,30 @@ const defaultProps: Props = deepFreeze({
|
||||
townSquareDisplayName: 'Town Square',
|
||||
});
|
||||
|
||||
let props = defaultProps;
|
||||
|
||||
describe('AddToChannels', () => {
|
||||
beforeEach(() => {
|
||||
props = defaultProps;
|
||||
});
|
||||
|
||||
describe('placeholder selection', () => {
|
||||
it('should use townSquareDisplayName when not in a channel', () => {
|
||||
props = {...props, currentChannel: undefined};
|
||||
renderWithIntl(<AddToChannels {...props}/>);
|
||||
const props = {...baseProps, currentChannel: undefined};
|
||||
renderWithContext(<AddToChannels {...props}/>);
|
||||
expect(screen.getByText(props.townSquareDisplayName, {exact: false})).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should use townSqureDisplayName when not in a public or private channel', () => {
|
||||
props = {...props, currentChannel: {type: 'D', display_name: ''} as Channel};
|
||||
renderWithIntl(<AddToChannels {...props}/>);
|
||||
const props = {...baseProps, currentChannel: {type: 'D', display_name: ''} as Channel};
|
||||
renderWithContext(<AddToChannels {...props}/>);
|
||||
expect(screen.getByText(props.townSquareDisplayName, {exact: false})).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should use the currentChannel display_name when in a channel', () => {
|
||||
props = {...props, currentChannel: {type: 'O', display_name: 'My Awesome Channel'} as Channel};
|
||||
renderWithIntl(<AddToChannels {...props}/>);
|
||||
const props = {...baseProps, currentChannel: {type: 'O', display_name: 'My Awesome Channel'} as Channel};
|
||||
renderWithContext(<AddToChannels {...props}/>);
|
||||
expect(screen.getByText('My Awesome Channel', {exact: false})).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe('custom message', () => {
|
||||
it('UI to toggle custom message opens it when closed', () => {
|
||||
const props = baseProps;
|
||||
const wrapper = mountWithIntl(<AddToChannels {...props}/>);
|
||||
expect(props.toggleCustomMessage).not.toHaveBeenCalled();
|
||||
wrapper.find('a').at(0).simulate('click');
|
||||
@@ -71,10 +66,10 @@ describe('AddToChannels', () => {
|
||||
});
|
||||
|
||||
it('UI to toggle custom message closes it when opened', () => {
|
||||
props = {
|
||||
...props,
|
||||
const props = {
|
||||
...baseProps,
|
||||
customMessage: {
|
||||
...props.customMessage,
|
||||
...baseProps.customMessage,
|
||||
open: true,
|
||||
},
|
||||
};
|
||||
@@ -85,10 +80,10 @@ describe('AddToChannels', () => {
|
||||
});
|
||||
|
||||
it('UI to write custom message calls the on change handler with its input', () => {
|
||||
props = {
|
||||
...props,
|
||||
const props = {
|
||||
...baseProps,
|
||||
customMessage: {
|
||||
...props.customMessage,
|
||||
...baseProps.customMessage,
|
||||
open: true,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -11,9 +11,8 @@ import {General} from 'mattermost-redux/constants';
|
||||
import {trackEvent} from 'actions/telemetry_actions';
|
||||
|
||||
import {
|
||||
act,
|
||||
fireEvent,
|
||||
renderWithIntlAndStore,
|
||||
renderWithContext,
|
||||
screen,
|
||||
} from 'tests/react_testing_utils';
|
||||
import {LicenseLinks, OverActiveUserLimits, Preferences, SelfHostedProducts, StatTypes} from 'utils/constants';
|
||||
@@ -24,10 +23,6 @@ import type {GlobalState} from 'types/store';
|
||||
|
||||
import OverageUsersBannerNotice from './index';
|
||||
|
||||
type RenderComponentArgs = {
|
||||
store?: any;
|
||||
}
|
||||
|
||||
jest.mock('react-redux', () => ({
|
||||
...jest.requireActual('react-redux'),
|
||||
useDispatch: jest.fn().mockReturnValue(() => {}),
|
||||
@@ -128,13 +123,8 @@ describe('components/invitation_modal/overage_users_banner_notice', () => {
|
||||
windowSpy.mockRestore();
|
||||
});
|
||||
|
||||
const renderComponent = ({store}: RenderComponentArgs = {store: initialState}) => {
|
||||
return renderWithIntlAndStore(
|
||||
<OverageUsersBannerNotice/>, store);
|
||||
};
|
||||
|
||||
it('should not render the banner because we are not on overage state', () => {
|
||||
renderComponent();
|
||||
renderWithContext(<OverageUsersBannerNotice/>);
|
||||
|
||||
expect(screen.queryByText(notifyText, {exact: false})).not.toBeInTheDocument();
|
||||
});
|
||||
@@ -153,9 +143,10 @@ describe('components/invitation_modal/overage_users_banner_notice', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderComponent({
|
||||
renderWithContext(
|
||||
<OverageUsersBannerNotice/>,
|
||||
store,
|
||||
});
|
||||
);
|
||||
|
||||
expect(screen.queryByText(notifyText, {exact: false})).not.toBeInTheDocument();
|
||||
});
|
||||
@@ -168,9 +159,10 @@ describe('components/invitation_modal/overage_users_banner_notice', () => {
|
||||
Cloud: 'true',
|
||||
};
|
||||
|
||||
renderComponent({
|
||||
renderWithContext(
|
||||
<OverageUsersBannerNotice/>,
|
||||
store,
|
||||
});
|
||||
);
|
||||
|
||||
expect(screen.queryByText(notifyText, {exact: false})).not.toBeInTheDocument();
|
||||
});
|
||||
@@ -195,9 +187,10 @@ describe('components/invitation_modal/overage_users_banner_notice', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderComponent({
|
||||
renderWithContext(
|
||||
<OverageUsersBannerNotice/>,
|
||||
store,
|
||||
});
|
||||
);
|
||||
|
||||
expect(screen.queryByText(text5PercentageState)).not.toBeInTheDocument();
|
||||
});
|
||||
@@ -212,9 +205,10 @@ describe('components/invitation_modal/overage_users_banner_notice', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderComponent({
|
||||
renderWithContext(
|
||||
<OverageUsersBannerNotice/>,
|
||||
store,
|
||||
});
|
||||
);
|
||||
|
||||
expect(screen.getByText(text5PercentageState)).toBeInTheDocument();
|
||||
expect(screen.getByText(notifyText, {exact: false})).toBeInTheDocument();
|
||||
@@ -238,9 +232,10 @@ describe('components/invitation_modal/overage_users_banner_notice', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderComponent({
|
||||
renderWithContext(
|
||||
<OverageUsersBannerNotice/>,
|
||||
store,
|
||||
});
|
||||
);
|
||||
|
||||
fireEvent.click(screen.getByText(contactSalesTextLink));
|
||||
expect(screen.getByRole('link')).toHaveAttribute(
|
||||
@@ -275,9 +270,10 @@ describe('components/invitation_modal/overage_users_banner_notice', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderComponent({
|
||||
renderWithContext(
|
||||
<OverageUsersBannerNotice/>,
|
||||
store,
|
||||
});
|
||||
);
|
||||
|
||||
expect(screen.getByText(text5PercentageState)).toBeInTheDocument();
|
||||
expect(screen.getByText(notifyText, {exact: false})).toBeInTheDocument();
|
||||
@@ -293,9 +289,10 @@ describe('components/invitation_modal/overage_users_banner_notice', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderComponent({
|
||||
renderWithContext(
|
||||
<OverageUsersBannerNotice/>,
|
||||
store,
|
||||
});
|
||||
);
|
||||
|
||||
fireEvent.click(screen.getByRole('button'));
|
||||
|
||||
@@ -318,9 +315,10 @@ describe('components/invitation_modal/overage_users_banner_notice', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderComponent({
|
||||
renderWithContext(
|
||||
<OverageUsersBannerNotice/>,
|
||||
store,
|
||||
});
|
||||
);
|
||||
|
||||
expect(screen.getByText(text10PercentageState)).toBeInTheDocument();
|
||||
expect(screen.getByText(notifyText, {exact: false})).toBeInTheDocument();
|
||||
@@ -344,9 +342,10 @@ describe('components/invitation_modal/overage_users_banner_notice', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderComponent({
|
||||
renderWithContext(
|
||||
<OverageUsersBannerNotice/>,
|
||||
store,
|
||||
});
|
||||
);
|
||||
|
||||
fireEvent.click(screen.getByText(contactSalesTextLink));
|
||||
expect(screen.getByRole('link')).toHaveAttribute(
|
||||
@@ -381,9 +380,10 @@ describe('components/invitation_modal/overage_users_banner_notice', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderComponent({
|
||||
renderWithContext(
|
||||
<OverageUsersBannerNotice/>,
|
||||
store,
|
||||
});
|
||||
);
|
||||
|
||||
expect(screen.getByText(text10PercentageState)).toBeInTheDocument();
|
||||
expect(screen.getByText(notifyText, {exact: false})).toBeInTheDocument();
|
||||
@@ -409,9 +409,10 @@ describe('components/invitation_modal/overage_users_banner_notice', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderComponent({
|
||||
renderWithContext(
|
||||
<OverageUsersBannerNotice/>,
|
||||
store,
|
||||
});
|
||||
);
|
||||
|
||||
expect(screen.queryByText(text10PercentageState)).not.toBeInTheDocument();
|
||||
expect(screen.queryByText(notifyText, {exact: false})).not.toBeInTheDocument();
|
||||
@@ -427,9 +428,10 @@ describe('components/invitation_modal/overage_users_banner_notice', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderComponent({
|
||||
renderWithContext(
|
||||
<OverageUsersBannerNotice/>,
|
||||
store,
|
||||
});
|
||||
);
|
||||
|
||||
fireEvent.click(screen.getByRole('button'));
|
||||
|
||||
@@ -460,9 +462,10 @@ describe('components/invitation_modal/overage_users_banner_notice', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderComponent({
|
||||
renderWithContext(
|
||||
<OverageUsersBannerNotice/>,
|
||||
store,
|
||||
});
|
||||
);
|
||||
|
||||
fireEvent.click(screen.getByText(expandSeatsTextLink));
|
||||
expect(screen.getByRole('link')).toHaveAttribute('href', `http://testing/subscribe/expand?licenseId=${licenseId}`);
|
||||
@@ -491,9 +494,10 @@ describe('components/invitation_modal/overage_users_banner_notice', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderComponent({
|
||||
renderWithContext(
|
||||
<OverageUsersBannerNotice/>,
|
||||
store,
|
||||
});
|
||||
);
|
||||
|
||||
fireEvent.click(screen.getByText(expandSeatsTextLink));
|
||||
expect(screen.getByRole('link')).toHaveAttribute('href', `http://testing/subscribe/expand?licenseId=${licenseId}`);
|
||||
@@ -523,11 +527,10 @@ describe('components/invitation_modal/overage_users_banner_notice', () => {
|
||||
};
|
||||
store.entities.general.license.IsGovSku = 'true';
|
||||
|
||||
await act(async () => {
|
||||
renderComponent({
|
||||
store,
|
||||
});
|
||||
});
|
||||
renderWithContext(
|
||||
<OverageUsersBannerNotice/>,
|
||||
store,
|
||||
);
|
||||
|
||||
screen.getByText(text10PercentageState);
|
||||
expect(screen.queryByText(notifyText)).not.toBeInTheDocument();
|
||||
|
||||
@@ -7,7 +7,7 @@ import {DotsVerticalIcon} from '@mattermost/compass-icons/components';
|
||||
import {GenericModal} from '@mattermost/components';
|
||||
|
||||
import {
|
||||
renderWithFullContext,
|
||||
renderWithContext,
|
||||
screen,
|
||||
userEvent,
|
||||
waitForElementToBeRemoved,
|
||||
@@ -19,7 +19,7 @@ import {SubMenu} from './sub_menu';
|
||||
|
||||
describe('menu click handlers', () => {
|
||||
test('should be able to open a React Bootstrap modal with the mouse', async () => {
|
||||
renderWithFullContext(
|
||||
renderWithContext(
|
||||
<MenuWithModal/>,
|
||||
);
|
||||
|
||||
@@ -42,7 +42,7 @@ describe('menu click handlers', () => {
|
||||
|
||||
for (const enterOrSpace of ['enter', 'space']) {
|
||||
test(`should be able to open a React Bootstrap modal with the keyboard using the ${enterOrSpace} key`, async () => {
|
||||
renderWithFullContext(
|
||||
renderWithContext(
|
||||
<MenuWithModal/>,
|
||||
);
|
||||
|
||||
@@ -77,7 +77,7 @@ describe('menu click handlers', () => {
|
||||
}
|
||||
|
||||
test('should be able to open a React Bootstrap modal from a submenu with the mouse', async () => {
|
||||
renderWithFullContext(
|
||||
renderWithContext(
|
||||
<MenuWithSubMenuModal/>,
|
||||
);
|
||||
|
||||
@@ -108,7 +108,7 @@ describe('menu click handlers', () => {
|
||||
|
||||
for (const enterOrSpace of ['enter', 'space']) {
|
||||
test(`should be able to open a React Bootstrap modal with the keyboard using the ${enterOrSpace} key`, async () => {
|
||||
renderWithFullContext(
|
||||
renderWithContext(
|
||||
<MenuWithSubMenuModal/>,
|
||||
);
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import Permissions from 'mattermost-redux/constants/permissions';
|
||||
|
||||
import {
|
||||
render,
|
||||
renderWithIntl,
|
||||
renderWithContext,
|
||||
screen,
|
||||
userEvent,
|
||||
waitFor,
|
||||
@@ -404,7 +404,7 @@ describe('components/new_channel_modal', () => {
|
||||
test('should request team creation on submit', async () => {
|
||||
const name = 'Channel name';
|
||||
|
||||
renderWithIntl(
|
||||
renderWithContext(
|
||||
<NewChannelModal/>,
|
||||
);
|
||||
|
||||
|
||||
@@ -7,11 +7,12 @@ import * as reactRedux from 'react-redux';
|
||||
import {
|
||||
act,
|
||||
fireEvent,
|
||||
renderWithIntlAndStore,
|
||||
renderWithContext,
|
||||
screen,
|
||||
} from 'tests/react_testing_utils';
|
||||
import {TestHelper} from 'utils/test_helper';
|
||||
|
||||
import type {GatherIntentProps} from './gather_intent';
|
||||
import {GatherIntent} from './gather_intent';
|
||||
import type {GatherIntentModalProps} from './gather_intent_modal';
|
||||
|
||||
@@ -42,10 +43,6 @@ describe('components/gather_intent/gather_intent.tsx', () => {
|
||||
const gatherIntentText = 'gatherIntentText';
|
||||
const useDispatchMock = jest.spyOn(reactRedux, 'useDispatch');
|
||||
|
||||
beforeEach(() => {
|
||||
useDispatchMock.mockClear();
|
||||
});
|
||||
|
||||
const initialState = {
|
||||
entities: {
|
||||
cloud: {
|
||||
@@ -54,20 +51,17 @@ describe('components/gather_intent/gather_intent.tsx', () => {
|
||||
},
|
||||
};
|
||||
|
||||
//Any because renderWithIntlAndStore doesn't have the store parameter typed as deep partial.
|
||||
const renderComponent = ({store}: {store: any} = {store: initialState}) => {
|
||||
return renderWithIntlAndStore(
|
||||
<GatherIntent
|
||||
modalComponent={DummyModal}
|
||||
gatherIntentText={gatherIntentText}
|
||||
typeGatherIntent='monthlySubscription'
|
||||
/>,
|
||||
store,
|
||||
);
|
||||
const baseProps: GatherIntentProps = {
|
||||
modalComponent: DummyModal as any,
|
||||
gatherIntentText,
|
||||
typeGatherIntent: 'monthlySubscription',
|
||||
};
|
||||
|
||||
it('should display modal if the user click on the modal opener', () => {
|
||||
renderComponent();
|
||||
renderWithContext(
|
||||
<GatherIntent {...baseProps}/>,
|
||||
initialState,
|
||||
);
|
||||
|
||||
fireEvent.click(screen.getByText(gatherIntentText));
|
||||
|
||||
@@ -75,7 +69,10 @@ describe('components/gather_intent/gather_intent.tsx', () => {
|
||||
});
|
||||
|
||||
it('should display the modal opener after close the modal', () => {
|
||||
renderComponent();
|
||||
renderWithContext(
|
||||
<GatherIntent {...baseProps}/>,
|
||||
initialState,
|
||||
);
|
||||
|
||||
fireEvent.click(screen.getByText(gatherIntentText));
|
||||
fireEvent.click(screen.getByLabelText('Close'));
|
||||
@@ -87,7 +84,10 @@ describe('components/gather_intent/gather_intent.tsx', () => {
|
||||
useDispatchMock.mockReturnValue(jest.fn().mockImplementation(() => new Promise((resolve) => {
|
||||
resolve({});
|
||||
})));
|
||||
renderComponent();
|
||||
renderWithContext(
|
||||
<GatherIntent {...baseProps}/>,
|
||||
initialState,
|
||||
);
|
||||
|
||||
fireEvent.click(screen.getByText(gatherIntentText));
|
||||
|
||||
@@ -102,7 +102,10 @@ describe('components/gather_intent/gather_intent.tsx', () => {
|
||||
useDispatchMock.mockReturnValue(jest.fn().mockImplementation(() => new Promise((resolve) => {
|
||||
resolve({});
|
||||
})));
|
||||
renderComponent();
|
||||
renderWithContext(
|
||||
<GatherIntent {...baseProps}/>,
|
||||
initialState,
|
||||
);
|
||||
|
||||
fireEvent.click(screen.getByText(gatherIntentText));
|
||||
|
||||
@@ -126,9 +129,10 @@ describe('components/gather_intent/gather_intent.tsx', () => {
|
||||
monthly_subscription_alt_payment_method: 'Dummy feedback',
|
||||
};
|
||||
|
||||
renderComponent({
|
||||
store: newState,
|
||||
});
|
||||
renderWithContext(
|
||||
<GatherIntent {...baseProps}/>,
|
||||
newState,
|
||||
);
|
||||
|
||||
fireEvent.click(screen.getByText(gatherIntentText));
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ import {useGatherIntent} from './useGatherIntent';
|
||||
|
||||
import './gather_intent.scss';
|
||||
|
||||
interface GatherIntentProps {
|
||||
export interface GatherIntentProps {
|
||||
typeGatherIntent: keyof typeof TypePurchases;
|
||||
gatherIntentText: React.ReactNode;
|
||||
modalComponent: JSXElementConstructor<GatherIntentModalProps>;
|
||||
|
||||
@@ -3,36 +3,27 @@
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import {fireEvent, renderWithIntl, screen} from 'tests/react_testing_utils';
|
||||
import {fireEvent, renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
|
||||
import {GatherIntentModal} from './gather_intent_modal';
|
||||
import type {GatherIntentModalProps} from './gather_intent_modal';
|
||||
|
||||
describe('components/gather_intent/gather_intent_modal.tsx', () => {
|
||||
const renderComponent = (props: Partial<GatherIntentModalProps> | undefined = {}) => {
|
||||
const defaultProps: GatherIntentModalProps = {
|
||||
onClose: jest.fn(),
|
||||
onSave: jest.fn(),
|
||||
isSubmitting: false,
|
||||
showError: false,
|
||||
};
|
||||
|
||||
return renderWithIntl(
|
||||
<GatherIntentModal
|
||||
{...defaultProps}
|
||||
{...props}
|
||||
/>,
|
||||
);
|
||||
const baseProps: GatherIntentModalProps = {
|
||||
onClose: jest.fn(),
|
||||
onSave: jest.fn(),
|
||||
isSubmitting: false,
|
||||
showError: false,
|
||||
};
|
||||
|
||||
it('shouldn\'t be able to save the feedback if the user don\'t click on any option', () => {
|
||||
renderComponent();
|
||||
renderWithContext(<GatherIntentModal {...baseProps}/>);
|
||||
|
||||
expect(screen.queryByText('Save')).toBeDisabled();
|
||||
});
|
||||
|
||||
it('shouldn\'t be able to save the feedback if the user only click in other and leave the input empty', () => {
|
||||
renderComponent();
|
||||
renderWithContext(<GatherIntentModal {...baseProps}/>);
|
||||
|
||||
fireEvent.click(screen.getByText('Other'));
|
||||
|
||||
@@ -40,7 +31,7 @@ describe('components/gather_intent/gather_intent_modal.tsx', () => {
|
||||
});
|
||||
|
||||
it('shouldn\'t be able to save the feedback if the user only click in other and write only white spaces in the input', () => {
|
||||
renderComponent();
|
||||
renderWithContext(<GatherIntentModal {...baseProps}/>);
|
||||
|
||||
fireEvent.click(screen.getByText('Other'));
|
||||
fireEvent.change(screen.getByPlaceholderText('Enter payment option here'), {target: {value: ' \n\t'}});
|
||||
@@ -49,7 +40,7 @@ describe('components/gather_intent/gather_intent_modal.tsx', () => {
|
||||
});
|
||||
|
||||
it('should be able to save the feedback if the user only click in other, leave the input empty and press other option', () => {
|
||||
renderComponent();
|
||||
renderWithContext(<GatherIntentModal {...baseProps}/>);
|
||||
|
||||
fireEvent.click(screen.getByText('Other'));
|
||||
fireEvent.click(screen.getByText('Wire'));
|
||||
@@ -58,7 +49,7 @@ describe('components/gather_intent/gather_intent_modal.tsx', () => {
|
||||
});
|
||||
|
||||
it('should be able save the feedback if the user click in Wire option', () => {
|
||||
renderComponent();
|
||||
renderWithContext(<GatherIntentModal {...baseProps}/>);
|
||||
|
||||
fireEvent.click(screen.getByText('Wire'));
|
||||
|
||||
@@ -66,7 +57,7 @@ describe('components/gather_intent/gather_intent_modal.tsx', () => {
|
||||
});
|
||||
|
||||
it('should be able save the feedback if the user click in ACH option', () => {
|
||||
renderComponent();
|
||||
renderWithContext(<GatherIntentModal {...baseProps}/>);
|
||||
|
||||
fireEvent.click(screen.getByText('ACH'));
|
||||
|
||||
@@ -74,7 +65,7 @@ describe('components/gather_intent/gather_intent_modal.tsx', () => {
|
||||
});
|
||||
|
||||
it('should be able save the feedback if the user click in other option and fill the option', () => {
|
||||
renderComponent();
|
||||
renderWithContext(<GatherIntentModal {...baseProps}/>);
|
||||
|
||||
fireEvent.click(screen.getByText('Other'));
|
||||
fireEvent.change(screen.getByPlaceholderText('Enter payment option here'), {target: {value: 'Test'}});
|
||||
|
||||
@@ -6,7 +6,7 @@ import React from 'react';
|
||||
import type {DeepPartial} from '@mattermost/types/utilities';
|
||||
|
||||
import mergeObjects from 'packages/mattermost-redux/test/merge_objects';
|
||||
import {renderWithFullContext, screen, userEvent} from 'tests/react_testing_utils';
|
||||
import {renderWithContext, screen, userEvent} from 'tests/react_testing_utils';
|
||||
import {getHistory} from 'utils/browser_history';
|
||||
import {Locations} from 'utils/constants';
|
||||
import {TestHelper} from 'utils/test_helper';
|
||||
@@ -65,7 +65,7 @@ describe('PostComponent', () => {
|
||||
};
|
||||
|
||||
test('should show reactions in the center channel', () => {
|
||||
renderWithFullContext(<PostComponent {...baseProps}/>, baseState);
|
||||
renderWithContext(<PostComponent {...baseProps}/>, baseState);
|
||||
|
||||
expect(screen.getByLabelText('reactions')).toBeInTheDocument();
|
||||
});
|
||||
@@ -83,7 +83,7 @@ describe('PostComponent', () => {
|
||||
...baseProps,
|
||||
location: Locations.RHS_ROOT,
|
||||
};
|
||||
const {rerender} = renderWithFullContext(<PostComponent {...props}/>, state);
|
||||
const {rerender} = renderWithContext(<PostComponent {...props}/>, state);
|
||||
|
||||
expect(screen.getByLabelText('reactions')).toBeInTheDocument();
|
||||
|
||||
@@ -101,7 +101,7 @@ describe('PostComponent', () => {
|
||||
...baseProps,
|
||||
location: Locations.SEARCH,
|
||||
};
|
||||
const {rerender} = renderWithFullContext(<PostComponent {...props}/>, baseState);
|
||||
const {rerender} = renderWithContext(<PostComponent {...props}/>, baseState);
|
||||
|
||||
expect(screen.queryByLabelText('reactions')).not.toBeInTheDocument();
|
||||
|
||||
@@ -128,7 +128,7 @@ describe('PostComponent', () => {
|
||||
describe('thread footer', () => {
|
||||
test('should never show thread footer for a post that isn\'t part of a thread', () => {
|
||||
let props: Props = baseProps;
|
||||
const {rerender} = renderWithFullContext(<PostComponent {...props}/>);
|
||||
const {rerender} = renderWithContext(<PostComponent {...props}/>);
|
||||
|
||||
expect(screen.queryByText(/Follow|Following/)).not.toBeInTheDocument();
|
||||
|
||||
@@ -164,7 +164,7 @@ describe('PostComponent', () => {
|
||||
post: rootPost,
|
||||
replyCount: 1,
|
||||
};
|
||||
const {rerender} = renderWithFullContext(<PostComponent {...props}/>, state);
|
||||
const {rerender} = renderWithContext(<PostComponent {...props}/>, state);
|
||||
|
||||
expect(screen.queryByText(/Follow|Following/)).toBeInTheDocument();
|
||||
|
||||
@@ -194,7 +194,7 @@ describe('PostComponent', () => {
|
||||
root_id: 'some_other_post_id',
|
||||
},
|
||||
};
|
||||
const {rerender} = renderWithFullContext(<PostComponent {...props}/>);
|
||||
const {rerender} = renderWithContext(<PostComponent {...props}/>);
|
||||
|
||||
expect(screen.queryByText(/Follow|Following/)).not.toBeInTheDocument();
|
||||
|
||||
@@ -238,7 +238,7 @@ describe('PostComponent', () => {
|
||||
post: rootPost,
|
||||
replyCount: 1,
|
||||
};
|
||||
const {rerender} = renderWithFullContext(<PostComponent {...props}/>, state);
|
||||
const {rerender} = renderWithContext(<PostComponent {...props}/>, state);
|
||||
|
||||
expect(screen.queryByText(/Follow|Following/)).not.toBeInTheDocument();
|
||||
|
||||
@@ -275,7 +275,7 @@ describe('PostComponent', () => {
|
||||
};
|
||||
|
||||
test('should select post in RHS when clicked in center channel', () => {
|
||||
renderWithFullContext(<PostComponent {...propsForRootPost}/>, state);
|
||||
renderWithContext(<PostComponent {...propsForRootPost}/>, state);
|
||||
|
||||
userEvent.click(screen.getByText('1 reply'));
|
||||
|
||||
@@ -288,7 +288,7 @@ describe('PostComponent', () => {
|
||||
...propsForRootPost,
|
||||
team: undefined,
|
||||
};
|
||||
renderWithFullContext(<PostComponent {...props}/>, state);
|
||||
renderWithContext(<PostComponent {...props}/>, state);
|
||||
|
||||
userEvent.click(screen.getByText('1 reply'));
|
||||
|
||||
@@ -302,7 +302,7 @@ describe('PostComponent', () => {
|
||||
...propsForRootPost,
|
||||
location: Locations.SEARCH,
|
||||
};
|
||||
renderWithFullContext(<PostComponent {...props}/>, state);
|
||||
renderWithContext(<PostComponent {...props}/>, state);
|
||||
|
||||
userEvent.click(screen.getByText('1 reply'));
|
||||
|
||||
@@ -316,7 +316,7 @@ describe('PostComponent', () => {
|
||||
location: Locations.SEARCH,
|
||||
team: TestHelper.getTeamMock({id: 'another_team'}),
|
||||
};
|
||||
renderWithFullContext(<PostComponent {...props}/>, state);
|
||||
renderWithContext(<PostComponent {...props}/>, state);
|
||||
|
||||
userEvent.click(screen.getByText('1 reply'));
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import type {ComponentProps} from 'react';
|
||||
|
||||
import {Client4} from 'mattermost-redux/client';
|
||||
|
||||
import {act, renderWithIntlAndStore} from 'tests/react_testing_utils';
|
||||
import {renderWithContext, waitFor} from 'tests/react_testing_utils';
|
||||
import {TestHelper} from 'utils/test_helper';
|
||||
|
||||
import PostEditHistory from './post_edit_history';
|
||||
@@ -35,31 +35,23 @@ describe('components/post_edit_history', () => {
|
||||
];
|
||||
mock.mockResolvedValue(data);
|
||||
|
||||
let wrapper: HTMLElement;
|
||||
const wrapper = await waitFor(() => {
|
||||
return renderWithContext(<PostEditHistory {...baseProps}/>);
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
const {container} = renderWithIntlAndStore(<PostEditHistory {...baseProps}/>, {});
|
||||
wrapper = container;
|
||||
});
|
||||
await act(async () => {
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(mock).toBeCalledWith(baseProps.originalPost.id);
|
||||
});
|
||||
expect(wrapper.container).toMatchSnapshot();
|
||||
expect(mock).toBeCalledWith(baseProps.originalPost.id);
|
||||
});
|
||||
|
||||
test('should display error screen if errors are present', async () => {
|
||||
const error = new Error('An example error');
|
||||
mock.mockRejectedValue(error);
|
||||
|
||||
let wrapper: HTMLElement;
|
||||
const wrapper = await waitFor(() => {
|
||||
return renderWithContext(<PostEditHistory {...baseProps}/>);
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
const {container} = renderWithIntlAndStore(<PostEditHistory {...baseProps}/>, {});
|
||||
wrapper = container;
|
||||
});
|
||||
await act(async () => {
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(mock).toBeCalledWith(baseProps.originalPost.id);
|
||||
});
|
||||
expect(wrapper.container).toMatchSnapshot();
|
||||
expect(mock).toBeCalledWith(baseProps.originalPost.id);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -7,7 +7,7 @@ import type {Post, PostType} from '@mattermost/types/posts';
|
||||
|
||||
import {Posts} from 'mattermost-redux/constants';
|
||||
|
||||
import {renderWithIntlAndStore, screen} from 'tests/react_testing_utils';
|
||||
import {renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
import {TestHelper} from 'utils/test_helper';
|
||||
|
||||
import PostMarkdown from './post_markdown';
|
||||
@@ -56,13 +56,13 @@ describe('components/PostMarkdown', () => {
|
||||
const props = {...baseProps};
|
||||
|
||||
Reflect.deleteProperty(props, 'post');
|
||||
renderWithIntlAndStore(<PostMarkdown {...props}/>, state);
|
||||
renderWithContext(<PostMarkdown {...props}/>, state);
|
||||
|
||||
expect(screen.getByText('message')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should render properly with an empty post', () => {
|
||||
renderWithIntlAndStore(
|
||||
renderWithContext(
|
||||
<PostMarkdown
|
||||
{...baseProps}
|
||||
post={{} as any}
|
||||
@@ -86,7 +86,7 @@ describe('components/PostMarkdown', () => {
|
||||
},
|
||||
}),
|
||||
};
|
||||
renderWithIntlAndStore(<PostMarkdown {...props}/>, state);
|
||||
renderWithContext(<PostMarkdown {...props}/>, state);
|
||||
|
||||
const link = screen.getByRole('link');
|
||||
|
||||
@@ -115,7 +115,7 @@ describe('components/PostMarkdown', () => {
|
||||
},
|
||||
}),
|
||||
};
|
||||
renderWithIntlAndStore(<PostMarkdown {...props}/>, state);
|
||||
renderWithContext(<PostMarkdown {...props}/>, state);
|
||||
expect(screen.getByText('No highlight')).toBeInTheDocument();
|
||||
|
||||
expect(screen.queryByRole('link')).not.toBeInTheDocument();
|
||||
@@ -132,7 +132,7 @@ describe('components/PostMarkdown', () => {
|
||||
},
|
||||
}),
|
||||
};
|
||||
renderWithIntlAndStore(<PostMarkdown {...props}/>, state);
|
||||
renderWithContext(<PostMarkdown {...props}/>, state);
|
||||
|
||||
const groupMention = screen.getByText('@group');
|
||||
|
||||
@@ -152,7 +152,7 @@ describe('components/PostMarkdown', () => {
|
||||
id: 'post_id',
|
||||
}),
|
||||
};
|
||||
renderWithIntlAndStore(<PostMarkdown {...props}/>, state);
|
||||
renderWithContext(<PostMarkdown {...props}/>, state);
|
||||
expect(screen.getByText('message')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -176,7 +176,7 @@ describe('components/PostMarkdown', () => {
|
||||
}),
|
||||
};
|
||||
|
||||
renderWithIntlAndStore(<PostMarkdown {...props}/>, state);
|
||||
renderWithContext(<PostMarkdown {...props}/>, state);
|
||||
expect(screen.getByText('@user')).toBeInTheDocument();
|
||||
expect(screen.getByText('updated the channel header')).toBeInTheDocument();
|
||||
expect(screen.getByText('From:')).toBeInTheDocument();
|
||||
@@ -226,7 +226,7 @@ describe('components/PostMarkdown', () => {
|
||||
},
|
||||
],
|
||||
};
|
||||
renderWithIntlAndStore(<PostMarkdown {...props}/>, state);
|
||||
renderWithContext(<PostMarkdown {...props}/>, state);
|
||||
expect(screen.queryByText('world', {exact: true})).not.toBeInTheDocument();
|
||||
|
||||
// hook message
|
||||
@@ -260,7 +260,7 @@ describe('components/PostMarkdown', () => {
|
||||
},
|
||||
],
|
||||
};
|
||||
renderWithIntlAndStore(<PostMarkdown {...props}/>, state);
|
||||
renderWithContext(<PostMarkdown {...props}/>, state);
|
||||
expect(screen.queryByText('world', {exact: true})).not.toBeInTheDocument();
|
||||
expect(screen.queryByText('world!', {exact: true})).toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -6,7 +6,7 @@ import React from 'react';
|
||||
import type {Channel, ChannelType} from '@mattermost/types/channels';
|
||||
import type {UserProfile} from '@mattermost/types/users';
|
||||
|
||||
import {renderWithIntlAndStore, screen} from 'tests/react_testing_utils';
|
||||
import {renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
import {Constants} from 'utils/constants';
|
||||
import {TestHelper} from 'utils/test_helper';
|
||||
|
||||
@@ -85,7 +85,7 @@ describe('components/post_view/ChannelIntroMessages', () => {
|
||||
|
||||
describe('test Open Channel', () => {
|
||||
test('should match component state, without boards', () => {
|
||||
renderWithIntlAndStore(
|
||||
renderWithContext(
|
||||
<ChannelIntroMessage{...baseProps}/>, initialState,
|
||||
);
|
||||
|
||||
@@ -110,7 +110,7 @@ describe('components/post_view/ChannelIntroMessages', () => {
|
||||
};
|
||||
|
||||
test('should match component state, no profiles', () => {
|
||||
renderWithIntlAndStore(
|
||||
renderWithContext(
|
||||
<ChannelIntroMessage
|
||||
{...props}
|
||||
/>, initialState,
|
||||
@@ -126,7 +126,7 @@ describe('components/post_view/ChannelIntroMessages', () => {
|
||||
});
|
||||
|
||||
test('should match component state, with profiles', () => {
|
||||
renderWithIntlAndStore(
|
||||
renderWithContext(
|
||||
<ChannelIntroMessage
|
||||
{...props}
|
||||
channelProfiles={users}
|
||||
@@ -171,7 +171,7 @@ describe('components/post_view/ChannelIntroMessages', () => {
|
||||
};
|
||||
|
||||
test('should match component state, without teammate', () => {
|
||||
renderWithIntlAndStore(
|
||||
renderWithContext(
|
||||
<ChannelIntroMessage
|
||||
{...props}
|
||||
/>, initialState,
|
||||
@@ -183,7 +183,7 @@ describe('components/post_view/ChannelIntroMessages', () => {
|
||||
});
|
||||
|
||||
test('should match component state, with teammate', () => {
|
||||
renderWithIntlAndStore(
|
||||
renderWithContext(
|
||||
<ChannelIntroMessage
|
||||
{...props}
|
||||
teammate={user1 as UserProfile}
|
||||
@@ -229,7 +229,7 @@ describe('components/post_view/ChannelIntroMessages', () => {
|
||||
};
|
||||
|
||||
test('should match component state, readonly', () => {
|
||||
renderWithIntlAndStore(
|
||||
renderWithContext(
|
||||
<ChannelIntroMessage
|
||||
{...props}
|
||||
isReadOnly={true}
|
||||
@@ -246,7 +246,7 @@ describe('components/post_view/ChannelIntroMessages', () => {
|
||||
});
|
||||
|
||||
test('should match component state without any permission', () => {
|
||||
renderWithIntlAndStore(
|
||||
renderWithContext(
|
||||
<ChannelIntroMessage
|
||||
{...props}
|
||||
teamIsGroupConstrained={true}
|
||||
@@ -278,7 +278,7 @@ describe('components/post_view/ChannelIntroMessages', () => {
|
||||
};
|
||||
|
||||
test('should match component state', () => {
|
||||
renderWithIntlAndStore(
|
||||
renderWithContext(
|
||||
<ChannelIntroMessage
|
||||
{...props}
|
||||
/>, initialState,
|
||||
|
||||
@@ -5,7 +5,7 @@ import React from 'react';
|
||||
|
||||
import {Posts} from 'mattermost-redux/constants';
|
||||
|
||||
import {renderWithIntlAndStore, screen, userEvent} from 'tests/react_testing_utils';
|
||||
import {renderWithContext, screen, userEvent} from 'tests/react_testing_utils';
|
||||
import {TestHelper} from 'utils/test_helper';
|
||||
|
||||
import LastUsers from './last_users';
|
||||
@@ -49,7 +49,7 @@ describe('components/post_view/combined_system_message/LastUsers', () => {
|
||||
} as any;
|
||||
|
||||
test('should match component state', () => {
|
||||
renderWithIntlAndStore(
|
||||
renderWithContext(
|
||||
<LastUsers {...baseProps}/>, initialState,
|
||||
);
|
||||
|
||||
@@ -66,7 +66,7 @@ describe('components/post_view/combined_system_message/LastUsers', () => {
|
||||
});
|
||||
|
||||
test('should match component state, expanded', () => {
|
||||
renderWithIntlAndStore(
|
||||
renderWithContext(
|
||||
<LastUsers {...baseProps}/>, initialState,
|
||||
);
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import {render, renderWithIntl, screen} from 'tests/react_testing_utils';
|
||||
import {render, renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
|
||||
import CommentedOnFilesMessage from './commented_on_files_message';
|
||||
|
||||
@@ -45,7 +45,7 @@ describe('components/CommentedOnFilesMessage', () => {
|
||||
fileInfos,
|
||||
};
|
||||
|
||||
renderWithIntl(
|
||||
renderWithContext(
|
||||
<CommentedOnFilesMessage {...props}/>,
|
||||
);
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import {renderWithIntlAndStore, screen} from 'tests/react_testing_utils';
|
||||
import {renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
|
||||
import DateSeparator from './date_separator';
|
||||
|
||||
@@ -20,7 +20,7 @@ describe('components/post_view/DateSeparator', () => {
|
||||
} as any;
|
||||
test('should render Timestamp inside of a BasicSeparator and pass date/value to it', () => {
|
||||
const value = new Date('Fri Jan 12 2018 20:15:13 GMT+1200 (+12)');
|
||||
renderWithIntlAndStore(
|
||||
renderWithContext(
|
||||
<DateSeparator
|
||||
date={value}
|
||||
/>, initialState,
|
||||
|
||||
@@ -7,13 +7,13 @@ import type {AppBinding, AppCallResponse} from '@mattermost/types/apps';
|
||||
import type {Post} from '@mattermost/types/posts';
|
||||
|
||||
import {
|
||||
renderWithIntlAndStore,
|
||||
renderWithContext,
|
||||
screen,
|
||||
userEvent,
|
||||
waitFor,
|
||||
} from 'tests/react_testing_utils';
|
||||
|
||||
import ButtonBinding, {ButtonBinding as ButtonBindingUnwrapped} from './button_binding';
|
||||
import ButtonBinding from './button_binding';
|
||||
|
||||
describe('components/post_view/embedded_bindings/button_binding/', () => {
|
||||
const post = {
|
||||
@@ -80,25 +80,14 @@ describe('components/post_view/embedded_bindings/button_binding/', () => {
|
||||
},
|
||||
};
|
||||
|
||||
const intl = {
|
||||
formatMessage: (message: {id: string; defaultMessage: string}) => {
|
||||
return message.defaultMessage;
|
||||
},
|
||||
} as any;
|
||||
|
||||
test('should match default component state', () => {
|
||||
renderWithIntlAndStore(<ButtonBinding {...baseProps}/>, initialState);
|
||||
renderWithContext(<ButtonBinding {...baseProps}/>, initialState);
|
||||
|
||||
screen.getByText('some_label');
|
||||
});
|
||||
|
||||
test('should call doAppSubmit on click', async () => {
|
||||
const props = {
|
||||
...baseProps,
|
||||
intl,
|
||||
};
|
||||
|
||||
renderWithIntlAndStore(<ButtonBindingUnwrapped {...props}/>, initialState);
|
||||
renderWithContext(<ButtonBinding {...baseProps}/>, initialState);
|
||||
|
||||
screen.getByText('some_label');
|
||||
|
||||
@@ -144,10 +133,9 @@ describe('components/post_view/embedded_bindings/button_binding/', () => {
|
||||
postEphemeralCallResponseForPost: jest.fn(),
|
||||
openAppsModal: jest.fn(),
|
||||
},
|
||||
intl,
|
||||
};
|
||||
|
||||
renderWithIntlAndStore(<ButtonBindingUnwrapped {...props}/>, initialState);
|
||||
renderWithContext(<ButtonBinding {...props}/>, initialState);
|
||||
|
||||
screen.getByText('some_label');
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ type State = {
|
||||
executing: boolean;
|
||||
}
|
||||
|
||||
export class ButtonBinding extends React.PureComponent<Props, State> {
|
||||
class ButtonBinding extends React.PureComponent<Props, State> {
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
|
||||
@@ -5,7 +5,7 @@ import React from 'react';
|
||||
|
||||
import FailedPostOptions from 'components/post_view/failed_post_options/failed_post_options';
|
||||
|
||||
import {renderWithIntl, screen, userEvent} from 'tests/react_testing_utils';
|
||||
import {renderWithContext, screen, userEvent} from 'tests/react_testing_utils';
|
||||
import {TestHelper} from 'utils/test_helper';
|
||||
|
||||
describe('components/post_view/FailedPostOptions', () => {
|
||||
@@ -18,7 +18,7 @@ describe('components/post_view/FailedPostOptions', () => {
|
||||
};
|
||||
|
||||
test('should match default component state', () => {
|
||||
renderWithIntl(<FailedPostOptions {...baseProps}/>);
|
||||
renderWithContext(<FailedPostOptions {...baseProps}/>);
|
||||
|
||||
const retryLink = screen.getByText('Retry');
|
||||
const cancelLink = screen.getByText('Cancel');
|
||||
@@ -43,7 +43,7 @@ describe('components/post_view/FailedPostOptions', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderWithIntl(<FailedPostOptions {...props}/>);
|
||||
renderWithContext(<FailedPostOptions {...props}/>);
|
||||
|
||||
const retryLink = screen.getByText('Retry');
|
||||
|
||||
@@ -65,7 +65,7 @@ describe('components/post_view/FailedPostOptions', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderWithIntl(<FailedPostOptions {...props}/>);
|
||||
renderWithContext(<FailedPostOptions {...props}/>);
|
||||
|
||||
const cancelLink = screen.getByText('Cancel');
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import {renderWithIntlAndStore, screen} from 'tests/react_testing_utils';
|
||||
import {renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
|
||||
import FloatingTimestamp from './floating_timestamp';
|
||||
|
||||
@@ -26,7 +26,7 @@ describe('components/post_view/FloatingTimestamp', () => {
|
||||
};
|
||||
|
||||
test('should match component state with given props', () => {
|
||||
renderWithIntlAndStore(<FloatingTimestamp {...baseProps}/>, initialState);
|
||||
renderWithContext(<FloatingTimestamp {...baseProps}/>, initialState);
|
||||
|
||||
const floatingTimeStamp = screen.getByTestId('floatingTimestamp');
|
||||
const time = screen.getByText('January 01, 1970');
|
||||
|
||||
@@ -7,7 +7,7 @@ import {Preferences} from 'mattermost-redux/constants';
|
||||
import type {Theme} from 'mattermost-redux/selectors/entities/preferences';
|
||||
import {changeOpacity} from 'mattermost-redux/utils/theme_utils';
|
||||
|
||||
import {screen, userEvent, renderWithIntl} from 'tests/react_testing_utils';
|
||||
import {renderWithContext, screen, userEvent} from 'tests/react_testing_utils';
|
||||
|
||||
import ActionButton from './action_button';
|
||||
|
||||
@@ -19,7 +19,7 @@ describe('components/post_view/message_attachments/action_button.jsx', () => {
|
||||
};
|
||||
|
||||
test('should match default component state with given props', () => {
|
||||
renderWithIntl(<ActionButton {...baseProps}/>);
|
||||
renderWithContext(<ActionButton {...baseProps}/>);
|
||||
|
||||
const button = screen.getByRole('button');
|
||||
expect(button).toHaveAttribute('data-action-cookie', 'cookie-contents');
|
||||
@@ -30,7 +30,7 @@ describe('components/post_view/message_attachments/action_button.jsx', () => {
|
||||
});
|
||||
|
||||
test('should call handleAction on click', () => {
|
||||
renderWithIntl(<ActionButton {...baseProps}/>);
|
||||
renderWithContext(<ActionButton {...baseProps}/>);
|
||||
|
||||
const button = screen.getByRole('button');
|
||||
|
||||
@@ -45,7 +45,7 @@ describe('components/post_view/message_attachments/action_button.jsx', () => {
|
||||
action: {...baseProps.action, style: 'onlineIndicator'},
|
||||
};
|
||||
|
||||
renderWithIntl(<ActionButton {...props}/>);
|
||||
renderWithContext(<ActionButton {...props}/>);
|
||||
|
||||
const button = screen.getByRole('button');
|
||||
|
||||
@@ -60,7 +60,7 @@ describe('components/post_view/message_attachments/action_button.jsx', () => {
|
||||
action: {...baseProps.action, style: 'danger'},
|
||||
};
|
||||
|
||||
renderWithIntl(<ActionButton {...props}/>);
|
||||
renderWithContext(<ActionButton {...props}/>);
|
||||
|
||||
const button = screen.getByRole('button');
|
||||
|
||||
@@ -74,7 +74,7 @@ describe('components/post_view/message_attachments/action_button.jsx', () => {
|
||||
action: {...baseProps.action, style: 'success'},
|
||||
};
|
||||
|
||||
renderWithIntl(<ActionButton {...props}/>);
|
||||
renderWithContext(<ActionButton {...props}/>);
|
||||
const button = screen.getByRole('button');
|
||||
|
||||
expect(button).toHaveStyle(`background-color: ${changeOpacity('#339970', 0.08)}`);
|
||||
@@ -87,7 +87,7 @@ describe('components/post_view/message_attachments/action_button.jsx', () => {
|
||||
action: {...baseProps.action, style: '#28a745'},
|
||||
};
|
||||
|
||||
renderWithIntl(<ActionButton {...props}/>);
|
||||
renderWithContext(<ActionButton {...props}/>);
|
||||
const button = screen.getByRole('button');
|
||||
|
||||
expect(button).toHaveStyle(`background-color: ${changeOpacity(props.action.style, 0.08)}`);
|
||||
@@ -100,7 +100,7 @@ describe('components/post_view/message_attachments/action_button.jsx', () => {
|
||||
action: {...baseProps.action, style: '#wrong'},
|
||||
};
|
||||
|
||||
renderWithIntl(<ActionButton {...props}/>);
|
||||
renderWithContext(<ActionButton {...props}/>);
|
||||
const button = screen.getByRole('button');
|
||||
|
||||
expect(button.style.length).toBe(0);
|
||||
@@ -112,7 +112,7 @@ describe('components/post_view/message_attachments/action_button.jsx', () => {
|
||||
action: {...baseProps.action, style: undefined},
|
||||
};
|
||||
|
||||
renderWithIntl(<ActionButton {...props}/>);
|
||||
renderWithContext(<ActionButton {...props}/>);
|
||||
const button = screen.getByRole('button');
|
||||
|
||||
expect(button.style.length).toBe(0);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import {renderWithIntlAndStore, screen} from 'tests/react_testing_utils';
|
||||
import {renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
|
||||
import ActionMenu from './action_menu';
|
||||
|
||||
@@ -32,7 +32,7 @@ describe('components/post_view/message_attachments/ActionMenu', () => {
|
||||
};
|
||||
|
||||
test('should start with nothing selected', async () => {
|
||||
renderWithIntlAndStore(<ActionMenu {...baseProps}/>, {});
|
||||
renderWithContext(<ActionMenu {...baseProps}/>);
|
||||
|
||||
const autoCompleteSelector = screen.getByTestId('autoCompleteSelector');
|
||||
const input = screen.getByPlaceholderText('action');
|
||||
@@ -55,7 +55,7 @@ describe('components/post_view/message_attachments/ActionMenu', () => {
|
||||
default_option: '2',
|
||||
},
|
||||
};
|
||||
renderWithIntlAndStore(<ActionMenu {...props}/>, {});
|
||||
renderWithContext(<ActionMenu {...props}/>);
|
||||
|
||||
const input = screen.getByPlaceholderText('action');
|
||||
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import {renderWithIntl, screen} from 'tests/react_testing_utils';
|
||||
import {renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
|
||||
import NewMessageSeparator from './new_message_separator';
|
||||
|
||||
describe('components/post_view/new_message_separator', () => {
|
||||
test('should render new_message_separator', () => {
|
||||
renderWithIntl(
|
||||
renderWithContext(
|
||||
<NewMessageSeparator
|
||||
separatorId='1234'
|
||||
newMessagesSeparatorActions={[]}
|
||||
|
||||
@@ -6,7 +6,7 @@ import React from 'react';
|
||||
import type {GlobalState} from '@mattermost/types/store';
|
||||
import type {DeepPartial} from '@mattermost/types/utilities';
|
||||
|
||||
import {renderWithIntlAndStore, screen} from 'tests/react_testing_utils';
|
||||
import {renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
|
||||
import PostAttachmentContainer from './post_attachment_container';
|
||||
import type {Props} from './post_attachment_container';
|
||||
@@ -37,7 +37,7 @@ describe('PostAttachmentContainer', () => {
|
||||
};
|
||||
|
||||
test('should render correctly', () => {
|
||||
renderWithIntlAndStore(
|
||||
renderWithContext(
|
||||
<PostAttachmentContainer {...baseProps}/>, initialState,
|
||||
);
|
||||
|
||||
|
||||
@@ -3,12 +3,10 @@
|
||||
|
||||
import React from 'react';
|
||||
import {createIntl, useIntl} from 'react-intl';
|
||||
import {Provider} from 'react-redux';
|
||||
|
||||
import enMessages from 'i18n/en.json';
|
||||
import esMessages from 'i18n/es.json';
|
||||
import {render, renderWithIntlAndStore, screen} from 'tests/react_testing_utils';
|
||||
import {mockStore} from 'tests/test_store';
|
||||
import {renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
import {TestHelper} from 'utils/test_helper';
|
||||
|
||||
import LatestPostReader from './latest_post_reader';
|
||||
@@ -58,14 +56,11 @@ describe('LatestPostReader', () => {
|
||||
};
|
||||
|
||||
test('should render aria-label as a child in the given locale', () => {
|
||||
const store = mockStore(baseState);
|
||||
|
||||
(useIntl as jest.Mock).mockImplementation(() => createIntl({locale: 'en', messages: enMessages, defaultLocale: 'en'}));
|
||||
|
||||
const {rerender} = render(
|
||||
<Provider store={store.store}>
|
||||
<LatestPostReader {...baseProps}/>
|
||||
</Provider>,
|
||||
const {rerender} = renderWithContext(
|
||||
<LatestPostReader {...baseProps}/>,
|
||||
baseState,
|
||||
);
|
||||
|
||||
const prevMessage = screen.getByText(`January 1, ${author.username} wrote, This is a test`, {exact: false});
|
||||
@@ -74,7 +69,7 @@ describe('LatestPostReader', () => {
|
||||
|
||||
(useIntl as jest.Mock).mockImplementation(() => createIntl({locale: 'es', messages: esMessages, defaultLocale: 'es'}));
|
||||
|
||||
rerender(<Provider store={store.store}> <LatestPostReader {...baseProps}/></Provider>);
|
||||
rerender(<LatestPostReader {...baseProps}/>);
|
||||
const januaryInSpanish = 'enero';
|
||||
const message = screen.getByText(`${januaryInSpanish}, ${author.username} wrote, This is a test`, {exact: false});
|
||||
|
||||
@@ -88,7 +83,7 @@ describe('LatestPostReader', () => {
|
||||
postIds: [],
|
||||
};
|
||||
|
||||
renderWithIntlAndStore(<LatestPostReader {...props}/>, baseState);
|
||||
renderWithContext(<LatestPostReader {...props}/>, baseState);
|
||||
|
||||
// body should be empty
|
||||
const message = screen.queryByText('This is a test');
|
||||
|
||||
@@ -9,7 +9,7 @@ import {Client4} from 'mattermost-redux/client';
|
||||
|
||||
import {STORAGE_KEY_PURCHASE_IN_PROGRESS} from 'components/self_hosted_purchases/constants';
|
||||
|
||||
import {renderWithIntlAndStore, screen} from 'tests/react_testing_utils';
|
||||
import {renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
import {TestHelper as TH} from 'utils/test_helper';
|
||||
|
||||
import type {GlobalState} from 'types/store';
|
||||
@@ -59,7 +59,7 @@ describe('PurchaseInProgressModal', () => {
|
||||
it('when purchaser and user emails are different, user is instructed to wait', () => {
|
||||
const stateOverride: DeepPartial<GlobalState> = JSON.parse(JSON.stringify(initialState));
|
||||
stateOverride.entities!.users!.currentUserId = 'otherUserId';
|
||||
renderWithIntlAndStore(
|
||||
renderWithContext(
|
||||
<div id='root-portal'>
|
||||
<PurchaseInProgressModal
|
||||
purchaserEmail={'admin@example.com'}
|
||||
@@ -72,7 +72,7 @@ describe('PurchaseInProgressModal', () => {
|
||||
});
|
||||
|
||||
it('when purchaser and user emails are same, allows user to reset purchase flow', () => {
|
||||
renderWithIntlAndStore(
|
||||
renderWithContext(
|
||||
<div id='root-portal'>
|
||||
<PurchaseInProgressModal
|
||||
purchaserEmail={'admin@example.com'}
|
||||
|
||||
@@ -5,13 +5,13 @@ import React from 'react';
|
||||
|
||||
import * as controlModalHooks from 'components/common/hooks/useControlModal';
|
||||
|
||||
import {renderWithIntlAndStore, screen} from 'tests/react_testing_utils';
|
||||
import {renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
|
||||
import ScreeningInProgressModal from './';
|
||||
|
||||
describe('ScreeningInProgressModal', () => {
|
||||
it('informs customer that the subscription is under review', () => {
|
||||
renderWithIntlAndStore(<ScreeningInProgressModal/>, {});
|
||||
renderWithContext(<ScreeningInProgressModal/>);
|
||||
screen.getByText('Your transaction is being reviewed');
|
||||
});
|
||||
|
||||
@@ -19,7 +19,7 @@ describe('ScreeningInProgressModal', () => {
|
||||
const mockClose = jest.fn();
|
||||
jest.spyOn(controlModalHooks, 'useControlScreeningInProgressModal').mockImplementation(() => ({close: mockClose, open: jest.fn()}));
|
||||
|
||||
renderWithIntlAndStore(<ScreeningInProgressModal/>, {});
|
||||
renderWithContext(<ScreeningInProgressModal/>);
|
||||
screen.getAllByText('Close')[1].click();
|
||||
expect(mockClose).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@@ -3,16 +3,12 @@
|
||||
|
||||
import React from 'react';
|
||||
import type {ComponentProps} from 'react';
|
||||
import {IntlProvider} from 'react-intl';
|
||||
import {Provider} from 'react-redux';
|
||||
|
||||
import SearchChannelProvider from 'components/suggestion/search_channel_provider';
|
||||
import SearchDateProvider from 'components/suggestion/search_date_provider';
|
||||
import SearchUserProvider from 'components/suggestion/search_user_provider';
|
||||
|
||||
import en from 'i18n/en.json';
|
||||
import {render} from 'tests/react_testing_utils';
|
||||
import mockStore from 'tests/test_store';
|
||||
import {renderWithContext} from 'tests/react_testing_utils';
|
||||
|
||||
import SearchBar from './search_bar';
|
||||
|
||||
@@ -22,24 +18,7 @@ const suggestionProviders = [
|
||||
new SearchUserProvider(jest.fn()),
|
||||
];
|
||||
|
||||
const wrapIntl = (component: JSX.Element) => (
|
||||
<IntlProvider
|
||||
locale={'en'}
|
||||
messages={en}
|
||||
>
|
||||
{component}
|
||||
</IntlProvider>
|
||||
);
|
||||
|
||||
describe('components/search_bar/SearchBar', () => {
|
||||
const store = mockStore({});
|
||||
|
||||
const wrapStore = (component: JSX.Element) => (
|
||||
<Provider store={store}>
|
||||
{component}
|
||||
</Provider>
|
||||
);
|
||||
|
||||
const baseProps: ComponentProps<typeof SearchBar> = {
|
||||
suggestionProviders,
|
||||
searchTerms: '',
|
||||
@@ -61,54 +40,46 @@ describe('components/search_bar/SearchBar', () => {
|
||||
};
|
||||
|
||||
it('should match snapshot without search', () => {
|
||||
const {container} = render(
|
||||
wrapStore(wrapIntl(<SearchBar {...baseProps}/>)),
|
||||
const {container} = renderWithContext(
|
||||
<SearchBar {...baseProps}/>,
|
||||
);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should match snapshot without search, without searchType', () => {
|
||||
const {container} = render(
|
||||
wrapStore(wrapIntl((
|
||||
<SearchBar {...baseProps}/>
|
||||
))),
|
||||
const {container} = renderWithContext(
|
||||
<SearchBar {...baseProps}/>,
|
||||
);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should match snapshot without search, with searchType', () => {
|
||||
const {container} = render(
|
||||
wrapStore(wrapIntl((
|
||||
<SearchBar
|
||||
{...baseProps}
|
||||
searchType='files'
|
||||
/>
|
||||
))),
|
||||
const {container} = renderWithContext(
|
||||
<SearchBar
|
||||
{...baseProps}
|
||||
searchType='files'
|
||||
/>,
|
||||
);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should match snapshot with search, with searchType', () => {
|
||||
const {container} = render(
|
||||
wrapStore(wrapIntl((
|
||||
<SearchBar
|
||||
{...baseProps}
|
||||
searchTerms={'test'}
|
||||
searchType='files'
|
||||
/>
|
||||
))),
|
||||
const {container} = renderWithContext(
|
||||
<SearchBar
|
||||
{...baseProps}
|
||||
searchTerms={'test'}
|
||||
searchType='files'
|
||||
/>,
|
||||
);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should match snapshot with search', () => {
|
||||
const {container} = render(
|
||||
wrapStore(wrapIntl((
|
||||
<SearchBar
|
||||
{...baseProps}
|
||||
searchTerms={'test'}
|
||||
/>
|
||||
))),
|
||||
const {container} = renderWithContext(
|
||||
<SearchBar
|
||||
{...baseProps}
|
||||
searchTerms={'test'}
|
||||
/>,
|
||||
);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import {renderWithIntl, screen} from 'tests/react_testing_utils';
|
||||
import {renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
import {RHSStates} from 'utils/constants';
|
||||
|
||||
import type {RhsState} from 'types/store/rhs';
|
||||
@@ -12,7 +12,7 @@ import Header from './search_results_header';
|
||||
|
||||
describe('search_results_header', () => {
|
||||
test('should display back button when the parent is channel info', () => {
|
||||
renderWithIntl(
|
||||
renderWithContext(
|
||||
<Header
|
||||
previousRhsState={RHSStates.CHANNEL_INFO as RhsState}
|
||||
canGoBack={true}
|
||||
@@ -30,7 +30,7 @@ describe('search_results_header', () => {
|
||||
expect(screen.getByLabelText('Back Icon')).toBeInTheDocument();
|
||||
});
|
||||
test('should NOT diplay expand when the parent is channel info', () => {
|
||||
renderWithIntl(
|
||||
renderWithContext(
|
||||
<Header
|
||||
previousRhsState={RHSStates.CHANNEL_INFO as RhsState}
|
||||
canGoBack={true}
|
||||
@@ -48,7 +48,7 @@ describe('search_results_header', () => {
|
||||
expect(screen.queryByLabelText('Expand Sidebar Icon')).not.toBeInTheDocument();
|
||||
});
|
||||
test('should diplay expand when the parent is NOT channel info', () => {
|
||||
renderWithIntl(
|
||||
renderWithContext(
|
||||
<Header
|
||||
previousRhsState={RHSStates.FLAG as RhsState}
|
||||
canGoBack={true}
|
||||
|
||||
@@ -11,7 +11,7 @@ import type {DeepPartial} from '@mattermost/types/utilities';
|
||||
import mergeObjects from 'packages/mattermost-redux/test/merge_objects';
|
||||
import {
|
||||
fireEvent,
|
||||
renderWithIntlAndStore,
|
||||
renderWithContext,
|
||||
screen,
|
||||
waitFor,
|
||||
} from 'tests/react_testing_utils';
|
||||
@@ -270,7 +270,7 @@ function fillForm(form: PurchaseForm) {
|
||||
|
||||
describe('SelfHostedExpansionModal Open', () => {
|
||||
it('renders the form', () => {
|
||||
renderWithIntlAndStore(<div id='root-portal'><SelfHostedExpansionModal/></div>, initialState);
|
||||
renderWithContext(<div id='root-portal'><SelfHostedExpansionModal/></div>, initialState);
|
||||
|
||||
screen.getByText('Provide your payment details');
|
||||
screen.getByText('Add new seats');
|
||||
@@ -283,13 +283,13 @@ describe('SelfHostedExpansionModal Open', () => {
|
||||
});
|
||||
|
||||
it('filling the form enables expansion', () => {
|
||||
renderWithIntlAndStore(<div id='root-portal'><SelfHostedExpansionModal/></div>, initialState);
|
||||
renderWithContext(<div id='root-portal'><SelfHostedExpansionModal/></div>, initialState);
|
||||
expect(screen.getByText('Complete purchase')).toBeDisabled();
|
||||
fillForm(defaultSuccessForm);
|
||||
});
|
||||
|
||||
it('happy path submit shows success screen when confirmation succeeds', async () => {
|
||||
renderWithIntlAndStore(<div id='root-portal'><SelfHostedExpansionModal/></div>, initialState);
|
||||
renderWithContext(<div id='root-portal'><SelfHostedExpansionModal/></div>, initialState);
|
||||
expect(screen.getByText('Complete purchase')).toBeDisabled();
|
||||
|
||||
const upgradeButton = fillForm(defaultSuccessForm);
|
||||
@@ -299,7 +299,7 @@ describe('SelfHostedExpansionModal Open', () => {
|
||||
});
|
||||
|
||||
it('happy path submit shows submitting screen while requesting confirmation', async () => {
|
||||
renderWithIntlAndStore(<div id='root-portal'><SelfHostedExpansionModal/></div>, initialState);
|
||||
renderWithContext(<div id='root-portal'><SelfHostedExpansionModal/></div>, initialState);
|
||||
expect(screen.getByText('Complete purchase')).toBeDisabled();
|
||||
|
||||
const upgradeButton = fillForm(defaultSuccessForm);
|
||||
@@ -309,7 +309,7 @@ describe('SelfHostedExpansionModal Open', () => {
|
||||
});
|
||||
|
||||
it('sad path submit shows error screen', async () => {
|
||||
renderWithIntlAndStore(<div id='root-portal'><SelfHostedExpansionModal/></div>, initialState);
|
||||
renderWithContext(<div id='root-portal'><SelfHostedExpansionModal/></div>, initialState);
|
||||
expect(screen.getByText('Complete purchase')).toBeDisabled();
|
||||
fillForm(defaultSuccessForm);
|
||||
changeByPlaceholder('Organization Name', failOrg);
|
||||
@@ -323,7 +323,7 @@ describe('SelfHostedExpansionModal Open', () => {
|
||||
|
||||
describe('SelfHostedExpansionModal RHS Card', () => {
|
||||
it('New seats input should be pre-populated with the difference from the active users and licensed seats', () => {
|
||||
renderWithIntlAndStore(<div id='root-portal'><SelfHostedExpansionModal/></div>, initialState);
|
||||
renderWithContext(<div id='root-portal'><SelfHostedExpansionModal/></div>, initialState);
|
||||
|
||||
const expectedPrePopulatedSeats = (initialState.entities?.users?.filteredStats?.total_users_count || 1) - parseInt(initialState.entities?.general?.license?.Users || '1', 10);
|
||||
|
||||
@@ -335,7 +335,7 @@ describe('SelfHostedExpansionModal RHS Card', () => {
|
||||
it('Seat input only allows users to fill input with the licensed seats and active users difference if it is not 0', () => {
|
||||
const expectedUserOverage = '50';
|
||||
|
||||
renderWithIntlAndStore(<div id='root-portal'><SelfHostedExpansionModal/></div>, initialState);
|
||||
renderWithContext(<div id='root-portal'><SelfHostedExpansionModal/></div>, initialState);
|
||||
fillForm(defaultSuccessForm);
|
||||
|
||||
// The seat input should already have the expected value.
|
||||
@@ -362,7 +362,7 @@ describe('SelfHostedExpansionModal RHS Card', () => {
|
||||
|
||||
const expectedAddNewSeats = '1';
|
||||
|
||||
renderWithIntlAndStore(<div id='root-portal'><SelfHostedExpansionModal/></div>, state);
|
||||
renderWithContext(<div id='root-portal'><SelfHostedExpansionModal/></div>, state);
|
||||
fillForm(defaultSuccessForm);
|
||||
|
||||
// Try to set a negative value.
|
||||
@@ -375,7 +375,7 @@ describe('SelfHostedExpansionModal RHS Card', () => {
|
||||
});
|
||||
|
||||
it('Cost per User should be represented as the current subscription price multiplied by the remaining months', () => {
|
||||
renderWithIntlAndStore(<div id='root-portal'><SelfHostedExpansionModal/></div>, initialState);
|
||||
renderWithContext(<div id='root-portal'><SelfHostedExpansionModal/></div>, initialState);
|
||||
|
||||
const expectedCostPerUser = monthsUntilLicenseExpiry * mockProfessionalProduct.price_per_seat;
|
||||
|
||||
@@ -389,7 +389,7 @@ describe('SelfHostedExpansionModal RHS Card', () => {
|
||||
});
|
||||
|
||||
it('Total cost User should be represented as the current subscription price multiplied by the remaining months multiplied by the number of users', () => {
|
||||
renderWithIntlAndStore(<div id='root-portal'><SelfHostedExpansionModal/></div>, initialState);
|
||||
renderWithContext(<div id='root-portal'><SelfHostedExpansionModal/></div>, initialState);
|
||||
const seatsInputValue = 100;
|
||||
changeByTestId('seatsInput', seatsInputValue.toString());
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import type {DeepPartial} from '@mattermost/types/utilities';
|
||||
|
||||
import {
|
||||
fireEvent,
|
||||
renderWithIntlAndStore,
|
||||
renderWithContext,
|
||||
screen,
|
||||
waitFor,
|
||||
} from 'tests/react_testing_utils';
|
||||
@@ -254,7 +254,7 @@ function fillForm(form: PurchaseForm) {
|
||||
|
||||
describe('SelfHostedPurchaseModal', () => {
|
||||
it('renders the form', () => {
|
||||
renderWithIntlAndStore(<div id='root-portal'><SelfHostedPurchaseModal productId={'prod_professional'}/></div>, initialState);
|
||||
renderWithContext(<div id='root-portal'><SelfHostedPurchaseModal productId={'prod_professional'}/></div>, initialState);
|
||||
|
||||
// check title, and some of the most prominent details and secondary actions
|
||||
screen.getByText('Provide your payment details');
|
||||
@@ -267,13 +267,13 @@ describe('SelfHostedPurchaseModal', () => {
|
||||
});
|
||||
|
||||
it('filling the form enables signup', () => {
|
||||
renderWithIntlAndStore(<div id='root-portal'><SelfHostedPurchaseModal productId={'prod_professional'}/></div>, initialState);
|
||||
renderWithContext(<div id='root-portal'><SelfHostedPurchaseModal productId={'prod_professional'}/></div>, initialState);
|
||||
expect(screen.getByText('Upgrade')).toBeDisabled();
|
||||
fillForm(defaultSuccessForm);
|
||||
});
|
||||
|
||||
it('disables signup if too few seats chosen', () => {
|
||||
renderWithIntlAndStore(<div id='root-portal'><SelfHostedPurchaseModal productId={'prod_professional'}/></div>, initialState);
|
||||
renderWithContext(<div id='root-portal'><SelfHostedPurchaseModal productId={'prod_professional'}/></div>, initialState);
|
||||
fillForm(defaultSuccessForm);
|
||||
|
||||
const tooFewSeats = existingUsers - 1;
|
||||
@@ -283,7 +283,7 @@ describe('SelfHostedPurchaseModal', () => {
|
||||
});
|
||||
|
||||
it('Minimum of 10 seats is required for sign up', () => {
|
||||
renderWithIntlAndStore(<div id='root-portal'><SelfHostedPurchaseModal productId={'prod_professional'}/></div>, initialState);
|
||||
renderWithContext(<div id='root-portal'><SelfHostedPurchaseModal productId={'prod_professional'}/></div>, initialState);
|
||||
fillForm(defaultSuccessForm);
|
||||
|
||||
const tooFewSeats = 9;
|
||||
@@ -293,7 +293,7 @@ describe('SelfHostedPurchaseModal', () => {
|
||||
});
|
||||
|
||||
it('happy path submit shows success screen', async () => {
|
||||
renderWithIntlAndStore(<div id='root-portal'><SelfHostedPurchaseModal productId={'prod_professional'}/></div>, initialState);
|
||||
renderWithContext(<div id='root-portal'><SelfHostedPurchaseModal productId={'prod_professional'}/></div>, initialState);
|
||||
expect(screen.getByText('Upgrade')).toBeDisabled();
|
||||
const upgradeButton = fillForm(defaultSuccessForm);
|
||||
|
||||
@@ -302,7 +302,7 @@ describe('SelfHostedPurchaseModal', () => {
|
||||
});
|
||||
|
||||
it('sad path submit shows error screen', async () => {
|
||||
renderWithIntlAndStore(<div id='root-portal'><SelfHostedPurchaseModal productId={'prod_professional'}/></div>, initialState);
|
||||
renderWithContext(<div id='root-portal'><SelfHostedPurchaseModal productId={'prod_professional'}/></div>, initialState);
|
||||
expect(screen.getByText('Upgrade')).toBeDisabled();
|
||||
fillForm(defaultSuccessForm);
|
||||
changeByPlaceholder('Organization Name', failOrg);
|
||||
|
||||
@@ -9,7 +9,7 @@ import type {DeepPartial} from '@mattermost/types/utilities';
|
||||
import {Preferences} from 'mattermost-redux/constants';
|
||||
|
||||
import mergeObjects from 'packages/mattermost-redux/test/merge_objects';
|
||||
import {renderWithFullContext, screen} from 'tests/react_testing_utils';
|
||||
import {renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
import Constants, {ModalIdentifiers} from 'utils/constants';
|
||||
import {TestHelper} from 'utils/test_helper';
|
||||
|
||||
@@ -180,7 +180,7 @@ describe('components/sidebar', () => {
|
||||
},
|
||||
});
|
||||
|
||||
renderWithFullContext(
|
||||
renderWithContext(
|
||||
<Sidebar {...baseProps}/>,
|
||||
mergeObjects(baseState, testState),
|
||||
);
|
||||
@@ -204,7 +204,7 @@ describe('components/sidebar', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderWithFullContext(
|
||||
renderWithContext(
|
||||
<Sidebar {...baseProps}/>,
|
||||
mergeObjects(baseState, testState),
|
||||
);
|
||||
@@ -223,7 +223,7 @@ describe('components/sidebar', () => {
|
||||
},
|
||||
};
|
||||
|
||||
renderWithFullContext(
|
||||
renderWithContext(
|
||||
<Sidebar {...baseProps}/>,
|
||||
mergeObjects(baseState, testState),
|
||||
);
|
||||
@@ -242,12 +242,12 @@ describe('components/sidebar', () => {
|
||||
},
|
||||
views: {
|
||||
channel: {
|
||||
lastUnreadChannel: {id: channel1.id},
|
||||
lastUnreadChannel: {id: channel1.id} as any,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
renderWithFullContext(
|
||||
renderWithContext(
|
||||
<Sidebar {...baseProps}/>,
|
||||
mergeObjects(baseState, testState),
|
||||
);
|
||||
|
||||
@@ -18,7 +18,7 @@ import Input from 'components/widgets/inputs/input/input';
|
||||
import PasswordInput from 'components/widgets/inputs/password_input/password_input';
|
||||
|
||||
import {mountWithIntl} from 'tests/helpers/intl-test-helper';
|
||||
import {act, renderWithIntlAndStore, screen} from 'tests/react_testing_utils';
|
||||
import {act, renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
import {WindowSizes} from 'utils/constants';
|
||||
|
||||
import type {GlobalState} from 'types/store';
|
||||
@@ -293,10 +293,9 @@ describe('components/signup/Signup', () => {
|
||||
jest.spyOn(useCWSAvailabilityCheckAll, 'default').mockImplementation(() => true);
|
||||
mockLicense = {IsLicensed: 'true', Cloud: 'false'};
|
||||
|
||||
const {container: signupContainer} = renderWithIntlAndStore(
|
||||
<BrowserRouter>
|
||||
<Signup/>
|
||||
</BrowserRouter>, {});
|
||||
const {container: signupContainer} = renderWithContext(
|
||||
<Signup/>,
|
||||
);
|
||||
|
||||
screen.getByTestId('signup-body-card-form-check-newsletter');
|
||||
const checkInput = screen.getByTestId('signup-body-card-form-check-newsletter');
|
||||
@@ -309,10 +308,9 @@ describe('components/signup/Signup', () => {
|
||||
jest.spyOn(useCWSAvailabilityCheckAll, 'default').mockImplementation(() => false);
|
||||
mockLicense = {IsLicensed: 'true', Cloud: 'false'};
|
||||
|
||||
const {container: signupContainer} = renderWithIntlAndStore(
|
||||
<BrowserRouter>
|
||||
<Signup/>
|
||||
</BrowserRouter>, {});
|
||||
const {container: signupContainer} = renderWithContext(
|
||||
<Signup/>,
|
||||
);
|
||||
|
||||
expect(() => screen.getByTestId('signup-body-card-form-check-newsletter')).toThrow();
|
||||
expect(signupContainer).toHaveTextContent('Interested in receiving Mattermost security, product, promotions, and company updates updates via newsletter?Sign up at https://mattermost.com/security-updates/.');
|
||||
@@ -322,10 +320,9 @@ describe('components/signup/Signup', () => {
|
||||
jest.spyOn(useCWSAvailabilityCheckAll, 'default').mockImplementation(() => true);
|
||||
mockLicense = {IsLicensed: 'true', Cloud: 'true'};
|
||||
|
||||
const {container: signupContainer} = renderWithIntlAndStore(
|
||||
<BrowserRouter>
|
||||
<Signup/>
|
||||
</BrowserRouter>, {});
|
||||
const {container: signupContainer} = renderWithContext(
|
||||
<Signup/>,
|
||||
);
|
||||
|
||||
screen.getByTestId('signup-body-card-form-check-newsletter');
|
||||
const checkInput = screen.getByTestId('signup-body-card-form-check-newsletter');
|
||||
|
||||
@@ -389,7 +389,9 @@ Object {
|
||||
"queryByTestId": [Function],
|
||||
"queryByText": [Function],
|
||||
"queryByTitle": [Function],
|
||||
"replaceStoreState": [Function],
|
||||
"rerender": [Function],
|
||||
"unmount": [Function],
|
||||
"updateStoreState": [Function],
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -2,21 +2,21 @@
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import {Provider} from 'react-redux';
|
||||
import {BrowserRouter} from 'react-router-dom';
|
||||
|
||||
import type {DeepPartial} from '@mattermost/types/utilities';
|
||||
|
||||
import {trackEvent} from 'actions/telemetry_actions';
|
||||
|
||||
import {
|
||||
act,
|
||||
renderWithIntl,
|
||||
renderWithContext,
|
||||
screen,
|
||||
waitFor,
|
||||
} from 'tests/react_testing_utils';
|
||||
import type {
|
||||
RenderResult} from 'tests/react_testing_utils';
|
||||
import mockStore from 'tests/test_store';
|
||||
import {ModalIdentifiers} from 'utils/constants';
|
||||
|
||||
import type {GlobalState} from 'types/store';
|
||||
|
||||
import StartTrialFormModal from '.';
|
||||
|
||||
jest.mock('actions/telemetry_actions.jsx', () => {
|
||||
@@ -28,7 +28,7 @@ jest.mock('actions/telemetry_actions.jsx', () => {
|
||||
});
|
||||
|
||||
describe('components/start_trial_form_modal/start_trial_form_modal', () => {
|
||||
const state = {
|
||||
const state: DeepPartial<GlobalState> = {
|
||||
entities: {
|
||||
users: {
|
||||
currentUserId: 'user1',
|
||||
@@ -54,7 +54,7 @@ describe('components/start_trial_form_modal/start_trial_form_modal', () => {
|
||||
modals: {
|
||||
modalState: {
|
||||
[ModalIdentifiers.START_TRIAL_FORM_MODAL]: {
|
||||
open: 'true',
|
||||
open: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -74,42 +74,38 @@ describe('components/start_trial_form_modal/start_trial_form_modal', () => {
|
||||
};
|
||||
|
||||
test('should match snapshot', async () => {
|
||||
const store = await mockStore(state);
|
||||
let wrapper: RenderResult | HTMLElement | null;
|
||||
await act(async () => {
|
||||
wrapper = await renderWithIntl(
|
||||
<Provider store={store}>
|
||||
<BrowserRouter>
|
||||
<StartTrialFormModal {...props}/>
|
||||
</BrowserRouter>
|
||||
</Provider>);
|
||||
const wrapper = await waitFor(() => {
|
||||
return renderWithContext(
|
||||
<BrowserRouter>
|
||||
<StartTrialFormModal {...props}/>
|
||||
</BrowserRouter>,
|
||||
state,
|
||||
);
|
||||
});
|
||||
expect(wrapper!).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should pre-fill email, fire trackEvent', async () => {
|
||||
const store = await mockStore(state);
|
||||
await act(async () => {
|
||||
await renderWithIntl(
|
||||
<Provider store={store}>
|
||||
<BrowserRouter>
|
||||
<StartTrialFormModal {...props}/>
|
||||
</BrowserRouter>
|
||||
</Provider>);
|
||||
test('should pre-fill email, fire trackEvent', () => {
|
||||
waitFor(() => {
|
||||
renderWithContext(
|
||||
<BrowserRouter>
|
||||
<StartTrialFormModal {...props}/>
|
||||
</BrowserRouter>,
|
||||
state,
|
||||
);
|
||||
});
|
||||
expect(screen.getByDisplayValue('test@mattermost.com')).toBeInTheDocument();
|
||||
expect(trackEvent).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('Start trial button should be disabled on load', async () => {
|
||||
const store = await mockStore(state);
|
||||
await act(async () => {
|
||||
await renderWithIntl(
|
||||
<Provider store={store}>
|
||||
<BrowserRouter>
|
||||
<StartTrialFormModal {...props}/>
|
||||
</BrowserRouter>
|
||||
</Provider>);
|
||||
test('Start trial button should be disabled on load', () => {
|
||||
waitFor(() => {
|
||||
renderWithContext(
|
||||
<BrowserRouter>
|
||||
<StartTrialFormModal {...props}/>
|
||||
</BrowserRouter>,
|
||||
state,
|
||||
);
|
||||
});
|
||||
expect(screen.getByRole('button', {name: 'Start trial'})).toBeDisabled();
|
||||
});
|
||||
|
||||
@@ -12,7 +12,7 @@ import {HINT_TOAST_TESTID} from 'components/hint-toast/hint_toast';
|
||||
import {SCROLL_TO_BOTTOM_DISMISS_BUTTON_TESTID, SCROLL_TO_BOTTOM_TOAST_TESTID} from 'components/scroll_to_bottom_toast/scroll_to_bottom_toast';
|
||||
|
||||
import {shallowWithIntl} from 'tests/helpers/intl-test-helper';
|
||||
import {renderWithIntlAndStore} from 'tests/react_testing_utils';
|
||||
import {renderWithContext} from 'tests/react_testing_utils';
|
||||
import {getHistory} from 'utils/browser_history';
|
||||
import {PostListRowListIds} from 'utils/constants';
|
||||
|
||||
@@ -630,7 +630,7 @@ describe('components/ToastWrapper', () => {
|
||||
newRecentMessagesCount: 5,
|
||||
showScrollToBottomToast: true,
|
||||
};
|
||||
renderWithIntlAndStore(<ToastWrapper {...props}/>);
|
||||
renderWithContext(<ToastWrapper {...props}/>);
|
||||
const scrollToBottomToast = screen.queryByTestId(SCROLL_TO_BOTTOM_TOAST_TESTID);
|
||||
expect(scrollToBottomToast).not.toBeInTheDocument();
|
||||
});
|
||||
@@ -644,7 +644,7 @@ describe('components/ToastWrapper', () => {
|
||||
showScrollToBottomToast: true,
|
||||
};
|
||||
|
||||
renderWithIntlAndStore(<ToastWrapper {...props}/>);
|
||||
renderWithContext(<ToastWrapper {...props}/>);
|
||||
|
||||
const scrollToBottomToast = screen.queryByTestId(SCROLL_TO_BOTTOM_TOAST_TESTID);
|
||||
expect(scrollToBottomToast).not.toBeInTheDocument();
|
||||
@@ -656,7 +656,7 @@ describe('components/ToastWrapper', () => {
|
||||
showScrollToBottomToast: false,
|
||||
};
|
||||
|
||||
renderWithIntlAndStore(<ToastWrapper {...props}/>);
|
||||
renderWithContext(<ToastWrapper {...props}/>);
|
||||
|
||||
const scrollToBottomToast = screen.queryByTestId(SCROLL_TO_BOTTOM_TOAST_TESTID);
|
||||
expect(scrollToBottomToast).not.toBeInTheDocument();
|
||||
@@ -669,7 +669,7 @@ describe('components/ToastWrapper', () => {
|
||||
showScrollToBottomToast: true,
|
||||
};
|
||||
|
||||
renderWithIntlAndStore(<ToastWrapper {...props}/>);
|
||||
renderWithContext(<ToastWrapper {...props}/>);
|
||||
|
||||
const scrollToBottomToast = screen.queryByTestId(SCROLL_TO_BOTTOM_TOAST_TESTID);
|
||||
expect(scrollToBottomToast).toBeInTheDocument();
|
||||
@@ -682,7 +682,7 @@ describe('components/ToastWrapper', () => {
|
||||
showScrollToBottomToast: true,
|
||||
};
|
||||
|
||||
renderWithIntlAndStore(<ToastWrapper {...props}/>);
|
||||
renderWithContext(<ToastWrapper {...props}/>);
|
||||
|
||||
const scrollToBottomToast = screen.queryByTestId(SCROLL_TO_BOTTOM_TOAST_TESTID);
|
||||
const hintToast = screen.queryByTestId(HINT_TOAST_TESTID);
|
||||
@@ -698,7 +698,7 @@ describe('components/ToastWrapper', () => {
|
||||
showScrollToBottomToast: true,
|
||||
};
|
||||
|
||||
renderWithIntlAndStore(<ToastWrapper {...props}/>);
|
||||
renderWithContext(<ToastWrapper {...props}/>);
|
||||
const scrollToBottomToast = screen.getByTestId(SCROLL_TO_BOTTOM_TOAST_TESTID);
|
||||
fireEvent.click(scrollToBottomToast);
|
||||
|
||||
@@ -715,7 +715,7 @@ describe('components/ToastWrapper', () => {
|
||||
showScrollToBottomToast: true,
|
||||
};
|
||||
|
||||
renderWithIntlAndStore(<ToastWrapper {...props}/>);
|
||||
renderWithContext(<ToastWrapper {...props}/>);
|
||||
const scrollToBottomToastDismiss = screen.getByTestId(SCROLL_TO_BOTTOM_DISMISS_BUTTON_TESTID);
|
||||
fireEvent.click(scrollToBottomToastDismiss);
|
||||
|
||||
|
||||
@@ -4,13 +4,10 @@
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
import type {ComponentProps} from 'react';
|
||||
import {IntlProvider} from 'react-intl';
|
||||
import {Provider} from 'react-redux';
|
||||
|
||||
import {Preferences} from 'mattermost-redux/constants';
|
||||
|
||||
import {render, fireEvent, screen} from 'tests/react_testing_utils';
|
||||
import mockStore from 'tests/test_store';
|
||||
import {fireEvent, renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
|
||||
import UserSettingsTheme from './user_settings_theme';
|
||||
|
||||
@@ -34,7 +31,6 @@ describe('components/user_settings/display/user_settings_theme/user_settings_the
|
||||
},
|
||||
},
|
||||
};
|
||||
const store = mockStore(initialState);
|
||||
|
||||
const requiredProps: ComponentProps<typeof UserSettingsTheme> = {
|
||||
theme: Preferences.THEMES.denim,
|
||||
@@ -105,12 +101,9 @@ describe('components/user_settings/display/user_settings_theme/user_settings_the
|
||||
selected: true,
|
||||
};
|
||||
|
||||
render(
|
||||
<IntlProvider locale={'en'}>
|
||||
<Provider store={store}>
|
||||
<UserSettingsTheme {...props}/>
|
||||
</Provider>
|
||||
</IntlProvider>,
|
||||
renderWithContext(
|
||||
<UserSettingsTheme {...props}/>,
|
||||
initialState,
|
||||
);
|
||||
|
||||
// Click the Slack Import button
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import React from 'react';
|
||||
import {type IntlShape} from 'react-intl';
|
||||
|
||||
import {renderWithFullContext, screen} from 'tests/react_testing_utils';
|
||||
import {renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
import {TestHelper} from 'utils/test_helper';
|
||||
|
||||
import UserSettingsNotifications from './user_settings_notifications';
|
||||
@@ -25,7 +25,7 @@ describe('components/user_settings/display/UserSettingsDisplay', () => {
|
||||
};
|
||||
|
||||
test('should match snapshot', () => {
|
||||
const wrapper = renderWithFullContext(
|
||||
const wrapper = renderWithContext(
|
||||
<UserSettingsNotifications {...defaultProps}/>,
|
||||
);
|
||||
|
||||
@@ -35,7 +35,7 @@ describe('components/user_settings/display/UserSettingsDisplay', () => {
|
||||
test('should show reply notifications section when CRT off', () => {
|
||||
const props = {...defaultProps, isCollapsedThreadsEnabled: false};
|
||||
|
||||
renderWithFullContext(<UserSettingsNotifications {...props}/>);
|
||||
renderWithContext(<UserSettingsNotifications {...props}/>);
|
||||
|
||||
expect(screen.getByText('Reply notifications')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -2,12 +2,10 @@
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import {Provider} from 'react-redux';
|
||||
|
||||
import type {LimitSummary} from 'components/common/hooks/useGetHighestThresholdCloudLimit';
|
||||
|
||||
import {renderWithIntl, screen} from 'tests/react_testing_utils';
|
||||
import mockStore from 'tests/test_store';
|
||||
import {renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
import {FileSizes} from 'utils/file_utils';
|
||||
import {LimitTypes} from 'utils/limits';
|
||||
|
||||
@@ -158,7 +156,7 @@ describe('useWords', () => {
|
||||
},
|
||||
];
|
||||
|
||||
const store = mockStore({
|
||||
const initialState = {
|
||||
entities: {
|
||||
general: {
|
||||
license: {
|
||||
@@ -166,13 +164,12 @@ describe('useWords', () => {
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
tests.forEach((t: Test) => {
|
||||
test(t.label, () => {
|
||||
renderWithIntl(
|
||||
<Provider store={store}>
|
||||
<TestEl {...t.props}/>
|
||||
</Provider>,
|
||||
renderWithContext(
|
||||
<TestEl {...t.props}/>,
|
||||
initialState,
|
||||
);
|
||||
if (t.expects.empty) {
|
||||
screen.getByText(emptyText);
|
||||
|
||||
@@ -3,18 +3,18 @@
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import {renderWithIntlAndStore, screen} from 'tests/react_testing_utils';
|
||||
import {renderWithContext, screen} from 'tests/react_testing_utils';
|
||||
|
||||
import GuestTag from './guest_tag';
|
||||
|
||||
describe('components/widgets/tag/GuestTag', () => {
|
||||
test('should match the snapshot', () => {
|
||||
renderWithIntlAndStore(<GuestTag className={'test'}/>);
|
||||
renderWithContext(<GuestTag className={'test'}/>);
|
||||
screen.getByText('GUEST');
|
||||
});
|
||||
|
||||
test('should not render when hideTags is true', () => {
|
||||
renderWithIntlAndStore(<GuestTag className={'test'}/>, {entities: {general: {config: {HideGuestTags: 'true'}}}});
|
||||
renderWithContext(<GuestTag className={'test'}/>, {entities: {general: {config: {HideGuestTags: 'true'}}}});
|
||||
expect(() => screen.getByText('GUEST')).toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,25 +3,37 @@
|
||||
|
||||
import React from 'react';
|
||||
import {FormattedMessage, useIntl} from 'react-intl';
|
||||
import {connect, useSelector} from 'react-redux';
|
||||
import {connect, useDispatch, useSelector} from 'react-redux';
|
||||
import {Link, Route} from 'react-router-dom';
|
||||
|
||||
import {GenericModal} from '@mattermost/components';
|
||||
|
||||
import {UserTypes} from 'mattermost-redux/action_types';
|
||||
import {getUser} from 'mattermost-redux/selectors/entities/users';
|
||||
|
||||
import {openModal} from 'actions/views/modals';
|
||||
|
||||
import ModalController from 'components/modal_controller';
|
||||
|
||||
import mergeObjects from 'packages/mattermost-redux/test/merge_objects';
|
||||
import {TestHelper} from 'utils/test_helper';
|
||||
|
||||
import type {GlobalState} from 'types/store';
|
||||
|
||||
import {renderWithFullContext, screen} from './react_testing_utils';
|
||||
import {
|
||||
renderWithContext,
|
||||
screen,
|
||||
userEvent,
|
||||
waitFor,
|
||||
} from './react_testing_utils';
|
||||
|
||||
describe('renderWithFullContext', () => {
|
||||
describe('renderWithContext', () => {
|
||||
test('should be able to render anything', () => {
|
||||
const TestComponent = () => {
|
||||
return <div>{'Anything'}</div>;
|
||||
};
|
||||
|
||||
renderWithFullContext(
|
||||
renderWithContext(
|
||||
<TestComponent/>,
|
||||
{},
|
||||
);
|
||||
@@ -39,7 +51,7 @@ describe('renderWithFullContext', () => {
|
||||
);
|
||||
};
|
||||
|
||||
renderWithFullContext(
|
||||
renderWithContext(
|
||||
<TestComponent/>,
|
||||
);
|
||||
|
||||
@@ -53,7 +65,7 @@ describe('renderWithFullContext', () => {
|
||||
return <div>{intl.formatMessage({id: 'about.hash', defaultMessage: 'Build Hash:'})}</div>;
|
||||
};
|
||||
|
||||
renderWithFullContext(
|
||||
renderWithContext(
|
||||
<TestComponent/>,
|
||||
);
|
||||
|
||||
@@ -76,7 +88,7 @@ describe('renderWithFullContext', () => {
|
||||
);
|
||||
};
|
||||
|
||||
renderWithFullContext(
|
||||
renderWithContext(
|
||||
<TestComponent/>,
|
||||
);
|
||||
|
||||
@@ -92,7 +104,7 @@ describe('renderWithFullContext', () => {
|
||||
numProfiles: Object.keys(state.entities.users.profiles).length,
|
||||
}))(UnconnectedTestComponent);
|
||||
|
||||
renderWithFullContext(
|
||||
renderWithContext(
|
||||
<TestComponent/>,
|
||||
);
|
||||
|
||||
@@ -105,7 +117,7 @@ describe('renderWithFullContext', () => {
|
||||
return <div>{`There are ${numProfiles} users loaded`}</div>;
|
||||
};
|
||||
|
||||
renderWithFullContext(
|
||||
renderWithContext(
|
||||
<TestComponent/>,
|
||||
);
|
||||
|
||||
@@ -125,7 +137,7 @@ describe('renderWithFullContext', () => {
|
||||
);
|
||||
};
|
||||
|
||||
const {rerender} = renderWithFullContext(
|
||||
const {rerender} = renderWithContext(
|
||||
<TestComponent appTitle='Mattermost'/>,
|
||||
);
|
||||
|
||||
@@ -157,7 +169,7 @@ describe('renderWithFullContext', () => {
|
||||
return <div>{`User1 is ${user1.username} and User2 is ${user2.username}!`}</div>;
|
||||
};
|
||||
|
||||
const {replaceStoreState} = renderWithFullContext(
|
||||
const {replaceStoreState} = renderWithContext(
|
||||
<TestComponent/>,
|
||||
initialState,
|
||||
);
|
||||
@@ -209,7 +221,7 @@ describe('renderWithFullContext', () => {
|
||||
return <div>{`User1 is ${user1.username} and User2 is ${user2.username}!`}</div>;
|
||||
};
|
||||
|
||||
const {updateStoreState} = renderWithFullContext(
|
||||
const {updateStoreState} = renderWithContext(
|
||||
<TestComponent/>,
|
||||
initialState,
|
||||
);
|
||||
@@ -240,4 +252,141 @@ describe('renderWithFullContext', () => {
|
||||
|
||||
expect(screen.getByText('User1 is Golf and User2 is Hotel!')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should be able to mix rerendering and updating store state', () => {
|
||||
const initialState = {
|
||||
entities: {
|
||||
users: {
|
||||
profiles: {
|
||||
user1: TestHelper.getUserMock({id: 'user1', username: 'India'}),
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const TestComponent = (props: {greeting: string}) => {
|
||||
const user1 = useSelector((state: GlobalState) => getUser(state, 'user1'));
|
||||
|
||||
return <div>{`${props.greeting}, ${user1.username}!`}</div>;
|
||||
};
|
||||
|
||||
const {rerender, updateStoreState} = renderWithContext(
|
||||
<TestComponent greeting='Hello'/>,
|
||||
initialState,
|
||||
);
|
||||
|
||||
expect(screen.getByText('Hello, India!')).toBeInTheDocument();
|
||||
|
||||
updateStoreState({
|
||||
entities: {
|
||||
users: {
|
||||
profiles: {
|
||||
user1: {username: 'Juliet'},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(screen.getByText('Hello, Juliet!')).toBeInTheDocument();
|
||||
|
||||
rerender(<TestComponent greeting='Salutations'/>);
|
||||
|
||||
expect(screen.getByText('Salutations, Juliet!')).toBeInTheDocument();
|
||||
|
||||
updateStoreState({
|
||||
entities: {
|
||||
users: {
|
||||
profiles: {
|
||||
user1: {username: 'Kilo'},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(screen.getByText('Salutations, Kilo!')).toBeInTheDocument();
|
||||
|
||||
rerender(<TestComponent greeting='Bonjour'/>);
|
||||
|
||||
expect(screen.getByText('Bonjour, Kilo!')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should be able to dispatch and handle redux actions', () => {
|
||||
const TestComponent = () => {
|
||||
const user1 = useSelector((state: GlobalState) => getUser(state, 'user1'));
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const username = user1 ? user1.username : 'NOT_LOADED';
|
||||
|
||||
const loadUser = () => {
|
||||
dispatch({
|
||||
type: UserTypes.RECEIVED_PROFILE,
|
||||
data: {id: 'user1', username: 'Lima'},
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<span>{`User1 is ${username}!`}</span>
|
||||
<button onClick={loadUser}>{'Load User'}</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
renderWithContext(<TestComponent/>);
|
||||
|
||||
expect(screen.getByText('User1 is NOT_LOADED!')).toBeInTheDocument();
|
||||
|
||||
userEvent.click(screen.getByText('Load User'));
|
||||
|
||||
expect(screen.getByText('User1 is Lima!')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should be able to render modals using a ModalController', async () => {
|
||||
const TestComponent = () => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const openTestModal = () => {
|
||||
dispatch(openModal({
|
||||
modalId: 'test_modal',
|
||||
dialogType: TestModal,
|
||||
}));
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<button onClick={openTestModal}>{'Open Modal'}</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const TestModal = (props: {onExited: () => void}) => {
|
||||
return (
|
||||
<GenericModal onExited={props.onExited}>
|
||||
<p>{'This is a modal!'}</p>
|
||||
</GenericModal>
|
||||
);
|
||||
};
|
||||
|
||||
renderWithContext(
|
||||
<>
|
||||
<TestComponent/>
|
||||
<ModalController/>
|
||||
</>,
|
||||
);
|
||||
|
||||
expect(screen.getByText('Open Modal')).toBeVisible();
|
||||
|
||||
userEvent.click(screen.getByText('Open Modal'));
|
||||
|
||||
// Use waitFor because the modal animates in and out
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByText('This is a modal!')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
userEvent.click(screen.getByLabelText('Close'));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByText('This is a modal!')).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -22,50 +22,42 @@ import type {GlobalState} from 'types/store';
|
||||
export * from '@testing-library/react';
|
||||
export {userEvent};
|
||||
|
||||
export const renderWithIntl = (component: React.ReactNode | React.ReactNodeArray, locale = 'en') => {
|
||||
return render(<IntlProvider locale={locale}>{component}</IntlProvider>);
|
||||
};
|
||||
export type FullContextOptions = {
|
||||
locale?: string;
|
||||
useMockedStore?: boolean;
|
||||
}
|
||||
|
||||
export const renderWithIntlAndStore = (component: React.ReactNode | React.ReactNodeArray, initialState: DeepPartial<GlobalState> = {}, locale = 'en', divContainer?: HTMLDivElement) => {
|
||||
// We use a redux-mock-store store for testing, but we set up a real store to ensure the initial state is complete
|
||||
const realStore = configureStore(initialState);
|
||||
export const renderWithContext = (
|
||||
component: React.ReactElement,
|
||||
initialState: DeepPartial<GlobalState> = {},
|
||||
partialOptions?: FullContextOptions,
|
||||
) => {
|
||||
const options = {
|
||||
locale: partialOptions?.locale ?? 'en',
|
||||
useMockedStore: partialOptions?.useMockedStore ?? false,
|
||||
};
|
||||
|
||||
const store = mockStore(realStore.getState());
|
||||
|
||||
return render(
|
||||
<IntlProvider locale={locale}>
|
||||
<Provider store={store}>
|
||||
{component}
|
||||
</Provider>
|
||||
</IntlProvider>,
|
||||
{container: divContainer},
|
||||
);
|
||||
};
|
||||
|
||||
export const renderWithFullContext = (component: React.ReactNode | React.ReactNodeArray, initialState: DeepPartial<GlobalState> = {}, locale = 'en') => {
|
||||
// We use a redux-mock-store store for testing, but we set up a real store to ensure the initial state is complete
|
||||
const testState = configureStore(initialState).getState();
|
||||
const testStore = configureOrMockStore(initialState, options.useMockedStore);
|
||||
|
||||
// Store these in an object so that they can be maintained through rerenders
|
||||
const renderState = {
|
||||
component,
|
||||
history: createBrowserHistory(),
|
||||
locale,
|
||||
state: testState,
|
||||
store: mockStore(testState),
|
||||
options,
|
||||
store: testStore,
|
||||
};
|
||||
|
||||
// This should wrap the component in roughly the same providers used in App and RootProvider
|
||||
function wrapComponent() {
|
||||
function WrapComponent(props: {children: React.ReactElement}) {
|
||||
// Every time this is called, these values should be updated from `renderState`
|
||||
return (
|
||||
<Provider store={renderState.store}>
|
||||
<Router history={renderState.history}>
|
||||
<IntlProvider
|
||||
locale={renderState.locale}
|
||||
locale={renderState.options.locale}
|
||||
>
|
||||
<WebSocketContext.Provider value={WebSocketClient}>
|
||||
{renderState.component}
|
||||
{props.children}
|
||||
</WebSocketContext.Provider>
|
||||
</IntlProvider>
|
||||
</Router>
|
||||
@@ -73,36 +65,41 @@ export const renderWithFullContext = (component: React.ReactNode | React.ReactNo
|
||||
);
|
||||
}
|
||||
|
||||
const results = render(wrapComponent());
|
||||
const results = render(component, {wrapper: WrapComponent});
|
||||
|
||||
return {
|
||||
...results,
|
||||
rerender: (newComponent: React.ReactNode | React.ReactNodeArray) => {
|
||||
rerender: (newComponent: React.ReactElement) => {
|
||||
renderState.component = newComponent;
|
||||
|
||||
results.rerender(wrapComponent());
|
||||
results.rerender(renderState.component);
|
||||
},
|
||||
|
||||
/**
|
||||
* Rerenders the component after replacing the entire store state with the provided one.
|
||||
*/
|
||||
replaceStoreState: (newInitialState: DeepPartial<GlobalState>) => {
|
||||
const newTestState = configureStore(newInitialState).getState();
|
||||
renderState.state = newTestState;
|
||||
renderState.store = mockStore(newTestState);
|
||||
renderState.store = configureOrMockStore(newInitialState, renderState.options.useMockedStore);
|
||||
|
||||
results.rerender(wrapComponent());
|
||||
results.rerender(renderState.component);
|
||||
},
|
||||
|
||||
/**
|
||||
* Rerenders the component after merging the current store state with the provided one.
|
||||
*/
|
||||
updateStoreState: (stateDiff: DeepPartial<GlobalState>) => {
|
||||
const newTestState = mergeObjects(renderState.state, stateDiff);
|
||||
renderState.state = newTestState;
|
||||
renderState.store = mockStore(newTestState);
|
||||
const newInitialState = mergeObjects(renderState.store.getState(), stateDiff);
|
||||
renderState.store = configureOrMockStore(newInitialState, renderState.options.useMockedStore);
|
||||
|
||||
results.rerender(wrapComponent());
|
||||
results.rerender(renderState.component);
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
function configureOrMockStore<T>(initialState: DeepPartial<T>, useMockedStore: boolean) {
|
||||
let testStore = configureStore(initialState);
|
||||
if (useMockedStore) {
|
||||
testStore = mockStore(testStore.getState());
|
||||
}
|
||||
return testStore;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,14 @@ export type RelationOneToManyUnique<E1 extends {id: string}, E2 extends {id: str
|
||||
export type IDMappedObjects<E extends {id: string}> = RelationOneToOne<E, E>;
|
||||
|
||||
export type DeepPartial<T> = {
|
||||
[P in keyof T]?: DeepPartial<T[P]>;
|
||||
// For each field of T, make it optional and...
|
||||
[K in keyof T]?:
|
||||
// If that field is an object, make it a deep partial object
|
||||
T[K] extends object ? DeepPartial<T[K]> :
|
||||
// Else if that field is an optional object, make that a deep partial object
|
||||
T[K] extends object | undefined ? DeepPartial<T[K]> :
|
||||
// Else leave it as an optional primitive
|
||||
T[K];
|
||||
}
|
||||
|
||||
export type ValueOf<T> = T[keyof T];
|
||||
@@ -26,4 +33,4 @@ export type RequireOnlyOne<T, Keys extends keyof T = keyof T> =
|
||||
Pick<T, Exclude<keyof T, Keys>> & {[K in Keys]-?: Required<Pick<T, K>> & Partial<Record<Exclude<Keys, K>, undefined>>}[Keys];
|
||||
|
||||
export type Intersection<T1, T2> =
|
||||
Omit<Omit<T1&T2, keyof(Omit<T1, keyof(T2)>)>, keyof(Omit<T2, keyof(T1)>)>;
|
||||
Omit<Omit<T1&T2, keyof(Omit<T1, keyof(T2)>)>, keyof(Omit<T2, keyof(T1)>)>;
|
||||
|
||||
Ссылка в новой задаче
Block a user