0

I have a method that is hooked to the rest_api_init

  /**
   * Set allowed headers for the rest request
   */
  public function set_allowed_rest_headers() {

    remove_filter( 'rest_pre_serve_request', 'rest_send_cors_headers' );

    add_filter(
      'rest_pre_serve_request', function( $value ) {
        header( 'Access-Control-Allow-Origin: ' . esc_url_raw( 'some url pulled from options' ) );
        header( 'Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE, PATCH' );
        header( 'Access-Control-Allow-Credentials: true' );

        return $value;
      }
    );
  }

I want to test this using phpunit.

I've created a test case

<?php
/**
 * Class Test_Admin
 *
 * @package test
 */

/**
 * Class that tests the REST functionality.
 */
class Test_Rest extends WP_UnitTestCase {
  /**
   * Initial set up for the test
   */
  public function setUp() {
    parent::setUp();

    /**
     * Global $wp_rest_server variable
     *
     * @var WP_REST_Server $wp_rest_server Mock REST server.
     */
    global $wp_rest_server;

    $wp_rest_server = new \WP_REST_Server();
    $this->server   = $wp_rest_server;

    do_action( 'rest_api_init' );

  }

  /**
   * Tear down after test ends
   */
  public function tearDown() {
    parent::tearDown();

    global $wp_rest_server;
    $wp_rest_server = null;

  }

  /**
   * Test if the REST API headers are set
   *
   * @since 1.1.0
   */
  public function test_allowed_rest_headers() {

    $request  = new WP_REST_Request( 'GET', '/wp/v2/posts' );
    $response = $this->server->dispatch( $request );

    $this->assertEquals( 200, $response->get_status() );

    $headers  = $request->get_headers();
    $headers2 = $response->get_headers();
    error_log( print_r( $headers, true ) );
    error_log( print_r( $headers2, true ) );
  }
}

The assertion that response is 200 is passing, but the error_log returns nothing for the request headers, and

Array
(
    [X-WP-Total] => 0
    [X-WP-TotalPages] => 0
)

For the response headers. But I'd need to test that the Access-Control-Allow-* headers are set correctly.

How to do that (besides manually setting them during the unit test)?

I've tried calling the set_allowed_rest_headers() method inside the test, but nothing.

1

The question actually has nothing specific to wordpress, but maybe it is worth answering.

There is simply no code of your own in that sample that can be/is worth testing, therefor there isn't much to unit test.

Lets look at the details. add_filter is integration with core code, remove_filter is integration with core code and header is integration with PHP core. If you remove all of those lines you are left with zero code.

Or to say it differently, the three functions mentions above are changing the global state and not your internal state, and while you might be able to construct a relevant test, in the end you are going to be testing them much more than testing your own code.

What you need here is an integration test, set a wordpress instance with your code, send an api request and inspect the result.

  • I meant integration test, not unit test, since this is the code from the plugin. I'm using wp-cli's scaffold. – dingo_d Jun 7 '18 at 16:46
  • You need to decide what is it that you are testing. If you test the way the whole application is functioning than you need to do it from the outside. As I said for the specific code you showed there is basically nothing else to test, and any test oriented abstraction you might do will only result in needlessly complex code. – Mark Kaplun Jun 7 '18 at 17:02
  • What do you mean 'from the outside'? I'm using WordPress in a decoupled way. The front end app is communicating with it via REST API. I'm setting the headers for any rest requests because I need to avoid CORS issues. By setting the headers on rest_pre_serve_request I'm modifying the request. So basically I need to have an automated test proving that it works (not my requirement, clients). I know that it works because I've tested it with the frontend app. I just need to have a code coverage :/ – dingo_d Jun 7 '18 at 17:34
  • If you need to test how the plugin behaves, than the only thing is to test it from outside of wordpress. For proper test of what you need it is not enough to test that segment in isolation, because maybe that code is never included. So again the question is what is it that you want to test, if it is the end result of sending a request and getting the result than you have to do it from outside of wordpress – Mark Kaplun Jun 7 '18 at 17:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.