Skip to content

Commit

Permalink
Welcome guide: Add unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
noisysocks committed Nov 22, 2019
1 parent 0ce1ee1 commit 99c80cc
Show file tree
Hide file tree
Showing 5 changed files with 232 additions and 8 deletions.
21 changes: 13 additions & 8 deletions packages/nux/src/components/guide/index.js
Expand Up @@ -6,10 +6,10 @@ import classnames from 'classnames';
/**
* WordPress dependencies
*/
import { useSelect } from '@wordpress/data';
import { useState, Children } from '@wordpress/element';
import { Modal, KeyboardShortcuts, IconButton } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { withSelect } from '@wordpress/data';

/**
* Internal dependencies
Expand All @@ -18,10 +18,7 @@ import PageControl from './page-control';
import { BackButtonIcon, ForwardButtonIcon } from './icons';
import FinishButton from './finish-button';

function Guide( { className, onFinish, finishButtonText, children } ) {
const isMobile = useSelect( ( select ) =>
select( 'core/viewport' ).isViewportMatch( '< small' ) );

export function Guide( { children, className, finishButtonText, isMobile, onFinish } ) {
const [ currentPage, setCurrentPage ] = useState( 0 );

const numberOfPages = Children.count( children );
Expand All @@ -40,6 +37,10 @@ function Guide( { className, onFinish, finishButtonText, children } ) {
}
};

if ( numberOfPages === 0 ) {
return null;
}

return (
<Modal className={ classnames( 'nux-guide', className ) } onRequestClose={ onFinish }>

Expand Down Expand Up @@ -98,10 +99,14 @@ function Guide( { className, onFinish, finishButtonText, children } ) {
);
}

function Page( props ) {
export function Page( props ) {
return <div { ...props } />;
}

Guide.Page = Page;
const EnhancedGuide = withSelect( ( select ) => ( {
isMobile: select( 'core/viewport' ).isViewportMatch( '< small' ),
} ) )( Guide );

EnhancedGuide.Page = Page;

export default Guide;
export default EnhancedGuide;
40 changes: 40 additions & 0 deletions packages/nux/src/components/guide/test/__snapshots__/index.js.snap
@@ -0,0 +1,40 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Guide renders when there are pages 1`] = `
<WithInstanceId(Modal)
className="nux-guide"
>
<KeyboardShortcuts
key="0"
shortcuts={
Object {
"left": [Function],
"right": [Function],
}
}
/>
<div
className="nux-guide__container"
>
<Page>
Page 1
</Page>
<div
className="nux-guide__footer"
>
<PageControl
currentPage={0}
numberOfPages={2}
setCurrentPage={[Function]}
/>
<ForwardRef(IconButton)
className="nux-guide__forward-button"
icon={<ForwardButtonIcon />}
onClick={[Function]}
>
Next
</ForwardRef(IconButton)>
</div>
</div>
</WithInstanceId(Modal)>
`;
49 changes: 49 additions & 0 deletions packages/nux/src/components/guide/test/finish-button.js
@@ -0,0 +1,49 @@
/**
* External dependencies
*/
import { shallow } from 'enzyme';
import { create } from 'react-test-renderer';

/**
* WordPress dependencies
*/
import { Button } from '@wordpress/components';

/**
* Internal dependencies
*/
import FinishButton from '../finish-button';

describe( 'FinishButton', () => {
it( 'renders a button', () => {
const wrapper = shallow( <FinishButton /> );
expect( wrapper.find( Button ) ).toHaveLength( 1 );
} );

it( 'calls onClick when the button is clicked', () => {
const onClick = jest.fn();
const wrapper = shallow( <FinishButton onClick={ onClick } /> );
wrapper.find( Button ).prop( 'onClick' )();
expect( onClick ).toHaveBeenCalled();
} );

it( 'receives focus on mount when nothing is focused', () => {
const focus = jest.fn();
create( <FinishButton />, {
createNodeMock: () => ( { focus } ),
} );
expect( focus ).toHaveBeenCalled();
} );

it( 'does not receive focus on mount when something is already focused', () => {
const button = document.createElement( 'button' );
document.body.append( button );
button.focus();

const focus = jest.fn();
create( <FinishButton />, {
createNodeMock: () => ( { focus } ),
} );
expect( focus ).not.toHaveBeenCalled();
} );
} );
91 changes: 91 additions & 0 deletions packages/nux/src/components/guide/test/index.js
@@ -0,0 +1,91 @@
/**
* External dependencies
*/
import { shallow } from 'enzyme';

/**
* WordPress dependencies
*/
import { Modal } from '@wordpress/components';

/**
* Internal dependencies
*/
import { Guide, Page } from '../';
import PageControl from '../page-control';

describe( 'Guide', () => {
it( 'renders nothing when there are no pages', () => {
const wrapper = shallow( <Guide /> );
expect( wrapper.isEmptyRender() ).toBe( true );
} );

it( 'renders when there are pages', () => {
const wrapper = shallow(
<Guide>
<Page>Page 1</Page>
<Page>Page 2</Page>
</Guide>
);
expect( wrapper ).toMatchSnapshot();
} );

it( 'hides back button and shows forward button on the first page', () => {
const wrapper = shallow(
<Guide>
<Page>Page 1</Page>
<Page>Page 2</Page>
</Guide>
);
expect( wrapper.find( PageControl ).prop( 'currentPage' ) ).toBe( 0 );
expect( wrapper.find( '.nux-guide__back-button' ) ).toHaveLength( 0 );
expect( wrapper.find( '.nux-guide__forward-button' ) ).toHaveLength( 1 );
expect( wrapper.find( '.nux-guide__finish-button' ) ).toHaveLength( 0 );
} );

it( 'shows back button and shows finish button on the last page', () => {
const wrapper = shallow(
<Guide>
<Page>Page 1</Page>
<Page>Page 2</Page>
</Guide>
);
wrapper.find( '.nux-guide__forward-button' ).simulate( 'click' );
expect( wrapper.find( PageControl ).prop( 'currentPage' ) ).toBe( 1 );
expect( wrapper.find( '.nux-guide__back-button' ) ).toHaveLength( 1 );
expect( wrapper.find( '.nux-guide__forward-button' ) ).toHaveLength( 0 );
expect( wrapper.find( '.nux-guide__finish-button' ) ).toHaveLength( 1 );
} );

it( 'shows the finish button inline with the content on mobile', () => {
const wrapper = shallow(
<Guide isMobile>
<Page>Page 1</Page>
</Guide>
);
expect( wrapper.find( '.nux-guide__finish-button' ) ).toHaveLength( 0 );
expect( wrapper.findWhere( ( node ) => node.text() === 'Finish' ) ).toHaveLength( 1 );
} );

it( 'calls onFinish when the finish button is clicked', () => {
const onFinish = jest.fn();
const wrapper = shallow(
<Guide onFinish={ onFinish }>
<Page>Page 1</Page>
</Guide>
);
wrapper.find( '.nux-guide__finish-button' ).simulate( 'click' );
expect( onFinish ).toHaveBeenCalled();
} );

it( 'calls onFinish when the modal is closed', () => {
const onFinish = jest.fn();
const wrapper = shallow(
<Guide onFinish={ onFinish }>
<Page>Page 1</Page>
</Guide>
);
wrapper.find( Modal ).prop( 'onRequestClose' )();
expect( onFinish ).toHaveBeenCalled();
} );
} );
39 changes: 39 additions & 0 deletions packages/nux/src/components/guide/test/page-control.js
@@ -0,0 +1,39 @@
/**
* External dependencies
*/
import { shallow } from 'enzyme';

/**
* WordPress dependencies
*/
import { IconButton } from '@wordpress/components';

/**
* Internal dependencies
*/
import PageControl from '../page-control';

describe( 'PageControl', () => {
it( 'renders an empty list when there are no pages', () => {
const wrapper = shallow( <PageControl currentPage={ 0 } numberOfPages={ 0 } /> );
expect( wrapper.find( IconButton ) ).toHaveLength( 0 );
} );

it( 'renders a button for each page', () => {
const wrapper = shallow( <PageControl currentPage={ 0 } numberOfPages={ 5 } /> );
expect( wrapper.find( IconButton ) ).toHaveLength( 5 );
} );

it( 'sets the current page when a button is clicked', () => {
const setCurrentPage = jest.fn();
const wrapper = shallow(
<PageControl
currentPage={ 0 }
numberOfPages={ 2 }
setCurrentPage={ setCurrentPage }
/>
);
wrapper.find( IconButton ).at( 1 ).simulate( 'click' );
expect( setCurrentPage ).toHaveBeenCalledWith( 1 );
} );
} );

0 comments on commit 99c80cc

Please sign in to comment.