Skip to content

Commit cae145a

Browse files
Menus: Add tests to prevent nav_menu_item_args filter leakage between items
1 parent 628417e commit cae145a

File tree

1 file changed

+68
-0
lines changed

1 file changed

+68
-0
lines changed

tests/phpunit/tests/menu/walker-nav-menu.php

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,4 +435,72 @@ public function data_build_atts_should_build_attributes() {
435435
),
436436
);
437437
}
438+
439+
/**
440+
* Tests that modifications to `$args` in the `nav_menu_item_args` filter do not leak between menu items.
441+
*
442+
* @ticket 37344
443+
*
444+
* @covers Walker_Nav_Menu::start_el
445+
*/
446+
public function test_walker_nav_menu_start_el_should_not_leak_nav_menu_item_args_filter_changes_between_items() {
447+
add_filter( 'nav_menu_item_args', array( $this, 'filter_nav_menu_item_args_append_marker' ), 10, 3 );
448+
449+
$item1 = array(
450+
'ID' => 1,
451+
'title' => 'Item 1',
452+
'classes' => array(),
453+
'current' => false,
454+
'target' => '',
455+
'xfn' => '',
456+
'url' => 'http://example.com/item1',
457+
);
458+
459+
$item2 = array(
460+
'ID' => 2,
461+
'title' => 'Item 2',
462+
'classes' => array(),
463+
'current' => false,
464+
'target' => '',
465+
'xfn' => '',
466+
'url' => 'http://example.com/item2',
467+
);
468+
469+
$args = array(
470+
'before' => '',
471+
'after' => '',
472+
'link_before' => '',
473+
'link_after' => '',
474+
);
475+
476+
$output1 = '';
477+
$this->walker->start_el( $output1, (object) $item1, 0, (object) $args );
478+
479+
$output2 = '';
480+
$this->walker->start_el( $output2, (object) $item2, 0, (object) $args );
481+
482+
remove_filter( 'nav_menu_item_args', array( $this, 'filter_nav_menu_item_args_append_marker' ), 10 );
483+
484+
// Both menu items should have exactly one 'X' marker, not accumulating.
485+
$this->assertStringContainsString( '>X<a href="http://example.com/item1">Item 1</a>', $output1 );
486+
$this->assertStringContainsString( '>X<a href="http://example.com/item2">Item 2</a>', $output2 );
487+
488+
// Ensure no accumulation - Item 2 should not contain 'XX'.
489+
$this->assertStringNotContainsString( '>XX<a href="http://example.com/item2">Item 2</a>', $output2 );
490+
}
491+
492+
/**
493+
* Filter callback for testing nav_menu_item_args filter side effects.
494+
*
495+
* Appends a marker character to the 'before' argument to test for accumulation.
496+
*
497+
* @param stdClass $args An object of wp_nav_menu() arguments.
498+
* @param WP_Post $menu_item Menu item data object.
499+
* @param int $depth Depth of menu item. Used for padding.
500+
* @return stdClass Modified arguments object.
501+
*/
502+
public function filter_nav_menu_item_args_append_marker( $args, $menu_item, $depth ) {
503+
$args->before .= 'X';
504+
return $args;
505+
}
438506
}

0 commit comments

Comments
 (0)