From b8f88aa5977c71f52cc0616787a658a1d041556d Mon Sep 17 00:00:00 2001 From: Peter Wilson Date: Sat, 27 Aug 2016 11:27:17 +0000 Subject: [PATCH] Unit tests: Enforce $args object in `wp_nav_menu()` & `Walker_Nav_Menu`. WordPress always* passes $args to filters as an array of arugments. A exception is made in `wp_nav_menu()` and the associated walker where these are passed to filters as an object, this has been the case for seven years (since [13368]). These new tests enforce the use of an object in these filters to ensure backward compatibility is maintained. See #24587. git-svn-id: https://develop.svn.wordpress.org/trunk@38400 602fd350-edb4-49c9-b593-d223f7449a82 --- tests/phpunit/tests/post/nav-menu.php | 87 +++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/tests/phpunit/tests/post/nav-menu.php b/tests/phpunit/tests/post/nav-menu.php index 693f1fb40a..83272e7c66 100644 --- a/tests/phpunit/tests/post/nav-menu.php +++ b/tests/phpunit/tests/post/nav-menu.php @@ -275,4 +275,91 @@ class Test_Nav_Menus extends WP_UnitTestCase { $this->assertEmpty( $post_type_archive_item->description ); } + + /** + * Confirm `wp_nav_menu()` and `Walker_Nav_Menu` passes an $args object to filters. + * + * `wp_nav_menu()` is unique in that it uses an $args object rather than an array. + * This has been the case for some time and should be maintained for reasons of + * backward compatibility. + * + * @ticket 24587 + */ + function test_wp_nav_menu_filters_are_passed_args_object() { + $tag_id = self::factory()->tag->create(); + + $tag_insert = wp_update_nav_menu_item( $this->menu_id, 0, array( + 'menu-item-type' => 'taxonomy', + 'menu-item-object' => 'post_tag', + 'menu-item-object-id' => $tag_id, + 'menu-item-status' => 'publish', + ) ); + + /* + * The tests take place in a range of filters to ensure the passed + * arguments are an object. + */ + // In function. + add_filter( 'pre_wp_nav_menu', array( $this, '_confirm_second_param_args_object' ), 10, 2 ); + add_filter( 'wp_nav_menu_objects', array( $this, '_confirm_second_param_args_object' ), 10, 2 ); + add_filter( 'wp_nav_menu_items', array( $this, '_confirm_second_param_args_object' ), 10, 2 ); + + // In walker. + add_filter( 'nav_menu_item_args', array( $this, '_confirm_nav_menu_item_args_object' ) ); + + add_filter( 'nav_menu_css_class', array( $this, '_confirm_third_param_args_object' ), 10, 3 ); + add_filter( 'nav_menu_item_id', array( $this, '_confirm_third_param_args_object' ), 10, 3 ); + add_filter( 'nav_menu_link_attributes', array( $this, '_confirm_third_param_args_object' ), 10, 3 ); + add_filter( 'nav_menu_item_title', array( $this, '_confirm_third_param_args_object' ), 10, 3 ); + + add_filter( 'walker_nav_menu_start_el', array( $this, '_confirm_forth_param_args_object' ), 10, 4 ); + + wp_nav_menu( array( + 'echo' => false, + 'menu' => $this->menu_id, + ) ); + wp_delete_term( $tag_id, 'post_tag' ); + + /* + * Remove test filters. + */ + // In function. + remove_filter( 'pre_wp_nav_menu', array( $this, '_confirm_second_param_args_object' ), 10, 2 ); + remove_filter( 'wp_nav_menu_objects', array( $this, '_confirm_second_param_args_object' ), 10, 2 ); + remove_filter( 'wp_nav_menu_items', array( $this, '_confirm_second_param_args_object' ), 10, 2 ); + + // In walker. + remove_filter( 'nav_menu_item_args', array( $this, '_confirm_nav_menu_item_args_object' ) ); + + remove_filter( 'nav_menu_css_class', array( $this, '_confirm_third_param_args_object' ), 10, 3 ); + remove_filter( 'nav_menu_item_id', array( $this, '_confirm_third_param_args_object' ), 10, 3 ); + remove_filter( 'nav_menu_link_attributes', array( $this, '_confirm_third_param_args_object' ), 10, 3 ); + remove_filter( 'nav_menu_item_title', array( $this, '_confirm_third_param_args_object' ), 10, 3 ); + + remove_filter( 'walker_nav_menu_start_el', array( $this, '_confirm_forth_param_args_object' ), 10, 4 ); + + } + + /** + * Run tests required to confrim Walker_Nav_Menu receives an $args object. + */ + function _confirm_nav_menu_item_args_object( $args ) { + $this->assertTrue( is_object( $args ) ); + return $args; + } + + function _confirm_second_param_args_object( $ignored_1, $args ) { + $this->assertTrue( is_object( $args ) ); + return $ignored_1; + } + + function _confirm_third_param_args_object( $ignored_1, $ignored_2, $args ) { + $this->assertTrue( is_object( $args ) ); + return $ignored_1; + } + + function _confirm_forth_param_args_object( $ignored_1, $ignored_2, $ignored_3, $args ) { + $this->assertTrue( is_object( $args ) ); + return $ignored_1; + } }