diff --git a/packages/block-editor/src/components/link-control/index.js b/packages/block-editor/src/components/link-control/index.js index 2d7b850e552fc7..27e21649a29c2b 100644 --- a/packages/block-editor/src/components/link-control/index.js +++ b/packages/block-editor/src/components/link-control/index.js @@ -31,16 +31,21 @@ import LinkControlSearchInput from './search-input'; const MODE_EDIT = 'edit'; -export function LinkControl( { +function LinkControl( { value, settings, onChange = noop, showInitialSuggestions, - fetchSearchSuggestions, } ) { const instanceId = useInstanceId( LinkControl ); const [ inputValue, setInputValue ] = useState( '' ); const [ isEditingLink, setIsEditingLink ] = useState( ! value || ! value.url ); + const { fetchSearchSuggestions } = useSelect( ( select ) => { + const { getSettings } = select( 'core/block-editor' ); + return { + fetchSearchSuggestions: getSettings().__experimentalFetchLinkSuggestions, + }; + }, [] ); // Handlers @@ -226,15 +231,4 @@ export function LinkControl( { ); } -function ConnectedLinkControl( props ) { - const { fetchSearchSuggestions } = useSelect( ( select ) => { - const { getSettings } = select( 'core/block-editor' ); - return { - fetchSearchSuggestions: getSettings().__experimentalFetchLinkSuggestions, - }; - }, [] ); - - return ; -} - -export default ConnectedLinkControl; +export default LinkControl; diff --git a/packages/block-editor/src/components/link-control/test/index.js b/packages/block-editor/src/components/link-control/test/index.js index 88fa58ed6dde7d..944018ba155e23 100644 --- a/packages/block-editor/src/components/link-control/test/index.js +++ b/packages/block-editor/src/components/link-control/test/index.js @@ -12,9 +12,15 @@ import { UP, DOWN, ENTER } from '@wordpress/keycodes'; /** * Internal dependencies */ -import { LinkControl } from '../index'; +import LinkControl from '../'; import { fauxEntitySuggestions, fetchFauxEntitySuggestions } from './fixtures'; +const mockFetchSearchSuggestions = jest.fn(); + +jest.mock( '@wordpress/data/src/components/use-select', () => () => ( { + fetchSearchSuggestions: mockFetchSearchSuggestions, +} ) ); + /** * Wait for next tick of event loop. This is required * because the `fetchSearchSuggestions` Promise will @@ -33,6 +39,7 @@ beforeEach( () => { // setup a DOM element as a render target container = document.createElement( 'div' ); document.body.appendChild( container ); + mockFetchSearchSuggestions.mockImplementation( fetchFauxEntitySuggestions ); } ); afterEach( () => { @@ -40,6 +47,7 @@ afterEach( () => { unmountComponentAtNode( container ); container.remove(); container = null; + mockFetchSearchSuggestions.mockReset(); } ); describe( 'Basic rendering', () => { @@ -71,12 +79,10 @@ describe( 'Searching for a link', () => { resolver = resolve; } ); + mockFetchSearchSuggestions.mockImplementation( fauxRequest ); + act( () => { - render( - , container - ); + render( , container ); } ); // Search Input UI @@ -115,11 +121,7 @@ describe( 'Searching for a link', () => { const firstFauxSuggestion = first( fauxEntitySuggestions ); act( () => { - render( - , container - ); + render( , container ); } ); // Search Input UI @@ -153,11 +155,7 @@ describe( 'Searching for a link', () => { [ 'ThisCouldAlsoBeAValidURL' ], ] )( 'should display a URL suggestion as a default fallback for the search term "%s" which could potentially be a valid url.', async ( searchTerm ) => { act( () => { - render( - , container - ); + render( , container ); } ); // Search Input UI @@ -190,11 +188,7 @@ describe( 'Searching for a link', () => { const searchTerm = 'Hello world'; act( () => { - render( - , container - ); + render( , container ); } ); let searchResultElements; @@ -242,11 +236,7 @@ describe( 'Manual link entry', () => { [ 'www.wordpress.org' ], // usage of "www" ] )( 'should display a single suggestion result when the current input value is URL-like (eg: %s)', async ( searchTerm ) => { act( () => { - render( - , container - ); + render( , container ); } ); // Search Input UI @@ -279,9 +269,7 @@ describe( 'Manual link entry', () => { ] )( 'should recognise "%s" as a %s link and handle as manual entry by displaying a single suggestion', async ( searchTerm, searchType ) => { act( () => { render( - , container + , container ); } ); @@ -311,15 +299,11 @@ describe( 'Manual link entry', () => { describe( 'Default search suggestions', () => { it( 'should display a list of initial search suggestions when there is no search value or suggestions', async () => { - const searchSuggestionsSpy = jest.fn( fetchFauxEntitySuggestions ); const expectedResultsLength = 3; // set within `LinkControl` act( () => { render( - , container + , container ); } ); @@ -341,7 +325,7 @@ describe( 'Default search suggestions', () => { // Ensure only called once as a guard against potential infinite // re-render loop within `componentDidUpdate` calling `updateSuggestions` // which has calls to `setState` within it. - expect( searchSuggestionsSpy ).toHaveBeenCalledTimes( 1 ); + expect( mockFetchSearchSuggestions ).toHaveBeenCalledTimes( 1 ); // Verify the search results already display the initial suggestions expect( initialSearchResultElements ).toHaveLength( expectedResultsLength ); @@ -350,7 +334,6 @@ describe( 'Default search suggestions', () => { } ); it( 'should not display initial suggestions when input value is present', async () => { - const searchSuggestionsSpy = jest.fn( fetchFauxEntitySuggestions ); let searchResultElements; // // Render with an initial value an ensure that no initial suggestions @@ -359,8 +342,7 @@ describe( 'Default search suggestions', () => { act( () => { render( , container ); @@ -368,7 +350,7 @@ describe( 'Default search suggestions', () => { await eventLoopTick(); - expect( searchSuggestionsSpy ).not.toHaveBeenCalled(); + expect( mockFetchSearchSuggestions ).not.toHaveBeenCalled(); // // Click the "Edit/Change" button and check initial suggestions are not @@ -387,7 +369,7 @@ describe( 'Default search suggestions', () => { expect( searchResultElements ).toHaveLength( 0 ); - expect( searchSuggestionsSpy ).not.toHaveBeenCalled(); + expect( mockFetchSearchSuggestions ).not.toHaveBeenCalled(); // // Reset the search to empty and check the initial suggestions are now shown. @@ -407,7 +389,7 @@ describe( 'Default search suggestions', () => { // Ensure only called once as a guard against potential infinite // re-render loop within `componentDidUpdate` calling `updateSuggestions` // which has calls to `setState` within it. - expect( searchSuggestionsSpy ).toHaveBeenCalledTimes( 1 ); + expect( mockFetchSearchSuggestions ).toHaveBeenCalledTimes( 1 ); } ); } ); @@ -418,18 +400,11 @@ describe( 'Selecting links', () => { const LinkControlConsumer = () => { const [ link ] = useState( selectedLink ); - return ( - - ); + return ; }; act( () => { - render( - , container - ); + render( , container ); } ); // TODO: select by aria role or visible text @@ -453,15 +428,12 @@ describe( 'Selecting links', () => { setLink( suggestion ) } - fetchSearchSuggestions={ fetchFauxEntitySuggestions } /> ); }; act( () => { - render( - , container - ); + render( , container ); } ); // Required in order to select the button below @@ -499,7 +471,6 @@ describe( 'Selecting links', () => { setLink( suggestion ) } - fetchSearchSuggestions={ fetchFauxEntitySuggestions } /> ); }; @@ -559,7 +530,6 @@ describe( 'Selecting links', () => { setLink( suggestion ) } - fetchSearchSuggestions={ fetchFauxEntitySuggestions } /> ); }; @@ -644,18 +614,11 @@ describe( 'Addition Settings UI', () => { const LinkControlConsumer = () => { const [ link ] = useState( selectedLink ); - return ( - - ); + return ; }; act( () => { - render( - , container - ); + render( , container ); } ); const newTabSettingLabel = Array.from( container.querySelectorAll( 'label' ) ).find( ( label ) => label.innerHTML && label.innerHTML.includes( expectedSettingText ) ); @@ -689,16 +652,13 @@ describe( 'Addition Settings UI', () => { return ( ); }; act( () => { - render( - , container - ); + render( , container ); } ); // Grab the elements using user perceivable DOM queries