Skip to content

Commit

Permalink
feat(AlertMeeting): allow props to be passed to internal components
Browse files Browse the repository at this point in the history
  • Loading branch information
bfbiggs authored and pauljeter committed Jun 25, 2019
1 parent 915a5fa commit 80fa1e3
Show file tree
Hide file tree
Showing 4 changed files with 183 additions and 19 deletions.
4 changes: 2 additions & 2 deletions react/src/lib/AlertMeeting/examples/Default.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ export default class Default extends React.PureComponent {
title='Important Meeting'
status='In 5 mins.'
message='This is important'
onHide={() => this.handleOnHide}
onSnooze={() => this.handleOnSnooze}
onHide={this.handleOnHide}
onSnooze={this.handleOnSnooze}
attendees={[{title: 'J $'}]}
show={this.state.show}
/>
Expand Down
39 changes: 31 additions & 8 deletions react/src/lib/AlertMeeting/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,18 @@ const AlertMeeting = props => {
avatar,
className,
closeAriaLabel,
closeBtnProps,
message,
onClick,
onKeyDown,
onHide,
onSnooze,
remindAriaLabel,
show,
snoozeBtnProps,
status,
title,
...otherProps
} = props;

const renderAvatar = () => {
Expand All @@ -36,11 +40,13 @@ const AlertMeeting = props => {
title={attendees[0].title}
alt={attendees[0].alt}
src={attendees[0].src}
{...attendees[0].props}
/>
<Avatar
title={attendees[1].title}
alt={attendees[1].alt}
src={attendees[1].src}
{...attendees[1].props}
/>
</CompositeAvatar>
);
Expand All @@ -50,10 +56,11 @@ const AlertMeeting = props => {
title={attendees[0].title}
alt={attendees[0].alt}
src={attendees[0].src}
{...attendees[0].props}
/>
);
} else {
throw new Error('MeetingAlert needs at least one attendee to render an avatar.');
throw new Error('AlertMeeting needs at least one attendee to render an avatar.');
}
}
};
Expand All @@ -64,10 +71,12 @@ const AlertMeeting = props => {
|| e.which === 13
|| e.charCode === 32
|| e.charCode === 13
) {
onClick && onClick(e);
e.preventDefault();
) {
onClick && onClick(e);
e.preventDefault();
}

onKeyDown && onKeyDown(e);
};

return (
Expand All @@ -78,12 +87,15 @@ const AlertMeeting = props => {
`${(className && ` ${className}`) || ''}`
}
{
...onClick && {
onClick: onClick,
...onClick && { onClick }
}
{
...(onClick || onKeyDown) && {
onKeyDown: e => handleKeyDown(e),
role: 'button'
}
}
{...otherProps}
>
{renderAvatar()}
<div
Expand Down Expand Up @@ -116,16 +128,18 @@ const AlertMeeting = props => {
ariaLabel={remindAriaLabel}
circle
size={44}
{...snoozeBtnProps}
/>
</div>
}
<div className='md-alert__button'>
<Button
children={<Icon name='cancel_16' />}
onClick={onHide}
ariaLabel={closeAriaLabel}
circle
children={<Icon name='cancel_16' />}
onClick={onHide}
size={44}
{...closeBtnProps}
/>
</div>
</div>
Expand All @@ -138,11 +152,14 @@ AlertMeeting.defaultProps = {
avatar: null,
className: '',
closeAriaLabel: 'close',
closeBtnProps: null,
message: '',
onClick: null,
onKeyDown: null,
onHide: null,
onSnooze: null,
remindAriaLabel: 'snooze',
snoozeBtnProps: null,
status: '',
title: '',
};
Expand All @@ -162,8 +179,12 @@ AlertMeeting.propTypes = {
className: PropTypes.string,
/** @prop Optional aria label for the close button | 'close' */
closeAriaLabel: PropTypes.string,
/** @prop Props to be passed to close button | null */
closeBtnProps: PropTypes.object,
/** @prop Optional callback function invoked on click of alert | null */
onClick: PropTypes.func,
/** @prop Optional callback function invoked on keydown on alert | null */
onKeyDown: PropTypes.func,
/** @prop Mandatory handler invoked when the user presses on the Alert's close button or hit's the esc key | null */
onHide: PropTypes.func,
/** @prop Optional callback function invoked when the snooze button is clicked | null */
Expand All @@ -174,6 +195,8 @@ AlertMeeting.propTypes = {
remindAriaLabel: PropTypes.string,
/** @prop Set AlertMeeting visibility */
show: PropTypes.bool.isRequired,
/** @prop Props to be passed to snooze button | null */
snoozeBtnProps: PropTypes.object,
/** @prop Optional AlertMeeting status | '' */
status: PropTypes.string,
/** @prop Optional AlertMeeting title | '' */
Expand Down
10 changes: 10 additions & 0 deletions react/src/lib/AlertMeeting/tests/__snapshots__/index.spec.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,25 @@ ShallowWrapper {
attendees={
Array [
Object {
"props": Object {
"id": "testid",
},
"title": "J $",
},
]
}
avatar={null}
className=""
closeAriaLabel="close"
closeBtnProps={null}
message=""
onClick={null}
onHide={null}
onKeyDown={null}
onSnooze={[Function]}
remindAriaLabel="snooze"
show={true}
snoozeBtnProps={null}
status=""
title=""
/>,
Expand Down Expand Up @@ -48,6 +54,7 @@ ShallowWrapper {
hasNotification={false}
hideDefaultTooltip={false}
icon={null}
id="testid"
isDecrypting={false}
isOverview={false}
onClick={null}
Expand Down Expand Up @@ -187,6 +194,7 @@ ShallowWrapper {
"hasNotification": false,
"hideDefaultTooltip": false,
"icon": null,
"id": "testid",
"isDecrypting": false,
"isOverview": false,
"onClick": null,
Expand Down Expand Up @@ -535,6 +543,7 @@ ShallowWrapper {
hasNotification={false}
hideDefaultTooltip={false}
icon={null}
id="testid"
isDecrypting={false}
isOverview={false}
onClick={null}
Expand Down Expand Up @@ -674,6 +683,7 @@ ShallowWrapper {
"hasNotification": false,
"hideDefaultTooltip": false,
"icon": null,
"id": "testid",
"isDecrypting": false,
"isOverview": false,
"onClick": null,
Expand Down
149 changes: 140 additions & 9 deletions react/src/lib/AlertMeeting/tests/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import AlertMeeting from '../index';
import { Avatar, CompositeAvatar } from '@momentum-ui/react';

describe('tests for <AlertMeeting />', () => {
const attendeeOne = {title: 'J $'};
const attendeeTwo = {title: 'Hee Haw'};
const attendeeOne = {title: 'J $', props: { id: 'testid' }};
const attendeeTwo = {title: 'Hee Haw', props: { id: 'testid2' }};
const attendeeThree = {title: 'Hollywood Squarepants'};

const attendeeListOne = [attendeeOne];
Expand All @@ -24,6 +24,13 @@ describe('tests for <AlertMeeting />', () => {
expect(container.find('.md-alert.md-alert--meeting').length).toEqual(1);
});

it('should pass className prop', () => {
const container = mount(<AlertMeeting show attendees={attendeeListOne} className='testing' />);

expect(container.find('.testing').exists()).toEqual(true);
expect(container.find('AlertMeeting').hasClass('testing')).toEqual(true);
});

it('should render meeting title', () => {
const container = shallow(<AlertMeeting show attendees={attendeeListOne} title="Super Important Meeting" />);

Expand Down Expand Up @@ -103,25 +110,74 @@ describe('tests for <AlertMeeting />', () => {
it('should handle onClick event', () => {
let count = 0;
const countUp = () => count++;
const container = mount(<AlertMeeting show attendees={attendeeListOne} onClick={countUp} />);
const container = mount(
<AlertMeeting
attendees={attendeeListOne}
onClick={countUp}
show
/>);

container.find('.md-alert').first().simulate('click');
expect(count).toEqual(1);
});

it('should handle keyDown event', () => {
it('should handle keyDown event with onClick (Enter)', () => {
let count = 0;
const countUp = () => count++;
const container = mount(<AlertMeeting show attendees={attendeeListOne} onClick={countUp} />);
const container = mount(
<AlertMeeting
attendees={attendeeListOne}
onClick={countUp}
show
tabIndex={0}
/>);

container.find('.md-alert').first().simulate('keyDown', { which: 32 });
expect(count).toEqual(1);
container.find('.md-alert').first().simulate('keyDown', { charCode: 32 });
expect(count).toEqual(2);
});

container.find('.md-alert').first().simulate('keyDown', { which: 13, charCode: 13, key: 'Space' });
it('should handle keyDown event with onClick (Space)', () => {
let count = 0;
const countUp = () => count++;
const container = mount(
<AlertMeeting
attendees={attendeeListOne}
onClick={countUp}
show
tabIndex={0}
/>);

container.find('.md-alert').first().simulate('keyDown', { which: 13 });
expect(count).toEqual(1);
container.find('.md-alert').first().simulate('keyDown', { charCode: 13 });
expect(count).toEqual(2);
});

it('should handle onKeyDown event', () => {
let count = 0;
const countUp = () => count++;
const container = mount(
<AlertMeeting
attendees={attendeeListOne}
onKeyDown={countUp}
show
/>);

container.find('.md-alert').first().simulate('keyDown', { which: 100 });
expect(count).toEqual(1);
});

it('should handle onSnooze event', () => {
let count = 0;
const countUp = () => count++;
const container = mount(<AlertMeeting show attendees={attendeeListOne} onSnooze={countUp} />);
const container = mount(
<AlertMeeting
attendees={attendeeListOne}
onSnooze={countUp}
show
/>);

container.find('.md-button').first().simulate('click');
expect(count).toEqual(1);
Expand All @@ -130,9 +186,84 @@ describe('tests for <AlertMeeting />', () => {
it('should handle onHide event', () => {
let count = 0;
const countUp = () => count++;
const container = mount(<AlertMeeting show attendees={attendeeListOne} onHide={countUp} />);
const container = mount(
<AlertMeeting
attendees={attendeeListOne}
onHide={countUp}
show
/>);

container.find('.md-button').last().simulate('click');
expect(count).toEqual(1);
});
});

it('should pass snoozeBtnProps prop', () => {
const container = mount(
<AlertMeeting
attendees={attendeeListOne}
onSnooze={()=>{}}
show
snoozeBtnProps={{ ariaLabel: 'test' }}
/>
);

expect(container.find('Button').first().props().ariaLabel).toEqual('test');
});

it('should pass closeBtnProps prop', () => {
const container = mount(
<AlertMeeting
attendees={attendeeListOne}
show
closeBtnProps={{ ariaLabel: 'test' }}
/>
);

expect(container.find('Button').last().props().ariaLabel).toEqual('test');
});

it('should pass avatar props when single attendee', () => {
const container = mount(
<AlertMeeting
attendees={attendeeListOne}
show
/>
);

expect(container.find('#testid').exists()).toEqual(true);
});

it('should pass avatar props with multiple attendees', () => {
const container = mount(
<AlertMeeting
attendees={attendeeListTwo}
show
/>
);

expect(container.find('#testid').exists()).toEqual(true);
expect(container.find('#testid2').exists()).toEqual(true);
});

it('should render an avatar prop', () => {
const container = mount(
<AlertMeeting
avatar={<Avatar title='#' id='testid' />}
show
/>
);

expect(container.find(Avatar).length).toEqual(1);
expect(container.find('#testid').exists()).toEqual(true);
});

it('should throw error if no attendees or avatar prop', () => {
try {
shallow(
<AlertMeeting show/>
);
} catch(e) {
expect(e.message).toEqual('AlertMeeting needs at least one attendee to render an avatar.');
}
});
});

0 comments on commit 80fa1e3

Please sign in to comment.