From 117c5868e877e19584602e06490b734aca415291 Mon Sep 17 00:00:00 2001 From: Paul Bearne Date: Thu, 29 Jan 2026 16:56:47 -0500 Subject: [PATCH 1/2] Add PHPUnit tests for admin trash redirect functionality and improve edit.php handling. --- src/wp-admin/edit.php | 13 +++ .../phpunit/tests/admin/testTrashRedirect.php | 96 +++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 tests/phpunit/tests/admin/testTrashRedirect.php diff --git a/src/wp-admin/edit.php b/src/wp-admin/edit.php index 15cb17d303bd3..12e8581ceebf6 100644 --- a/src/wp-admin/edit.php +++ b/src/wp-admin/edit.php @@ -188,6 +188,13 @@ ++$deleted; } $sendback = add_query_arg( 'deleted', $deleted, $sendback ); + + if ( isset( $_REQUEST['post_status'] ) && 'trash' === $_REQUEST['post_status'] ) { + $post_counts = (array) wp_count_posts( $post_type, 'readable' ); + if ( empty( $post_counts['trash'] ) ) { + $sendback = remove_query_arg( array( 'post_status', 'paged' ), $sendback ); + } + } break; case 'edit': if ( isset( $_REQUEST['bulk_edit'] ) ) { @@ -234,6 +241,12 @@ $wp_list_table->prepare_items(); +if ( ! $wp_list_table->has_items() && isset( $_REQUEST['post_status'] ) && 'trash' === $_REQUEST['post_status'] ) { + $sendback = remove_query_arg( array( 'post_status', 'paged' ), wp_unslash( $_SERVER['REQUEST_URI'] ) ); + wp_redirect( $sendback ); + exit; +} + wp_enqueue_script( 'inline-edit-post' ); wp_enqueue_script( 'heartbeat' ); diff --git a/tests/phpunit/tests/admin/testTrashRedirect.php b/tests/phpunit/tests/admin/testTrashRedirect.php new file mode 100644 index 0000000000000..05e5a08267102 --- /dev/null +++ b/tests/phpunit/tests/admin/testTrashRedirect.php @@ -0,0 +1,96 @@ +admin_user_id = self::factory()->user->create( array( 'role' => 'administrator' ) ); + wp_set_current_user( $this->admin_user_id ); + + // Ensure we are in the admin context. + set_current_screen( 'edit-post' ); + + // Define ABSPATH if not defined (though it should be in tests). + if ( ! defined( 'ABSPATH' ) ) { + define( 'ABSPATH', dirname( __DIR__, 4 ) . '/src/' ); + } + + add_filter( 'wp_redirect', array( $this, 'catch_redirect' ), 1, 1 ); + } + + public function tear_down() { + remove_filter( 'wp_redirect', array( $this, 'catch_redirect' ), 1 ); + parent::tear_down(); + } + + public function catch_redirect( $location ) { + throw new Tests_Admin_TrashRedirect_Exception( $location ); + } + + /** + * Test that visiting an empty trash view redirects to all posts view. + */ + public function test_empty_trash_view_redirects_to_all_posts() { + // Mock the request for empty trash. + $_GET['post_status'] = 'trash'; + $_GET['post_type'] = 'post'; + $_REQUEST['post_status'] = 'trash'; + $_SERVER['REQUEST_URI'] = admin_url( 'edit.php?post_status=trash' ); + + try { + ob_start(); + include ABSPATH . 'wp-admin/edit.php'; + ob_end_clean(); + } catch ( Tests_Admin_TrashRedirect_Exception $e ) { + ob_end_clean(); + $this->assertStringNotContainsString( 'post_status=trash', $e->get_location() ); + $this->assertStringContainsString( 'edit.php', $e->get_location() ); + return; + } + + $this->fail( 'Redirect expected when visiting empty trash view.' ); + } + + /** + * Test that emptying trash via 'delete_all' redirects to all posts view. + */ + public function test_empty_trash_action_redirects_to_all_posts() { + // Create a post in trash. + $post_id = self::factory()->post->create( array( 'post_status' => 'trash' ) ); + + $_REQUEST['post_status'] = 'trash'; + $_REQUEST['post_type'] = 'post'; + $_REQUEST['action'] = 'delete_all'; + $_REQUEST['_wpnonce'] = wp_create_nonce( 'bulk-posts' ); + $_SERVER['REQUEST_URI'] = admin_url( 'edit.php?post_status=trash' ); + $_SERVER['HTTP_REFERER'] = admin_url( 'edit.php?post_status=trash' ); + + try { + ob_start(); + include ABSPATH . 'wp-admin/edit.php'; + ob_end_clean(); + } catch ( Tests_Admin_TrashRedirect_Exception $e ) { + ob_end_clean(); + $this->assertStringNotContainsString( 'post_status=trash', $e->get_location() ); + $this->assertStringContainsString( 'edit.php', $e->get_location() ); + // Check if post is actually deleted. + $this->assertNull( get_post( $post_id ) ); + return; + } + + $this->fail( 'Redirect expected after emptying trash.' ); + } +} + +class Tests_Admin_TrashRedirect_Exception extends Exception { + protected $location; + public function __construct( $location ) { + $this->location = $location; + } + public function get_location() { + return $this->location; + } +} From 219d1ff91d2660313c46e05cc0c349c0b64d4774 Mon Sep 17 00:00:00 2001 From: Paul Bearne Date: Thu, 29 Jan 2026 17:01:26 -0500 Subject: [PATCH 2/2] Align spacing in `test_empty_trash_view_redirects_to_all_posts` for readability. --- tests/phpunit/tests/admin/testTrashRedirect.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/phpunit/tests/admin/testTrashRedirect.php b/tests/phpunit/tests/admin/testTrashRedirect.php index 05e5a08267102..a8eb8c5254bef 100644 --- a/tests/phpunit/tests/admin/testTrashRedirect.php +++ b/tests/phpunit/tests/admin/testTrashRedirect.php @@ -35,10 +35,10 @@ public function catch_redirect( $location ) { */ public function test_empty_trash_view_redirects_to_all_posts() { // Mock the request for empty trash. - $_GET['post_status'] = 'trash'; - $_GET['post_type'] = 'post'; + $_GET['post_status'] = 'trash'; + $_GET['post_type'] = 'post'; $_REQUEST['post_status'] = 'trash'; - $_SERVER['REQUEST_URI'] = admin_url( 'edit.php?post_status=trash' ); + $_SERVER['REQUEST_URI'] = admin_url( 'edit.php?post_status=trash' ); try { ob_start();