From bedbd1f154e4bcc3a74b61b9ff88e6a46ee64965 Mon Sep 17 00:00:00 2001 From: Andrei Draganescu Date: Tue, 19 Sep 2023 22:55:25 +0300 Subject: [PATCH 1/6] limit initial suggestions to pages --- .../__experimental-fetch-link-suggestions.js | 157 ++++++++++-------- 1 file changed, 90 insertions(+), 67 deletions(-) diff --git a/packages/core-data/src/fetch/__experimental-fetch-link-suggestions.js b/packages/core-data/src/fetch/__experimental-fetch-link-suggestions.js index bb1bf41d9e2cd..ec0cafb671c45 100644 --- a/packages/core-data/src/fetch/__experimental-fetch-link-suggestions.js +++ b/packages/core-data/src/fetch/__experimental-fetch-link-suggestions.js @@ -88,7 +88,7 @@ const fetchLinkSuggestions = async ( type = undefined, subtype = undefined, page = undefined, - perPage = isInitialSuggestions ? 3 : 20, + perPage = 20, } = searchOptions; const { disablePostFormats = false } = settings; @@ -96,7 +96,7 @@ const fetchLinkSuggestions = async ( /** @type {Promise[]} */ const queries = []; - if ( ! type || type === 'post' ) { + if ( isInitialSuggestions ) { queries.push( apiFetch( { path: addQueryArgs( '/wp/v2/search', { @@ -104,7 +104,7 @@ const fetchLinkSuggestions = async ( page, per_page: perPage, type: 'post', - subtype, + subtype: 'page', } ), } ) .then( ( results ) => { @@ -117,73 +117,96 @@ const fetchLinkSuggestions = async ( } ) .catch( () => [] ) // Fail by returning no results. ); - } - - if ( ! type || type === 'term' ) { - queries.push( - apiFetch( { - path: addQueryArgs( '/wp/v2/search', { - search, - page, - per_page: perPage, - type: 'term', - subtype, - } ), - } ) - .then( ( results ) => { - return results.map( ( result ) => { - return { - ...result, - meta: { kind: 'taxonomy', subtype }, - }; - } ); + } else { + if ( ! type || type === 'post' ) { + queries.push( + apiFetch( { + path: addQueryArgs( '/wp/v2/search', { + search, + page, + per_page: perPage, + type: 'post', + subtype, + } ), } ) - .catch( () => [] ) // Fail by returning no results. - ); - } - - if ( ! disablePostFormats && ( ! type || type === 'post-format' ) ) { - queries.push( - apiFetch( { - path: addQueryArgs( '/wp/v2/search', { - search, - page, - per_page: perPage, - type: 'post-format', - subtype, - } ), - } ) - .then( ( results ) => { - return results.map( ( result ) => { - return { - ...result, - meta: { kind: 'taxonomy', subtype }, - }; - } ); + .then( ( results ) => { + return results.map( ( result ) => { + return { + ...result, + meta: { kind: 'post-type', subtype }, + }; + } ); + } ) + .catch( () => [] ) // Fail by returning no results. + ); + } + + if ( ! type || type === 'term' ) { + queries.push( + apiFetch( { + path: addQueryArgs( '/wp/v2/search', { + search, + page, + per_page: perPage, + type: 'term', + subtype, + } ), } ) - .catch( () => [] ) // Fail by returning no results. - ); - } - - if ( ! type || type === 'attachment' ) { - queries.push( - apiFetch( { - path: addQueryArgs( '/wp/v2/media', { - search, - page, - per_page: perPage, - } ), - } ) - .then( ( results ) => { - return results.map( ( result ) => { - return { - ...result, - meta: { kind: 'media' }, - }; - } ); + .then( ( results ) => { + return results.map( ( result ) => { + return { + ...result, + meta: { kind: 'taxonomy', subtype }, + }; + } ); + } ) + .catch( () => [] ) // Fail by returning no results. + ); + } + + if ( ! disablePostFormats && ( ! type || type === 'post-format' ) ) { + queries.push( + apiFetch( { + path: addQueryArgs( '/wp/v2/search', { + search, + page, + per_page: perPage, + type: 'post-format', + subtype, + } ), } ) - .catch( () => [] ) // Fail by returning no results. - ); + .then( ( results ) => { + return results.map( ( result ) => { + return { + ...result, + meta: { kind: 'taxonomy', subtype }, + }; + } ); + } ) + .catch( () => [] ) // Fail by returning no results. + ); + } + + if ( ! type || type === 'attachment' ) { + queries.push( + apiFetch( { + path: addQueryArgs( '/wp/v2/media', { + search, + page, + per_page: perPage, + } ), + } ) + .then( ( results ) => { + return results.map( ( result ) => { + return { + ...result, + meta: { kind: 'media' }, + }; + } ); + } ) + .catch( () => [] ) // Fail by returning no results. + ); + } } return Promise.all( queries ).then( ( results ) => { From 038690fb6b6b09f6df46c31e5663c73c7ceeb473 Mon Sep 17 00:00:00 2001 From: Andrei Draganescu Date: Fri, 29 Sep 2023 17:45:53 +0300 Subject: [PATCH 2/6] Revert "limit initial suggestions to pages" This reverts commit bedbd1f154e4bcc3a74b61b9ff88e6a46ee64965. --- .../__experimental-fetch-link-suggestions.js | 157 ++++++++---------- 1 file changed, 67 insertions(+), 90 deletions(-) diff --git a/packages/core-data/src/fetch/__experimental-fetch-link-suggestions.js b/packages/core-data/src/fetch/__experimental-fetch-link-suggestions.js index ec0cafb671c45..bb1bf41d9e2cd 100644 --- a/packages/core-data/src/fetch/__experimental-fetch-link-suggestions.js +++ b/packages/core-data/src/fetch/__experimental-fetch-link-suggestions.js @@ -88,7 +88,7 @@ const fetchLinkSuggestions = async ( type = undefined, subtype = undefined, page = undefined, - perPage = 20, + perPage = isInitialSuggestions ? 3 : 20, } = searchOptions; const { disablePostFormats = false } = settings; @@ -96,7 +96,7 @@ const fetchLinkSuggestions = async ( /** @type {Promise[]} */ const queries = []; - if ( isInitialSuggestions ) { + if ( ! type || type === 'post' ) { queries.push( apiFetch( { path: addQueryArgs( '/wp/v2/search', { @@ -104,7 +104,7 @@ const fetchLinkSuggestions = async ( page, per_page: perPage, type: 'post', - subtype: 'page', + subtype, } ), } ) .then( ( results ) => { @@ -117,96 +117,73 @@ const fetchLinkSuggestions = async ( } ) .catch( () => [] ) // Fail by returning no results. ); - } else { - if ( ! type || type === 'post' ) { - queries.push( - apiFetch( { - path: addQueryArgs( '/wp/v2/search', { - search, - page, - per_page: perPage, - type: 'post', - subtype, - } ), - } ) - .then( ( results ) => { - return results.map( ( result ) => { - return { - ...result, - meta: { kind: 'post-type', subtype }, - }; - } ); - } ) - .catch( () => [] ) // Fail by returning no results. - ); - } - - if ( ! type || type === 'term' ) { - queries.push( - apiFetch( { - path: addQueryArgs( '/wp/v2/search', { - search, - page, - per_page: perPage, - type: 'term', - subtype, - } ), + } + + if ( ! type || type === 'term' ) { + queries.push( + apiFetch( { + path: addQueryArgs( '/wp/v2/search', { + search, + page, + per_page: perPage, + type: 'term', + subtype, + } ), + } ) + .then( ( results ) => { + return results.map( ( result ) => { + return { + ...result, + meta: { kind: 'taxonomy', subtype }, + }; + } ); } ) - .then( ( results ) => { - return results.map( ( result ) => { - return { - ...result, - meta: { kind: 'taxonomy', subtype }, - }; - } ); - } ) - .catch( () => [] ) // Fail by returning no results. - ); - } - - if ( ! disablePostFormats && ( ! type || type === 'post-format' ) ) { - queries.push( - apiFetch( { - path: addQueryArgs( '/wp/v2/search', { - search, - page, - per_page: perPage, - type: 'post-format', - subtype, - } ), + .catch( () => [] ) // Fail by returning no results. + ); + } + + if ( ! disablePostFormats && ( ! type || type === 'post-format' ) ) { + queries.push( + apiFetch( { + path: addQueryArgs( '/wp/v2/search', { + search, + page, + per_page: perPage, + type: 'post-format', + subtype, + } ), + } ) + .then( ( results ) => { + return results.map( ( result ) => { + return { + ...result, + meta: { kind: 'taxonomy', subtype }, + }; + } ); } ) - .then( ( results ) => { - return results.map( ( result ) => { - return { - ...result, - meta: { kind: 'taxonomy', subtype }, - }; - } ); - } ) - .catch( () => [] ) // Fail by returning no results. - ); - } - - if ( ! type || type === 'attachment' ) { - queries.push( - apiFetch( { - path: addQueryArgs( '/wp/v2/media', { - search, - page, - per_page: perPage, - } ), + .catch( () => [] ) // Fail by returning no results. + ); + } + + if ( ! type || type === 'attachment' ) { + queries.push( + apiFetch( { + path: addQueryArgs( '/wp/v2/media', { + search, + page, + per_page: perPage, + } ), + } ) + .then( ( results ) => { + return results.map( ( result ) => { + return { + ...result, + meta: { kind: 'media' }, + }; + } ); } ) - .then( ( results ) => { - return results.map( ( result ) => { - return { - ...result, - meta: { kind: 'media' }, - }; - } ); - } ) - .catch( () => [] ) // Fail by returning no results. - ); - } + .catch( () => [] ) // Fail by returning no results. + ); } return Promise.all( queries ).then( ( results ) => { From 0894f7f61d6c768ceadf815c69271d325284b700 Mon Sep 17 00:00:00 2001 From: Andrei Draganescu Date: Fri, 29 Sep 2023 18:03:31 +0300 Subject: [PATCH 3/6] adds a special search options key that can override the search options for initial suggestions on link UI --- .../block-library/src/navigation-link/link-ui.js | 10 +++++++++- .../__experimental-fetch-link-suggestions.js | 15 +++++++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/packages/block-library/src/navigation-link/link-ui.js b/packages/block-library/src/navigation-link/link-ui.js index 3a7b7d28f9e80..e3d7153be566b 100644 --- a/packages/block-library/src/navigation-link/link-ui.js +++ b/packages/block-library/src/navigation-link/link-ui.js @@ -44,7 +44,15 @@ export function getSuggestionsQuery( type, kind ) { if ( kind === 'post-type' ) { return { type: 'post', subtype: type }; } - return {}; + return { + // for custom link which has no type + // always show pages as initial suggestions + initialSuggestionsOptions: { + type: 'post', + subtype: 'page', + perPage: 20, + }, + }; } } diff --git a/packages/core-data/src/fetch/__experimental-fetch-link-suggestions.js b/packages/core-data/src/fetch/__experimental-fetch-link-suggestions.js index bb1bf41d9e2cd..4c3483776fbc8 100644 --- a/packages/core-data/src/fetch/__experimental-fetch-link-suggestions.js +++ b/packages/core-data/src/fetch/__experimental-fetch-link-suggestions.js @@ -85,17 +85,28 @@ const fetchLinkSuggestions = async ( ) => { const { isInitialSuggestions = false, + initialSuggestionsOptions = undefined, + } = searchOptions; + + const { disablePostFormats = false } = settings; + + let { type = undefined, subtype = undefined, page = undefined, perPage = isInitialSuggestions ? 3 : 20, } = searchOptions; - const { disablePostFormats = false } = settings; - /** @type {Promise[]} */ const queries = []; + if ( isInitialSuggestions && initialSuggestionsOptions ) { + type = initialSuggestionsOptions.type; + subtype = initialSuggestionsOptions.subtype; + page = initialSuggestionsOptions.page; + perPage = initialSuggestionsOptions.perPage; + } + if ( ! type || type === 'post' ) { queries.push( apiFetch( { From 02ee8a228859543dcabc4c76a1f7a2ed0ffeb0b6 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Fri, 29 Sep 2023 20:55:58 +0100 Subject: [PATCH 4/6] Add test coverage for initial suggestions and fix bug --- .../__experimental-fetch-link-suggestions.js | 8 +- .../__experimental-fetch-link-suggestions.js | 81 +++++++++++++++---- 2 files changed, 70 insertions(+), 19 deletions(-) diff --git a/packages/core-data/src/fetch/__experimental-fetch-link-suggestions.js b/packages/core-data/src/fetch/__experimental-fetch-link-suggestions.js index 4c3483776fbc8..88b8dff57e113 100644 --- a/packages/core-data/src/fetch/__experimental-fetch-link-suggestions.js +++ b/packages/core-data/src/fetch/__experimental-fetch-link-suggestions.js @@ -101,10 +101,10 @@ const fetchLinkSuggestions = async ( const queries = []; if ( isInitialSuggestions && initialSuggestionsOptions ) { - type = initialSuggestionsOptions.type; - subtype = initialSuggestionsOptions.subtype; - page = initialSuggestionsOptions.page; - perPage = initialSuggestionsOptions.perPage; + type = initialSuggestionsOptions.type || type; + subtype = initialSuggestionsOptions.subtype || subtype; + page = initialSuggestionsOptions.page || page; + perPage = initialSuggestionsOptions.perPage || perPage; } if ( ! type || type === 'post' ) { diff --git a/packages/core-data/src/fetch/test/__experimental-fetch-link-suggestions.js b/packages/core-data/src/fetch/test/__experimental-fetch-link-suggestions.js index 23e889344c0e4..16a4becd8515b 100644 --- a/packages/core-data/src/fetch/test/__experimental-fetch-link-suggestions.js +++ b/packages/core-data/src/fetch/test/__experimental-fetch-link-suggestions.js @@ -231,22 +231,73 @@ describe( 'fetchLinkSuggestions', () => { ] ) ); } ); - it( 'initial search suggestions limits results', () => { - return fetchLinkSuggestions( '', { - type: 'post', - subtype: 'page', - isInitialSuggestions: true, - } ).then( ( suggestions ) => - expect( suggestions ).toEqual( [ - { - id: 11, - title: 'Limit Case', - url: 'http://wordpress.local/limit-case/', - type: 'page', - kind: 'post-type', + describe( 'Initial search suggestions', () => { + it( 'initial search suggestions limits results', () => { + return fetchLinkSuggestions( '', { + type: 'post', + subtype: 'page', + isInitialSuggestions: true, + } ).then( ( suggestions ) => + expect( suggestions ).toEqual( [ + { + id: 11, + title: 'Limit Case', + url: 'http://wordpress.local/limit-case/', + type: 'page', + kind: 'post-type', + }, + ] ) + ); + } ); + + it( 'should allow custom search options for initial suggestions', () => { + return fetchLinkSuggestions( '', { + type: 'term', + subtype: 'category', + page: 11, + isInitialSuggestions: true, + initialSuggestionsOptions: { + type: 'post', + subtype: 'page', + perPage: 20, + page: 11, }, - ] ) - ); + } ).then( ( suggestions ) => + expect( suggestions ).toEqual( [ + { + id: 22, + title: 'Page Case', + url: 'http://wordpress.local/page-case/', + type: 'page', + kind: 'post-type', + }, + ] ) + ); + } ); + + it( 'should default any missing initial search options to those from the main search options', () => { + return fetchLinkSuggestions( '', { + type: 'post', + subtype: 'page', + page: 11, + perPage: 20, + isInitialSuggestions: true, + initialSuggestionsOptions: { + // intentionally missing. + // expected to default to those from the main search options. + }, + } ).then( ( suggestions ) => + expect( suggestions ).toEqual( [ + { + id: 22, + title: 'Page Case', + url: 'http://wordpress.local/page-case/', + type: 'page', + kind: 'post-type', + }, + ] ) + ); + } ); } ); it( 'allows searching from a page', () => { return fetchLinkSuggestions( '', { From 9bd8998f2dad56a3ebd7aaf87692648864152d6d Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Fri, 29 Sep 2023 20:56:42 +0100 Subject: [PATCH 5/6] Rename var for consistency --- .../block-library/src/navigation-link/link-ui.js | 2 +- .../fetch/__experimental-fetch-link-suggestions.js | 12 ++++++------ .../test/__experimental-fetch-link-suggestions.js | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/block-library/src/navigation-link/link-ui.js b/packages/block-library/src/navigation-link/link-ui.js index e3d7153be566b..3c3d91e7b0a05 100644 --- a/packages/block-library/src/navigation-link/link-ui.js +++ b/packages/block-library/src/navigation-link/link-ui.js @@ -47,7 +47,7 @@ export function getSuggestionsQuery( type, kind ) { return { // for custom link which has no type // always show pages as initial suggestions - initialSuggestionsOptions: { + initialSuggestionsSearchOptions: { type: 'post', subtype: 'page', perPage: 20, diff --git a/packages/core-data/src/fetch/__experimental-fetch-link-suggestions.js b/packages/core-data/src/fetch/__experimental-fetch-link-suggestions.js index 88b8dff57e113..3bba760b20c45 100644 --- a/packages/core-data/src/fetch/__experimental-fetch-link-suggestions.js +++ b/packages/core-data/src/fetch/__experimental-fetch-link-suggestions.js @@ -85,7 +85,7 @@ const fetchLinkSuggestions = async ( ) => { const { isInitialSuggestions = false, - initialSuggestionsOptions = undefined, + initialSuggestionsSearchOptions = undefined, } = searchOptions; const { disablePostFormats = false } = settings; @@ -100,11 +100,11 @@ const fetchLinkSuggestions = async ( /** @type {Promise[]} */ const queries = []; - if ( isInitialSuggestions && initialSuggestionsOptions ) { - type = initialSuggestionsOptions.type || type; - subtype = initialSuggestionsOptions.subtype || subtype; - page = initialSuggestionsOptions.page || page; - perPage = initialSuggestionsOptions.perPage || perPage; + if ( isInitialSuggestions && initialSuggestionsSearchOptions ) { + type = initialSuggestionsSearchOptions.type || type; + subtype = initialSuggestionsSearchOptions.subtype || subtype; + page = initialSuggestionsSearchOptions.page || page; + perPage = initialSuggestionsSearchOptions.perPage || perPage; } if ( ! type || type === 'post' ) { diff --git a/packages/core-data/src/fetch/test/__experimental-fetch-link-suggestions.js b/packages/core-data/src/fetch/test/__experimental-fetch-link-suggestions.js index 16a4becd8515b..d283226cca090 100644 --- a/packages/core-data/src/fetch/test/__experimental-fetch-link-suggestions.js +++ b/packages/core-data/src/fetch/test/__experimental-fetch-link-suggestions.js @@ -256,7 +256,7 @@ describe( 'fetchLinkSuggestions', () => { subtype: 'category', page: 11, isInitialSuggestions: true, - initialSuggestionsOptions: { + initialSuggestionsSearchOptions: { type: 'post', subtype: 'page', perPage: 20, @@ -282,7 +282,7 @@ describe( 'fetchLinkSuggestions', () => { page: 11, perPage: 20, isInitialSuggestions: true, - initialSuggestionsOptions: { + initialSuggestionsSearchOptions: { // intentionally missing. // expected to default to those from the main search options. }, From e90579aa5e9fceaba8442af8dc1458696fbcf5ac Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Fri, 29 Sep 2023 21:15:47 +0100 Subject: [PATCH 6/6] Add e2e test coverage specifically for Nav block --- .../blocks/navigation-list-view.spec.js | 31 +++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/test/e2e/specs/editor/blocks/navigation-list-view.spec.js b/test/e2e/specs/editor/blocks/navigation-list-view.spec.js index 6490fbee97f1f..fd7113fe17095 100644 --- a/test/e2e/specs/editor/blocks/navigation-list-view.spec.js +++ b/test/e2e/specs/editor/blocks/navigation-list-view.spec.js @@ -195,8 +195,8 @@ test.describe( 'Navigation block - List view editing', () => { await expect( blockResultOptions.nth( 1 ) ).toHaveText( 'Custom Link' ); // Select the Page Link option. - const pageLinkResult = blockResultOptions.nth( 0 ); - await pageLinkResult.click(); + const customLinkResult = blockResultOptions.nth( 1 ); + await customLinkResult.click(); // Expect to see the Link creation UI be focused. const linkUIInput = linkControl.getSearchInput(); @@ -209,7 +209,26 @@ test.describe( 'Navigation block - List view editing', () => { await expect( linkUIInput ).toBeFocused(); await expect( linkUIInput ).toBeEmpty(); + // Provides test coverage for feature whereby Custom Link type + // should default to `Pages` when displaying the "initial suggestions" + // in the Link UI. + // See https://github.com/WordPress/gutenberg/pull/54622. const firstResult = await linkControl.getNthSearchResult( 0 ); + const secondResult = await linkControl.getNthSearchResult( 1 ); + const thirdResult = await linkControl.getNthSearchResult( 2 ); + + const firstResultType = + await linkControl.getSearchResultType( firstResult ); + + const secondResultType = + await linkControl.getSearchResultType( secondResult ); + + const thirdResultType = + await linkControl.getSearchResultType( thirdResult ); + + expect( firstResultType ).toBe( 'Page' ); + expect( secondResultType ).toBe( 'Page' ); + expect( thirdResultType ).toBe( 'Page' ); // Grab the text from the first result so we can check (later on) that it was inserted. const firstResultText = @@ -573,4 +592,12 @@ class LinkControl { .locator( '.components-menu-item__item' ) // this is the only way to get the label text without the URL. .innerText(); } + + async getSearchResultType( result ) { + await expect( result ).toBeVisible(); + + return result + .locator( '.components-menu-item__shortcut' ) // this is the only way to get the type text. + .innerText(); + } }