From 6f08c7d4c1ec9cff94d9dc871f09e71ce02b6ec2 Mon Sep 17 00:00:00 2001 From: Connor Jennings Date: Tue, 4 Feb 2020 16:08:56 -0500 Subject: [PATCH 1/2] Correct file permissions --- bin/prepare-svn-release.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 bin/prepare-svn-release.sh diff --git a/bin/prepare-svn-release.sh b/bin/prepare-svn-release.sh old mode 100644 new mode 100755 From 419d1fad1ec3eeef9c281db0e544bc9ff05e299e Mon Sep 17 00:00:00 2001 From: Connor Jennings Date: Tue, 17 Dec 2019 20:09:12 -0500 Subject: [PATCH 2/2] Ensure post_name is set/unset given context of request --- modules/custom-status/custom-status.php | 196 ++++------ tests/test-edit-flow-custom-status.php | 484 ++++++++++++++++++++++++ 2 files changed, 562 insertions(+), 118 deletions(-) diff --git a/modules/custom-status/custom-status.php b/modules/custom-status/custom-status.php index 0086c70a1..34aced218 100644 --- a/modules/custom-status/custom-status.php +++ b/modules/custom-status/custom-status.php @@ -98,7 +98,8 @@ function init() { // These seven-ish methods are hacks for fixing bugs in WordPress core add_action( 'admin_init', array( $this, 'check_timestamp_on_publish' ) ); add_filter( 'wp_insert_post_data', array( $this, 'fix_custom_status_timestamp' ), 10, 2 ); - add_action( 'wp_insert_post', array( $this, 'fix_post_name' ), 10, 2 ); + add_filter( 'wp_insert_post_data', array( $this, 'maybe_keep_post_name_empty' ), 10, 2 ); + add_filter( 'pre_wp_unique_post_slug', array( $this, 'fix_unique_post_slug' ), 10, 6 ); add_filter( 'preview_post_link', array( $this, 'fix_preview_link_part_one' ) ); add_filter( 'post_link', array( $this, 'fix_preview_link_part_two' ), 10, 3 ); add_filter( 'page_link', array( $this, 'fix_preview_link_part_two' ), 10, 3 ); @@ -1367,41 +1368,66 @@ function fix_custom_status_timestamp( $data, $postarr ) { } /** - * Another hack! hack! hack! until core better supports custom statuses` + * A new hack! hack! hack! until core better supports custom statuses` * - * @since 0.7.4 + * @since 0.9.4 * - * Keep the post_name value empty for posts with custom statuses - * Unless they've set it customly + * If the post_name is set, set it, otherwise keep it empty + * * @see https://github.com/Automattic/Edit-Flow/issues/123 * @see http://core.trac.wordpress.org/browser/tags/3.4.2/wp-includes/post.php#L2530 * @see http://core.trac.wordpress.org/browser/tags/3.4.2/wp-includes/post.php#L2646 */ - public function fix_post_name( $post_id, $post ) { - global $pagenow; + public function maybe_keep_post_name_empty( $data, $postarr ) { + $status_slugs = wp_list_pluck( $this->get_custom_statuses(), 'slug' ); - /* - * Filters the $post object that will be modified - * - * @param $post WP_Post Post object being processed. - */ - $post = apply_filters( 'ef_fix_post_name_post', $post ); + // Ignore if it's not a post status and post type we support + if ( ! in_array( $data['post_status'], $status_slugs ) + || ! in_array( $data['post_type'], $this->get_post_types_for_module( $this->module ) ) ) { + return $data; + } - // Only modify if we're using a pre-publish status on a supported custom post type + // If the post_name was intentionally set, set the post_name + if ( ! empty( $postarr['post_name'] ) ) { + $data['post_name'] = $postarr['post_name']; + return $data; + } + + // Otherwise, keep the post_name empty + $data['post_name'] = ''; + + return $data; + } + +/** + * A new hack! hack! hack! until core better supports custom statuses` + * + * @since 0.9.4 + * + * `wp_unique_post_slug` is used to set the `post_name`. When a custom status is used, WordPress will try + * really hard to set `post_name`, and we leverage `wp_unique_post_slug` to prevent it being set + * + * @see: https://github.com/WordPress/WordPress/blob/396647666faebb109d9cd4aada7bb0c7d0fb8aca/wp-includes/post.php#L3932 + */ + public function fix_unique_post_slug( $override_slug, $slug, $post_ID, $post_status, $post_type, $post_parent ) { $status_slugs = wp_list_pluck( $this->get_custom_statuses(), 'slug' ); - if ( 'post.php' != $pagenow - || ! in_array( $post->post_status, $status_slugs ) - || ! in_array( $post->post_type, $this->get_post_types_for_module( $this->module ) ) ) - return; - // The slug has been set by the meta box - if ( ! empty( $_POST['post_name'] ) ) - return; + if ( ! in_array( $post_status, $status_slugs ) + || ! in_array( $post_type, $this->get_post_types_for_module( $this->module ) ) ) { + return null; + } - global $wpdb; + $post = get_post( $post_ID ); + + if ( empty( $post ) ) { + return null; + } - $wpdb->update( $wpdb->posts, array( 'post_name' => '' ), array( 'ID' => $post_id ) ); - clean_post_cache( $post_id ); + if ( $post->post_name ) { + return $slug; + } + + return ''; } @@ -1509,49 +1535,30 @@ public function fix_preview_link_part_three( $preview_link, $query_args ) { * @return string $link Direct link to complete the action */ public function fix_get_sample_permalink( $permalink, $post_id, $title, $name, $post ) { - //Should we be doing anything at all? - if( !in_array( $post->post_type, $this->get_post_types_for_module( $this->module ) ) ) - return $permalink; - //Is this published? - if( in_array( $post->post_status, $this->published_statuses ) ) - return $permalink; + $status_slugs = wp_list_pluck( $this->get_custom_statuses(), 'slug' ); - //Are we overriding the permalink? Don't do anything - if( isset( $_POST['action'] ) && $_POST['action'] == 'sample-permalink' ) + if ( ! in_array( $post->post_status, $status_slugs ) + || ! in_array( $post->post_type, $this->get_post_types_for_module( $this->module ) ) ) { return $permalink; + } - list( $permalink, $post_name ) = $permalink; - - $post_name = $post->post_name ? $post->post_name : sanitize_title( $post->post_title ); - $post->post_name = $post_name; - - $ptype = get_post_type_object( $post->post_type ); - - if ( $ptype->hierarchical ) { - $post->filter = 'sample'; + remove_filter( 'get_sample_permalink', array( $this, 'fix_get_sample_permalink' ), 10, 5 ); - $uri = get_page_uri( $post->ID ) . $post_name; + $new_name = ! is_null( $name ) ? $name : $post->post_name; + $new_title = ! is_null( $title ) ? $title : $post->post_title; - if ( $uri ) { - $uri = untrailingslashit($uri); - $uri = strrev( stristr( strrev( $uri ), '/' ) ); - $uri = untrailingslashit($uri); - } + $post = get_post( $post_id ); + $status_before = $post->post_status; + $post->post_status = 'draft'; - /** This filter is documented in wp-admin/edit-tag-form.php */ - $uri = apply_filters( 'editable_slug', $uri, $post ); + $permalink = get_sample_permalink( $post, $title, sanitize_title( $new_name ? $new_name : $new_title, $post->ID ) ); - if ( !empty($uri) ) { - $uri .= '/'; - } + $post->post_status = $status_before; - $permalink = str_replace('%pagename%', "{$uri}%pagename%", $permalink); - } - - unset($post->post_name); + add_filter( 'get_sample_permalink', array( $this, 'fix_get_sample_permalink' ), 10, 5 ); - return array( $permalink, $post_name ); + return $permalink; } /** @@ -1566,75 +1573,28 @@ public function fix_get_sample_permalink( $permalink, $post_id, $title, $name, $ * * @since 0.8.2 * - * @param string $return Sample permalink HTML markup - * @param int $post_id Post ID - * @param string $new_title New sample permalink title - * @param string $new_slug New sample permalink kslug - * @param WP_Post $post Post object + * @param string $return Sample permalink HTML markup. + * @param int $post_id Post ID. + * @param string $new_title New sample permalink title. + * @param string $new_slug New sample permalink slug. + * @param WP_Post $post Post object. */ - function fix_get_sample_permalink_html( $return, $post_id, $new_title, $new_slug, $post ) { + public function fix_get_sample_permalink_html( $permalink, $post_id, $new_title, $new_slug, $post ) { $status_slugs = wp_list_pluck( $this->get_custom_statuses(), 'slug' ); - list($permalink, $post_name) = get_sample_permalink($post->ID, $new_title, $new_slug); - - $view_link = false; - $preview_target = ''; - - if ( current_user_can( 'read_post', $post_id ) ) { - if ( in_array( $post->post_status, $status_slugs ) ) { - $view_link = $this->get_preview_link( $post ); - $preview_target = " target='wp-preview-{$post->ID}'"; - } else { - if ( 'publish' === $post->post_status || 'attachment' === $post->post_type ) { - $view_link = get_permalink( $post ); - } else { - // Allow non-published (private, future) to be viewed at a pretty permalink. - $view_link = str_replace( array( '%pagename%', '%postname%' ), $post->post_name, $permalink ); - } - } + if ( ! in_array( $post->post_status, $status_slugs ) + || ! in_array( $post->post_type, $this->get_post_types_for_module( $this->module ) ) ) { + return $permalink; } - // Permalinks without a post/page name placeholder don't have anything to edit - if ( false === strpos( $permalink, '%postname%' ) && false === strpos( $permalink, '%pagename%' ) ) { - $return = '' . __( 'Permalink:' ) . "\n"; - - if ( false !== $view_link ) { - $display_link = urldecode( $view_link ); - $return .= '' . $display_link . "\n"; - } else { - $return .= '' . $permalink . "\n"; - } - - // Encourage a pretty permalink setting - if ( '' == get_option( 'permalink_structure' ) && current_user_can( 'manage_options' ) && !( 'page' == get_option('show_on_front') && $id == get_option('page_on_front') ) ) { - $return .= '' . __('Change Permalinks') . "\n"; - } - } else { - if ( function_exists( 'mb_strlen' ) ) { - if ( mb_strlen( $post_name ) > 34 ) { - $post_name_abridged = mb_substr( $post_name, 0, 16 ) . '…' . mb_substr( $post_name, -16 ); - } else { - $post_name_abridged = $post_name; - } - } else { - if ( strlen( $post_name ) > 34 ) { - $post_name_abridged = substr( $post_name, 0, 16 ) . '…' . substr( $post_name, -16 ); - } else { - $post_name_abridged = $post_name; - } - } + remove_filter( 'get_sample_permalink_html', array( $this, 'fix_get_sample_permalink_html' ), 10, 5 ); - $post_name_html = '' . $post_name_abridged . ''; - $display_link = str_replace( array( '%pagename%', '%postname%' ), $post_name_html, urldecode( $permalink ) ); + $post->post_status = 'draft'; + $sample_permalink_html = get_sample_permalink_html( $post, $new_title, $new_slug ); - $return = '' . __( 'Permalink:' ) . "\n"; - $return .= '' . $display_link . "\n"; - $return .= '‎'; // Fix bi-directional text display defect in RTL languages. - $return .= '\n"; - $return .= '' . $post_name . "\n"; - } + add_filter( 'get_sample_permalink_html', array( $this, 'fix_get_sample_permalink_html' ), 10, 5 ); - return $return; + return $sample_permalink_html; } diff --git a/tests/test-edit-flow-custom-status.php b/tests/test-edit-flow-custom-status.php index 291ce2580..dd79a05f1 100644 --- a/tests/test-edit-flow-custom-status.php +++ b/tests/test-edit-flow-custom-status.php @@ -372,4 +372,488 @@ public function test_ensure_post_state_is_skipped_when_filtered() { $post_states = apply_filters( 'display_post_states', array(), get_post( $post ) ); $this->assertFalse( array_key_exists( 'pitch', $post_states ) ); } + + /** + * When a post with a custom status is inserted, post_name should remain empty + */ + public function test_post_with_custom_status_post_name_not_set() { + $post = array( + 'post_type' => 'post', + 'post_title' => 'Post', + 'post_status' => 'pitch', + 'post_author' => self::$admin_user_id, + ); + + $post_id = wp_insert_post( $post ); + + $post_inserted = get_post( $post_id ); + + wp_delete_post( $post_id, true ); + + $this->assertEmpty( $post_inserted->post_name ); + } + + /** + * When a post with a custom status that replaces a core status is inserted, post_name should remain empty + */ + public function test_post_with_custom_status_replacing_core_status_post_name_not_set() { + $post = array( + 'post_type' => 'post', + 'post_title' => 'Post', + 'post_status' => 'draft', + 'post_author' => self::$admin_user_id, + ); + + $post_id = wp_insert_post( $post ); + + $post_inserted = get_post( $post_id ); + + wp_delete_post( $post_id, true ); + + $this->assertEmpty( $post_inserted->post_name ); + } + + /** + * When a post with a "scheduled" status is inserted, post_name should be set + */ + public function test_post_with_scheduled_status_post_name_not_set() { + $post = array( + 'post_type' => 'post', + 'post_title' => 'Post', + 'post_status' => 'future', + 'post_author' => self::$admin_user_id, + ); + + $post_id = wp_insert_post( $post ); + + $post_inserted = get_post( $post_id ); + + wp_delete_post( $post_id, true ); + + $this->assertNotEmpty( $post_inserted->post_name ); + } + + /** + * When a post with a "publish" status is inserted, post_name should be set + */ + public function test_post_with_publish_status_post_name_is_set() { + $post = array( + 'post_type' => 'post', + 'post_title' => 'Post', + 'post_status' => 'publish', + 'post_author' => self::$admin_user_id, + ); + + $post_id = wp_insert_post( $post ); + + $post_inserted = get_post( $post_id ); + + wp_delete_post( $post_id, true ); + + $this->assertNotEmpty( $post_inserted->post_name ); + } + + /** + * When a page with a custom status is inserted, post_name should remain empty + */ + public function test_page_with_custom_status_post_name_not_set() { + $post = array( + 'post_type' => 'page', + 'post_title' => 'Page', + 'post_status' => 'pitch', + 'post_author' => self::$admin_user_id, + ); + + $post_id = wp_insert_post( $post ); + + $post_inserted = get_post( $post_id ); + + wp_delete_post( $post_id, true ); + + $this->assertEmpty( $post_inserted->post_name ); + } + + /** + * When a page with a custom status that replaces a core status is inserted, post_name should remain empty + */ + public function test_page_with_custom_status_replacing_core_status_post_name_not_set() { + $post = array( + 'post_type' => 'page', + 'post_title' => 'Page', + 'post_status' => 'draft', + 'post_author' => self::$admin_user_id, + ); + + $post_id = wp_insert_post( $post ); + + $post_inserted = get_post( $post_id ); + + wp_delete_post( $post_id, true ); + + $this->assertEmpty( $post_inserted->post_name ); + } + + /** + * When a page with a "scheduled" status is inserted, post_name should be set + */ + public function test_page_with_scheduled_status_post_name_not_set() { + $post = array( + 'post_type' => 'page', + 'post_title' => 'Page', + 'post_status' => 'future', + 'post_author' => self::$admin_user_id, + ); + + $post_id = wp_insert_post( $post ); + + $post_inserted = get_post( $post_id ); + + wp_delete_post( $post_id, true ); + + $this->assertNotEmpty( $post_inserted->post_name ); + } + + /** + * When a post with a "publish" status is inserted, post_name should be set + */ + public function test_page_with_publish_status_post_name_is_set() { + $post = array( + 'post_type' => 'page', + 'post_title' => 'Page', + 'post_status' => 'publish', + 'post_author' => self::$admin_user_id, + ); + + $post_id = wp_insert_post( $post ); + + $post_inserted = get_post( $post_id ); + + wp_delete_post( $post_id, true ); + + $this->assertNotEmpty( $post_inserted->post_name ); + } + + /** + * When a post with a custom status is updated, post_name should remain empty + */ + public function test_post_with_custom_status_updated_post_name_not_set() { + $post = array( + 'post_type' => 'post', + 'post_title' => 'Post', + 'post_status' => 'pitch', + 'post_author' => self::$admin_user_id, + ); + + $post_id = wp_insert_post( $post ); + + $post_inserted = get_post( $post_id ); + + wp_insert_post( array_merge( $post, array( 'post_title' => 'New Post' ) ) ); + + wp_delete_post( $post_id, true ); + + $this->assertEmpty( $post_inserted->post_name ); + } + + /** + * When a post with a custom status replacing a core status is updated, post_name should remain empty + */ + public function test_post_with_custom_status_replacing_core_status_updated_post_name_not_set() { + $post = array( + 'post_type' => 'post', + 'post_title' => 'Post', + 'post_status' => 'draft', + 'post_author' => self::$admin_user_id, + ); + + $post_id = wp_insert_post( $post ); + + $post_inserted = get_post( $post_id ); + + wp_insert_post( array_merge( $post, array( 'post_title' => 'New Post' ) ) ); + + wp_delete_post( $post_id, true ); + + $this->assertEmpty( $post_inserted->post_name ); + } + + /** + * When a post with a "publish" status is updated, post_name should not change + */ + public function test_post_with_publish_status_updated_post_name_does_not_change() { + $post = array( + 'post_type' => 'post', + 'post_title' => 'Post', + 'post_status' => 'publish', + 'post_author' => self::$admin_user_id, + ); + + $post_id = wp_insert_post( $post ); + + $post_inserted = get_post( $post_id ); + + wp_insert_post( array_merge( $post_inserted->to_array(), array( 'post_title' => 'New Post' ) ) ); + + $post_updated = get_post( $post_id ); + + wp_delete_post( $post_id, true ); + + $this->assertEquals( $post_inserted->post_name, $post_updated->post_name ); + } + + /** + * When a post with a "publish" status is updated and post name is explicitly set, post_name should change + */ + public function test_post_with_publish_status_updated_post_name_set_post_name_should_change() { + $post = array( + 'post_type' => 'post', + 'post_title' => 'Post', + 'post_status' => 'publish', + 'post_author' => self::$admin_user_id, + ); + + $post_id = wp_insert_post( $post ); + + $post_inserted = get_post( $post_id ); + + wp_insert_post( array_merge( $post_inserted->to_array(), array( 'post_name' => 'a-new-slug' ) ) ); + + $post_updated = get_post( $post_id ); + + wp_delete_post( $post_id, true ); + + $this->assertNotEquals( $post_inserted->post_name, $post_updated->post_name ); + } + + /** + * When a request with the REST API is made to create a post with a custom status, + * the post name should not be set + */ + public function test_post_with_custom_status_post_name_not_set_rest_api() { + wp_set_current_user( self::$admin_user_id ); + + $request = new WP_REST_Request( 'POST', '/wp/v2/posts' ); + $request->add_header( 'content-type', 'application/x-www-form-urlencoded' ); + $params = array( + 'title' => 'Post title', + 'content' => 'Post content', + 'status' => 'pitch', + 'author' => self::$admin_user_id, + 'type' => 'post', + ); + $request->set_body_params( $params ); + $response = rest_get_server()->dispatch( $request ); + + $data = $response->get_data(); + $post = get_post( $data['id'] ); + + $this->assertEmpty( $post->post_name ); + } + + /** + * When a request with the REST API is made to create a post with a custom status that replaces a core status, + * the post name should not be set + */ + public function test_post_with_custom_status_replacing_core_status_post_name_not_set_rest_api() { + wp_set_current_user( self::$admin_user_id ); + + $request = new WP_REST_Request( 'POST', '/wp/v2/posts' ); + $request->add_header( 'content-type', 'application/x-www-form-urlencoded' ); + $params = array( + 'title' => 'Post title', + 'content' => 'Post content', + 'status' => 'draft', + 'author' => self::$admin_user_id, + 'type' => 'post', + ); + $request->set_body_params( $params ); + $response = rest_get_server()->dispatch( $request ); + + $data = $response->get_data(); + $post = get_post( $data['id'] ); + + $this->assertEmpty( $post->post_name ); + } + + /** + * When a request with the REST API is made to update a post with a custom status, + * the post name should not be set + */ + public function test_post_with_custom_status_updated_post_name_not_set_rest_api() { + wp_set_current_user( self::$admin_user_id ); + + $request = new WP_REST_Request( 'POST', '/wp/v2/posts' ); + $request->add_header( 'content-type', 'application/x-www-form-urlencoded' ); + $params = array( + 'title' => 'Post title', + 'content' => 'Post content', + 'status' => 'pitch', + 'author' => self::$admin_user_id, + 'type' => 'post', + ); + $request->set_body_params( $params ); + $response = rest_get_server()->dispatch( $request ); + $data = $response->get_data(); + + $update_request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', $data['id'] ) ); + $update_request->add_header( 'content-type', 'application/x-www-form-urlencoded' ); + $update_params = array( + 'title' => 'Post title new', + 'content' => 'Post content new', + 'status' => 'pitch', + 'author' => self::$admin_user_id, + 'type' => 'post', + ); + + $update_request->set_body_params( $update_params ); + $update_response = rest_get_server()->dispatch( $update_request ); + + $updated_data = $update_response->get_data(); + $updated_post = get_post( $updated_data['id'] ); + + $this->assertEmpty( $updated_post->post_name ); + } + + /** + * When a request with the REST API is made to create a post with a "publish" status, + * the post name should be set + */ + public function test_post_with_publish_status_post_name_set_rest_api() { + wp_set_current_user( self::$admin_user_id ); + + $request = new WP_REST_Request( 'POST', '/wp/v2/posts' ); + $request->add_header( 'content-type', 'application/x-www-form-urlencoded' ); + $params = array( + 'title' => 'Post title', + 'content' => 'Post content', + 'status' => 'publish', + 'author' => self::$admin_user_id, + 'type' => 'post', + ); + + $request->set_body_params( $params ); + $response = rest_get_server()->dispatch( $request ); + + $data = $response->get_data(); + $post = get_post( $data['id'] ); + + $this->assertNotEmpty( $post->post_name ); + } + + /** + * When a request with the REST API is made to create a post with a custom status, and the the post_name is set, + * if the post is updated the post_name should remain the same + */ + public function test_post_with_custom_status_set_post_name_stays_set_rest_api() { + wp_set_current_user( self::$admin_user_id ); + + $custom_post_name = 'a-post-name'; + + $p = self::factory()->post->create( + array( + 'post_status' => 'pitch', + 'post_author' => self::$admin_user_id , + ) + ); + + $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', $p ) ); + $request->add_header( 'content-type', 'application/x-www-form-urlencoded' ); + $params = array( + 'title' => 'Post title new', + 'content' => 'Post content new', + 'slug' => $custom_post_name, + 'status' => 'pitch', + 'author' => self::$admin_user_id, + 'type' => 'post', + ); + $request->set_body_params( $params ); + rest_get_server()->dispatch( $request ); + + $update_request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', $p ) ); + $update_request->add_header( 'content-type', 'application/x-www-form-urlencoded' ); + $update_params = array( + 'title' => 'Post title new', + 'content' => 'Post content new', + 'status' => 'pitch', + 'author' => self::$admin_user_id, + 'type' => 'post', + ); + $update_request->set_body_params( $update_params ); + $update_response = rest_get_server()->dispatch( $update_request ); + + $update_data = $update_response->get_data(); + $update_post = get_post( $update_data['id'] ); + + $this->assertEquals( $custom_post_name, $update_post->post_name ); + } + + /** + * When a request with the REST API is made to create a page with a custom status, + * the page name should not be set + */ + public function test_page_with_custom_status_post_name_not_set_rest_api() { + wp_set_current_user( self::$admin_user_id ); + + $request = new WP_REST_Request( 'POST', '/wp/v2/pages' ); + $request->add_header( 'content-type', 'application/x-www-form-urlencoded' ); + $params = array( + 'title' => 'Page title', + 'content' => 'Page content', + 'status' => 'pitch', + 'author' => self::$admin_user_id, + 'type' => 'page', + ); + $request->set_body_params( $params ); + $response = rest_get_server()->dispatch( $request ); + + $data = $response->get_data(); + $post = get_post( $data['id'] ); + + $this->assertEmpty( $post->post_name ); + } + + /** + * When a request with the REST API is made to create a page with a custom status, and the the post_name is set, + * if the page is updated the post_name should remain the same + */ + public function test_page_with_custom_status_set_post_name_stays_set_rest_api() { + wp_set_current_user( self::$admin_user_id ); + + $custom_post_name = 'a-page-name'; + + $p = self::factory()->post->create( + array( + 'title' => 'Page title new', + 'content' => 'Page content new', + 'post_status' => 'pitch', + 'post_type' => 'page', + ) + ); + + $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/pages/%d', $p ) ); + $request->add_header( 'content-type', 'application/x-www-form-urlencoded' ); + $params = array( + 'title' => 'Page title new', + 'content' => 'Page content new', + 'slug' => $custom_post_name, + 'status' => 'pitch', + ); + $request->set_body_params( $params ); + rest_get_server()->dispatch( $request ); + + $update_request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/pages/%d', $p ) ); + $update_request->add_header( 'content-type', 'application/x-www-form-urlencoded' ); + $update_params = array( + 'title' => 'Page title new', + 'content' => 'Page content new', + 'status' => 'pitch', + ); + $update_request->set_body_params( $update_params ); + $update_response = rest_get_server()->dispatch( $update_request ); + + $update_data = $update_response->get_data(); + $update_post = get_post( $update_data['id'] ); + + $this->assertEquals( $custom_post_name, $update_post->post_name ); + } }