diff --git a/src/Service/PostcodeApiClient.php b/src/Service/PostcodeApiClient.php index 6a2785a..4e2f9b9 100644 --- a/src/Service/PostcodeApiClient.php +++ b/src/Service/PostcodeApiClient.php @@ -3,6 +3,7 @@ namespace Hurnell\PostcodeApiBundle\Service; use GuzzleHttp\ClientInterface; +use GuzzleHttp\Exception\ClientException; use GuzzleHttp\Psr7\Request; use GuzzleHttp\Exception\GuzzleException; use Hurnell\PostcodeApiBundle\Exception\InvalidHouseNumberException; @@ -107,6 +108,12 @@ public function makeRequest(string $postcode, $number, string $extra): self } catch (InvalidJsonException $exception) { throw new InvalidApiResponseException('The API response could not be parsed'); } + } catch (ClientException $e) { + $message = 'The API request failed'; + if (429 === $e->getResponse()->getStatusCode()) { + $message = 'The API request failed due to too many requests'; + } + throw new InvalidApiResponseException($message); } catch (GuzzleException $e) { throw new InvalidApiResponseException('The Guzzle client failed'); } diff --git a/tests/Service/PostcodeApiClientTest.php b/tests/Service/PostcodeApiClientTest.php index 7fcec4b..86691a8 100644 --- a/tests/Service/PostcodeApiClientTest.php +++ b/tests/Service/PostcodeApiClientTest.php @@ -300,6 +300,30 @@ public function invalidExtraButValidWhenWithoutExtraProvider(): array ]; } + public function testPostcodeApiTooManyRequests():void + { + $this->guzzleExpectsApiException(429); + $this->expectException(InvalidApiResponseException::class); + $this->expectExceptionMessage('The API request failed due to too many requests'); + $this->postcodeApiClient + ->makeRequest( + '2013AH', + 34, + '' + ); + } + public function testPostcodeApiTooStatusCodeNotFound():void + { + $this->guzzleExpectsApiException(404); + $this->expectException(InvalidApiResponseException::class); + $this->expectExceptionMessage('The API request failed'); + $this->postcodeApiClient + ->makeRequest( + '2013AH', + 34, + '' + ); + } /** * Finally check that a valid request does not throw an error and diff --git a/tests/Service/PostcodeApiClientTestMock.php b/tests/Service/PostcodeApiClientTestMock.php index b42a88d..c167764 100644 --- a/tests/Service/PostcodeApiClientTestMock.php +++ b/tests/Service/PostcodeApiClientTestMock.php @@ -2,7 +2,9 @@ namespace Hurnell\PostcodeApiBundle\Tests\Service; +use GuzzleHttp\Exception\ClientException; use GuzzleHttp\Exception\ConnectException; +use GuzzleHttp\Psr7\Response; use Psr\Http\Message\RequestInterface; use PHPUnit\Framework\TestCase; use GuzzleHttp\ClientInterface; @@ -28,6 +30,7 @@ class PostcodeApiClientTestMock extends TestCase private $guzzleException; + public function setUp(): void { $this->guzzleClient = $this->mockGuzzleClientInterface(); @@ -35,6 +38,7 @@ public function setUp(): void $this->response = $this->mockResponseInterface(); $this->stream = $this->mockStreamInterface(); $this->guzzleException = $this->mockGuzzleException(); + } /** @@ -64,6 +68,11 @@ private function mockGuzzleException(): ConnectException { return new ConnectException('this is a guzzle exception', $this->request); } + private function mockGuzzleApiException($statusCode): ClientException + { + $response = new Response($statusCode); + return new ClientException('this is a guzzle exception', $this->request, $response); + } protected function guzzleExpectsResponse(): void @@ -79,6 +88,12 @@ protected function guzzleExpectsException(): void ->method('send') ->willThrowException($this->guzzleException); } + protected function guzzleExpectsApiException($statusCode): void + { + $this->guzzleClient->expects($this->once()) + ->method('send') + ->willThrowException($this->mockGuzzleApiException($statusCode)); + } /** * @param int $statusCode