Skip to content

Commit 878a0ca

Browse files
committed
done
1 parent 5939e2c commit 878a0ca

File tree

4 files changed

+86
-2
lines changed

4 files changed

+86
-2
lines changed

src/Toast/Toast.jsx

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,21 @@ import classNames from 'classnames';
55

66
import { Alert } from 'src/Alert';
77
import FadeTransition from 'src/FadeTransition';
8+
import { isObject } from '../utils';
89

910
import './Toast.scss';
1011

12+
function buildAlertMessageProps(message) {
13+
if (isObject(message) && !React.isValidElement(message)) {
14+
return {
15+
title: message.title,
16+
message: message.body,
17+
};
18+
}
19+
20+
return { message };
21+
}
22+
1123
export default function Toast(props) {
1224
const groupClassNames = classNames(
1325
'Toast',
@@ -23,9 +35,9 @@ export default function Toast(props) {
2335
action={message.action}
2436
autoDismiss={props.autoDismiss}
2537
id={message.id}
26-
message={message.message}
2738
type={message.type}
2839
onDismiss={props.onToastClosed}
40+
{...buildAlertMessageProps(message.message)}
2941
/>
3042
</FadeTransition>
3143
))
@@ -40,7 +52,14 @@ Toast.propTypes = {
4052
messages: PropTypes.arrayOf(
4153
PropTypes.shape({
4254
id: PropTypes.string,
43-
message: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
55+
message: PropTypes.oneOfType([
56+
PropTypes.string,
57+
PropTypes.node,
58+
PropTypes.shape({
59+
body: PropTypes.string,
60+
title: PropTypes.string,
61+
}),
62+
]),
4463
type: PropTypes.string,
4564
}),
4665
).isRequired,

src/Toast/Toast.test.jsx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React from 'react';
22
import { create } from 'react-test-renderer';
33

44
import { Toast } from 'src/Toast';
5+
import { Alert } from 'src/Alert';
56

67
describe('Toast', () => {
78
test('no header classes', () => {
@@ -17,4 +18,33 @@ describe('Toast', () => {
1718
expect(props.className).toContain('Toast');
1819
expect(props.className).toContain('Toast--no-header');
1920
});
21+
22+
describe('when building alert message props', () => {
23+
const setup = (message) => create(
24+
<Toast
25+
messages={[
26+
{ id: '1', type: 'success', message },
27+
]}
28+
/>,
29+
);
30+
31+
test('builds props from string message', () => {
32+
const { root } = setup('hello');
33+
34+
expect(root.findByType(Alert).props.message).toBe('hello');
35+
});
36+
37+
test('builds props from node message', () => {
38+
const { root } = setup(<div>hello</div>);
39+
40+
expect(root.findByType(Alert).props.message).toEqual(<div>hello</div>);
41+
});
42+
43+
test('builds props from object message', () => {
44+
const { root } = setup({ title: 'woohoo', body: 'you did it!' });
45+
46+
expect(root.findByType(Alert).props.message).toBe('you did it!');
47+
expect(root.findByType(Alert).props.title).toBe('woohoo');
48+
});
49+
});
2050
});

src/utils.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export function isObject(value) {
2+
return (
3+
typeof value === 'object' &&
4+
value !== null &&
5+
value !== undefined &&
6+
value.constructor.name === 'Object'
7+
);
8+
}

src/utils.test.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { isObject } from './utils';
2+
3+
describe('isObject', () => {
4+
describe('when value is an object', () => {
5+
test('returns true', () => {
6+
expect(isObject({})).toBe(true);
7+
});
8+
});
9+
10+
describe('when value is undefined', () => {
11+
test('returns false', () => {
12+
expect(isObject()).toBe(false);
13+
});
14+
});
15+
16+
describe('when value is null', () => {
17+
test('returns false', () => {
18+
expect(isObject(null)).toBe(false);
19+
});
20+
});
21+
22+
describe('when value is an array', () => {
23+
test('returns false', () => {
24+
expect(isObject([])).toBe(false);
25+
});
26+
});
27+
});

0 commit comments

Comments
 (0)