@@ -4549,6 +4549,61 @@ public function test_update_item_with_same_template_that_no_longer_exists() {
45494549 $ this ->assertSame ( 'post-my-invalid-template.php ' , $ data ['template ' ] );
45504550 }
45514551
4552+ /**
4553+ * Tests If-Unmodified-Since conditional updates and Last-Modified headers.
4554+ *
4555+ * @covers WP_REST_Posts_Controller::update_item_permissions_check
4556+ * @covers WP_REST_Posts_Controller::get_item
4557+ * @covers WP_REST_Posts_Controller::add_last_modified_header
4558+ * @ticket 47676
4559+ */
4560+ public function test_update_item_with_if_unmodified_since_precondition () {
4561+ wp_set_current_user ( self ::$ editor_id );
4562+
4563+ $ get_request = new WP_REST_Request ( 'GET ' , sprintf ( '/wp/v2/posts/%d ' , self ::$ post_id ) );
4564+ $ get_request ->set_param ( 'context ' , 'edit ' );
4565+ $ get_response = rest_get_server ()->dispatch ( $ get_request );
4566+ $ this ->assertSame ( 200 , $ get_response ->get_status () );
4567+ $ headers = $ get_response ->get_headers ();
4568+ $ this ->assertArrayHasKey ( 'Last-Modified ' , $ headers );
4569+ $ last_modified = $ headers ['Last-Modified ' ];
4570+
4571+ $ request = new WP_REST_Request ( 'PUT ' , sprintf ( '/wp/v2/posts/%d ' , self ::$ post_id ) );
4572+ $ request ->add_header ( 'content-type ' , 'application/json ' );
4573+ $ title1 = 'Same as last modified ' ;
4574+ $ request ->set_body ( wp_json_encode ( $ this ->set_post_data ( array ( 'title ' => $ title1 ) ) ) );
4575+ $ request ->set_header ( 'If-Unmodified-Since ' , $ last_modified );
4576+ $ response = rest_get_server ()->dispatch ( $ request );
4577+ $ this ->assertSame ( 200 , $ response ->get_status (), 'Update should succeed when If-Unmodified-Since matches Last-Modified. ' );
4578+ $ new_data = $ response ->get_data ();
4579+ $ this ->assertSame ( $ title1 , $ new_data ['title ' ]['raw ' ] );
4580+ $ this ->assertSame ( $ title1 , get_post ( self ::$ post_id )->post_title );
4581+
4582+ $ get_response = rest_get_server ()->dispatch ( $ get_request );
4583+ $ headers = $ get_response ->get_headers ();
4584+ $ this ->assertArrayHasKey ( 'Last-Modified ' , $ headers );
4585+ $ last_modified_after_update = $ headers ['Last-Modified ' ];
4586+
4587+ $ request = new WP_REST_Request ( 'PUT ' , sprintf ( '/wp/v2/posts/%d ' , self ::$ post_id ) );
4588+ $ request ->add_header ( 'content-type ' , 'application/json ' );
4589+ $ title2 = '1 second after last modified ' ;
4590+ $ request ->set_body ( wp_json_encode ( $ this ->set_post_data ( array ( 'title ' => $ title2 ) ) ) );
4591+ $ request ->set_header ( 'If-Unmodified-Since ' , gmdate ( 'D, d M Y H:i:s ' , strtotime ( $ last_modified_after_update ) + 1 ) . ' GMT ' );
4592+ $ response = rest_get_server ()->dispatch ( $ request );
4593+ $ this ->assertSame ( 200 , $ response ->get_status (), 'Update should succeed when If-Unmodified-Since is after the server modified time. ' );
4594+ $ new_data = $ response ->get_data ();
4595+ $ this ->assertSame ( $ title2 , $ new_data ['title ' ]['raw ' ] );
4596+
4597+ $ request = new WP_REST_Request ( 'PUT ' , sprintf ( '/wp/v2/posts/%d ' , self ::$ post_id ) );
4598+ $ request ->add_header ( 'content-type ' , 'application/json ' );
4599+ $ title3 = 'Should not save ' ;
4600+ $ request ->set_body ( wp_json_encode ( $ this ->set_post_data ( array ( 'title ' => $ title3 ) ) ) );
4601+ $ request ->set_header ( 'If-Unmodified-Since ' , $ last_modified );
4602+ $ response = rest_get_server ()->dispatch ( $ request );
4603+ $ this ->assertSame ( 412 , $ response ->get_status (), 'Update should fail when If-Unmodified-Since predates current revision. ' );
4604+ $ this ->assertSame ( $ title2 , get_post ( self ::$ post_id )->post_title , 'Expected title not to update due to failed precondition. ' );
4605+ }
4606+
45524607 public function verify_post_roundtrip ( $ input = array (), $ expected_output = array () ) {
45534608 // Create the post.
45544609 $ request = new WP_REST_Request ( 'POST ' , '/wp/v2/posts ' );
0 commit comments