diff --git a/packages/components/src/placeholder/README.md b/packages/components/src/placeholder/README.md index bc59b593b463a..f260ab15378f0 100644 --- a/packages/components/src/placeholder/README.md +++ b/packages/components/src/placeholder/README.md @@ -39,7 +39,7 @@ Changes placeholder children layout from flex-row to flex-column. Title of the placeholder. -- Required: Yes +- Required: No ### `notices`: `ReactNode` diff --git a/packages/components/src/placeholder/test/index.js b/packages/components/src/placeholder/test/index.js deleted file mode 100644 index e2a6090764cb2..0000000000000 --- a/packages/components/src/placeholder/test/index.js +++ /dev/null @@ -1,163 +0,0 @@ -/** - * External dependencies - */ -import { shallow } from 'enzyme'; - -/** - * WordPress dependencies - */ -import { more } from '@wordpress/icons'; -import { useResizeObserver } from '@wordpress/compose'; - -/** - * Internal dependencies - */ -import Placeholder from '../'; - -jest.mock( '@wordpress/compose', () => { - return { - ...jest.requireActual( '@wordpress/compose' ), - useResizeObserver: jest.fn( () => [] ), - }; -} ); - -describe( 'Placeholder', () => { - beforeEach( () => { - useResizeObserver.mockReturnValue( [ -
, - { width: 320 }, - ] ); - } ); - - describe( 'basic rendering', () => { - it( 'should by default render label section and fieldset.', () => { - const placeholder = shallow( ); - const placeholderLabel = placeholder.find( - '.components-placeholder__label' - ); - const placeholderInstructions = placeholder.find( - '.components-placeholder__instructions' - ); - const placeholderFieldset = placeholder.find( - '.components-placeholder__fieldset' - ); - - expect( placeholder.hasClass( 'components-placeholder' ) ).toBe( - true - ); - // Test for empty label. - expect( placeholderLabel.exists() ).toBe( true ); - expect( placeholderLabel.find( 'Dashicon' ).exists() ).toBe( - false - ); - // Test for non existant instructions. - expect( placeholderInstructions.exists() ).toBe( false ); - // Test for empty fieldset. - expect( placeholderFieldset.exists() ).toBe( true ); - } ); - - it( 'should render an Icon in the label section', () => { - const placeholder = shallow( ); - const placeholderLabel = placeholder.find( - '.components-placeholder__label' - ); - - expect( placeholderLabel.exists() ).toBe( true ); - expect( placeholderLabel.find( 'Icon' ).exists() ).toBe( true ); - } ); - - it( 'should render a label section', () => { - const label = 'WordPress'; - const placeholder = shallow( ); - const placeholderLabel = placeholder.find( - '.components-placeholder__label' - ); - const child = placeholderLabel.childAt( 1 ); - - expect( child.text() ).toBe( label ); - } ); - - it( 'should display an instructions element', () => { - const element =
Instructions
; - const placeholder = shallow( - - ); - const placeholderInstructions = placeholder.find( - '.components-placeholder__instructions' - ); - const child = placeholderInstructions.childAt( 0 ); - - expect( placeholderInstructions.exists() ).toBe( true ); - expect( child.matchesElement( element ) ).toBe( true ); - } ); - - it( 'should display a fieldset from the children property', () => { - const element =
Fieldset
; - const placeholder = shallow( ); - const placeholderFieldset = placeholder.find( - 'fieldset.components-placeholder__fieldset' - ); - const child = placeholderFieldset.childAt( 0 ); - - expect( placeholderFieldset.exists() ).toBe( true ); - expect( child.matchesElement( element ) ).toBe( true ); - } ); - - it( 'should display a legend if instructions are passed', () => { - const element =
Fieldset
; - const instructions = 'Choose an option.'; - const placeholder = shallow( - - ); - const placeholderLegend = placeholder.find( - 'legend.components-placeholder__instructions' - ); - - expect( placeholderLegend.exists() ).toBe( true ); - expect( placeholderLegend.text() ).toEqual( instructions ); - } ); - - it( 'should add an additional className to the top container', () => { - const placeholder = shallow( - - ); - expect( placeholder.hasClass( 'wp-placeholder' ) ).toBe( true ); - } ); - - it( 'should add additional props to the top level container', () => { - const placeholder = shallow( ); - expect( placeholder.prop( 'test' ) ).toBe( 'test' ); - } ); - } ); - - describe( 'resize aware', () => { - it( 'should not assign modifier class in first-pass `null` width from `useResizeObserver`', () => { - useResizeObserver.mockReturnValue( [ -
, - { width: 480 }, - ] ); - - const placeholder = shallow( ); - - expect( placeholder.hasClass( 'is-large' ) ).toBe( true ); - expect( placeholder.hasClass( 'is-medium' ) ).toBe( false ); - expect( placeholder.hasClass( 'is-small' ) ).toBe( false ); - } ); - - it( 'should assign modifier class', () => { - useResizeObserver.mockReturnValue( [ -
, - { width: null }, - ] ); - - const placeholder = shallow( ); - - expect( placeholder.hasClass( 'is-large' ) ).toBe( false ); - expect( placeholder.hasClass( 'is-medium' ) ).toBe( false ); - expect( placeholder.hasClass( 'is-small' ) ).toBe( false ); - } ); - } ); -} ); diff --git a/packages/components/src/placeholder/test/index.tsx b/packages/components/src/placeholder/test/index.tsx new file mode 100644 index 0000000000000..9e47d4d016a7f --- /dev/null +++ b/packages/components/src/placeholder/test/index.tsx @@ -0,0 +1,174 @@ +/** + * External dependencies + */ +import { render, screen, within } from '@testing-library/react'; + +/** + * WordPress dependencies + */ +import { useResizeObserver } from '@wordpress/compose'; +import { SVG, Path } from '@wordpress/primitives'; + +/** + * Internal dependencies + */ +import BasePlaceholder from '../'; +import type { WordPressComponentProps } from '../../ui/context'; +import type { PlaceholderProps } from '../types'; + +jest.mock( '@wordpress/compose', () => { + return { + ...jest.requireActual( '@wordpress/compose' ), + useResizeObserver: jest.fn( () => [] ), + }; +} ); + +/** + * Test icon that can be queried by `getByTestId` + */ +const testIcon = ( + + + +); + +const Placeholder = ( + props: Omit< + WordPressComponentProps< PlaceholderProps< unknown >, 'div', false >, + 'ref' + > +) => ; + +const getPlaceholder = () => screen.getByTestId( 'placeholder' ); + +describe( 'Placeholder', () => { + beforeEach( () => { + // @ts-ignore + useResizeObserver.mockReturnValue( [ +
, + { width: 320 }, + ] ); + } ); + + describe( 'basic rendering', () => { + it( 'should by default render label section and fieldset.', () => { + render( ); + const placeholder = getPlaceholder(); + + expect( placeholder ).toHaveClass( 'components-placeholder' ); + + // Test for empty label. When the label is empty, the only way to + // query the div is with `querySelector`. + const label = placeholder.querySelector( + '.components-placeholder__label' + ); + expect( label ).toBeInTheDocument(); + expect( label ).toBeEmptyDOMElement(); + + // Test for non existent instructions. When the instructions is + // empty, the only way to query the div is with `querySelector`. + const placeholderInstructions = placeholder.querySelector( + '.components-placeholder__instructions' + ); + expect( placeholderInstructions ).not.toBeInTheDocument(); + + // Test for empty fieldset. + const placeholderFieldset = + within( placeholder ).getByRole( 'group' ); + expect( placeholderFieldset ).toBeInTheDocument(); + expect( placeholderFieldset ).toBeEmptyDOMElement(); + } ); + + it( 'should render an Icon in the label section', () => { + render( ); + + const placeholder = getPlaceholder(); + const icon = within( placeholder ).getByTestId( 'icon' ); + expect( icon.parentNode ).toHaveClass( + 'components-placeholder__label' + ); + expect( icon ).toBeInTheDocument(); + } ); + + it( 'should render a label section', () => { + const label = 'WordPress'; + render( ); + const placeholderLabel = screen.getByText( label ); + + expect( placeholderLabel ).toHaveClass( + 'components-placeholder__label' + ); + expect( placeholderLabel ).toBeInTheDocument(); + } ); + + it( 'should display a fieldset from the children property', () => { + const content = 'Fieldset'; + render( { content } ); + const placeholderFieldset = screen.getByRole( 'group' ); + + expect( placeholderFieldset ).toBeInTheDocument(); + expect( placeholderFieldset ).toHaveTextContent( content ); + } ); + + it( 'should display a legend if instructions are passed', () => { + const instructions = 'Choose an option.'; + render( + +
Fieldset
+
+ ); + const captionedFieldset = screen.getByRole( 'group', { + name: instructions, + } ); + + expect( captionedFieldset ).toBeInTheDocument(); + } ); + + it( 'should add an additional className to the top container', () => { + render( ); + const placeholder = getPlaceholder(); + + expect( placeholder ).toHaveClass( 'components-placeholder' ); + expect( placeholder ).toHaveClass( 'wp-placeholder' ); + } ); + + it( 'should add additional props to the top level container', () => { + render( ); + const placeholder = getPlaceholder(); + + expect( placeholder ).toHaveAttribute( 'data-test', 'test' ); + } ); + } ); + + describe( 'resize aware', () => { + it( 'should not assign modifier class in first-pass `null` width from `useResizeObserver`', () => { + // @ts-ignore + useResizeObserver.mockReturnValue( [ +
, + { width: 480 }, + ] ); + + render( ); + const placeholder = getPlaceholder(); + + expect( placeholder ).toHaveClass( 'is-large' ); + expect( placeholder ).not.toHaveClass( 'is-medium' ); + expect( placeholder ).not.toHaveClass( 'is-small' ); + } ); + + it( 'should assign modifier class', () => { + // @ts-ignore + useResizeObserver.mockReturnValue( [ +
, + { width: null }, + ] ); + + render( ); + const placeholder = getPlaceholder(); + + expect( placeholder ).not.toHaveClass( 'is-large' ); + expect( placeholder ).not.toHaveClass( 'is-medium' ); + expect( placeholder ).not.toHaveClass( 'is-small' ); + } ); + } ); +} );