I have a /auth/refresh API backend endpoint that refreshes an access token: when the user logs in in the frontend, a httpOnly cookie with the refresh token is set; after five minutes, the access token expires and a silent request to /auth/refresh is made in the background, to which the httpOnly cookie is automatically attached as a HTTP header.
Then, the endpoint grabs the cookie from $_COOKIE, and uses the refresh token to generate a new access token. The endpoint looks something like this:
class RefreshAuthHandler {
public function handle() {
$refreshToken = $_COOKIE["refresh_token"] ?? null;
if( ! $refreshToken ) {
return new \WP_Error( "refresh_token_not_found", "Refresh token not found" );
}
// The refresh token was found. Proceed and generate a new access token
}
}
This works fine in non-test code, but when I write a test for that endpoint, the test fails because $_COOKIE turns out to be empty, so the endpoint returns WP_Error. Notice that, while in non-test code the httpOnly cookie is set on login, in the test I am setting the cookie manually (because you should test components in isolation, right?) by attaching a header to my WP_REST_Request.
Here's the test:
class RefreshAuthHandlerTest extends \Codeception\TestCase\WPTestCase {
public function setUp(): void {
parent::setUp();
global $wp_rest_server;
$this->server = $wp_rest_server = new \WP_REST_Server;
do_action( 'rest_api_init' );
}
public function testRefreshesAuth() {
$Request = new \WP_REST_Request( "GET", "/namespace/v1/auth/refresh" );
$Request->set_header( "Set-Cookie", "refresh_token=d9ed6ee5330bc7857d20a5bd114a0b7d08bab4e400fe4055b432a3851470680c;");
$Response = $this->server->dispatch( $Request );
$this->seeAccessToken( $Response->data );
}
}
The test fails because, since $_COOKIE is empty, my endpoint returns WP_Error instead of the access token.
I also tried setting the cookie in the test not with set_header, but with the setCookie method provided by Codeception's PHPBrowser:
$this->tester->setCookie( "refresh_token", "d9ed6ee5330bc7857d20a5bd114a0b7d08bab4e400fe4055b432a3851470680c" );
but the test still fails.
So, how do you set a httpOnly header in a Codeception test so that my endpoint can grab it from $_COOKIE?