diff --git a/inc/namespace.php b/inc/namespace.php index bd505e1..c451dc4 100644 --- a/inc/namespace.php +++ b/inc/namespace.php @@ -304,8 +304,14 @@ function render_block_search( string $block_content, array $block, \WP_Block $in $inherit = ! empty( $instance->context['query']['inherit'] ); + // An inherited query is the main query, and WordPress resolves that from + // its own `s`: a term only reaches the search template because `s` is what + // routing reads. Naming the field anything else leaves the field blank on + // arrival, and clearing it deletes a parameter the URL never carried, so + // the results never change. `query-s` is still transposed onto the main + // query for anything that already links to it. $query_var = $inherit - ? 'query-s' + ? 's' : sprintf( 'query-%d-s', $instance->context['queryId'] ?? 0 ); // A search is a new set of results, so it belongs on the first page. Left diff --git a/tests/e2e/README.md b/tests/e2e/README.md index 83b3186..36ccf5b 100644 --- a/tests/e2e/README.md +++ b/tests/e2e/README.md @@ -34,7 +34,9 @@ run and `npm run playground:start`: deliberately private ones. It also records any PHP notice raised from this plugin's files and prints it into the page as a `qf-php-error:` comment, followed by a `qf-php-errors-checked` marker, so a spec can assert a page - rendered cleanly without depending on `display_errors`. + rendered cleanly without depending on `display_errors`, and rewrites the + theme's search results template to put a search block inside the inheriting + query loop, the one arrangement in which the blocks see an inherited query. 5. Runs `tests/seed.php`, which creates the fixture terms, posts and the demo pages the specs visit. diff --git a/tests/e2e/inherited-search.spec.js b/tests/e2e/inherited-search.spec.js new file mode 100644 index 0000000..371d0b9 --- /dev/null +++ b/tests/e2e/inherited-search.spec.js @@ -0,0 +1,41 @@ +const { test, expect, POSTS } = require( './fixtures' ); + +/** + * The search results template carries a query loop that inherits the main + * query, with a search block inside it — see tests/mu-plugins. A term reaches + * that page in WordPress' own `s`, because that is what routing reads, so the + * wired field has to be named `s` as well. + */ +test.describe( 'Search filter in an inherited query', () => { + test( 'the field is wired to the site search term', async ( { + page, + loop, + } ) => { + await page.goto( '/?s=Alpha' ); + + const input = page.locator( '.wp-block-query .wp-block-search__input' ); + await expect( input ).toHaveAttribute( 'name', 's' ); + await expect( input ).toHaveValue( 'Alpha' ); + + // The main query orders search results its own way, so compare as a set. + await expect + .poll( async () => ( await loop.titles() ).sort() ) + .toEqual( POSTS.alpha ); + } ); + + test( 'clearing the field clears the search', async ( { page, loop } ) => { + await page.goto( '/?s=Alpha' ); + await expect + .poll( async () => ( await loop.titles() ).sort() ) + .toEqual( POSTS.alpha ); + + await page + .locator( '.wp-block-query .wp-block-search__input' ) + .fill( '' ); + + await page.waitForURL( /\?s=$/ ); + + // An empty term is still a search to WordPress, and returns everything. + await expect.poll( () => loop.titles() ).toContain( POSTS.beta[ 0 ] ); + } ); +} ); diff --git a/tests/mu-plugins/register-test-content.php b/tests/mu-plugins/register-test-content.php index caa8015..dee9572 100644 --- a/tests/mu-plugins/register-test-content.php +++ b/tests/mu-plugins/register-test-content.php @@ -12,6 +12,7 @@ namespace HM\Query_Loop_Filter\Tests; add_action( 'init', __NAMESPACE__ . '\\register_test_content' ); +add_filter( 'get_block_templates', __NAMESPACE__ . '\\replace_search_template', 10, 2 ); /** * Register the test post types and taxonomies. @@ -100,3 +101,39 @@ function print_plugin_php_errors() : void { echo "\n"; } + +/** + * Put a searchable, inheriting query loop on the search results template. + * + * The bundled themes render search results through a query loop that inherits + * the main query, but none of them place a search block inside it. That is the + * arrangement a dedicated search page uses, and the only one where the filter + * blocks see an inherited query, so the tests need a template that has it. + * + * @param \WP_Block_Template[] $templates Templates matching the query. + * @param array $query Arguments the templates were queried with. + * @return \WP_Block_Template[] Templates, with the search template rewritten. + */ +function replace_search_template( array $templates, array $query ) : array { + if ( ! in_array( 'search', (array) ( $query['slug__in'] ?? [] ), true ) ) { + return $templates; + } + + foreach ( $templates as $template ) { + if ( $template->slug !== 'search' ) { + continue; + } + + $template->content = implode( '', [ + '', + '', + '