Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix error when using a navigation block that returns an empty fallback result #56629

Merged
merged 4 commits into from
Dec 11, 2023

Conversation

talldan
Copy link
Contributor

@talldan talldan commented Nov 29, 2023

What?

Fixes #56600

That issue explains how an error can trigger when navigation fallbacks return empty results.

How?

After the refactor in #55605, some of the code was moved from the navigation block's render function (where the code returned an empty string to indicate empty block content) over to smaller helper functions that return fallback blocks.

In these new smaller helper functions, the code should return an array when there are no results, as the new calling code expects to handle arrays/iterables. Probably as a result of the copy/paste, some of them were still returning strings.

Testing Instructions

Testing is a little challenging. I think you need to:

  • Delete all wp_navigation menus (so that you don't fallback to using the first one)
  • Not have a page list block registered (so that the page list fallback isn't used)
  • Delete all classic menus (so that you don't fall back to those either)
  • Have a navigation block that has an __unstableLocation attribute specified, and no ref attribute.

All you need to then is view the front end of the site that renders that navigation block and you should be able to trigger the error in trunk.

Screenshots or screencast

Before

Screenshot 2023-11-29 at 4 35 34 pm

After

Screenshot 2023-11-29 at 4 35 45 pm

@talldan talldan added [Type] Bug An existing feature does not function as intended [Block] Navigation Affects the Navigation Block labels Nov 29, 2023
@talldan talldan self-assigned this Nov 29, 2023
Copy link

github-actions bot commented Nov 29, 2023

This pull request has changed or added PHP files. Please confirm whether these changes need to be synced to WordPress Core, and therefore featured in the next release of WordPress.

If so, it is recommended to create a new Trac ticket and submit a pull request to the WordPress Core Github repository soon after this pull request is merged.

If you're unsure, you can always ask for help in the #core-editor channel in WordPress Slack.

Thank you! ❤️

View changed files
❔ lib/compat/wordpress-6.5/class-wp-navigation-block-renderer.php
❔ phpunit/class-wp-navigation-block-renderer-test.php

Copy link

github-actions bot commented Nov 29, 2023

Flaky tests detected in c23ede6.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/7162763338
📝 Reported issues:

@talldan talldan changed the title Fix error when using a navigation block fallback that returns an empty result Fix error when using a navigation block that returns an empty fallback result Nov 29, 2023
Copy link
Contributor

@getdave getdave left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried my best to test this by following the instructions. Here's what I did (you can correct me if I am wrong or you have a better way):

  • De-registered the core/page-list block by putting the following in a Plugin file
function getdave_unregister_core_page_list_block() {
	unregister_block_type( 'core/page-list' );
}
add_action( 'wp_loaded', 'getdave_unregister_core_page_list_block' );
  • Cleared all Block-based and Classic Navigation Menus.
    • You can check for Nav Posts using npm run wp-env run cli wp post list -- --post_type=wp_navigation --format=ids and then delete with npm run wp-env run cli wp post delete {ID} -- --force.
  • New Post -> Switch to Code view
  • Open dev tools console. De-register the page list within the editor:
wp.blocks.unregisterBlockType( 'core/page-list' );
  • Insert following block into the code editor view in the editor:
<!-- wp:navigation {"__unstableLocation":"foo"} /-->
  • Save the post

  • View Post on front of site

  • On trunk I then observed the error.

  • On this branch I no longer observed the error.

My only comment would be should we augment the PHPUnit test suite to provide coverage for this?

@talldan
Copy link
Contributor Author

talldan commented Dec 11, 2023

Thanks for the review, @getdave! I realise it was a tricky one to test.

My only comment would be should we augment the PHPUnit test suite to provide coverage for this?

I'm personally not sure about adding unit tests after the fact, I think they're most valuable for asserting code that's being written at the time does what's expected and is nicely structured.

That said, it was easy enough to add one for the failing branch of code in get_inner_blocks_from_navigation_post, so I did that.

For get_inner_blocks_from_fallback, I think block_core_navigation_get_fallback_blocks would need to be mocked and I personally don't know how. I had a search online to see if it's possible and couldn't see any. Most results said to refactor the code and make it a method, so that could be an option for the future.

@talldan talldan merged commit b6860f0 into trunk Dec 11, 2023
51 checks passed
@talldan talldan deleted the fix/navigation-block-fatal-error branch December 11, 2023 09:34
@github-actions github-actions bot added this to the Gutenberg 17.3 milestone Dec 11, 2023
@getdave
Copy link
Contributor

getdave commented Dec 11, 2023

Thanks for the review, @getdave! I realise it was a tricky one to test.

You are welcome. It was a fun exercise 😅

I'm personally not sure about adding unit tests after the fact, I think they're most valuable for asserting code that's being written at the time does what's expected and is nicely structured.
That said, it was easy enough to add one for the failing branch of code in get_inner_blocks_from_navigation_post, so I did that.

Thank you for taking the time to add that. As you know, in the past we've suffered a number of regressions on the Nav block and so we [regular contributors] are now focused on providing test coverage where we can - especially when the overhead of running the tests is low (like the one you kindly wrote here). Appreciate it.

For get_inner_blocks_from_fallback, I think block_core_navigation_get_fallback_blocks would need to be mocked and I personally don't know how. I had a search online to see if it's possible and couldn't see any. Most results said to refactor the code and make it a method, so that could be an option for the future.

I think you could add_filter on block_core_navigation_render_fallback?

return '';
return new WP_Block_List( array(), $attributes );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed present in new block-library version of this file

// Fallback my have been filtered so do basic test for validity.
if ( empty( $fallback_blocks ) || ! is_array( $fallback_blocks ) ) {
return new WP_Block_List( array(), $attributes );
}

@getdave
Copy link
Contributor

getdave commented Jan 25, 2024

✅ I updated the PHP Sync Tracking Issue for WP 6.5 to note this PR no longer requires a backport for WP 6.5.

Why? Because the code was moved into the block-library package in #57979 and thus should be automatically handled by the packages sync process.

@talldan
Copy link
Contributor Author

talldan commented Jan 30, 2024

Thanks ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Block] Navigation Affects the Navigation Block [Type] Bug An existing feature does not function as intended
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Navigation Block: __unstableLocation can trigger a fatal in block_core_navigation_get_post_ids()
2 participants