From ce7a93c235fbc42b68e65bf799d94a14eba67e3e Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 17 Oct 2017 20:14:56 +0000 Subject: [PATCH] Customize: Allow post/page stubs to be edited in WP Admin as "customization drafts" when changeset is saved as draft or scheduled. * Update stubs to have draft status when changeset is saved as draft, instead of preventing auto-draft garbage collection by giving them a far-future `post_date`. * Show notice in publish metabox when editing a customization draft indicating that it will be published automatically with its changeset; a link to Customizer is included. * Include a new "Customization Draft" display post state in the post list table. * Disconnect stubs from their changesets when they are updated with a status other than "Draft". * Trash customization drafts when their related changeset is trashed or deleted. * Add a `_customize_changeset_uuid` postmeta to stubs to link them with their associated changeset. * Include `customize_changeset_uuid` as context when requesting to insert a new auto-draft. Props westonruter, melchoyce. See #39896, #39752, #34923. Fixes #42220. git-svn-id: https://develop.svn.wordpress.org/trunk@41887 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/css/common.css | 5 + src/wp-admin/includes/meta-boxes.php | 20 ++++ src/wp-admin/includes/template.php | 11 ++- src/wp-admin/js/customize-nav-menus.js | 1 + .../class-wp-customize-nav-menus.php | 16 +++- src/wp-includes/nav-menu.php | 12 ++- src/wp-includes/theme.php | 51 +++++++--- tests/phpunit/tests/ajax/CustomizeMenus.php | 1 + tests/phpunit/tests/customize/nav-menus.php | 94 ++++++++++++++++--- tests/phpunit/tests/post/nav-menu.php | 24 ++++- tests/phpunit/tests/theme.php | 31 +++++- 11 files changed, 225 insertions(+), 41 deletions(-) diff --git a/src/wp-admin/css/common.css b/src/wp-admin/css/common.css index f0c0b0ae6f..a0beadd330 100644 --- a/src/wp-admin/css/common.css +++ b/src/wp-admin/css/common.css @@ -964,6 +964,11 @@ th.action-links { text-align: right; } +#misc-publishing-actions .notice { + margin-left: 10px; + margin-right: 10px; +} + /* Filter bar */ .wp-filter { display: inline-block; diff --git a/src/wp-admin/includes/meta-boxes.php b/src/wp-admin/includes/meta-boxes.php index aff859e5c0..4780fefb84 100644 --- a/src/wp-admin/includes/meta-boxes.php +++ b/src/wp-admin/includes/meta-boxes.php @@ -223,6 +223,26 @@ if ( $can_publish ) : // Contributors don't get to choose the date of publish ?> +post_status && get_post_meta( $post->ID, '_customize_changeset_uuid', true ) ) : ?> +
+

+ unpublished customization changes. You can edit, but there’s no need to publish now. It will be published automatically with those changes.' ), + esc_url( + add_query_arg( + 'changeset_uuid', + rawurlencode( get_post_meta( $post->ID, '_customize_changeset_uuid', true ) ), + admin_url( 'customize.php' ) + ) + ) + ); + ?> +

+
+ + post_status && 'private' != $post_status ) $post_states['private'] = __('Private'); - if ( 'draft' == $post->post_status && 'draft' != $post_status ) - $post_states['draft'] = __('Draft'); + if ( 'draft' === $post->post_status ) { + if ( get_post_meta( $post->ID, '_customize_changeset_uuid', true ) ) { + $post_states[] = __( 'Customization Draft' ); + } elseif ( 'draft' !== $post_status ) { + $post_states['draft'] = __( 'Draft' ); + } + } elseif ( 'trash' === $post->post_status && get_post_meta( $post->ID, '_customize_changeset_uuid', true ) ) { + $post_states[] = __( 'Customization Draft' ); + } if ( 'pending' == $post->post_status && 'pending' != $post_status ) $post_states['pending'] = _x('Pending', 'post status'); if ( is_sticky($post->ID) ) diff --git a/src/wp-admin/js/customize-nav-menus.js b/src/wp-admin/js/customize-nav-menus.js index 84a5447ed4..6ca5daba46 100644 --- a/src/wp-admin/js/customize-nav-menus.js +++ b/src/wp-admin/js/customize-nav-menus.js @@ -97,6 +97,7 @@ request = wp.ajax.post( 'customize-nav-menus-insert-auto-draft', { 'customize-menus-nonce': api.settings.nonce['customize-menus'], 'wp_customize': 'on', + 'customize_changeset_uuid': api.settings.changeset.uuid, 'params': params } ); diff --git a/src/wp-includes/class-wp-customize-nav-menus.php b/src/wp-includes/class-wp-customize-nav-menus.php index 7b14412780..2e76097578 100644 --- a/src/wp-includes/class-wp-customize-nav-menus.php +++ b/src/wp-includes/class-wp-customize-nav-menus.php @@ -794,6 +794,10 @@ final class WP_Customize_Nav_Menus { return new WP_Error( 'status_forbidden', __( 'Status is forbidden' ) ); } + /* + * If the changeset is a draft, this will change to draft the next time the changeset + * is updated; otherwise, auto-draft will persist in autosave revisions, until save. + */ $postarr['post_status'] = 'auto-draft'; // Auto-drafts are allowed to have empty post_names, so it has to be explicitly set. @@ -804,6 +808,7 @@ final class WP_Customize_Nav_Menus { $postarr['meta_input'] = array(); } $postarr['meta_input']['_customize_draft_post_name'] = $postarr['post_name']; + $postarr['meta_input']['_customize_changeset_uuid'] = $this->manager->changeset_uuid(); unset( $postarr['post_name'] ); add_filter( 'wp_insert_post_empty_content', '__return_false', 1000 ); @@ -1172,7 +1177,7 @@ final class WP_Customize_Nav_Menus { } /** - * Sanitize post IDs for auto-draft posts created for nav menu items to be published. + * Sanitize post IDs for posts created for nav menu items to be published. * * @since 4.7.0 * @@ -1186,7 +1191,7 @@ final class WP_Customize_Nav_Menus { continue; } $post = get_post( $post_id ); - if ( 'auto-draft' !== $post->post_status ) { + if ( 'auto-draft' !== $post->post_status && 'draft' !== $post->post_status ) { continue; } $post_type_obj = get_post_type_object( $post->post_type ); @@ -1217,6 +1222,13 @@ final class WP_Customize_Nav_Menus { $post_ids = $setting->post_value(); if ( ! empty( $post_ids ) ) { foreach ( $post_ids as $post_id ) { + + // Prevent overriding the status that a user may have prematurely updated the post to. + $current_status = get_post_status( $post_id ); + if ( 'auto-draft' !== $current_status && 'draft' !== $current_status ) { + continue; + } + $target_status = 'attachment' === get_post_type( $post_id ) ? 'inherit' : 'publish'; $args = array( 'ID' => $post_id, diff --git a/src/wp-includes/nav-menu.php b/src/wp-includes/nav-menu.php index aff8a54373..a9c2bd35f3 100644 --- a/src/wp-includes/nav-menu.php +++ b/src/wp-includes/nav-menu.php @@ -1051,9 +1051,15 @@ function _wp_delete_customize_changeset_dependent_auto_drafts( $post_id ) { return; } remove_action( 'delete_post', '_wp_delete_customize_changeset_dependent_auto_drafts' ); - foreach ( $data['nav_menus_created_posts']['value'] as $post_id ) { - if ( ! empty( $post_id ) && 'auto-draft' === get_post_status( $post_id ) ) { - wp_delete_post( $post_id, true ); + foreach ( $data['nav_menus_created_posts']['value'] as $stub_post_id ) { + if ( empty( $stub_post_id ) ) { + continue; + } + if ( 'auto-draft' === get_post_status( $stub_post_id ) ) { + wp_delete_post( $stub_post_id, true ); + } elseif ( 'draft' === get_post_status( $stub_post_id ) ) { + wp_trash_post( $stub_post_id ); + delete_post_meta( $stub_post_id, '_customize_changeset_uuid' ); } } add_action( 'delete_post', '_wp_delete_customize_changeset_dependent_auto_drafts' ); diff --git a/src/wp-includes/theme.php b/src/wp-includes/theme.php index ff9cf0d31e..66390ff2bf 100644 --- a/src/wp-includes/theme.php +++ b/src/wp-includes/theme.php @@ -3051,7 +3051,7 @@ function is_customize_preview() { } /** - * Make sure that auto-draft posts get their post_date bumped to prevent premature garbage-collection. + * Make sure that auto-draft posts get their post_date bumped or status changed to draft to prevent premature garbage-collection. * * When a changeset is updated but remains an auto-draft, ensure the post_date * for the auto-draft posts remains the same so that it will be @@ -3060,6 +3060,14 @@ function is_customize_preview() { * to have a far-future post_date so that they will never be garbage collected * unless the changeset post itself is deleted. * + * When a changeset is updated to be a persistent draft or to be scheduled for + * publishing, then transition any dependent auto-drafts to a draft status so + * that they likewise will not be garbage-collected but also so that they can + * be edited in the admin before publishing since there is not yet a post/page + * editing flow in the Customizer. See #39752. + * + * @link https://core.trac.wordpress.org/ticket/39752 + * * @since 4.8.0 * @access private * @see wp_delete_auto_drafts() @@ -3078,34 +3086,55 @@ function _wp_keep_alive_customize_changeset_dependent_auto_drafts( $new_status, return; } + $data = json_decode( $post->post_content, true ); + if ( empty( $data['nav_menus_created_posts']['value'] ) ) { + return; + } + + /* + * Actually, in lieu of keeping alive, trash any customization drafts here if the changeset itself is + * getting trashed. This is needed because when a changeset transitions to a draft, then any of the + * dependent auto-draft post/page stubs will also get transitioned to customization drafts which + * are then visible in the WP Admin. We cannot wait for the deletion of the changeset in which + * _wp_delete_customize_changeset_dependent_auto_drafts() will be called, since they need to be + * trashed to remove from visibility immediately. + */ + if ( 'trash' === $new_status ) { + foreach ( $data['nav_menus_created_posts']['value'] as $post_id ) { + if ( ! empty( $post_id ) && 'draft' === get_post_status( $post_id ) ) { + wp_trash_post( $post_id ); + } + } + return; + } + + $post_args = array(); if ( 'auto-draft' === $new_status ) { /* * Keep the post date for the post matching the changeset * so that it will not be garbage-collected before the changeset. */ - $new_post_date = $post->post_date; + $post_args['post_date'] = $post->post_date; // Note wp_delete_auto_drafts() only looks at this date. } else { /* * Since the changeset no longer has an auto-draft (and it is not published) * it is now a persistent changeset, a long-lived draft, and so any - * associated auto-draft posts should have their dates - * pushed out very far into the future to prevent them from ever - * being garbage-collected. + * associated auto-draft posts should likewise transition into having a draft + * status. These drafts will be treated differently than regular drafts in + * that they will be tied to the given changeset. The publish metabox is + * replaced with a notice about how the post is part of a set of customized changes + * which will be published when the changeset is published. */ - $new_post_date = gmdate( 'Y-m-d H:i:d', strtotime( '+100 years' ) ); + $post_args['post_status'] = 'draft'; } - $data = json_decode( $post->post_content, true ); - if ( empty( $data['nav_menus_created_posts']['value'] ) ) { - return; - } foreach ( $data['nav_menus_created_posts']['value'] as $post_id ) { if ( empty( $post_id ) || 'auto-draft' !== get_post_status( $post_id ) ) { continue; } $wpdb->update( $wpdb->posts, - array( 'post_date' => $new_post_date ), // Note wp_delete_auto_drafts() only looks at this date. + $post_args, array( 'ID' => $post_id ) ); clean_post_cache( $post_id ); diff --git a/tests/phpunit/tests/ajax/CustomizeMenus.php b/tests/phpunit/tests/ajax/CustomizeMenus.php index 7dc2bf1f7a..98293087d0 100644 --- a/tests/phpunit/tests/ajax/CustomizeMenus.php +++ b/tests/phpunit/tests/ajax/CustomizeMenus.php @@ -603,6 +603,7 @@ class Tests_Ajax_CustomizeMenus extends WP_Ajax_UnitTestCase { $this->assertEquals( 'post', $post->post_type ); $this->assertEquals( '', $post->post_name ); $this->assertEquals( 'hello-world', get_post_meta( $post->ID, '_customize_draft_post_name', true ) ); + $this->assertEquals( $this->wp_customize->changeset_uuid(), get_post_meta( $post->ID, '_customize_changeset_uuid', true ) ); } /** diff --git a/tests/phpunit/tests/customize/nav-menus.php b/tests/phpunit/tests/customize/nav-menus.php index 393790af43..aefb373737 100644 --- a/tests/phpunit/tests/customize/nav-menus.php +++ b/tests/phpunit/tests/customize/nav-menus.php @@ -541,6 +541,7 @@ class Test_WP_Customize_Nav_Menus extends WP_UnitTestCase { // Non-existent post types allowed as of #39610. $r = $menus->insert_auto_draft_post( array( 'post_title' => 'Non-existent', 'post_type' => 'nonexistent' ) ); $this->assertInstanceOf( 'WP_Post', $r ); + $this->assertEquals( $this->wp_customize->changeset_uuid(), get_post_meta( $r->ID, '_customize_changeset_uuid', true ) ); $r = $menus->insert_auto_draft_post( array( 'post_type' => 'post' ) ); $this->assertInstanceOf( 'WP_Error', $r ); @@ -555,6 +556,7 @@ class Test_WP_Customize_Nav_Menus extends WP_UnitTestCase { $this->assertEquals( 'Hello World', $r->post_title ); $this->assertEquals( '', $r->post_name ); $this->assertEquals( 'hello-world', get_post_meta( $r->ID, '_customize_draft_post_name', true ) ); + $this->assertEquals( $this->wp_customize->changeset_uuid(), get_post_meta( $r->ID, '_customize_changeset_uuid', true ) ); $this->assertEquals( 'post', $r->post_type ); $r = $menus->insert_auto_draft_post( array( 'post_title' => 'Hello World', 'post_type' => 'post', 'post_name' => 'greetings-world', 'post_content' => 'Hi World' ) ); @@ -563,6 +565,7 @@ class Test_WP_Customize_Nav_Menus extends WP_UnitTestCase { $this->assertEquals( 'post', $r->post_type ); $this->assertEquals( '', $r->post_name ); $this->assertEquals( 'greetings-world', get_post_meta( $r->ID, '_customize_draft_post_name', true ) ); + $this->assertEquals( $this->wp_customize->changeset_uuid(), get_post_meta( $r->ID, '_customize_changeset_uuid', true ) ); $this->assertEquals( 'Hi World', $r->post_content ); } @@ -716,11 +719,25 @@ class Test_WP_Customize_Nav_Menus extends WP_UnitTestCase { 'post_author' => $administrator_user_id, ) ); + $draft_post_id = $this->factory()->post->create( array( + 'post_status' => 'draft', + 'post_title' => 'Draft', + 'post_author' => $administrator_user_id, + ) ); + + $private_post_id = $this->factory()->post->create( array( + 'post_status' => 'private', + 'post_title' => 'Private', + 'post_author' => $administrator_user_id, + ) ); + $value = array( 'bad', $contributor_post_id, $author_post_id, $administrator_post_id, + $draft_post_id, + $private_post_id, ); wp_set_current_user( $contributor_user_id ); @@ -733,7 +750,7 @@ class Test_WP_Customize_Nav_Menus extends WP_UnitTestCase { wp_set_current_user( $administrator_user_id ); $sanitized = $menus->sanitize_nav_menus_created_posts( $value ); - $this->assertEquals( array( $contributor_post_id, $author_post_id, $administrator_post_id ), $sanitized ); + $this->assertEquals( array( $contributor_post_id, $author_post_id, $administrator_post_id, $draft_post_id ), $sanitized ); } /** @@ -746,15 +763,55 @@ class Test_WP_Customize_Nav_Menus extends WP_UnitTestCase { do_action( 'customize_register', $this->wp_customize ); $post_ids = array(); - for ( $i = 0; $i < 3; $i += 1 ) { - $r = $menus->insert_auto_draft_post( array( - 'post_title' => 'Auto Draft ' . $i, - 'post_type' => 'post', - 'post_name' => 'auto-draft-' . $i, - ) ); - $this->assertInstanceOf( 'WP_Post', $r ); - $post_ids[] = $r->ID; - } + + // Auto-draft. + $r = $menus->insert_auto_draft_post( array( + 'post_title' => 'Auto Draft', + 'post_type' => 'post', + 'post_name' => 'auto-draft-1', + ) ); + $this->assertInstanceOf( 'WP_Post', $r ); + $post_ids[] = $r->ID; + + // Draft. + $r = $menus->insert_auto_draft_post( array( + 'post_title' => 'Draft', + 'post_type' => 'post', + 'post_name' => 'auto-draft-2', + ) ); + $this->assertInstanceOf( 'WP_Post', $r ); + wp_update_post( array( + 'ID' => $r->ID, + 'post_status' => 'draft', + ) ); + $post_ids[] = $r->ID; + + $drafted_post_ids = $post_ids; + + // Private (this will exclude it from being considered a stub). + $r = $menus->insert_auto_draft_post( array( + 'post_title' => 'Private', + 'post_type' => 'post', + 'post_name' => 'auto-draft-3', + ) ); + $this->assertInstanceOf( 'WP_Post', $r ); + wp_update_post( array( + 'ID' => $r->ID, + 'post_status' => 'private', + ) ); + $post_ids[] = $r->ID; + $private_post_id = $r->ID; + + // Trashed (this will exclude it from being considered a stub). + $r = $menus->insert_auto_draft_post( array( + 'post_title' => 'Trash', + 'post_type' => 'post', + 'post_name' => 'auto-draft-4', + ) ); + $this->assertInstanceOf( 'WP_Post', $r ); + wp_trash_post( $r->ID ); + $post_ids[] = $r->ID; + $trashed_post_id = $r->ID; $pre_published_post_id = $this->factory()->post->create( array( 'post_status' => 'publish' ) ); @@ -763,9 +820,13 @@ class Test_WP_Customize_Nav_Menus extends WP_UnitTestCase { $setting = $this->wp_customize->get_setting( $setting_id ); $this->assertInstanceOf( 'WP_Customize_Filter_Setting', $setting ); $this->assertEquals( array( $menus, 'sanitize_nav_menus_created_posts' ), $setting->sanitize_callback ); - $this->assertEquals( $post_ids, $setting->post_value() ); - foreach ( $post_ids as $post_id ) { - $this->assertEquals( 'auto-draft', get_post_status( $post_id ) ); + $this->assertEquals( $drafted_post_ids, $setting->post_value() ); + $this->assertArrayNotHasKey( $private_post_id, $post_ids ); + $this->assertArrayNotHasKey( $trashed_post_id, $post_ids ); + + $this->assertEquals( 'auto-draft', get_post_status( $drafted_post_ids[0] ) ); + $this->assertEquals( 'draft', get_post_status( $drafted_post_ids[1] ) ); + foreach ( $drafted_post_ids as $post_id ) { $this->assertEmpty( get_post( $post_id )->post_name ); $this->assertNotEmpty( get_post_meta( $post_id, '_customize_draft_post_name', true ) ); } @@ -773,14 +834,17 @@ class Test_WP_Customize_Nav_Menus extends WP_UnitTestCase { $save_action_count = did_action( 'customize_save_nav_menus_created_posts' ); $setting->save(); $this->assertEquals( $save_action_count + 1, did_action( 'customize_save_nav_menus_created_posts' ) ); - foreach ( $post_ids as $post_id ) { + foreach ( $drafted_post_ids as $post_id ) { $this->assertEquals( 'publish', get_post_status( $post_id ) ); $this->assertRegExp( '/^auto-draft-\d+$/', get_post( $post_id )->post_name ); $this->assertEmpty( get_post_meta( $post_id, '_customize_draft_post_name', true ) ); } + $this->assertEquals( 'private', get_post_status( $private_post_id ) ); + $this->assertEquals( 'trash', get_post_status( $trashed_post_id ) ); + // Ensure that unique slugs were assigned. - $posts = array_map( 'get_post', $post_ids ); + $posts = array_map( 'get_post', $drafted_post_ids ); $post_names = wp_list_pluck( $posts, 'post_name' ); $this->assertEqualSets( $post_names, array_unique( $post_names ) ); } diff --git a/tests/phpunit/tests/post/nav-menu.php b/tests/phpunit/tests/post/nav-menu.php index 47194f5222..86676e6fe1 100644 --- a/tests/phpunit/tests/post/nav-menu.php +++ b/tests/phpunit/tests/post/nav-menu.php @@ -549,9 +549,21 @@ class Test_Nav_Menus extends WP_UnitTestCase { * @covers _wp_delete_customize_changeset_dependent_auto_drafts() */ function test_wp_delete_customize_changeset_dependent_auto_drafts() { - $nav_created_post_ids = $this->factory()->post->create_many(2, array( + $auto_draft_post_id = $this->factory()->post->create( array( 'post_status' => 'auto-draft', ) ); + $draft_post_id = $this->factory()->post->create( array( + 'post_status' => 'draft', + ) ); + $private_post_id = $this->factory()->post->create( array( + 'post_status' => 'private', + ) ); + + $nav_created_post_ids = array( + $auto_draft_post_id, + $draft_post_id, + $private_post_id, + ); $data = array( 'nav_menus_created_posts' => array( 'value' => $nav_created_post_ids, @@ -566,11 +578,13 @@ class Test_Nav_Menus extends WP_UnitTestCase { $wp_customize->save_changeset_post( array( 'data' => $data, ) ); - $this->assertInstanceOf( 'WP_Post', get_post( $nav_created_post_ids[0] ) ); - $this->assertInstanceOf( 'WP_Post', get_post( $nav_created_post_ids[1] ) ); + $this->assertEquals( 'auto-draft', get_post_status( $auto_draft_post_id ) ); + $this->assertEquals( 'draft', get_post_status( $draft_post_id ) ); + $this->assertEquals( 'private', get_post_status( $private_post_id ) ); wp_delete_post( $wp_customize->changeset_post_id(), true ); - $this->assertNotInstanceOf( 'WP_Post', get_post( $nav_created_post_ids[0] ) ); - $this->assertNotInstanceOf( 'WP_Post', get_post( $nav_created_post_ids[1] ) ); + $this->assertFalse( get_post_status( $auto_draft_post_id ) ); + $this->assertEquals( 'trash', get_post_status( $draft_post_id ) ); + $this->assertEquals( 'private', get_post_status( $private_post_id ) ); } /** diff --git a/tests/phpunit/tests/theme.php b/tests/phpunit/tests/theme.php index 3238f6edcb..8de690a185 100644 --- a/tests/phpunit/tests/theme.php +++ b/tests/phpunit/tests/theme.php @@ -318,6 +318,7 @@ class Tests_Theme extends WP_UnitTestCase { function test_wp_keep_alive_customize_changeset_dependent_auto_drafts() { $nav_created_post_ids = $this->factory()->post->create_many(2, array( 'post_status' => 'auto-draft', + 'post_date' => gmdate( 'Y-m-d H:i:s', strtotime( '-2 days' ) ), ) ); $data = array( 'nav_menus_created_posts' => array( @@ -328,17 +329,41 @@ class Tests_Theme extends WP_UnitTestCase { require_once ABSPATH . WPINC . '/class-wp-customize-manager.php'; $wp_customize = new WP_Customize_Manager(); do_action( 'customize_register', $wp_customize ); + + // The post_date for auto-drafts is bumped to match the changeset post_date whenever it is modified to keep them from from being garbage collected by wp_delete_auto_drafts(). $wp_customize->save_changeset_post( array( 'data' => $data, ) ); $this->assertEquals( get_post( $nav_created_post_ids[0] )->post_date, get_post( $wp_customize->changeset_post_id() )->post_date ); $this->assertEquals( get_post( $nav_created_post_ids[1] )->post_date, get_post( $wp_customize->changeset_post_id() )->post_date ); + $this->assertEquals( 'auto-draft', get_post_status( $nav_created_post_ids[0] ) ); + $this->assertEquals( 'auto-draft', get_post_status( $nav_created_post_ids[1] ) ); + + // Stubs transition to drafts when changeset is saved as a draft. $wp_customize->save_changeset_post( array( 'status' => 'draft', 'data' => $data, ) ); - $expected_year = date( 'Y' ) + 100; - $this->assertEquals( $expected_year, date( 'Y', strtotime( get_post( $nav_created_post_ids[0] )->post_date ) ) ); - $this->assertEquals( $expected_year, date( 'Y', strtotime( get_post( $nav_created_post_ids[1] )->post_date ) ) ); + $this->assertEquals( get_post( $nav_created_post_ids[0] )->post_date, get_post( $wp_customize->changeset_post_id() )->post_date ); + $this->assertEquals( get_post( $nav_created_post_ids[1] )->post_date, get_post( $wp_customize->changeset_post_id() )->post_date ); + $this->assertEquals( 'draft', get_post_status( $nav_created_post_ids[0] ) ); + $this->assertEquals( 'draft', get_post_status( $nav_created_post_ids[1] ) ); + + // Status remains unchanged for stub that the user broke out of the changeset. + wp_update_post( array( + 'ID' => $nav_created_post_ids[1], + 'post_status' => 'private', + ) ); + $wp_customize->save_changeset_post( array( + 'status' => 'draft', + 'data' => $data, + ) ); + $this->assertEquals( 'draft', get_post_status( $nav_created_post_ids[0] ) ); + $this->assertEquals( 'private', get_post_status( $nav_created_post_ids[1] ) ); + + // Draft stub is trashed when the changeset is trashed. + $wp_customize->trash_changeset_post( $wp_customize->changeset_post_id() ); + $this->assertEquals( 'trash', get_post_status( $nav_created_post_ids[0] ) ); + $this->assertEquals( 'private', get_post_status( $nav_created_post_ids[1] ) ); } }