diff --git a/src/Hyperwallet/Util/ApiClient.php b/src/Hyperwallet/Util/ApiClient.php index f51327dd..d0448bc6 100644 --- a/src/Hyperwallet/Util/ApiClient.php +++ b/src/Hyperwallet/Util/ApiClient.php @@ -3,6 +3,7 @@ use GuzzleHttp\Client; use GuzzleHttp\Exception\BadResponseException; use GuzzleHttp\Exception\ConnectException; +use GuzzleHttp\Exception\GuzzleException; use Hyperwallet\Exception\HyperwalletApiException; use Hyperwallet\Exception\HyperwalletException; use Hyperwallet\Model\BaseModel; @@ -149,6 +150,8 @@ public function doGet($partialUrl, array $uriParams, array $query) { * @return array * * @throws HyperwalletApiException + * @throws HyperwalletException + * @throws GuzzleException */ private function doRequest($method, $url, array $urlParams, array $options) { try { @@ -169,10 +172,8 @@ private function doRequest($method, $url, array $urlParams, array $options) { return array(); } $this->checkResponseHeaderContentType($response); - $body = $this->isEncrypted ? \GuzzleHttp\json_decode(\GuzzleHttp\json_encode($this->encryption->decrypt($response->getBody())), true) : - \GuzzleHttp\json_decode($response->getBody(), true); - return $body; + return $this->getBodyFromResponse($response); } catch (ConnectException $e) { $errorResponse = new ErrorResponse(0, array('errors' => array( array( @@ -182,7 +183,7 @@ private function doRequest($method, $url, array $urlParams, array $options) { ))); throw new HyperwalletApiException($errorResponse, $e); } catch (BadResponseException $e) { - $body = \GuzzleHttp\json_decode($e->getResponse()->getBody(), true); + $body = $this->getBodyFromResponse($e->getResponse()); if (is_null($body) || !isset($body['errors']) || empty($body['errors'])) { $body = array('errors' => array( array( @@ -196,6 +197,17 @@ private function doRequest($method, $url, array $urlParams, array $options) { } } + /** + * Get body from response and decrypt it if necessary + * + * @throws HyperwalletException + */ + private function getBodyFromResponse(ResponseInterface $response) { + return $this->isEncrypted + ? \GuzzleHttp\json_decode(\GuzzleHttp\json_encode($this->encryption->decrypt($response->getBody())), true) + : \GuzzleHttp\json_decode($response->getBody(), true); + } + /** * Checks whether Content-Type header is valid in response * diff --git a/tests/Hyperwallet/Tests/Util/ApiClientTest.php b/tests/Hyperwallet/Tests/Util/ApiClientTest.php index 980d42eb..652c6712 100644 --- a/tests/Hyperwallet/Tests/Util/ApiClientTest.php +++ b/tests/Hyperwallet/Tests/Util/ApiClientTest.php @@ -410,6 +410,67 @@ public function testDoPost_throw_exception_bad_request() { $this->validateRequest('POST', '/test', '', array('test2' => 'value2'), true); } + /** + * @throws HyperwalletException + */ + public function testDoPost_throw_exception_bad_request_with_encryption() { + $clientPath = __DIR__ . "/../../../resources/private-jwkset1"; + $hyperwalletPath = __DIR__ . "/../../../resources/public-jwkset1"; + $originalMessage = array( + 'errors' => array( + array( + 'fieldName' => 'testField', + 'code' => 'MY_CODE', + 'message' => 'My test message', + 'relatedResources' => array( + 'trm-f3d38df1-adb7-4127-9858-e72ebe682a79', 'trm-601b1401-4464-4f3f-97b3-09079ee7723b') + ), + array( + 'code' => 'MY_SECOND_CODE', + 'message' => 'My second test message' + ) + ) + ); + + // Setup data + $encryption = new HyperwalletEncryption($clientPath, $hyperwalletPath); + $encryptedMessage = $encryption->encrypt($originalMessage); + + $mockHandler = new MockHandler(array( + new Response(400, array('Content-Type' => 'application/jose+json'), $encryptedMessage) + )); + $this->createApiClientWithEncryption($mockHandler); + + $model = new BaseModel(array(), array('test2' => 'value2')); + + // Execute test + try { + $this->apiClient->doPost('/test', array(), $model, array()); + $this->fail('HyperwalletApiException expected'); + } catch (HyperwalletApiException $e) { + $this->assertEquals('My test message', $e->getMessage()); + $this->assertNotNull($e->getErrorResponse()); + + $this->assertEquals(400, $e->getErrorResponse()->getStatusCode()); + $this->assertCount(2, $e->getErrorResponse()->getErrors()); + + $this->assertEquals('MY_CODE', $e->getErrorResponse()->getErrors()[0]->getCode()); + $this->assertEquals('My test message', $e->getErrorResponse()->getErrors()[0]->getMessage()); + $this->assertEquals('testField', $e->getErrorResponse()->getErrors()[0]->getFieldName()); + + $this->assertEquals('MY_SECOND_CODE', $e->getErrorResponse()->getErrors()[1]->getCode()); + $this->assertEquals('My second test message', $e->getErrorResponse()->getErrors()[1]->getMessage()); + $this->assertNull($e->getErrorResponse()->getErrors()[1]->getFieldName()); + + $this->assertCount(2, $e->getRelatedResources()); + $this->assertEquals('trm-f3d38df1-adb7-4127-9858-e72ebe682a79', $e->getRelatedResources()[0]); + $this->assertEquals('trm-601b1401-4464-4f3f-97b3-09079ee7723b', $e->getRelatedResources()[1]); + } + + // Validate api request + $this->validateRequest('POST', '/test', '', array('test2' => 'value2'), true, array(), true); + } + public function testDoPost_throw_exception_server_error() { // Setup data $mockHandler = new MockHandler(array(