mirror of
https://github.com/ansible/awx.git
synced 2026-02-26 07:26:03 -03:30
Merge pull request #7785 from mabashian/convert-NotificationList-functional
Converts NotificationList to functional component and now uses useRequest Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
This commit is contained in:
@@ -1,15 +1,14 @@
|
|||||||
import React, { Component, Fragment } from 'react';
|
import React, { useEffect, useCallback, useState } from 'react';
|
||||||
import { number, shape, string, bool } from 'prop-types';
|
import { useLocation } from 'react-router-dom';
|
||||||
import { withRouter } from 'react-router-dom';
|
import { number, shape, bool } from 'prop-types';
|
||||||
import { withI18n } from '@lingui/react';
|
import { withI18n } from '@lingui/react';
|
||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
|
|
||||||
import AlertModal from '../AlertModal';
|
import AlertModal from '../AlertModal';
|
||||||
import ErrorDetail from '../ErrorDetail';
|
import ErrorDetail from '../ErrorDetail';
|
||||||
import NotificationListItem from './NotificationListItem';
|
import NotificationListItem from './NotificationListItem';
|
||||||
import PaginatedDataList from '../PaginatedDataList';
|
import PaginatedDataList from '../PaginatedDataList';
|
||||||
import { getQSConfig, parseQueryString } from '../../util/qs';
|
import { getQSConfig, parseQueryString } from '../../util/qs';
|
||||||
|
import useRequest from '../../util/useRequest';
|
||||||
import { NotificationTemplatesAPI } from '../../api';
|
import { NotificationTemplatesAPI } from '../../api';
|
||||||
|
|
||||||
const QS_CONFIG = getQSConfig('notification', {
|
const QS_CONFIG = getQSConfig('notification', {
|
||||||
@@ -18,64 +17,49 @@ const QS_CONFIG = getQSConfig('notification', {
|
|||||||
order_by: 'name',
|
order_by: 'name',
|
||||||
});
|
});
|
||||||
|
|
||||||
class NotificationList extends Component {
|
function NotificationList({ apiModel, canToggleNotifications, id, i18n }) {
|
||||||
constructor(props) {
|
const location = useLocation();
|
||||||
super(props);
|
const [isToggleLoading, setIsToggleLoading] = useState(false);
|
||||||
this.state = {
|
const [toggleError, setToggleError] = useState(null);
|
||||||
contentError: null,
|
|
||||||
hasContentLoading: true,
|
|
||||||
toggleError: false,
|
|
||||||
loadingToggleIds: [],
|
|
||||||
itemCount: 0,
|
|
||||||
notifications: [],
|
|
||||||
startedTemplateIds: [],
|
|
||||||
successTemplateIds: [],
|
|
||||||
errorTemplateIds: [],
|
|
||||||
typeLabels: null,
|
|
||||||
};
|
|
||||||
this.handleNotificationToggle = this.handleNotificationToggle.bind(this);
|
|
||||||
this.handleNotificationErrorClose = this.handleNotificationErrorClose.bind(
|
|
||||||
this
|
|
||||||
);
|
|
||||||
this.loadNotifications = this.loadNotifications.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
const {
|
||||||
this.loadNotifications();
|
result: fetchNotificationsResult,
|
||||||
}
|
result: {
|
||||||
|
notifications,
|
||||||
|
itemCount,
|
||||||
|
startedTemplateIds,
|
||||||
|
successTemplateIds,
|
||||||
|
errorTemplateIds,
|
||||||
|
typeLabels,
|
||||||
|
},
|
||||||
|
error: contentError,
|
||||||
|
isLoading,
|
||||||
|
request: fetchNotifications,
|
||||||
|
setValue,
|
||||||
|
} = useRequest(
|
||||||
|
useCallback(async () => {
|
||||||
|
const params = parseQueryString(QS_CONFIG, location.search);
|
||||||
|
const [
|
||||||
|
{
|
||||||
|
data: { results: notificationsResults, count: notificationsCount },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: { actions },
|
||||||
|
},
|
||||||
|
] = await Promise.all([
|
||||||
|
NotificationTemplatesAPI.read(params),
|
||||||
|
NotificationTemplatesAPI.readOptions(),
|
||||||
|
]);
|
||||||
|
|
||||||
componentDidUpdate(prevProps) {
|
const labels = actions.GET.notification_type.choices.reduce(
|
||||||
const { location } = this.props;
|
(map, notifType) => ({ ...map, [notifType[0]]: notifType[1] }),
|
||||||
if (location !== prevProps.location) {
|
{}
|
||||||
this.loadNotifications();
|
);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async loadNotifications() {
|
const idMatchParams =
|
||||||
const { id, location, apiModel } = this.props;
|
notificationsResults.length > 0
|
||||||
const { typeLabels } = this.state;
|
? { id__in: notificationsResults.map(n => n.id).join(',') }
|
||||||
const params = parseQueryString(QS_CONFIG, location.search);
|
: {};
|
||||||
|
|
||||||
const promises = [NotificationTemplatesAPI.read(params)];
|
|
||||||
|
|
||||||
if (!typeLabels) {
|
|
||||||
promises.push(NotificationTemplatesAPI.readOptions());
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setState({ contentError: null, hasContentLoading: true });
|
|
||||||
try {
|
|
||||||
const {
|
|
||||||
data: { count: itemCount = 0, results: notifications = [] },
|
|
||||||
} = await NotificationTemplatesAPI.read(params);
|
|
||||||
|
|
||||||
const optionsResponse = await NotificationTemplatesAPI.readOptions();
|
|
||||||
|
|
||||||
let idMatchParams;
|
|
||||||
if (notifications.length > 0) {
|
|
||||||
idMatchParams = { id__in: notifications.map(n => n.id).join(',') };
|
|
||||||
} else {
|
|
||||||
idMatchParams = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
const [
|
const [
|
||||||
{ data: startedTemplates },
|
{ data: startedTemplates },
|
||||||
@@ -87,69 +71,35 @@ class NotificationList extends Component {
|
|||||||
apiModel.readNotificationTemplatesError(id, idMatchParams),
|
apiModel.readNotificationTemplatesError(id, idMatchParams),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const stateToUpdate = {
|
return {
|
||||||
itemCount,
|
notifications: notificationsResults,
|
||||||
notifications,
|
itemCount: notificationsCount,
|
||||||
startedTemplateIds: startedTemplates.results.map(st => st.id),
|
startedTemplateIds: startedTemplates.results.map(st => st.id),
|
||||||
successTemplateIds: successTemplates.results.map(su => su.id),
|
successTemplateIds: successTemplates.results.map(su => su.id),
|
||||||
errorTemplateIds: errorTemplates.results.map(e => e.id),
|
errorTemplateIds: errorTemplates.results.map(e => e.id),
|
||||||
|
typeLabels: labels,
|
||||||
};
|
};
|
||||||
|
}, [apiModel, id, location]),
|
||||||
if (!typeLabels) {
|
{
|
||||||
const {
|
notifications: [],
|
||||||
data: {
|
itemCount: 0,
|
||||||
actions: {
|
startedTemplateIds: [],
|
||||||
GET: {
|
successTemplateIds: [],
|
||||||
notification_type: { choices },
|
errorTemplateIds: [],
|
||||||
},
|
typeLabels: {},
|
||||||
},
|
|
||||||
},
|
|
||||||
} = optionsResponse;
|
|
||||||
// The structure of choices looks like [['slack', 'Slack'], ['email', 'Email'], ...]
|
|
||||||
stateToUpdate.typeLabels = choices.reduce(
|
|
||||||
(map, notifType) => ({ ...map, [notifType[0]]: notifType[1] }),
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setState(stateToUpdate);
|
|
||||||
} catch (err) {
|
|
||||||
this.setState({ contentError: err });
|
|
||||||
} finally {
|
|
||||||
this.setState({ hasContentLoading: false });
|
|
||||||
}
|
}
|
||||||
}
|
);
|
||||||
|
|
||||||
async handleNotificationToggle(notificationId, isCurrentlyOn, status) {
|
useEffect(() => {
|
||||||
const { id, apiModel } = this.props;
|
fetchNotifications();
|
||||||
|
}, [fetchNotifications]);
|
||||||
|
|
||||||
let stateArrayName;
|
const handleNotificationToggle = async (
|
||||||
if (status === 'success') {
|
notificationId,
|
||||||
stateArrayName = 'successTemplateIds';
|
isCurrentlyOn,
|
||||||
} else if (status === 'error') {
|
status
|
||||||
stateArrayName = 'errorTemplateIds';
|
) => {
|
||||||
} else if (status === 'started') {
|
setIsToggleLoading(true);
|
||||||
stateArrayName = 'startedTemplateIds';
|
|
||||||
}
|
|
||||||
|
|
||||||
let stateUpdateFunction;
|
|
||||||
if (isCurrentlyOn) {
|
|
||||||
// when switching off, remove the toggled notification id from the array
|
|
||||||
stateUpdateFunction = prevState => ({
|
|
||||||
[stateArrayName]: prevState[stateArrayName].filter(
|
|
||||||
i => i !== notificationId
|
|
||||||
),
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// when switching on, add the toggled notification id to the array
|
|
||||||
stateUpdateFunction = prevState => ({
|
|
||||||
[stateArrayName]: prevState[stateArrayName].concat(notificationId),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setState(({ loadingToggleIds }) => ({
|
|
||||||
loadingToggleIds: loadingToggleIds.concat([notificationId]),
|
|
||||||
}));
|
|
||||||
try {
|
try {
|
||||||
if (isCurrentlyOn) {
|
if (isCurrentlyOn) {
|
||||||
await apiModel.disassociateNotificationTemplate(
|
await apiModel.disassociateNotificationTemplate(
|
||||||
@@ -157,128 +107,111 @@ class NotificationList extends Component {
|
|||||||
notificationId,
|
notificationId,
|
||||||
status
|
status
|
||||||
);
|
);
|
||||||
|
setValue({
|
||||||
|
...fetchNotificationsResult,
|
||||||
|
[`${status}TemplateIds`]: fetchNotificationsResult[
|
||||||
|
`${status}TemplateIds`
|
||||||
|
].filter(i => i !== notificationId),
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
await apiModel.associateNotificationTemplate(
|
await apiModel.associateNotificationTemplate(
|
||||||
id,
|
id,
|
||||||
notificationId,
|
notificationId,
|
||||||
status
|
status
|
||||||
);
|
);
|
||||||
|
setValue({
|
||||||
|
...fetchNotificationsResult,
|
||||||
|
[`${status}TemplateIds`]: fetchNotificationsResult[
|
||||||
|
`${status}TemplateIds`
|
||||||
|
].concat(notificationId),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
this.setState(stateUpdateFunction);
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.setState({ toggleError: err });
|
setToggleError(err);
|
||||||
} finally {
|
} finally {
|
||||||
this.setState(({ loadingToggleIds }) => ({
|
setIsToggleLoading(false);
|
||||||
loadingToggleIds: loadingToggleIds.filter(
|
|
||||||
item => item !== notificationId
|
|
||||||
),
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleNotificationErrorClose() {
|
return (
|
||||||
this.setState({ toggleError: false });
|
<>
|
||||||
}
|
<PaginatedDataList
|
||||||
|
contentError={contentError}
|
||||||
render() {
|
hasContentLoading={isLoading}
|
||||||
const { canToggleNotifications, i18n } = this.props;
|
items={notifications}
|
||||||
const {
|
itemCount={itemCount}
|
||||||
contentError,
|
pluralizedItemName={i18n._(t`Notifications`)}
|
||||||
hasContentLoading,
|
qsConfig={QS_CONFIG}
|
||||||
toggleError,
|
toolbarSearchColumns={[
|
||||||
loadingToggleIds,
|
{
|
||||||
itemCount,
|
name: i18n._(t`Name`),
|
||||||
notifications,
|
key: 'name',
|
||||||
startedTemplateIds,
|
isDefault: true,
|
||||||
successTemplateIds,
|
},
|
||||||
errorTemplateIds,
|
{
|
||||||
typeLabels,
|
name: i18n._(t`Type`),
|
||||||
} = this.state;
|
key: 'type',
|
||||||
|
options: [
|
||||||
return (
|
['email', i18n._(t`Email`)],
|
||||||
<Fragment>
|
['grafana', i18n._(t`Grafana`)],
|
||||||
<PaginatedDataList
|
['hipchat', i18n._(t`Hipchat`)],
|
||||||
contentError={contentError}
|
['irc', i18n._(t`IRC`)],
|
||||||
hasContentLoading={hasContentLoading}
|
['mattermost', i18n._(t`Mattermost`)],
|
||||||
items={notifications}
|
['pagerduty', i18n._(t`Pagerduty`)],
|
||||||
itemCount={itemCount}
|
['rocketchat', i18n._(t`Rocket.Chat`)],
|
||||||
pluralizedItemName={i18n._(t`Notifications`)}
|
['slack', i18n._(t`Slack`)],
|
||||||
qsConfig={QS_CONFIG}
|
['twilio', i18n._(t`Twilio`)],
|
||||||
toolbarSearchColumns={[
|
['webhook', i18n._(t`Webhook`)],
|
||||||
{
|
],
|
||||||
name: i18n._(t`Name`),
|
},
|
||||||
key: 'name',
|
{
|
||||||
isDefault: true,
|
name: i18n._(t`Created by (username)`),
|
||||||
},
|
key: 'created_by__username',
|
||||||
{
|
},
|
||||||
name: i18n._(t`Type`),
|
{
|
||||||
key: 'type',
|
name: i18n._(t`Modified by (username)`),
|
||||||
options: [
|
key: 'modified_by__username',
|
||||||
['email', i18n._(t`Email`)],
|
},
|
||||||
['grafana', i18n._(t`Grafana`)],
|
]}
|
||||||
['hipchat', i18n._(t`Hipchat`)],
|
toolbarSortColumns={[
|
||||||
['irc', i18n._(t`IRC`)],
|
{
|
||||||
['mattermost', i18n._(t`Mattermost`)],
|
name: i18n._(t`Name`),
|
||||||
['pagerduty', i18n._(t`Pagerduty`)],
|
key: 'name',
|
||||||
['rocketchat', i18n._(t`Rocket.Chat`)],
|
},
|
||||||
['slack', i18n._(t`Slack`)],
|
]}
|
||||||
['twilio', i18n._(t`Twilio`)],
|
renderItem={notification => (
|
||||||
['webhook', i18n._(t`Webhook`)],
|
<NotificationListItem
|
||||||
],
|
key={notification.id}
|
||||||
},
|
notification={notification}
|
||||||
{
|
detailUrl={`/notifications/${notification.id}`}
|
||||||
name: i18n._(t`Created By (Username)`),
|
canToggleNotifications={canToggleNotifications && !isToggleLoading}
|
||||||
key: 'created_by__username',
|
toggleNotification={handleNotificationToggle}
|
||||||
},
|
errorTurnedOn={errorTemplateIds.includes(notification.id)}
|
||||||
{
|
startedTurnedOn={startedTemplateIds.includes(notification.id)}
|
||||||
name: i18n._(t`Modified By (Username)`),
|
successTurnedOn={successTemplateIds.includes(notification.id)}
|
||||||
key: 'modified_by__username',
|
typeLabels={typeLabels}
|
||||||
},
|
/>
|
||||||
]}
|
)}
|
||||||
toolbarSortColumns={[
|
/>
|
||||||
{
|
{toggleError && (
|
||||||
name: i18n._(t`Name`),
|
|
||||||
key: 'name',
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
renderItem={notification => (
|
|
||||||
<NotificationListItem
|
|
||||||
key={notification.id}
|
|
||||||
notification={notification}
|
|
||||||
detailUrl={`/notifications/${notification.id}`}
|
|
||||||
canToggleNotifications={
|
|
||||||
canToggleNotifications &&
|
|
||||||
!loadingToggleIds.includes(notification.id)
|
|
||||||
}
|
|
||||||
toggleNotification={this.handleNotificationToggle}
|
|
||||||
errorTurnedOn={errorTemplateIds.includes(notification.id)}
|
|
||||||
startedTurnedOn={startedTemplateIds.includes(notification.id)}
|
|
||||||
successTurnedOn={successTemplateIds.includes(notification.id)}
|
|
||||||
typeLabels={typeLabels}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<AlertModal
|
<AlertModal
|
||||||
variant="error"
|
variant="error"
|
||||||
title={i18n._(t`Error!`)}
|
title={i18n._(t`Error!`)}
|
||||||
isOpen={toggleError && loadingToggleIds.length === 0}
|
isOpen={!isToggleLoading}
|
||||||
onClose={this.handleNotificationErrorClose}
|
onClose={() => setToggleError(null)}
|
||||||
>
|
>
|
||||||
{i18n._(t`Failed to toggle notification.`)}
|
{i18n._(t`Failed to toggle notification.`)}
|
||||||
<ErrorDetail error={toggleError} />
|
<ErrorDetail error={toggleError} />
|
||||||
</AlertModal>
|
</AlertModal>
|
||||||
</Fragment>
|
)}
|
||||||
);
|
</>
|
||||||
}
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
NotificationList.propTypes = {
|
NotificationList.propTypes = {
|
||||||
|
apiModel: shape({}).isRequired,
|
||||||
id: number.isRequired,
|
id: number.isRequired,
|
||||||
canToggleNotifications: bool.isRequired,
|
canToggleNotifications: bool.isRequired,
|
||||||
location: shape({
|
|
||||||
search: string.isRequired,
|
|
||||||
}).isRequired,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export { NotificationList as _NotificationList };
|
export default withI18n()(NotificationList);
|
||||||
export default withI18n()(withRouter(NotificationList));
|
|
||||||
|
|||||||
@@ -1,15 +1,13 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { act } from 'react-dom/test-utils';
|
||||||
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
|
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
|
||||||
import { sleep } from '../../../testUtils/testUtils';
|
|
||||||
|
|
||||||
import { NotificationTemplatesAPI } from '../../api';
|
import { NotificationTemplatesAPI } from '../../api';
|
||||||
|
|
||||||
import NotificationList from './NotificationList';
|
import NotificationList from './NotificationList';
|
||||||
|
|
||||||
jest.mock('../../api');
|
jest.mock('../../api');
|
||||||
|
|
||||||
describe('<NotificationList />', () => {
|
describe('<NotificationList />', () => {
|
||||||
|
let wrapper;
|
||||||
const data = {
|
const data = {
|
||||||
count: 2,
|
count: 2,
|
||||||
results: [
|
results: [
|
||||||
@@ -58,220 +56,185 @@ describe('<NotificationList />', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
NotificationTemplatesAPI.read.mockReturnValue({ data });
|
||||||
NotificationTemplatesAPI.read.mockReturnValue({ data });
|
|
||||||
MockModelAPI.readNotificationTemplatesSuccess.mockReturnValue({
|
MockModelAPI.readNotificationTemplatesSuccess.mockReturnValue({
|
||||||
data: { results: [{ id: 1 }] },
|
data: { results: [{ id: 1 }] },
|
||||||
});
|
});
|
||||||
MockModelAPI.readNotificationTemplatesError.mockReturnValue({
|
|
||||||
data: { results: [{ id: 2 }] },
|
MockModelAPI.readNotificationTemplatesError.mockReturnValue({
|
||||||
});
|
data: { results: [{ id: 2 }] },
|
||||||
MockModelAPI.readNotificationTemplatesStarted.mockReturnValue({
|
});
|
||||||
data: { results: [{ id: 3 }] },
|
|
||||||
|
MockModelAPI.readNotificationTemplatesStarted.mockReturnValue({
|
||||||
|
data: { results: [{ id: 3 }] },
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await act(async () => {
|
||||||
|
wrapper = mountWithContexts(
|
||||||
|
<NotificationList
|
||||||
|
id={1}
|
||||||
|
canToggleNotifications
|
||||||
|
apiModel={MockModelAPI}
|
||||||
|
/>
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
wrapper.update();
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
jest.clearAllMocks();
|
wrapper.unmount();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('initially renders succesfully', async () => {
|
test('initially renders succesfully', () => {
|
||||||
const wrapper = mountWithContexts(
|
expect(wrapper.find('PaginatedDataList')).toHaveLength(1);
|
||||||
<NotificationList id={1} canToggleNotifications apiModel={MockModelAPI} />
|
|
||||||
);
|
|
||||||
await sleep(0);
|
|
||||||
wrapper.update();
|
|
||||||
const dataList = wrapper.find('PaginatedDataList');
|
|
||||||
expect(dataList).toHaveLength(1);
|
|
||||||
expect(dataList.prop('items')).toEqual(data.results);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should render list fetched of items', async () => {
|
test('should render list fetched of items', () => {
|
||||||
const wrapper = mountWithContexts(
|
|
||||||
<NotificationList id={1} canToggleNotifications apiModel={MockModelAPI} />
|
|
||||||
);
|
|
||||||
await sleep(0);
|
|
||||||
wrapper.update();
|
|
||||||
|
|
||||||
expect(NotificationTemplatesAPI.read).toHaveBeenCalled();
|
expect(NotificationTemplatesAPI.read).toHaveBeenCalled();
|
||||||
expect(wrapper.find('NotificationList').state('notifications')).toEqual(
|
expect(NotificationTemplatesAPI.readOptions).toHaveBeenCalled();
|
||||||
data.results
|
expect(MockModelAPI.readNotificationTemplatesSuccess).toHaveBeenCalled();
|
||||||
);
|
expect(MockModelAPI.readNotificationTemplatesError).toHaveBeenCalled();
|
||||||
const items = wrapper.find('NotificationListItem');
|
expect(MockModelAPI.readNotificationTemplatesStarted).toHaveBeenCalled();
|
||||||
expect(items).toHaveLength(3);
|
expect(wrapper.find('NotificationListItem').length).toBe(3);
|
||||||
expect(items.at(0).prop('successTurnedOn')).toEqual(true);
|
expect(
|
||||||
expect(items.at(0).prop('errorTurnedOn')).toEqual(false);
|
wrapper.find('input#notification-1-success-toggle').props().checked
|
||||||
expect(items.at(0).prop('startedTurnedOn')).toEqual(false);
|
).toBe(true);
|
||||||
expect(items.at(1).prop('successTurnedOn')).toEqual(false);
|
expect(
|
||||||
expect(items.at(1).prop('errorTurnedOn')).toEqual(true);
|
wrapper.find('input#notification-1-error-toggle').props().checked
|
||||||
expect(items.at(1).prop('startedTurnedOn')).toEqual(false);
|
).toBe(false);
|
||||||
expect(items.at(2).prop('successTurnedOn')).toEqual(false);
|
expect(
|
||||||
expect(items.at(2).prop('errorTurnedOn')).toEqual(false);
|
wrapper.find('input#notification-1-started-toggle').props().checked
|
||||||
expect(items.at(2).prop('startedTurnedOn')).toEqual(true);
|
).toBe(false);
|
||||||
|
expect(
|
||||||
|
wrapper.find('input#notification-2-success-toggle').props().checked
|
||||||
|
).toBe(false);
|
||||||
|
expect(
|
||||||
|
wrapper.find('input#notification-2-error-toggle').props().checked
|
||||||
|
).toBe(true);
|
||||||
|
expect(
|
||||||
|
wrapper.find('input#notification-2-started-toggle').props().checked
|
||||||
|
).toBe(false);
|
||||||
|
expect(
|
||||||
|
wrapper.find('input#notification-3-success-toggle').props().checked
|
||||||
|
).toBe(false);
|
||||||
|
expect(
|
||||||
|
wrapper.find('input#notification-3-error-toggle').props().checked
|
||||||
|
).toBe(false);
|
||||||
|
expect(
|
||||||
|
wrapper.find('input#notification-3-started-toggle').props().checked
|
||||||
|
).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should enable success notification', async () => {
|
test('should enable success notification', async () => {
|
||||||
const wrapper = mountWithContexts(
|
|
||||||
<NotificationList id={1} canToggleNotifications apiModel={MockModelAPI} />
|
|
||||||
);
|
|
||||||
await sleep(0);
|
|
||||||
wrapper.update();
|
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
wrapper.find('NotificationList').state('successTemplateIds')
|
wrapper.find('input#notification-2-success-toggle').props().checked
|
||||||
).toEqual([1]);
|
).toBe(false);
|
||||||
const items = wrapper.find('NotificationListItem');
|
await act(async () => {
|
||||||
items
|
wrapper.find('Switch#notification-2-success-toggle').prop('onChange')();
|
||||||
.at(1)
|
});
|
||||||
.find('Switch[aria-label="Toggle notification success"]')
|
wrapper.update();
|
||||||
.prop('onChange')();
|
|
||||||
expect(MockModelAPI.associateNotificationTemplate).toHaveBeenCalledWith(
|
expect(MockModelAPI.associateNotificationTemplate).toHaveBeenCalledWith(
|
||||||
1,
|
1,
|
||||||
2,
|
2,
|
||||||
'success'
|
'success'
|
||||||
);
|
);
|
||||||
await sleep(0);
|
|
||||||
wrapper.update();
|
|
||||||
expect(
|
expect(
|
||||||
wrapper.find('NotificationList').state('successTemplateIds')
|
wrapper.find('input#notification-2-success-toggle').props().checked
|
||||||
).toEqual([1, 2]);
|
).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should enable error notification', async () => {
|
test('should enable error notification', async () => {
|
||||||
const wrapper = mountWithContexts(
|
expect(
|
||||||
<NotificationList id={1} canToggleNotifications apiModel={MockModelAPI} />
|
wrapper.find('input#notification-1-error-toggle').props().checked
|
||||||
);
|
).toBe(false);
|
||||||
await sleep(0);
|
await act(async () => {
|
||||||
|
wrapper.find('Switch#notification-1-error-toggle').prop('onChange')();
|
||||||
|
});
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
|
|
||||||
expect(wrapper.find('NotificationList').state('errorTemplateIds')).toEqual([
|
|
||||||
2,
|
|
||||||
]);
|
|
||||||
const items = wrapper.find('NotificationListItem');
|
|
||||||
items
|
|
||||||
.at(0)
|
|
||||||
.find('Switch[aria-label="Toggle notification failure"]')
|
|
||||||
.prop('onChange')();
|
|
||||||
expect(MockModelAPI.associateNotificationTemplate).toHaveBeenCalledWith(
|
expect(MockModelAPI.associateNotificationTemplate).toHaveBeenCalledWith(
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
'error'
|
'error'
|
||||||
);
|
);
|
||||||
await sleep(0);
|
expect(
|
||||||
wrapper.update();
|
wrapper.find('input#notification-1-error-toggle').props().checked
|
||||||
expect(wrapper.find('NotificationList').state('errorTemplateIds')).toEqual([
|
).toBe(true);
|
||||||
2,
|
|
||||||
1,
|
|
||||||
]);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should enable start notification', async () => {
|
test('should enable start notification', async () => {
|
||||||
const wrapper = mountWithContexts(
|
|
||||||
<NotificationList id={1} canToggleNotifications apiModel={MockModelAPI} />
|
|
||||||
);
|
|
||||||
await sleep(0);
|
|
||||||
wrapper.update();
|
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
wrapper.find('NotificationList').state('startedTemplateIds')
|
wrapper.find('input#notification-1-started-toggle').props().checked
|
||||||
).toEqual([3]);
|
).toBe(false);
|
||||||
const items = wrapper.find('NotificationListItem');
|
await act(async () => {
|
||||||
items
|
wrapper.find('Switch#notification-1-started-toggle').prop('onChange')();
|
||||||
.at(0)
|
});
|
||||||
.find('Switch[aria-label="Toggle notification start"]')
|
wrapper.update();
|
||||||
.prop('onChange')();
|
|
||||||
expect(MockModelAPI.associateNotificationTemplate).toHaveBeenCalledWith(
|
expect(MockModelAPI.associateNotificationTemplate).toHaveBeenCalledWith(
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
'started'
|
'started'
|
||||||
);
|
);
|
||||||
await sleep(0);
|
|
||||||
wrapper.update();
|
|
||||||
expect(
|
expect(
|
||||||
wrapper.find('NotificationList').state('startedTemplateIds')
|
wrapper.find('input#notification-1-started-toggle').props().checked
|
||||||
).toEqual([3, 1]);
|
).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should disable success notification', async () => {
|
test('should disable success notification', async () => {
|
||||||
const wrapper = mountWithContexts(
|
|
||||||
<NotificationList id={1} canToggleNotifications apiModel={MockModelAPI} />
|
|
||||||
);
|
|
||||||
await sleep(0);
|
|
||||||
wrapper.update();
|
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
wrapper.find('NotificationList').state('successTemplateIds')
|
wrapper.find('input#notification-1-success-toggle').props().checked
|
||||||
).toEqual([1]);
|
).toBe(true);
|
||||||
const items = wrapper.find('NotificationListItem');
|
await act(async () => {
|
||||||
items
|
wrapper.find('Switch#notification-1-success-toggle').prop('onChange')();
|
||||||
.at(0)
|
});
|
||||||
.find('Switch[aria-label="Toggle notification success"]')
|
wrapper.update();
|
||||||
.prop('onChange')();
|
|
||||||
expect(MockModelAPI.disassociateNotificationTemplate).toHaveBeenCalledWith(
|
expect(MockModelAPI.disassociateNotificationTemplate).toHaveBeenCalledWith(
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
'success'
|
'success'
|
||||||
);
|
);
|
||||||
await sleep(0);
|
|
||||||
wrapper.update();
|
|
||||||
expect(
|
expect(
|
||||||
wrapper.find('NotificationList').state('successTemplateIds')
|
wrapper.find('input#notification-1-success-toggle').props().checked
|
||||||
).toEqual([]);
|
).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should disable error notification', async () => {
|
test('should disable error notification', async () => {
|
||||||
const wrapper = mountWithContexts(
|
expect(
|
||||||
<NotificationList id={1} canToggleNotifications apiModel={MockModelAPI} />
|
wrapper.find('input#notification-2-error-toggle').props().checked
|
||||||
);
|
).toBe(true);
|
||||||
await sleep(0);
|
await act(async () => {
|
||||||
|
wrapper.find('Switch#notification-2-error-toggle').prop('onChange')();
|
||||||
|
});
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
|
|
||||||
expect(wrapper.find('NotificationList').state('errorTemplateIds')).toEqual([
|
|
||||||
2,
|
|
||||||
]);
|
|
||||||
const items = wrapper.find('NotificationListItem');
|
|
||||||
items
|
|
||||||
.at(1)
|
|
||||||
.find('Switch[aria-label="Toggle notification failure"]')
|
|
||||||
.prop('onChange')();
|
|
||||||
expect(MockModelAPI.disassociateNotificationTemplate).toHaveBeenCalledWith(
|
expect(MockModelAPI.disassociateNotificationTemplate).toHaveBeenCalledWith(
|
||||||
1,
|
1,
|
||||||
2,
|
2,
|
||||||
'error'
|
'error'
|
||||||
);
|
);
|
||||||
await sleep(0);
|
expect(
|
||||||
wrapper.update();
|
wrapper.find('input#notification-2-error-toggle').props().checked
|
||||||
expect(wrapper.find('NotificationList').state('errorTemplateIds')).toEqual(
|
).toBe(false);
|
||||||
[]
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should disable start notification', async () => {
|
test('should disable start notification', async () => {
|
||||||
const wrapper = mountWithContexts(
|
|
||||||
<NotificationList id={1} canToggleNotifications apiModel={MockModelAPI} />
|
|
||||||
);
|
|
||||||
await sleep(0);
|
|
||||||
wrapper.update();
|
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
wrapper.find('NotificationList').state('startedTemplateIds')
|
wrapper.find('input#notification-3-started-toggle').props().checked
|
||||||
).toEqual([3]);
|
).toBe(true);
|
||||||
const items = wrapper.find('NotificationListItem');
|
await act(async () => {
|
||||||
items
|
wrapper.find('Switch#notification-3-started-toggle').prop('onChange')();
|
||||||
.at(2)
|
});
|
||||||
.find('Switch[aria-label="Toggle notification start"]')
|
wrapper.update();
|
||||||
.prop('onChange')();
|
|
||||||
expect(MockModelAPI.disassociateNotificationTemplate).toHaveBeenCalledWith(
|
expect(MockModelAPI.disassociateNotificationTemplate).toHaveBeenCalledWith(
|
||||||
1,
|
1,
|
||||||
3,
|
3,
|
||||||
'started'
|
'started'
|
||||||
);
|
);
|
||||||
await sleep(0);
|
|
||||||
wrapper.update();
|
|
||||||
expect(
|
expect(
|
||||||
wrapper.find('NotificationList').state('startedTemplateIds')
|
wrapper.find('input#notification-3-started-toggle').props().checked
|
||||||
).toEqual([]);
|
).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should throw toggle error', async () => {
|
test('should throw toggle error', async () => {
|
||||||
MockModelAPI.associateNotificationTemplate.mockRejectedValue(
|
MockModelAPI.associateNotificationTemplate.mockRejectedValue(
|
||||||
new Error({
|
new Error({
|
||||||
@@ -284,27 +247,16 @@ describe('<NotificationList />', () => {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
const wrapper = mountWithContexts(
|
expect(wrapper.find('ErrorDetail').length).toBe(0);
|
||||||
<NotificationList id={1} canToggleNotifications apiModel={MockModelAPI} />
|
await act(async () => {
|
||||||
);
|
wrapper.find('Switch#notification-1-started-toggle').prop('onChange')();
|
||||||
await sleep(0);
|
});
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
|
|
||||||
expect(
|
|
||||||
wrapper.find('NotificationList').state('startedTemplateIds')
|
|
||||||
).toEqual([3]);
|
|
||||||
const items = wrapper.find('NotificationListItem');
|
|
||||||
items
|
|
||||||
.at(0)
|
|
||||||
.find('Switch[aria-label="Toggle notification start"]')
|
|
||||||
.prop('onChange')();
|
|
||||||
expect(MockModelAPI.associateNotificationTemplate).toHaveBeenCalledWith(
|
expect(MockModelAPI.associateNotificationTemplate).toHaveBeenCalledWith(
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
'started'
|
'started'
|
||||||
);
|
);
|
||||||
await sleep(0);
|
|
||||||
wrapper.update();
|
|
||||||
expect(wrapper.find('ErrorDetail').length).toBe(1);
|
expect(wrapper.find('ErrorDetail').length).toBe(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user