Skip to content

Commit d9c0501

Browse files
committed
Refactor NotificationMessage component
1 parent 2a30ec0 commit d9c0501

File tree

5 files changed

+221
-19
lines changed

5 files changed

+221
-19
lines changed
Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,16 @@
11
import React from 'react';
22
import PropTypes from 'prop-types';
33
import classNames from 'classnames';
4+
import { NotificationTypes } from '../helpers/notification-types';
45

5-
export const NotificationTypes = {
6-
info: 'info',
7-
danger: 'danger',
8-
success: 'success',
9-
warning: 'warning',
10-
};
11-
12-
const NotificationMessage = ({
13-
type, message,
14-
}) => {
15-
const valid = Object.values(NotificationTypes).includes(type);
16-
17-
if (valid && message) {
6+
/** Component to render a notification message. */
7+
const NotificationMessage = ({ type, message }) => {
8+
const validType = type && Object.keys(NotificationTypes).includes(type);
9+
const notification = validType ? NotificationTypes[type] : NotificationTypes.unknown;
10+
if (message) {
1811
return (
19-
<div className={classNames('alert', `alert-${type}`)}>
20-
<span className={classNames('pficon', `pficon-${type}`)} />
12+
<div className={classNames('miq-notification-message-container', 'alert', notification.alert)}>
13+
<span className={classNames('pficon', notification.icon)} />
2114
<strong>{message}</strong>
2215
</div>
2316
);
@@ -28,6 +21,11 @@ const NotificationMessage = ({
2821
export default NotificationMessage;
2922

3023
NotificationMessage.propTypes = {
31-
type: PropTypes.string.isRequired,
32-
message: PropTypes.string.isRequired,
24+
type: PropTypes.string,
25+
message: PropTypes.string,
26+
};
27+
28+
NotificationMessage.defaultProps = {
29+
type: undefined,
30+
message: undefined,
3331
};
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/** Types of notification messages
2+
* Used in NotificationMessage and ToastItem components.
3+
*/
4+
export const NotificationTypes = {
5+
error: { alert: 'alert-danger', icon: 'pficon-error-circle-o' },
6+
info: { alert: 'alert-info', icon: 'pficon-info' },
7+
success: { alert: 'alert-success', icon: 'pficon-ok' },
8+
warning: { alert: 'alert-warning', icon: 'pficon-warning-triangle-o' },
9+
unknown: { alert: 'alert-info', icon: 'fa fa-regular fa-question-circle' },
10+
};
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`NotificationMessage component blank message should not render message 1`] = `
4+
<NotificationMessage
5+
message=""
6+
type="error"
7+
/>
8+
`;
9+
10+
exports[`NotificationMessage component invalid type should not render message 1`] = `
11+
<NotificationMessage
12+
message={"No message will be displayed"}
13+
type="unknown"
14+
>
15+
<div
16+
className="miq-notification-message-container alert alert-info"
17+
>
18+
<span
19+
className="pficon fa fa-regular fa-question-circle"
20+
/>
21+
<strong>
22+
<Component />
23+
</strong>
24+
</div>
25+
</NotificationMessage>
26+
`;
27+
28+
exports[`NotificationMessage component should render error message 1`] = `
29+
<NotificationMessage
30+
message={"Error message goes here"}
31+
type="error"
32+
>
33+
<div
34+
className="miq-notification-message-container alert alert-danger"
35+
>
36+
<span
37+
className="pficon pficon-error-circle-o"
38+
/>
39+
<strong>
40+
<Component />
41+
</strong>
42+
</div>
43+
</NotificationMessage>
44+
`;
45+
46+
exports[`NotificationMessage component should render information message 1`] = `
47+
<NotificationMessage
48+
message={"Information message goes here"}
49+
type="info"
50+
>
51+
<div
52+
className="miq-notification-message-container alert alert-info"
53+
>
54+
<span
55+
className="pficon pficon-info"
56+
/>
57+
<strong>
58+
<Component />
59+
</strong>
60+
</div>
61+
</NotificationMessage>
62+
`;
63+
64+
exports[`NotificationMessage component should render success message 1`] = `
65+
<NotificationMessage
66+
message={"Success message goes here"}
67+
type="success"
68+
>
69+
<div
70+
className="miq-notification-message-container alert alert-success"
71+
>
72+
<span
73+
className="pficon pficon-ok"
74+
/>
75+
<strong>
76+
<Component />
77+
</strong>
78+
</div>
79+
</NotificationMessage>
80+
`;
81+
82+
exports[`NotificationMessage component should render warning message 1`] = `
83+
<NotificationMessage
84+
message={"Warning message goes here"}
85+
type="warning"
86+
>
87+
<div
88+
className="miq-notification-message-container alert alert-warning"
89+
>
90+
<span
91+
className="pficon pficon-warning-triangle-o"
92+
/>
93+
<strong>
94+
<Component />
95+
</strong>
96+
</div>
97+
</NotificationMessage>
98+
`;
99+
100+
exports[`NotificationMessage component unknown error type message should be rendered with blank type 1`] = `
101+
<NotificationMessage
102+
message={"Message goes here"}
103+
type=""
104+
>
105+
<div
106+
className="miq-notification-message-container alert alert-info"
107+
>
108+
<span
109+
className="pficon fa fa-regular fa-question-circle"
110+
/>
111+
<strong>
112+
<Component />
113+
</strong>
114+
</div>
115+
</NotificationMessage>
116+
`;
117+
118+
exports[`NotificationMessage component unknown error type message should be rendered with no type 1`] = `
119+
<NotificationMessage
120+
message={"Message goes here"}
121+
>
122+
<div
123+
className="miq-notification-message-container alert alert-info"
124+
>
125+
<span
126+
className="pficon fa fa-regular fa-question-circle"
127+
/>
128+
<strong>
129+
<Component />
130+
</strong>
131+
</div>
132+
</NotificationMessage>
133+
`;
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import React from 'react';
2+
import toJson from 'enzyme-to-json';
3+
import { mount } from 'enzyme';
4+
import NotificationMessage from '../../components/notification-message';
5+
6+
describe('NotificationMessage component', () => {
7+
it('should render error message', () => {
8+
const wrapper = mount(<NotificationMessage type="error" message={_('Error message goes here')} />);
9+
expect(toJson(wrapper)).toMatchSnapshot();
10+
expect(wrapper.find('.alert-danger')).toHaveLength(1);
11+
expect(wrapper.find('.pficon-error-circle-o')).toHaveLength(1);
12+
});
13+
14+
it('should render information message', () => {
15+
const wrapper = mount(<NotificationMessage type="info" message={_('Information message goes here')} />);
16+
expect(wrapper.find('.alert-info')).toHaveLength(1);
17+
expect(wrapper.find('.pficon-info')).toHaveLength(1);
18+
expect(toJson(wrapper)).toMatchSnapshot();
19+
});
20+
21+
it('should render success message', () => {
22+
const wrapper = mount(<NotificationMessage type="success" message={_('Success message goes here')} />);
23+
expect(wrapper.find('.alert-success')).toHaveLength(1);
24+
expect(wrapper.find('.pficon-ok')).toHaveLength(1);
25+
expect(toJson(wrapper)).toMatchSnapshot();
26+
});
27+
28+
it('should render warning message', () => {
29+
const wrapper = mount(<NotificationMessage type="warning" message={_('Warning message goes here')} />);
30+
expect(wrapper.find('.alert-warning')).toHaveLength(1);
31+
expect(wrapper.find('.pficon-warning-triangle-o')).toHaveLength(1);
32+
expect(toJson(wrapper)).toMatchSnapshot();
33+
});
34+
35+
it('invalid type should not render message', () => {
36+
const wrapper = mount(<NotificationMessage type="unknown" message={_('No message will be displayed')} />);
37+
expect(wrapper.find('.miq-notification-message-container')).toHaveLength(1);
38+
expect(wrapper.find('.fa-question-circle')).toHaveLength(1);
39+
expect(toJson(wrapper)).toMatchSnapshot();
40+
});
41+
42+
it('blank message should not render message', () => {
43+
const wrapper = mount(<NotificationMessage type="error" message="" />);
44+
expect(wrapper.find('.miq-notification-message-container')).toHaveLength(0);
45+
expect(toJson(wrapper)).toMatchSnapshot();
46+
});
47+
48+
it('unknown error type message should be rendered with blank type', () => {
49+
const wrapper = mount(<NotificationMessage type="" message={_('Message goes here')} />);
50+
expect(wrapper.find('.miq-notification-message-container')).toHaveLength(1);
51+
expect(wrapper.find('.fa-question-circle')).toHaveLength(1);
52+
expect(toJson(wrapper)).toMatchSnapshot();
53+
});
54+
55+
it('unknown error type message should be rendered with no type', () => {
56+
const wrapper = mount(<NotificationMessage message={_('Message goes here')} />);
57+
expect(wrapper.find('.miq-notification-message-container')).toHaveLength(1);
58+
expect(wrapper.find('.fa-question-circle')).toHaveLength(1);
59+
expect(toJson(wrapper)).toMatchSnapshot();
60+
});
61+
});

app/javascript/spec/settings-label-tag-mapping/__snapshots__/settings-label-tag-mapping.spec.js.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,10 +166,10 @@ exports[`SettingsLabelTagMapping component should render a SettingsLabelTagMappi
166166
type="warning"
167167
>
168168
<div
169-
className="alert alert-warning"
169+
className="miq-notification-message-container alert alert-warning"
170170
>
171171
<span
172-
className="pficon pficon-warning"
172+
className="pficon pficon-warning-triangle-o"
173173
/>
174174
<strong>
175175
Caution: Mappings with Resource Entity 'All-Entities' could cause overwriting existing tags on resources with mapped provider labels.

0 commit comments

Comments
 (0)