From fb1fac52e20fd06a31ccaf8962acd81639b13144 Mon Sep 17 00:00:00 2001 From: Lena Morita Date: Tue, 6 Feb 2024 05:24:01 +0900 Subject: [PATCH] SearchControl: Add unit tests --- .../src/search-control/test/index.tsx | 107 ++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 packages/components/src/search-control/test/index.tsx diff --git a/packages/components/src/search-control/test/index.tsx b/packages/components/src/search-control/test/index.tsx new file mode 100644 index 0000000000000..f130cab1b2a7c --- /dev/null +++ b/packages/components/src/search-control/test/index.tsx @@ -0,0 +1,107 @@ +/** + * External dependencies + */ +import { render, screen } from '@testing-library/react'; +import { click, type } from '@ariakit/test'; + +/** + * WordPress dependencies + */ +import { useState } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import SearchControl from '..'; + +function ControlledSearchControl( { + onChange, + ...restProps +}: React.ComponentProps< typeof SearchControl > ) { + const [ value, setValue ] = useState( '' ); + + return ( + { + setValue( ...args ); + onChange( ...args ); + } } + /> + ); +} + +describe( 'SearchControl', () => { + describe.each( [ + // TODO: Uncontrolled mode is not supported yet. + // [ 'Uncontrolled', SearchControl ], + [ 'Controlled mode', ControlledSearchControl ], + ] )( '%s', ( ...modeAndComponent ) => { + const [ , Component ] = modeAndComponent; + + it( 'should call onChange with input value when value is changed', async () => { + const onChangeSpy = jest.fn(); + render( ); + + const searchInput = screen.getByRole( 'searchbox' ); + await type( 'test', searchInput ); + expect( searchInput ).toHaveValue( 'test' ); + expect( onChangeSpy ).toHaveBeenLastCalledWith( 'test' ); + } ); + + it( 'should render a Reset search button if no onClose function is provided', async () => { + const onChangeSpy = jest.fn(); + render( ); + + const searchInput = screen.getByRole( 'searchbox' ); + + expect( + screen.queryByRole( 'button', { name: 'Reset search' } ) + ).not.toBeInTheDocument(); + + await type( 'test', searchInput ); + const resetButton = screen.getByRole( 'button', { + name: 'Reset search', + } ); + expect( resetButton ).toBeVisible(); + + await click( resetButton ); + expect( searchInput ).toHaveValue( '' ); + expect( onChangeSpy ).toHaveBeenLastCalledWith( '' ); + } ); + + it( 'should should render a Close button (instead of Reset) when onClose function is provided', async () => { + const onChangeSpy = jest.fn(); + const onCloseSpy = jest.fn(); + render( + + ); + + expect( + screen.queryByRole( 'button', { name: 'Close search' } ) + ).toBeVisible(); + expect( + screen.queryByRole( 'button', { name: 'Reset search' } ) + ).not.toBeInTheDocument(); + + const searchInput = screen.getByRole( 'searchbox' ); + await type( 'test', searchInput ); + + expect( + screen.queryByRole( 'button', { name: 'Close search' } ) + ).toBeVisible(); + expect( + screen.queryByRole( 'button', { name: 'Reset search' } ) + ).not.toBeInTheDocument(); + expect( onChangeSpy ).toHaveBeenCalledTimes( 'test'.length ); + + await click( + screen.getByRole( 'button', { name: 'Close search' } ) + ); + expect( onCloseSpy ).toHaveBeenCalledTimes( 1 ); + expect( searchInput ).toHaveValue( 'test' ); // no change + expect( onChangeSpy ).toHaveBeenCalledTimes( 'test'.length ); // no change + } ); + } ); +} );