diff --git a/src/Illuminate/Http/Client/Concerns/DeterminesStatusCode.php b/src/Illuminate/Http/Client/Concerns/DeterminesStatusCode.php new file mode 100644 index 000000000000..ab9132006ecf --- /dev/null +++ b/src/Illuminate/Http/Client/Concerns/DeterminesStatusCode.php @@ -0,0 +1,157 @@ +status() === 200; + } + + /** + * Determine if the response code was 201 "Created" response. + * + * @return bool + */ + public function created() + { + return $this->status() === 201; + } + + /** + * Determine if the response code was 202 "Accepted" response. + * + * @return bool + */ + public function accepted() + { + return $this->status() === 202; + } + + /** + * Determine if the response code was the given status code and the body has no content. + * + * @param int $status + * @return bool + */ + public function noContent($status = 204) + { + return $this->status() === $status && $this->body() === ''; + } + + /** + * Determine if the response code was a 301 "Moved Permanently". + * + * @return bool + */ + public function movedPermanently() + { + return $this->status() === 301; + } + + /** + * Determine if the response code was a 302 "Found" response. + * + * @return bool + */ + public function found() + { + return $this->status() === 302; + } + + /** + * Determine if the response was a 400 "Bad Request" response. + * + * @return bool + */ + public function badRequest() + { + return $this->status() === 400; + } + + /** + * Determine if the response was a 401 "Unauthorized" response. + * + * @return bool + */ + public function unauthorized() + { + return $this->status() === 401; + } + + /** + * Determine if the response was a 402 "Payment Required" response. + * + * @return bool + */ + public function paymentRequired() + { + return $this->status() === 402; + } + + /** + * Determine if the response was a 403 "Forbidden" response. + * + * @return bool + */ + public function forbidden() + { + return $this->status() === 403; + } + + /** + * Determine if the response was a 404 "Not Found" response. + * + * @return bool + */ + public function notFound() + { + return $this->status() === 404; + } + + /** + * Determine if the response was a 408 "Request Timeout" response. + * + * @return bool + */ + public function requestTimeout() + { + return $this->status() === 408; + } + + /** + * Determine if the response was a 409 "Conflict" response. + * + * @return bool + */ + public function conflict() + { + return $this->status() === 409; + } + + /** + * Determine if the response was a 422 "Unprocessable Entity" response. + * + * @return bool + */ + public function unprocessableEntity() + { + return $this->status() === 422; + } + + /** + * Determine if the response was a 429 "Too Many Requests" response. + * + * @return bool + */ + public function tooManyRequests() + { + return $this->status() === 429; + } +} diff --git a/src/Illuminate/Http/Client/Response.php b/src/Illuminate/Http/Client/Response.php index ea88958f9af0..65fda6063f00 100644 --- a/src/Illuminate/Http/Client/Response.php +++ b/src/Illuminate/Http/Client/Response.php @@ -9,7 +9,7 @@ class Response implements ArrayAccess { - use Macroable { + use Concerns\DeterminesStatusCode, Macroable { __call as macroCall; } @@ -164,16 +164,6 @@ public function successful() return $this->status() >= 200 && $this->status() < 300; } - /** - * Determine if the response code was "OK". - * - * @return bool - */ - public function ok() - { - return $this->status() === 200; - } - /** * Determine if the response was a redirect. * @@ -184,36 +174,6 @@ public function redirect() return $this->status() >= 300 && $this->status() < 400; } - /** - * Determine if the response was a 401 "Unauthorized" response. - * - * @return bool - */ - public function unauthorized() - { - return $this->status() === 401; - } - - /** - * Determine if the response was a 403 "Forbidden" response. - * - * @return bool - */ - public function forbidden() - { - return $this->status() === 403; - } - - /** - * Determine if the response was a 404 "Not Found" response. - * - * @return bool - */ - public function notFound() - { - return $this->status() === 404; - } - /** * Determine if the response indicates a client or server error occurred. * diff --git a/src/Illuminate/Testing/Concerns/AssertsStatusCodes.php b/src/Illuminate/Testing/Concerns/AssertsStatusCodes.php new file mode 100644 index 000000000000..5bdb144cb616 --- /dev/null +++ b/src/Illuminate/Testing/Concerns/AssertsStatusCodes.php @@ -0,0 +1,165 @@ +assertStatus(200); + } + + /** + * Assert that the response has a 201 "Created" status code. + * + * @return $this + */ + public function assertCreated() + { + return $this->assertStatus(201); + } + + /** + * Assert that the response has a 202 "Accepted" status code. + * + * @return $this + */ + public function assertAccepted() + { + return $this->assertStatus(202); + } + + /** + * Assert that the response has the given status code and no content. + * + * @param int $status + * @return $this + */ + public function assertNoContent($status = 204) + { + $this->assertStatus($status); + + PHPUnit::assertEmpty($this->getContent(), 'Response content is not empty.'); + + return $this; + } + + /** + * Assert that the response has a 301 "Moved Permanently" status code. + * + * @param int $status + * @return $this + */ + public function assertMovedPermanently() + { + return $this->assertStatus(301); + } + + /** + * Assert that the response has a 302 "Found" status code. + * + * @param int $status + * @return $this + */ + public function assertFound() + { + return $this->assertStatus(302); + } + + /** + * Assert that the response has a 400 "Bad Request" status code. + * + * @return $this + */ + public function assertBadRequest() + { + return $this->assertStatus(400); + } + + /** + * Assert that the response has a 402 "Unauthorized" status code. + * + * @return $this + */ + public function assertUnauthorized() + { + return $this->assertStatus(401); + } + + /** + * Assert that the response has a 402 "Payment Required" status code. + * + * @return $this + */ + public function assertPaymentRequired() + { + return $this->assertStatus(402); + } + + /** + * Assert that the response has a 403 "Forbidden" status code. + * + * @return $this + */ + public function assertForbidden() + { + return $this->assertStatus(403); + } + + /** + * Assert that the response has a 404 "Not Found" status code. + * + * @return $this + */ + public function assertNotFound() + { + return $this->assertStatus(404); + } + + /** + * Assert that the response has a 408 "Request Timeout" status code. + * + * @return $this + */ + public function assertRequestTimeout() + { + return $this->assertStatus(408); + } + + /** + * Assert that the response has a 409 "Conflict" status code. + * + * @return $this + */ + public function assertConflict() + { + return $this->assertStatus(409); + } + + /** + * Assert that the response has a 422 "Unprocessable Entity" status code. + * + * @return $this + */ + public function assertUnprocessable() + { + return $this->assertStatus(422); + } + + /** + * Assert that the response has a 429 "Too Many Requests" status code. + * + * @return $this + */ + public function assertTooManyRequests() + { + return $this->assertStatus(429); + } +} diff --git a/src/Illuminate/Testing/TestResponse.php b/src/Illuminate/Testing/TestResponse.php index 5c59ccfa4131..630fbb87a590 100644 --- a/src/Illuminate/Testing/TestResponse.php +++ b/src/Illuminate/Testing/TestResponse.php @@ -32,7 +32,7 @@ */ class TestResponse implements ArrayAccess { - use Tappable, Macroable { + use Concerns\AssertsStatusCodes, Tappable, Macroable { __call as macroCall; } @@ -95,81 +95,6 @@ public function assertSuccessful() return $this; } - /** - * Assert that the response has a 200 status code. - * - * @return $this - */ - public function assertOk() - { - return $this->assertStatus(200); - } - - /** - * Assert that the response has a 201 status code. - * - * @return $this - */ - public function assertCreated() - { - return $this->assertStatus(201); - } - - /** - * Assert that the response has the given status code and no content. - * - * @param int $status - * @return $this - */ - public function assertNoContent($status = 204) - { - $this->assertStatus($status); - - PHPUnit::assertEmpty($this->getContent(), 'Response content is not empty.'); - - return $this; - } - - /** - * Assert that the response has a not found status code. - * - * @return $this - */ - public function assertNotFound() - { - return $this->assertStatus(404); - } - - /** - * Assert that the response has a forbidden status code. - * - * @return $this - */ - public function assertForbidden() - { - return $this->assertStatus(403); - } - - /** - * Assert that the response has an unauthorized status code. - * - * @return $this - */ - public function assertUnauthorized() - { - return $this->assertStatus(401); - } - - /** - * Assert that the response has a 422 status code. - * - * @return $this - */ - public function assertUnprocessable() - { - return $this->assertStatus(422); - } - /** * Assert that the response is a server error. * diff --git a/tests/Http/HttpClientTest.php b/tests/Http/HttpClientTest.php index 398b1ff616b3..36a4eb168af1 100644 --- a/tests/Http/HttpClientTest.php +++ b/tests/Http/HttpClientTest.php @@ -17,6 +17,7 @@ use Illuminate\Http\Client\RequestException; use Illuminate\Http\Client\Response; use Illuminate\Http\Client\ResponseSequence; +use Illuminate\Http\Response as HttpResponse; use Illuminate\Support\Collection; use Illuminate\Support\Fluent; use Illuminate\Support\Str; @@ -56,6 +57,160 @@ public function testStubbedResponsesAreReturnedAfterFaking() $this->assertTrue($response->ok()); } + public function testCreatedRequest() + { + $this->factory->fake([ + 'vapor.laravel.com' => $this->factory::response('', HttpResponse::HTTP_CREATED), + 'forge.laravel.com' => $this->factory::response('', HttpResponse::HTTP_OK), + ]); + + $response = $this->factory->post('http://vapor.laravel.com'); + $this->assertTrue($response->created()); + + $response = $this->factory->post('http://forge.laravel.com'); + $this->assertFalse($response->created()); + } + + public function testAcceptedRequest() + { + $this->factory->fake([ + 'vapor.laravel.com' => $this->factory::response('', HttpResponse::HTTP_ACCEPTED), + 'forge.laravel.com' => $this->factory::response('', HttpResponse::HTTP_OK), + ]); + + $response = $this->factory->post('http://vapor.laravel.com'); + $this->assertTrue($response->accepted()); + + $response = $this->factory->post('http://forge.laravel.com'); + $this->assertFalse($response->accepted()); + } + + public function testMovedPermanentlyRequest() + { + $this->factory->fake([ + 'vapor.laravel.com' => $this->factory::response('', HttpResponse::HTTP_MOVED_PERMANENTLY), + 'forge.laravel.com' => $this->factory::response('', HttpResponse::HTTP_OK), + ]); + + $response = $this->factory->post('http://vapor.laravel.com'); + $this->assertTrue($response->movedPermanently()); + + $response = $this->factory->post('http://forge.laravel.com'); + $this->assertFalse($response->movedPermanently()); + } + + public function testNoContentRequest() + { + $this->factory->fake([ + 'vapor.laravel.com' => $this->factory::response('', HttpResponse::HTTP_NO_CONTENT), + 'forge.laravel.com' => $this->factory::response('', HttpResponse::HTTP_OK), + ]); + + $response = $this->factory->post('http://vapor.laravel.com'); + $this->assertTrue($response->noContent()); + + $response = $this->factory->post('http://forge.laravel.com'); + $this->assertFalse($response->noContent()); + } + + public function testFoundRequest() + { + $this->factory->fake([ + 'vapor.laravel.com' => $this->factory::response('', HttpResponse::HTTP_FOUND), + 'forge.laravel.com' => $this->factory::response('', HttpResponse::HTTP_OK), + ]); + + $response = $this->factory->post('http://vapor.laravel.com'); + $this->assertTrue($response->found()); + + $response = $this->factory->post('http://forge.laravel.com'); + $this->assertFalse($response->found()); + } + + public function testBadRequestRequest() + { + $this->factory->fake([ + 'vapor.laravel.com' => $this->factory::response('', HttpResponse::HTTP_BAD_REQUEST), + 'forge.laravel.com' => $this->factory::response('', HttpResponse::HTTP_OK), + ]); + + $response = $this->factory->post('http://vapor.laravel.com'); + $this->assertTrue($response->badRequest()); + + $response = $this->factory->post('http://forge.laravel.com'); + $this->assertFalse($response->badRequest()); + } + + public function testPaymentRequiredRequest() + { + $this->factory->fake([ + 'vapor.laravel.com' => $this->factory::response('', HttpResponse::HTTP_PAYMENT_REQUIRED), + 'forge.laravel.com' => $this->factory::response('', HttpResponse::HTTP_OK), + ]); + + $response = $this->factory->post('http://vapor.laravel.com'); + $this->assertTrue($response->paymentRequired()); + + $response = $this->factory->post('http://forge.laravel.com'); + $this->assertFalse($response->paymentRequired()); + } + + public function testRequestTimeoutRequest() + { + $this->factory->fake([ + 'vapor.laravel.com' => $this->factory::response('', HttpResponse::HTTP_REQUEST_TIMEOUT), + 'forge.laravel.com' => $this->factory::response('', HttpResponse::HTTP_OK), + ]); + + $response = $this->factory->post('http://vapor.laravel.com'); + $this->assertTrue($response->requestTimeout()); + + $response = $this->factory->post('http://forge.laravel.com'); + $this->assertFalse($response->requestTimeout()); + } + + public function testConflictResponseRequest() + { + $this->factory->fake([ + 'vapor.laravel.com' => $this->factory::response('', HttpResponse::HTTP_CONFLICT), + 'forge.laravel.com' => $this->factory::response('', HttpResponse::HTTP_OK), + ]); + + $response = $this->factory->post('http://vapor.laravel.com'); + $this->assertTrue($response->conflict()); + + $response = $this->factory->post('http://forge.laravel.com'); + $this->assertFalse($response->conflict()); + } + + public function testUnprocessableEntityRequest() + { + $this->factory->fake([ + 'vapor.laravel.com' => $this->factory::response('', HttpResponse::HTTP_UNPROCESSABLE_ENTITY), + 'forge.laravel.com' => $this->factory::response('', HttpResponse::HTTP_OK), + ]); + + $response = $this->factory->post('http://vapor.laravel.com'); + $this->assertTrue($response->unprocessableEntity()); + + $response = $this->factory->post('http://forge.laravel.com'); + $this->assertFalse($response->unprocessableEntity()); + } + + public function testTooManyRequestsRequest() + { + $this->factory->fake([ + 'vapor.laravel.com' => $this->factory::response('', HttpResponse::HTTP_TOO_MANY_REQUESTS), + 'forge.laravel.com' => $this->factory::response('', HttpResponse::HTTP_OK), + ]); + + $response = $this->factory->post('http://vapor.laravel.com'); + $this->assertTrue($response->tooManyRequests()); + + $response = $this->factory->post('http://forge.laravel.com'); + $this->assertFalse($response->tooManyRequests()); + } + public function testUnauthorizedRequest() { $this->factory->fake([ diff --git a/tests/Testing/TestResponseTest.php b/tests/Testing/TestResponseTest.php index 3a375d6c845c..474ff871bbb4 100644 --- a/tests/Testing/TestResponseTest.php +++ b/tests/Testing/TestResponseTest.php @@ -593,6 +593,158 @@ public function testAssertUnauthorized() $response->assertUnauthorized(); } + public function testAssertBadRequest() + { + $response = TestResponse::fromBaseResponse( + (new Response)->setStatusCode(Response::HTTP_BAD_REQUEST) + ); + + $response->assertBadRequest(); + + $response = TestResponse::fromBaseResponse( + (new Response)->setStatusCode(Response::HTTP_OK) + ); + + $this->expectException(AssertionFailedError::class); + $this->expectExceptionMessage("Expected response status code [400] but received 200.\nFailed asserting that 400 is identical to 200."); + + $response->assertBadRequest(); + $this->fail(); + } + + public function testAssertRequestTimeout() + { + $response = TestResponse::fromBaseResponse( + (new Response)->setStatusCode(Response::HTTP_REQUEST_TIMEOUT) + ); + + $response->assertRequestTimeout(); + + $response = TestResponse::fromBaseResponse( + (new Response)->setStatusCode(Response::HTTP_OK) + ); + + $this->expectException(AssertionFailedError::class); + $this->expectExceptionMessage("Expected response status code [408] but received 200.\nFailed asserting that 408 is identical to 200."); + + $response->assertRequestTimeout(); + $this->fail(); + } + + public function testAssertPaymentRequired() + { + $response = TestResponse::fromBaseResponse( + (new Response)->setStatusCode(Response::HTTP_PAYMENT_REQUIRED) + ); + + $response->assertPaymentRequired(); + + $response = TestResponse::fromBaseResponse( + (new Response)->setStatusCode(Response::HTTP_OK) + ); + + $this->expectException(AssertionFailedError::class); + $this->expectExceptionMessage("Expected response status code [402] but received 200.\nFailed asserting that 402 is identical to 200."); + + $response->assertPaymentRequired(); + $this->fail(); + } + + public function testAssertMovedPermanently() + { + $response = TestResponse::fromBaseResponse( + (new Response)->setStatusCode(Response::HTTP_MOVED_PERMANENTLY) + ); + + $response->assertMovedPermanently(); + + $response = TestResponse::fromBaseResponse( + (new Response)->setStatusCode(Response::HTTP_OK) + ); + + $this->expectException(AssertionFailedError::class); + $this->expectExceptionMessage("Expected response status code [301] but received 200.\nFailed asserting that 301 is identical to 200."); + + $response->assertMovedPermanently(); + $this->fail(); + } + + public function testAssertFound() + { + $response = TestResponse::fromBaseResponse( + (new Response)->setStatusCode(Response::HTTP_FOUND) + ); + + $response->assertFound(); + + $response = TestResponse::fromBaseResponse( + (new Response)->setStatusCode(Response::HTTP_OK) + ); + + $this->expectException(AssertionFailedError::class); + $this->expectExceptionMessage("Expected response status code [302] but received 200.\nFailed asserting that 302 is identical to 200."); + + $response->assertFound(); + $this->fail(); + } + + public function testAssertConflict() + { + $response = TestResponse::fromBaseResponse( + (new Response)->setStatusCode(Response::HTTP_CONFLICT) + ); + + $response->assertConflict(); + + $response = TestResponse::fromBaseResponse( + (new Response)->setStatusCode(Response::HTTP_OK) + ); + + $this->expectException(AssertionFailedError::class); + $this->expectExceptionMessage("Expected response status code [409] but received 200.\nFailed asserting that 409 is identical to 200."); + + $response->assertConflict(); + $this->fail(); + } + + public function testAssertTooManyRequests() + { + $response = TestResponse::fromBaseResponse( + (new Response)->setStatusCode(Response::HTTP_TOO_MANY_REQUESTS) + ); + + $response->assertTooManyRequests(); + + $response = TestResponse::fromBaseResponse( + (new Response)->setStatusCode(Response::HTTP_OK) + ); + + $this->expectException(AssertionFailedError::class); + $this->expectExceptionMessage("Expected response status code [429] but received 200.\nFailed asserting that 429 is identical to 200."); + + $response->assertTooManyRequests(); + $this->fail(); + } + + public function testAssertAccepted() + { + $response = TestResponse::fromBaseResponse( + (new Response)->setStatusCode(Response::HTTP_ACCEPTED) + ); + + $response->assertAccepted(); + + $response = TestResponse::fromBaseResponse( + (new Response)->setStatusCode(Response::HTTP_OK) + ); + + $this->expectException(AssertionFailedError::class); + $this->expectExceptionMessage("Expected response status code [202] but received 200.\nFailed asserting that 202 is identical to 200."); + + $response->assertAccepted(); + $this->fail(); + } + public function testAssertUnprocessable() { $statusCode = 500;