diff --git a/editor/components/block-switcher/index.js b/editor/components/block-switcher/index.js index add041a644510c..2dabeb6ed44703 100644 --- a/editor/components/block-switcher/index.js +++ b/editor/components/block-switcher/index.js @@ -24,7 +24,7 @@ import { getBlock } from '../../store/selectors'; */ const { DOWN } = keycodes; -function BlockSwitcher( { blocks, onTransform, isLocked } ) { +export function BlockSwitcher( { blocks, onTransform, isLocked } ) { const allowedBlocks = getPossibleBlockTransformations( blocks ); if ( isLocked || ! allowedBlocks.length ) { diff --git a/editor/components/block-switcher/multi-blocks-switcher.js b/editor/components/block-switcher/multi-blocks-switcher.js index 42a7b14f64882d..2772aa64baaa35 100644 --- a/editor/components/block-switcher/multi-blocks-switcher.js +++ b/editor/components/block-switcher/multi-blocks-switcher.js @@ -10,7 +10,7 @@ import './style.scss'; import BlockSwitcher from './'; import { getMultiSelectedBlockUids } from '../../store/selectors'; -function MultiBlocksSwitcher( { isMultiBlockSelection, selectedBlockUids } ) { +export function MultiBlocksSwitcher( { isMultiBlockSelection, selectedBlockUids } ) { if ( ! isMultiBlockSelection ) { return null; } diff --git a/editor/components/block-switcher/test/__snapshots__/index.js.snap b/editor/components/block-switcher/test/__snapshots__/index.js.snap new file mode 100644 index 00000000000000..3c19baa2d4fd1f --- /dev/null +++ b/editor/components/block-switcher/test/__snapshots__/index.js.snap @@ -0,0 +1,10 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`BlockSwitcher should render switcher with blocks 1`] = ` + +`; diff --git a/editor/components/block-switcher/test/__snapshots__/multi-blocks-switcher.js.snap b/editor/components/block-switcher/test/__snapshots__/multi-blocks-switcher.js.snap new file mode 100644 index 00000000000000..d4fa9836f70171 --- /dev/null +++ b/editor/components/block-switcher/test/__snapshots__/multi-blocks-switcher.js.snap @@ -0,0 +1,13 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`MultiBlocksSwitcher should return a BlockSwitcher element matching the snapshot. 1`] = ` + +`; diff --git a/editor/components/block-switcher/test/index.js b/editor/components/block-switcher/test/index.js new file mode 100644 index 00000000000000..156f419a72f22b --- /dev/null +++ b/editor/components/block-switcher/test/index.js @@ -0,0 +1,158 @@ +/** + * External dependencies + */ +import { shallow } from 'enzyme'; + +/** + * WordPress dependencies + */ +import { registerCoreBlocks } from '@wordpress/blocks'; +import { keycodes } from '@wordpress/utils'; + +/** + * Internal dependencies + */ +import { BlockSwitcher } from '../'; + +const { DOWN } = keycodes; + +describe( 'BlockSwitcher', () => { + const headingBlock1 = { + attributes: { + content: [ 'How are you?' ], + nodeName: 'H2', + }, + isValid: true, + name: 'core/heading', + originalContent: '

How are you?

', + uid: 'a1303fd6-3e60-4fff-a770-0e0ea656c5b9', + }; + + const textBlock = { + attributes: { + content: [ 'I am great!' ], + nodeName: 'P', + }, + isValid: true, + name: 'core/text', + originalContent: '

I am great!

', + uid: 'b1303fdb-3e60-43faf-a770-2e1ea656c5b8', + }; + + const headingBlock2 = { + attributes: { + content: [ 'I am the greatest!' ], + nodeName: 'H3', + }, + isValid: true, + name: 'core/text', + originalContent: '

I am the greatest!

', + uid: 'c2403fd2-4e63-5ffa-b71c-1e0ea656c5b0', + }; + + beforeAll( () => { + registerCoreBlocks(); + } ); + + test( 'should not render block switcher without blocks', () => { + const wrapper = shallow( ); + + expect( wrapper.html() ).toBeNull(); + } ); + + test( 'should render switcher with blocks', () => { + const blocks = [ + headingBlock1, + ]; + const wrapper = shallow( ); + + expect( wrapper ).toMatchSnapshot(); + } ); + + test( 'should not render block switcher with multi block of different types.', () => { + const blocks = [ + headingBlock1, + textBlock, + ]; + const wrapper = shallow( ); + + expect( wrapper.html() ).toBeNull(); + } ); + + test( 'should not render a component when the multi selected types of blocks match.', () => { + const blocks = [ + headingBlock1, + headingBlock2, + ]; + const wrapper = shallow( ); + + expect( wrapper.html() ).toBeNull(); + } ); + + describe( 'Dropdown', () => { + const blocks = [ + headingBlock1, + ]; + + const onTransformStub = jest.fn(); + const getDropdown = () => { + const blockSwitcher = shallow( ); + return blockSwitcher.find( 'Dropdown' ); + }; + + test( 'should dropdown exist', () => { + expect( getDropdown() ).toHaveLength( 1 ); + } ); + + describe( '.renderToggle', () => { + const onToggleStub = jest.fn(); + const mockKeyDown = { + preventDefault: () => {}, + stopPropagation: () => {}, + keyCode: DOWN, + }; + + afterEach( () => { + onToggleStub.mockReset(); + } ); + + test( 'should simulate a keydown event, which should call onToggle and open transform toggle.', () => { + const toggleClosed = shallow( getDropdown().props().renderToggle( { onToggle: onToggleStub, isOpen: false } ) ); + const iconButtonClosed = toggleClosed.find( 'IconButton' ); + + iconButtonClosed.simulate( 'keydown', mockKeyDown ); + + expect( onToggleStub ).toHaveBeenCalledTimes( 1 ); + } ); + + test( 'should simulate a click event, which should call onToggle.', () => { + const toggleOpen = shallow( getDropdown().props().renderToggle( { onToggle: onToggleStub, isOpen: true } ) ); + const iconButtonOpen = toggleOpen.find( 'IconButton' ); + + iconButtonOpen.simulate( 'keydown', mockKeyDown ); + + expect( onToggleStub ).toHaveBeenCalledTimes( 0 ); + } ); + } ); + + describe( '.renderContent', () => { + const onCloseStub = jest.fn(); + + const getIconButtons = () => { + const content = shallow( getDropdown().props().renderContent( { onClose: onCloseStub } ) ); + return content.find( 'IconButton' ); + }; + + test( 'should create the iconButtons for the chosen block. A heading block will have 3 items', () => { + expect( getIconButtons() ).toHaveLength( 3 ); + } ); + + test( 'should simulate the click event by closing the switcher and causing a block transform on iconButtons.', () => { + getIconButtons().first().simulate( 'click' ); + + expect( onCloseStub ).toHaveBeenCalledTimes( 1 ); + expect( onTransformStub ).toHaveBeenCalledTimes( 1 ); + } ); + } ); + } ); +} ); diff --git a/editor/components/block-switcher/test/multi-blocks-switcher.js b/editor/components/block-switcher/test/multi-blocks-switcher.js new file mode 100644 index 00000000000000..37935f47788f63 --- /dev/null +++ b/editor/components/block-switcher/test/multi-blocks-switcher.js @@ -0,0 +1,42 @@ +/** + * External dependencies + */ +import { shallow } from 'enzyme'; + +/** + * Internal dependencies + */ +import { MultiBlocksSwitcher } from '../multi-blocks-switcher'; + +describe( 'MultiBlocksSwitcher', () => { + test( 'should return null when the selection is not a multi block selection.', () => { + const isMultiBlockSelection = false; + const selectedBlockUids = [ + 'an-uid', + ]; + const wrapper = shallow( + + ); + + expect( wrapper.html() ).toBeNull(); + } ); + + test( 'should return a BlockSwitcher element matching the snapshot.', () => { + const isMultiBlockSelection = true; + const selectedBlockUids = [ + 'an-uid', + 'another-uid', + ]; + const wrapper = shallow( + + ); + + expect( wrapper ).toMatchSnapshot(); + } ); +} );