Skip to content

Commit

Permalink
Allow server to be reset, HTTPS control when testing requests (#588)
Browse files Browse the repository at this point in the history
* Trait to get the server reset between each run

* Rename internal trait to be clearer with its intention

* Allow HTTPS control with tests

* Lint fix
  • Loading branch information
srtfisher authored Sep 25, 2024
1 parent 97c0b2a commit eabe2fc
Show file tree
Hide file tree
Showing 9 changed files with 153 additions and 18 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added new `defer()` helper.
- Added `Cache::flexible()` method to add SWR support to the cache.
- Added dynamic creation of post type/taxonomy factories.
- Added `Reset_Server` trait to reset the server between tests.
- Add `with_https()` to control if the request being tested is over HTTPS.

### Changed

Expand Down
22 changes: 22 additions & 0 deletions src/mantle/testing/class-pending-testable-request.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ class Pending_Testable_Request {
*/
public HeaderBag $headers;

/**
* Indicates whether the request should be made over HTTPS.
*/
public bool $https = false;

/**
* The cookies for the request.
*/
Expand Down Expand Up @@ -89,6 +94,17 @@ public function with_header( string $name, string $value ): static {
return $this->with_headers( [ $name => $value ] );
}

/**
* Define whether the request should be made over HTTPS.
*
* @param bool $value Whether to use HTTPS.
*/
public function with_https( bool $value ): static {
$this->https = $value;

return $this;
}

/**
* Set the referer header and previous URL session value in order to simulate
* a previous request.
Expand Down Expand Up @@ -407,6 +423,12 @@ protected function reset_request_state(): void {
}
}

if ( $this->https ) {
$_SERVER['HTTPS'] = 'on';
} else {
unset( $_SERVER['HTTPS'] );
}

// phpcs:enable
}

Expand Down
29 changes: 20 additions & 9 deletions src/mantle/testing/class-test-case.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,16 +93,15 @@ public static function setUpBeforeClass(): void {
static::register_traits();

if ( ! empty( static::$test_uses ) ) {
static::get_test_case_traits()
->each(
function ( $trait ): void {
$method = strtolower( class_basename( $trait ) ) . '_set_up_before_class';

if ( method_exists( static::class, $method ) ) {
call_user_func( [ static::class, $method ] );
}
static::get_test_case_traits()->each(
function ( $trait ): void {
$method = strtolower( class_basename( $trait ) ) . '_set_up_before_class';

if ( method_exists( static::class, $method ) ) {
call_user_func( [ static::class, $method ] );
}
);
}
);
}

parent::setUpBeforeClass();
Expand All @@ -116,6 +115,18 @@ function ( $trait ): void {
* Runs the routine after all tests have been run.
*/
public static function tearDownAfterClass(): void {
if ( ! empty( static::$test_uses ) ) {
static::get_test_case_traits()->each(
function ( $trait ): void {
$method = strtolower( class_basename( $trait ) ) . '_tear_down_after_class';

if ( method_exists( static::class, $method ) ) {
call_user_func( [ static::class, $method ] );
}
}
);
}

parent::tearDownAfterClass();

if ( isset( static::$test_uses[ Refresh_Database::class ] ) ) {
Expand Down
2 changes: 1 addition & 1 deletion src/mantle/testing/class-test-response.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*/
class Test_Response {
use Concerns\Element_Assertions;
use Concerns\Snapshot_Testing;
use Concerns\Response_Snapshot_Testing;
use Macroable;

/**
Expand Down
36 changes: 30 additions & 6 deletions src/mantle/testing/concerns/trait-makes-http-requests.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,23 @@
*/
trait Makes_Http_Requests {
/**
* Additional headers for the request.
* Additional cookies for the request.
*
* @var array<string, string>
*/
protected array $default_headers = [];
protected array $default_cookies = [];

/**
* Additional cookies for the request.
* Additional headers for the request.
*
* @var array<string, string>
*/
protected array $default_cookies = [];
protected array $default_headers = [];

/**
* Whether to use HTTPS by default.
*/
protected bool|null $default_https = null;

/**
* The array of callbacks to be run before the event is started.
Expand Down Expand Up @@ -74,6 +79,7 @@ protected function create_pending_request(): Pending_Testable_Request {
function ( Pending_Testable_Request $request ): void {
$request->cookies->add( $this->default_cookies );
$request->headers->add( $this->default_headers );
$request->with_https( $this->default_https ?? false );
},
);
}
Expand All @@ -92,6 +98,15 @@ public function add_default_header( array|string $headers, ?string $value = null
}
}

/**
* Set the default HTTPS setting for all requests.
*
* @param bool|null $value Whether to use HTTPS by default.
*/
public function set_default_https( bool|null $value = true ): void {
$this->default_https = $value;
}

/**
* Flush all the configured headers.
*/
Expand All @@ -102,7 +117,7 @@ public function flush_default_headers(): static {
}

/**
* Define additional headers to be sent with the request.
* Create a pending request with a specific headers included.
*
* @param array $headers Headers for the request.
*/
Expand All @@ -111,7 +126,7 @@ public function with_headers( array $headers ): Pending_Testable_Request {
}

/**
* Define additional header to be sent with the request.
* Create a pending request with a specific header included.
*
* @param string $name Header name (key).
* @param string $value Header value.
Expand All @@ -120,6 +135,15 @@ public function with_header( string $name, string $value ): Pending_Testable_Req
return $this->with_headers( [ $name => $value ] );
}

/**
* Create a pending request with the HTTPS enabled/disabled.
*
* @param bool $value Whether to use HTTPS.
*/
public function with_https( bool $value = true ): Pending_Testable_Request {
return $this->create_pending_request()->with_https( $value );
}

/**
* Set the referer header and previous URL session value in order to simulate
* a previous request.
Expand Down
31 changes: 31 additions & 0 deletions src/mantle/testing/concerns/trait-reset-server.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php
/**
* Prevent_Remote_Requests trait file
*
* @package Mantle
*/

namespace Mantle\Testing\Concerns;

use Mantle\Testing\Utils;

/**
* Reset the server for each test case.
*
* @mixin \Mantle\Testing\Test_Case
*/
trait Reset_Server {
/**
* Setup the trait.
*/
public function reset_server_set_up(): void {
Utils::reset_server();
}

/**
* Tear down the trait after the test class.
*/
public static function reset_server_tear_down_after_class(): void {
Utils::reset_server();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@
use function Mantle\Support\Helpers\data_get;

/**
* Snapshot Testing
* Response Snapshot Testing
*
* @link https://github.com/spatie/phpunit-snapshot-assertions
*
* @mixin \Mantle\Testing\Test_Response
*/
trait Snapshot_Testing {
trait Response_Snapshot_Testing {
/**
* Assert that the response matches a stored snapshot comparing only the content.
*
Expand Down
12 changes: 12 additions & 0 deletions tests/Testing/Concerns/MakesHttpRequestsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Mantle\Framework\Providers\Routing_Service_Provider;
use Mantle\Http\Request;
use Mantle\Testing\Concerns\Refresh_Database;
use Mantle\Testing\Concerns\Reset_Server;
use Mantle\Testing\Framework_Test_Case;
use Mantle\Testing\Test_Response;
use PHPUnit\Framework\AssertionFailedError;
Expand All @@ -21,6 +22,7 @@
#[Group( 'testing' )]
class MakesHttpRequestsTest extends Framework_Test_Case {
use Refresh_Database;
use Reset_Server;

protected function setUp(): void {
parent::setUp();
Expand Down Expand Up @@ -386,6 +388,16 @@ public function test_match_snapshot_rest() {
] );
}

public function test_https_request() {
$this->get( '/' )->assertOk();

$this->assertEmpty( $_SERVER['HTTPS'] ?? '' );

$this->with_https()->get( 'https://example.com' )->assertOk();

$this->assertEquals( 'on', $_SERVER['HTTPS'] );
}

public function test_multiple_requests() {
$methods = collect( get_class_methods( $this ) )
->filter( fn ( $method ) => false === strpos( $method, '_snapshot_' ) )
Expand Down
33 changes: 33 additions & 0 deletions tests/Testing/Concerns/ResetServerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php
namespace Mantle\Tests\Testing\Concerns;

use Mantle\Testing\Concerns\Reset_Server;
use Mantle\Testing\Framework_Test_Case;
use Mantle\Testing\Utils;
use PHPUnit\Framework\Attributes\Group;

/**
* @group testing
*/
#[Group( 'testing' )]
class ResetServerTest extends Framework_Test_Case {
use Reset_Server;

public static function tearDownAfterClass(): void {
parent::tearDownAfterClass();

Utils::reset_server();
}

public function test_modify_server_http_host() {
$this->assertSame( WP_TESTS_DOMAIN, $_SERVER['HTTP_HOST'] );

$_SERVER['HTTP_HOST'] = 'other.org';

$this->assertSame( 'other.org', $_SERVER['HTTP_HOST'] );
}

public function test_modify_server_request_uri() {
$this->assertEquals( WP_TESTS_DOMAIN, $_SERVER['HTTP_HOST'] );
}
}

0 comments on commit eabe2fc

Please sign in to comment.