Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Guidelines: Add test for rest_api_init firing before init
Hosts can call rest_get_server() during plugins_loaded, which fires rest_api_init before init priority 10 has had a chance to register the wp_guideline post type. The rest_api_init callbacks in lib/experimental/guidelines/index.php dereference the post type object, so without a defensive guard they fatal (controllers) or trip _doing_it_wrong (register_post_meta).

This test simulates that ordering by unregistering the post type and firing rest_api_init directly.
  • Loading branch information
Xavier Lozano Carreras
Xavier Lozano Carreras committed May 15, 2026
commit cfbc691353f82f451cecee80df681f6fe5e7fbe3
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php
/**
* Tests for Gutenberg_Content_Guidelines_Revisions_Controller initialization.
*
* @package gutenberg
*/
class Gutenberg_Content_Guidelines_Revisions_Controller_Test extends WP_UnitTestCase {

/**
* Re-register the post type after each test, since some tests
* unregister it to simulate ordering edge cases.
*/
public function tear_down() {
if ( ! post_type_exists( Gutenberg_Guidelines_Post_Type::POST_TYPE ) ) {
Gutenberg_Guidelines_Post_Type::register();
}
parent::tear_down();
}

/**
* `rest_api_init` can fire before `init` priority 10 when something
* (e.g. an early `rest_get_server()` call from `plugins_loaded`)
* boots the REST server early. In that window the `wp_guideline`
* post type is not yet registered, so both controllers instantiated
* by the `rest_api_init` handler dereference a null post type object
* in their parent constructors and fatal — the singleton REST
* controller via WP_REST_Posts_Controller::__construct, the revisions
* controller via WP_REST_Revisions_Controller::__construct.
*
* The handler in lib/experimental/guidelines/index.php must defend
* against this ordering by ensuring the post type exists before
* instantiating the controllers.
*/
public function test_rest_api_init_does_not_fatal_when_post_type_not_yet_registered() {
unregister_post_type( Gutenberg_Guidelines_Post_Type::POST_TYPE );
$this->assertFalse(
post_type_exists( Gutenberg_Guidelines_Post_Type::POST_TYPE ),
'Pre-condition: post type must be unregistered to exercise the ordering bug.'
);

do_action( 'rest_api_init' );

$this->assertTrue(
post_type_exists( Gutenberg_Guidelines_Post_Type::POST_TYPE ),
'The rest_api_init handler should defensively register the post type.'
);
}
}