diff --git a/src/wp-admin/includes/class-wp-terms-list-table.php b/src/wp-admin/includes/class-wp-terms-list-table.php index efbf68a9f4..4160577591 100644 --- a/src/wp-admin/includes/class-wp-terms-list-table.php +++ b/src/wp-admin/includes/class-wp-terms-list-table.php @@ -474,18 +474,18 @@ class WP_Terms_List_Table extends WP_List_Table { $taxonomy = $this->screen->taxonomy; $uri = wp_doing_ajax() ? wp_get_referer() : $_SERVER['REQUEST_URI']; - $edit_link = add_query_arg( - 'wp_http_referer', - urlencode( wp_unslash( $uri ) ), - get_edit_term_link( $tag, $taxonomy, $this->screen->post_type ) - ); - $actions = array(); if ( current_user_can( 'edit_term', $tag->term_id ) ) { $actions['edit'] = sprintf( '%s', - esc_url( $edit_link ), + esc_url( + add_query_arg( + 'wp_http_referer', + urlencode( wp_unslash( $uri ) ), + get_edit_term_link( $tag, $taxonomy, $this->screen->post_type ) + ) + ), /* translators: %s: Taxonomy term name. */ esc_attr( sprintf( __( 'Edit “%s”' ), $tag->name ) ), __( 'Edit' ) diff --git a/tests/phpunit/tests/admin/wpTermsListTable.php b/tests/phpunit/tests/admin/wpTermsListTable.php new file mode 100644 index 0000000000..2eb566d970 --- /dev/null +++ b/tests/phpunit/tests/admin/wpTermsListTable.php @@ -0,0 +1,88 @@ +user->create( array( 'role' => 'administrator' ) ); + self::$author_id = self::factory()->user->create( array( 'role' => 'author' ) ); + + self::$term_object = self::factory()->term->create_and_get( array( 'taxonomy' => self::CATEGORY_TAXONOMY ) ); + + require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php'; + require_once ABSPATH . 'wp-admin/includes/class-wp-terms-list-table.php'; + } + + public function set_up() { + parent::set_up(); + + $this->terms_list_table = new WP_Terms_List_Table(); + } + + /** + * Call an inaccessible (private or protected) method. + * + * @param object|string $object Object instance or class string to call the method of. + * @param string $method_name Name of the method to call. + * @param array $args Optional. Array of arguments to pass to the method. + * @return mixed Return value of the method call. + * @throws ReflectionException If the object could not be reflected upon. + */ + private function call_inaccessible_method( $object, $method_name, $args = array() ) { + $method = ( new ReflectionClass( $object ) )->getMethod( $method_name ); + $method->setAccessible( true ); + return $method->invokeArgs( $object, $args ); + } + + /** + * @covers WP_Terms_List_Table::handle_row_actions() + * + * @ticket 59336 + */ + public function test_handle_row_actions_as_author() { + wp_set_current_user( self::$author_id ); + + $actions = $this->call_inaccessible_method( $this->terms_list_table, 'handle_row_actions', array( self::$term_object, 'title', 'title' ) ); + + $this->assertStringContainsString( '
', $actions, 'Row actions should be displayed.' ); + $this->assertStringContainsString( 'View', $actions, 'View action should be displayed to the author.' ); + $this->assertStringNotContainsString( 'Edit', $actions, 'Edit action should not be displayed to the author.' ); + $this->assertStringNotContainsString( 'Delete', $actions, 'Delete action should not be displayed to the author.' ); + } + + /** + * @covers WP_Terms_List_Table::handle_row_actions() + * + * @ticket 59336 + */ + public function test_handle_row_actions_as_admin() { + wp_set_current_user( self::$admin_id ); + + $actions = $this->call_inaccessible_method( $this->terms_list_table, 'handle_row_actions', array( self::$term_object, 'title', 'title' ) ); + + $this->assertStringContainsString( '
', $actions, 'Row actions should be displayed.' ); + $this->assertStringContainsString( 'View', $actions, 'View action should be displayed to the admin.' ); + $this->assertStringContainsString( 'Edit', $actions, 'Edit action should be displayed to the admin.' ); + $this->assertStringContainsString( 'Delete', $actions, 'Delete action should be displayed to the admin.' ); + $this->assertStringContainsString( admin_url( 'term.php' ), $actions, 'Edit term link should be displayed to the admin.' ); + } +}