test: REST PHPUnit tests#212
Conversation
There was a problem hiding this comment.
Pull request overview
Adds initial PHPUnit coverage for the REST layer in OneSearch, focusing on controller route registration, permission-sensitive behavior, and governing/consumer data flows. This fits the codebase by expanding unit coverage around the plugin’s cross-site REST integration points.
Changes:
- Adds new unit test files for the abstract REST controller and the main REST controllers/handler.
- Covers route registration, option reads/writes, brand config retrieval, indexable entities, and reindex behavior.
- Adds permission and origin/header checks for same-origin and cross-origin REST requests.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
tests/php/Unit/Modules/Rest/Abstract_REST_ControllerTest.php |
Adds tests for hook registration, API permission checks, and host/origin matching. |
tests/php/Unit/Modules/Rest/Basic_Options_ControllerTest.php |
Adds tests for basic settings REST endpoints such as site type, shared sites, health check, and governing site. |
tests/php/Unit/Modules/Rest/Governing_Data_ControllerTest.php |
Adds tests for brand-config and all-post-types controller behavior across site types. |
tests/php/Unit/Modules/Rest/Governing_Data_HandlerTest.php |
Adds tests for governing-data fetch/caching, child-site post type retrieval, and cache clearing. |
tests/php/Unit/Modules/Rest/Search_ControllerTest.php |
Adds tests for search controller routes, Algolia credentials, indexable entities, and reindex behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| $this->controller = new Concrete_REST_Controller(); | ||
| } | ||
|
|
||
| // ── register_hooks ────────────────────────────────────────────────── |
There was a problem hiding this comment.
Please get rid of all the AI slop 🙇
| #[CoversClass( Abstract_REST_Controller::class )] | ||
| class Abstract_REST_ControllerTest extends TestCase { |
There was a problem hiding this comment.
We're making integration tests, the focus of our tests should be on outcomes, not implementations like the underlying Abstract classes.
Instead, we should add #[CoversClass( Abstract_REST_Controller::class )] to the top of the other *_ControllerTests and only test here if there's particular edge cases that arent being covered.
(To fix, I recommend adding the #Covers*, delete all the the contents of Abstract_REST_ControllerTest, and then use the coverage report to see which of the existing tests here - if any - you should restore. )
| #[CoversClass( Basic_Options_Controller::class )] | ||
| class Basic_Options_ControllerTest extends TestCase { |
There was a problem hiding this comment.
Per #212 (comment)
| #[CoversClass( Basic_Options_Controller::class )] | |
| class Basic_Options_ControllerTest extends TestCase { | |
| #[CoversClass( Abstract_Rest_Controller::class )] | |
| #[CoversClass( Basic_Options_Controller::class )] | |
| class Basic_Options_ControllerTest extends TestCase { |
| /** | ||
| * Controller under test. | ||
| */ | ||
| private Basic_Options_Controller $controller; | ||
|
|
||
| /** | ||
| * {@inheritDoc} | ||
| */ | ||
| public function set_up(): void { | ||
| parent::set_up(); | ||
|
|
||
| global $wp_rest_server; | ||
| $wp_rest_server = null; | ||
|
|
||
| $this->controller = new Basic_Options_Controller(); | ||
| } |
There was a problem hiding this comment.
We're testing outcomes, so we want to make actual rest requests instead of hitting the controller.
| /** | |
| * Controller under test. | |
| */ | |
| private Basic_Options_Controller $controller; | |
| /** | |
| * {@inheritDoc} | |
| */ | |
| public function set_up(): void { | |
| parent::set_up(); | |
| global $wp_rest_server; | |
| $wp_rest_server = null; | |
| $this->controller = new Basic_Options_Controller(); | |
| } | |
| /** | |
| * REST server. | |
| */ | |
| private ?\WP_Rest_Server $server; | |
| /** | |
| * {@inheritDoc} | |
| */ | |
| public function set_up(): void { | |
| parent::set_up(); | |
| global $wp_rest_server; | |
| $this->server = $wp_rest_server = new \WP_REST_Server; | |
| do_action( 'rest_api_init' ); | |
| } | |
| /** | |
| * {@inheritDoc} | |
| */ | |
| public function tear_down(): void { | |
| global $wp_rest_server; | |
| $wp_rest_server = null; | |
| parent::tear_down(); | |
| } |
Then, for all of these test cases instead of trying to pass specific details to functions out of context, you would:
$request = new WP_REST_Request( ... );
$response = $this->server->dispatch( $request );
$actual = $response->get_data();
$this->assert*();...| * @expectedIncorrectUsage register_rest_route | ||
| */ | ||
| public function test_register_routes_for_governing_site(): void { | ||
| update_option( Settings::OPTION_SITE_TYPE, Settings::SITE_TYPE_GOVERNING ); |
There was a problem hiding this comment.
Only you're instantiating the endpoints for real per #212 (comment) you'll need to move this to the set_up() too. You might need to break the file into separate Governing_Data_Controller_{Governing|Brand}_SiteTest
| * Tests for brand config fetching, caching, and cross-site post type retrieval. | ||
| */ | ||
| #[CoversClass( Governing_Data_Handler::class )] | ||
| class Governing_Data_HandlerTest extends TestCase { |
There was a problem hiding this comment.
PTAL at the coverage report and use add_filter( 'pre_http_request', ...) to mock the wp_safe_remote_request() return value and finish testing those functions.
There was a problem hiding this comment.
We may need to mock some things to finish testing the important parts of this class. Will no more once everything's been converted to use $this->server->dispatch()
There was a problem hiding this comment.
These test cases look really good - great job @Kallyan01 !
As noted, we want these to be outcome-focused integration tests and get as close to making real REST requests as possible instead of calling the controller methods directly, and gotta ditch the // ai slop comments everywhere. Once that's done it'l be easier to spot if there's something missing or more likely if there's some that are too "implementation-detail" focused that we want to ditch.
Either way, shouldn't take much before we can merge 🙌
What
Added REST PHPUnit test cases.
Why
Improves development workflow by enabling faster and more reliable validation of REST functionality, reducing repetitive manual testing efforts.
Related Issue(s):
How
AI Disclosure
Hybrid approach = Written by Me + Copilot (Claude Opus 4.6, GPT 5.3) + Audited by me
Testing Instructions
Screenshots
Additional Info
Checklist