From fade2c78137071ecb61845357dba220e10fde7bf Mon Sep 17 00:00:00 2001 From: chriszarate Date: Thu, 19 Feb 2026 09:19:17 -0500 Subject: [PATCH 1/2] Fix autosave controller tests --- .../rest-api/rest-autosaves-controller.php | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/tests/phpunit/tests/rest-api/rest-autosaves-controller.php b/tests/phpunit/tests/rest-api/rest-autosaves-controller.php index 7815f8ced23c9..0d10bf99b2ce1 100644 --- a/tests/phpunit/tests/rest-api/rest-autosaves-controller.php +++ b/tests/phpunit/tests/rest-api/rest-autosaves-controller.php @@ -570,6 +570,9 @@ public function test_rest_autosave_published_post() { } public function test_rest_autosave_draft_post_same_author() { + $original_option = get_option( 'enable_real_time_collaboration' ); + update_option( 'enable_real_time_collaboration', false ); + wp_set_current_user( self::$editor_id ); $post_data = array( @@ -604,6 +607,7 @@ public function test_rest_autosave_draft_post_same_author() { $this->assertSame( $post_data['post_excerpt'], $post->post_excerpt ); wp_delete_post( $post_id ); + update_option( 'enable_real_time_collaboration', $original_option ); } public function test_rest_autosave_draft_post_different_author() { @@ -744,6 +748,9 @@ public function test_get_item_sets_up_postdata() { } public function test_update_item_draft_page_with_parent() { + $original_option = get_option( 'enable_real_time_collaboration' ); + update_option( 'enable_real_time_collaboration', false ); + wp_set_current_user( self::$editor_id ); $request = new WP_REST_Request( 'POST', '/wp/v2/pages/' . self::$child_draft_page_id . '/autosaves' ); $request->add_header( 'Content-Type', 'application/x-www-form-urlencoded' ); @@ -761,6 +768,7 @@ public function test_update_item_draft_page_with_parent() { $this->assertSame( self::$child_draft_page_id, $data['id'] ); $this->assertSame( self::$parent_page_id, $data['parent'] ); + update_option( 'enable_real_time_collaboration', $original_option ); } public function test_schema_validation_is_applied() { @@ -920,4 +928,81 @@ public static function data_head_request_with_specified_fields_returns_success_r 'get_items request' => array( '/wp/v2/posts/%d' ), ); } + + /** + * When real-time collaboration is enabled, autosaving a draft post by the + * same author should create a revision instead of updating the post directly. + */ + public function test_rest_autosave_draft_post_same_author_with_rtc() { + $original_option = get_option( 'enable_real_time_collaboration' ); + update_option( 'enable_real_time_collaboration', true ); + + wp_set_current_user( self::$editor_id ); + + $post_data = array( + 'post_content' => 'Test post content', + 'post_title' => 'Test post title', + 'post_excerpt' => 'Test post excerpt', + ); + $post_id = wp_insert_post( $post_data ); + + $autosave_data = array( + 'id' => $post_id, + 'content' => 'Updated post \ content', + 'title' => 'Updated post title', + ); + + $request = new WP_REST_Request( 'POST', '/wp/v2/posts/' . self::$post_id . '/autosaves' ); + $request->add_header( 'Content-Type', 'application/json' ); + $request->set_body( wp_json_encode( $autosave_data ) ); + + $response = rest_get_server()->dispatch( $request ); + $new_data = $response->get_data(); + $post = get_post( $post_id ); + + // With RTC enabled, a revision is created instead of updating the post. + $this->assertNotSame( $post_id, $new_data['id'] ); + $this->assertSame( $post_id, $new_data['parent'] ); + + // The autosave revision should have the updated content. + $this->assertSame( $autosave_data['content'], $new_data['content']['raw'] ); + $this->assertSame( $autosave_data['title'], $new_data['title']['raw'] ); + + // The draft post should not be updated. + $this->assertSame( $post_data['post_content'], $post->post_content ); + $this->assertSame( $post_data['post_title'], $post->post_title ); + $this->assertSame( $post_data['post_excerpt'], $post->post_excerpt ); + + wp_delete_post( $post_id ); + update_option( 'enable_real_time_collaboration', $original_option ); + } + + /** + * When real-time collaboration is enabled, autosaving a draft page with + * a parent should create a revision instead of updating the page directly. + */ + public function test_update_item_draft_page_with_parent_with_rtc() { + $original_option = get_option( 'enable_real_time_collaboration' ); + update_option( 'enable_real_time_collaboration', true ); + + wp_set_current_user( self::$editor_id ); + $request = new WP_REST_Request( 'POST', '/wp/v2/pages/' . self::$child_draft_page_id . '/autosaves' ); + $request->add_header( 'Content-Type', 'application/x-www-form-urlencoded' ); + + $params = $this->set_post_data( + array( + 'id' => self::$child_draft_page_id, + 'author' => self::$editor_id, + ) + ); + + $request->set_body_params( $params ); + $response = rest_get_server()->dispatch( $request ); + $data = $response->get_data(); + + // With RTC enabled, a revision is created instead of updating the page. + $this->assertNotSame( self::$child_draft_page_id, $data['id'] ); + $this->assertSame( self::$child_draft_page_id, $data['parent'] ); + update_option( 'enable_real_time_collaboration', $original_option ); + } } From c1cdc46042e61b9c87ff41dc56c2e59964745e33 Mon Sep 17 00:00:00 2001 From: chriszarate Date: Thu, 19 Feb 2026 10:00:39 -0500 Subject: [PATCH 2/2] Update qunit fixtures --- tests/qunit/fixtures/wp-api-generated.js | 108 ++++++++++++++++++++++- 1 file changed, 107 insertions(+), 1 deletion(-) diff --git a/tests/qunit/fixtures/wp-api-generated.js b/tests/qunit/fixtures/wp-api-generated.js index b0bbb70563b73..046afe6730090 100644 --- a/tests/qunit/fixtures/wp-api-generated.js +++ b/tests/qunit/fixtures/wp-api-generated.js @@ -20,7 +20,8 @@ mockedApiResponse.Schema = { "wp/v2", "wp-site-health/v1", "wp-block-editor/v1", - "wp-abilities/v1" + "wp-abilities/v1", + "wp-sync/v1" ], "authentication": { "application-passwords": { @@ -12698,6 +12699,111 @@ mockedApiResponse.Schema = { } } ] + }, + "/wp-sync/v1": { + "namespace": "wp-sync/v1", + "methods": [ + "GET" + ], + "endpoints": [ + { + "methods": [ + "GET" + ], + "args": { + "namespace": { + "default": "wp-sync/v1", + "required": false + }, + "context": { + "default": "view", + "required": false + } + } + } + ], + "_links": { + "self": [ + { + "href": "http://example.org/index.php?rest_route=/wp-sync/v1" + } + ] + } + }, + "/wp-sync/v1/updates": { + "namespace": "wp-sync/v1", + "methods": [ + "POST" + ], + "endpoints": [ + { + "methods": [ + "POST" + ], + "args": { + "rooms": { + "items": { + "properties": { + "after": { + "minimum": 0, + "required": true, + "type": "integer" + }, + "awareness": { + "required": true, + "type": "object" + }, + "client_id": { + "minimum": 1, + "required": true, + "type": "integer" + }, + "room": { + "required": true, + "type": "string", + "pattern": "^[^/]+/[^/:]+(?::\\S+)?$" + }, + "updates": { + "items": { + "properties": { + "data": { + "type": "string", + "required": true + }, + "type": { + "type": "string", + "required": true, + "enum": [ + "compaction", + "sync_step1", + "sync_step2", + "update" + ] + } + }, + "required": true, + "type": "object" + }, + "minItems": 0, + "required": true, + "type": "array" + } + }, + "type": "object" + }, + "type": "array", + "required": true + } + } + } + ], + "_links": { + "self": [ + { + "href": "http://example.org/index.php?rest_route=/wp-sync/v1/updates" + } + ] + } } }, "site_logo": 0,