Mock HTTP requests
Feature Request
- Yes, I reviewed the contribution guidelines.
Describe your use case and the problem you are facing
When writing my own CLI commands, they sometimes perform HTTP requests. E.g. I'm currently working with a software licence server, I want a CLI command to activate the licence, but I don't want to use a real licence server which would decrement the available licence activations and return different responses when the test is re-run.
Maybe WP CLI already has this utility, but I didn't see it.
Describe the solution you'd like
Filter pre_http_request by creating an mu-plugin for the test case which loads a PHP file containing the mocked response.
Add this to GivenStepDefinitions.php
/** * @Given /^a request to (.*?) responds? with (.*)$/ */ public function given_a_request_to_a_url_respond_with_file( $url_substring_pattern, $remote_request_response_file ) { $project_dir = realpath( self::get_vendor_dir() . '/../' ); switch ( true ) { case is_file( $remote_request_response_file ): $response_file = realpath( $remote_request_response_file ); break; case is_file( ltrim( $remote_request_response_file, './' ) ): $response_file = realpath( ltrim( $remote_request_response_file, './' ) ); break; case is_file( $project_dir . '/' . $remote_request_response_file ): $response_file = $project_dir . '/' . $remote_request_response_file; break; default: WP_CLI::error( "File not found: {$remote_request_response_file}" ); } if ( substr( $url_substring_pattern, 0, 1 ) !== substr( $url_substring_pattern, -1 ) ) { $url_substring_pattern = '/' . preg_quote( $url_substring_pattern, '/' ) . '/'; } $mu_plugin_name = basename( $remote_request_response_file ); $mu_php = <<<MU_PHP <?php /** * Plugin Name: $mu_plugin_name * Description: Mock a response for a remote request matching `$url_substring_pattern`. */ /** * Filter the HTTP request to return a mock response. * * @hooked pre_http_request * @see \WP_Http::request() * * @param false|array \$pre * @param array \$parsed_args * @param string \$url The request URL. * * @return false|array{headers:array,body:string,response:array{code:int|false,message:bool|string},cookies:array,http_response:null|array} */ add_filter( 'pre_http_request', function( \$pre, \$parsed_args, \$url ) { if ( 1 !== preg_match( '$url_substring_pattern', \$url ) ) { return \$pre; } return include '$response_file'; }, 10, 3 ); MU_PHP; file_put_contents( $this->variables['RUN_DIR'] . '/wp-content/mu-plugins/' . $mu_plugin_name, $mu_php ); }
And a feature would look like:
Scenario: licence set with activate flag Given a WP install Given a plugin located at ./test-plugin Given a request to wp-json/slswc/v1/activate? responds with tests/_data/features/activate-success.php When I run `wp test-plugin licence set-key abcdefghijklmnopqrstuvwxyzn --activate` Then STDERR should be empty And STDOUT should contain: """ Success: active """
This could be generalised to almost every filter, so maybe I missed it because I was looking for a http mock.
I need to write tests on that switch statement.