diff --git a/src/Tempest/Framework/Testing/Http/HttpRouterTester.php b/src/Tempest/Framework/Testing/Http/HttpRouterTester.php index c89a3f5c0..3dc6065c0 100644 --- a/src/Tempest/Framework/Testing/Http/HttpRouterTester.php +++ b/src/Tempest/Framework/Testing/Http/HttpRouterTester.php @@ -13,7 +13,7 @@ use Tempest\Http\Request; use Tempest\Router\RouteConfig; use Tempest\Router\Router; -use Tempest\Validation\Validator; +use Tempest\Support\Uri; use function Tempest\map; @@ -25,108 +25,108 @@ public function __construct( private Container $container, ) {} - public function get(string $uri, array $headers = []): TestResponseHelper + public function get(string $uri, array $query = [], array $headers = []): TestResponseHelper { return $this->sendRequest( new GenericRequest( method: Method::GET, - uri: $uri, + uri: Uri\merge_query($uri, ...$query), body: [], headers: $headers, ), ); } - public function head(string $uri, array $headers = []): TestResponseHelper + public function head(string $uri, array $query = [], array $headers = []): TestResponseHelper { return $this->sendRequest( new GenericRequest( method: Method::HEAD, - uri: $uri, + uri: Uri\merge_query($uri, ...$query), body: [], headers: $headers, ), ); } - public function post(string $uri, array $body = [], array $headers = []): TestResponseHelper + public function post(string $uri, array $body = [], array $query = [], array $headers = []): TestResponseHelper { return $this->sendRequest( new GenericRequest( method: Method::POST, - uri: $uri, + uri: Uri\merge_query($uri, ...$query), body: $body, headers: $headers, ), ); } - public function put(string $uri, array $body = [], array $headers = []): TestResponseHelper + public function put(string $uri, array $body = [], array $query = [], array $headers = []): TestResponseHelper { return $this->sendRequest( new GenericRequest( method: Method::PUT, - uri: $uri, + uri: Uri\merge_query($uri, ...$query), body: $body, headers: $headers, ), ); } - public function delete(string $uri, array $body = [], array $headers = []): TestResponseHelper + public function delete(string $uri, array $body = [], array $query = [], array $headers = []): TestResponseHelper { return $this->sendRequest( new GenericRequest( method: Method::DELETE, - uri: $uri, + uri: Uri\merge_query($uri, ...$query), body: $body, headers: $headers, ), ); } - public function connect(string $uri, array $body = [], array $headers = []): TestResponseHelper + public function connect(string $uri, array $query = [], array $headers = []): TestResponseHelper { return $this->sendRequest( new GenericRequest( method: Method::CONNECT, - uri: $uri, - body: $body, + uri: Uri\merge_query($uri, ...$query), + body: [], headers: $headers, ), ); } - public function options(string $uri, array $body = [], array $headers = []): TestResponseHelper + public function options(string $uri, array $query = [], array $headers = []): TestResponseHelper { return $this->sendRequest( new GenericRequest( method: Method::OPTIONS, - uri: $uri, - body: $body, + uri: Uri\merge_query($uri, ...$query), + body: [], headers: $headers, ), ); } - public function trace(string $uri, array $body = [], array $headers = []): TestResponseHelper + public function trace(string $uri, array $query = [], array $headers = []): TestResponseHelper { return $this->sendRequest( new GenericRequest( method: Method::TRACE, - uri: $uri, - body: $body, + uri: Uri\merge_query($uri, ...$query), + body: [], headers: $headers, ), ); } - public function patch(string $uri, array $body = [], array $headers = []): TestResponseHelper + public function patch(string $uri, array $body = [], array $query = [], array $headers = []): TestResponseHelper { return $this->sendRequest( new GenericRequest( method: Method::PATCH, - uri: $uri, + uri: Uri\merge_query($uri, ...$query), body: $body, headers: $headers, ), @@ -142,6 +142,7 @@ public function sendRequest(Request $request): TestResponseHelper return new TestResponseHelper( response: $router->dispatch(map($request)->with(RequestToPsrRequestMapper::class)->do()), + request: $request, container: $this->container, ); } diff --git a/src/Tempest/Framework/Testing/Http/TestResponseHelper.php b/src/Tempest/Framework/Testing/Http/TestResponseHelper.php index 68eec6cfa..350fe7489 100644 --- a/src/Tempest/Framework/Testing/Http/TestResponseHelper.php +++ b/src/Tempest/Framework/Testing/Http/TestResponseHelper.php @@ -12,6 +12,7 @@ use Tempest\Container\Container; use Tempest\Cryptography\Encryption\Encrypter; use Tempest\Http\Cookie\Cookie; +use Tempest\Http\Request; use Tempest\Http\Response; use Tempest\Http\Responses\Invalid; use Tempest\Http\Session\Session; @@ -22,13 +23,13 @@ use Tempest\View\View; use Tempest\View\ViewRenderer; -use function Tempest\get; use function Tempest\Support\arr; final class TestResponseHelper { public function __construct( private(set) Response $response, + private(set) Request $request, private(set) ?Container $container = null, ) {} diff --git a/tests/Integration/Testing/Http/HttpRouterTesterIntegrationTest.php b/tests/Integration/Testing/Http/HttpRouterTesterIntegrationTest.php index 47331e2ec..f634eb9a4 100644 --- a/tests/Integration/Testing/Http/HttpRouterTesterIntegrationTest.php +++ b/tests/Integration/Testing/Http/HttpRouterTesterIntegrationTest.php @@ -164,4 +164,18 @@ public function test_patch_requests_failure(): void ->patch('/this-route-does-not-exist') ->assertOk(); } + + public function test_query(): void + { + $this->assertSame($this->http->get('/test?foo=baz', query: ['foo' => 'bar'])->request->uri, '/test?foo=bar'); + $this->assertSame($this->http->get('/test?jon=doe', query: ['foo' => 'bar'])->request->uri, '/test?jon=doe&foo=bar'); + $this->assertSame($this->http->get('/test?jon=doe', query: ['foo' => ['bar' => 'baz']])->request->uri, '/test?jon=doe&foo%5Bbar%5D=baz'); + + $this->assertSame($this->http->get('/test', query: ['foo' => 'bar'])->request->uri, '/test?foo=bar'); + $this->assertSame($this->http->post('/test', query: ['foo' => 'bar'])->request->uri, '/test?foo=bar'); + $this->assertSame($this->http->put('/test', query: ['foo' => 'bar'])->request->uri, '/test?foo=bar'); + $this->assertSame($this->http->delete('/test', query: ['foo' => 'bar'])->request->uri, '/test?foo=bar'); + $this->assertSame($this->http->patch('/test', query: ['foo' => 'bar'])->request->uri, '/test?foo=bar'); + $this->assertSame($this->http->head('/test', query: ['foo' => 'bar'])->request->uri, '/test?foo=bar'); + } } diff --git a/tests/Integration/Testing/Http/TestResponseHelperTest.php b/tests/Integration/Testing/Http/TestResponseHelperTest.php index 4b51eb781..a65f8400c 100644 --- a/tests/Integration/Testing/Http/TestResponseHelperTest.php +++ b/tests/Integration/Testing/Http/TestResponseHelperTest.php @@ -8,7 +8,9 @@ use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Tempest\Framework\Testing\Http\TestResponseHelper; +use Tempest\Http\GenericRequest; use Tempest\Http\GenericResponse; +use Tempest\Http\Method; use Tempest\Http\Status; /** @@ -19,7 +21,7 @@ final class TestResponseHelperTest extends TestCase public function test_get_response(): void { $response = new GenericResponse(status: Status::OK); - $helper = new TestResponseHelper($response); + $helper = new TestResponseHelper($response, new GenericRequest(Method::GET, '/')); $this->assertSame($response, $helper->response); } @@ -31,6 +33,7 @@ public function test_assert_has_header(): void status: Status::OK, headers: ['Location' => '/new-location'], ), + new GenericRequest(Method::GET, '/'), ); $helper->assertHasHeader('Location'); @@ -39,9 +42,8 @@ public function test_assert_has_header(): void public function test_assert_has_header_failure(): void { $helper = new TestResponseHelper( - new GenericResponse( - status: Status::OK, - ), + new GenericResponse(status: Status::OK), + new GenericRequest(Method::GET, '/'), ); $this->expectException(AssertionFailedError::class); @@ -56,6 +58,7 @@ public function test_assert_header_value_equals(): void status: Status::OK, headers: ['Content-Type' => ['application/json']], ), + new GenericRequest(Method::GET, '/'), ); $helper->assertHeaderContains('Content-Type', 'application/json'); @@ -65,6 +68,7 @@ public function test_assert_header_value_equals_failure(): void { $helper = new TestResponseHelper( new GenericResponse(status: Status::OK), + new GenericRequest(Method::GET, '/'), ); $this->expectException(AssertionFailedError::class); @@ -81,6 +85,7 @@ public function test_assert_redirect(): void 'Location' => ['/other-location'], ], ), + new GenericRequest(Method::GET, '/'), ); $helper->assertRedirect(); @@ -90,6 +95,7 @@ public function test_assert_redirect_without_location_header(): void { $helper = new TestResponseHelper( new GenericResponse(status: Status::FOUND), + new GenericRequest(Method::GET, '/'), ); $this->expectException(AssertionFailedError::class); @@ -104,6 +110,7 @@ public function test_assert_redirect_without_3xx_status_code(): void status: Status::OK, headers: ['Location' => '/other-location'], ), + new GenericRequest(Method::GET, '/'), ); $this->expectException(AssertionFailedError::class); @@ -118,6 +125,7 @@ public function test_assert_redirect_to(): void status: Status::FOUND, headers: ['Location' => ['/other-location']], ), + new GenericRequest(Method::GET, '/'), ); $helper->assertRedirect('/other-location'); @@ -127,6 +135,7 @@ public function test_assert_ok(): void { $helper = new TestResponseHelper( new GenericResponse(status: Status::OK), + new GenericRequest(Method::GET, '/'), ); $helper->assertOk(); @@ -136,6 +145,7 @@ public function test_assert_ok_fails_with_not_okay_response(): void { $helper = new TestResponseHelper( new GenericResponse(status: Status::INTERNAL_SERVER_ERROR), + new GenericRequest(Method::GET, '/'), ); $this->expectException(AssertionFailedError::class); @@ -147,6 +157,7 @@ public function test_assert_not_found(): void { $helper = new TestResponseHelper( new GenericResponse(status: Status::NOT_FOUND), + new GenericRequest(Method::GET, '/'), ); $helper->assertNotFound(); @@ -156,6 +167,7 @@ public function test_assert_not_found_fails_with_okay_response(): void { $helper = new TestResponseHelper( new GenericResponse(status: Status::OK), + new GenericRequest(Method::GET, '/'), ); $this->expectException(AssertionFailedError::class); @@ -166,7 +178,7 @@ public function test_assert_not_found_fails_with_okay_response(): void #[DataProvider('provide_assert_status_cases')] public function test_assert_status(Status $expectedStatus, GenericResponse $response): void { - $helper = new TestResponseHelper($response); + $helper = new TestResponseHelper($response, new GenericRequest(Method::GET, '/')); $helper->assertStatus($expectedStatus); } @@ -174,7 +186,7 @@ public function test_assert_status(Status $expectedStatus, GenericResponse $resp #[DataProvider('provide_assert_status_fails_when_status_does_not_match_cases')] public function test_assert_status_fails_when_status_does_not_match(Status $expectedStatus, GenericResponse $response): void { - $helper = new TestResponseHelper($response); + $helper = new TestResponseHelper($response, new GenericRequest(Method::GET, '/')); $this->expectException(AssertionFailedError::class); @@ -185,6 +197,7 @@ public function test_assert_json_has_keys(): void { $helper = new TestResponseHelper( new GenericResponse(status: Status::OK, body: ['title' => 'Timeline Taxi', 'author' => ['name' => 'John']]), + new GenericRequest(Method::GET, '/'), ); $helper->assertJsonHasKeys('title', 'author.name'); @@ -194,6 +207,7 @@ public function test_assert_json_contains(): void { $helper = new TestResponseHelper( new GenericResponse(status: Status::OK, body: ['title' => 'Timeline Taxi', 'author' => ['name' => 'John']]), + new GenericRequest(Method::GET, '/'), ); $helper->assertJsonContains(['title' => 'Timeline Taxi']); @@ -205,6 +219,7 @@ public function test_assert_json(): void { $helper = new TestResponseHelper( new GenericResponse(status: Status::OK, body: ['title' => 'Timeline Taxi', 'author' => ['name' => 'John']]), + new GenericRequest(Method::GET, '/'), ); $helper->assertJson(['title' => 'Timeline Taxi', 'author' => ['name' => 'John']]);