diff --git a/.phpstan.ignoreErrors.neon b/.phpstan.ignoreErrors.neon index a312407e..14f5d8b0 100644 --- a/.phpstan.ignoreErrors.neon +++ b/.phpstan.ignoreErrors.neon @@ -12,5 +12,10 @@ parameters: - message: '/Access to undefined constant GuzzleHttp\\ClientInterface::/' - path: src/MollieApiClient.php + path: src/HttpAdapter/MollieHttpAdapterPicker.php + count: 1 + + - + message: '/Access to undefined constant GuzzleHttp\\ClientInterface::/' + path: src/HttpAdapter/Guzzle6And7MollieHttpAdapter.php count: 1 diff --git a/composer.json b/composer.json index ee012f20..d7f537d0 100644 --- a/composer.json +++ b/composer.json @@ -51,11 +51,11 @@ "ext-curl": "*", "ext-json": "*", "ext-openssl": "*", - "composer/ca-bundle": "^1.1", - "guzzlehttp/guzzle": "^6.3 || ^7.0" + "composer/ca-bundle": "^1.1" }, "require-dev": { "eloquent/liberator": "^2.0", + "guzzlehttp/guzzle": "^6.3 || ^7.0", "phpunit/phpunit": "^5.7 || ^6.5 || ^7.1 || ^8.5", "friendsofphp/php-cs-fixer": "^3.0" }, diff --git a/src/Endpoints/EndpointAbstract.php b/src/Endpoints/EndpointAbstract.php index fa3a17e3..bf4f6079 100644 --- a/src/Endpoints/EndpointAbstract.php +++ b/src/Endpoints/EndpointAbstract.php @@ -205,7 +205,7 @@ protected function parseRequestBody(array $body) } try { - $encoded = \GuzzleHttp\json_encode($body); + $encoded = @json_encode($body); } catch (\InvalidArgumentException $e) { throw new ApiException("Error encoding parameters into JSON: '".$e->getMessage()."'."); } diff --git a/src/Exceptions/ApiException.php b/src/Exceptions/ApiException.php index 67f17260..a80ba11e 100644 --- a/src/Exceptions/ApiException.php +++ b/src/Exceptions/ApiException.php @@ -3,8 +3,6 @@ namespace Mollie\Api\Exceptions; use DateTime; -use Psr\Http\Message\RequestInterface; -use Psr\Http\Message\ResponseInterface; class ApiException extends \Exception { @@ -14,12 +12,12 @@ class ApiException extends \Exception protected $field; /** - * @var RequestInterface + * @var \Psr\Http\Message\RequestInterface|null */ protected $request; /** - * @var ResponseInterface + * @var \Psr\Http\Message\ResponseInterface|null */ protected $response; @@ -39,8 +37,8 @@ class ApiException extends \Exception * @param string $message * @param int $code * @param string|null $field - * @param RequestInterface|null $request - * @param ResponseInterface|null $response + * @param \Psr\Http\Message\RequestInterface|null $request + * @param \Psr\Http\Message\ResponseInterface|null $response * @param \Throwable|null $previous * @throws \Mollie\Api\Exceptions\ApiException */ @@ -48,8 +46,8 @@ public function __construct( $message = "", $code = 0, $field = null, - RequestInterface $request = null, - ResponseInterface $response = null, + $request = null, + $response = null, $previous = null ) { $this->raisedAt = new \DateTimeImmutable(); @@ -91,35 +89,13 @@ public function __construct( } /** - * @param \GuzzleHttp\Exception\GuzzleException $guzzleException - * @param RequestInterface|null $request - * @param \Throwable|null $previous - * @return \Mollie\Api\Exceptions\ApiException - * @throws \Mollie\Api\Exceptions\ApiException - */ - public static function createFromGuzzleException( - $guzzleException, - $request = null, - $previous = null - ) { - // Not all Guzzle Exceptions implement hasResponse() / getResponse() - if (method_exists($guzzleException, 'hasResponse') && method_exists($guzzleException, 'getResponse')) { - if ($guzzleException->hasResponse()) { - return static::createFromResponse($guzzleException->getResponse(), $request, $previous); - } - } - - return new self($guzzleException->getMessage(), $guzzleException->getCode(), null, $request, null, $previous); - } - - /** - * @param ResponseInterface $response - * @param RequestInterface $request + * @param \Psr\Http\Message\ResponseInterface $response + * @param \Psr\Http\Message\RequestInterface $request * @param \Throwable|null $previous * @return \Mollie\Api\Exceptions\ApiException * @throws \Mollie\Api\Exceptions\ApiException */ - public static function createFromResponse(ResponseInterface $response, RequestInterface $request = null, $previous = null) + public static function createFromResponse($response, $request = null, $previous = null) { $object = static::parseResponseBody($response); @@ -163,7 +139,7 @@ public function getDashboardUrl() } /** - * @return ResponseInterface|null + * @return \Psr\Http\Message\ResponseInterface|null */ public function getResponse() { @@ -214,7 +190,7 @@ public function getUrl($key) } /** - * @return RequestInterface + * @return \Psr\Http\Message\RequestInterface */ public function getRequest() { @@ -232,8 +208,8 @@ public function getRaisedAt() } /** - * @param ResponseInterface $response - * @return mixed + * @param \Psr\Http\Message\ResponseInterface $response + * @return \stdClass * @throws \Mollie\Api\Exceptions\ApiException */ protected static function parseResponseBody($response) diff --git a/src/Exceptions/UnrecognizedClientException.php b/src/Exceptions/UnrecognizedClientException.php new file mode 100644 index 00000000..58c786d1 --- /dev/null +++ b/src/Exceptions/UnrecognizedClientException.php @@ -0,0 +1,7 @@ +parseHeaders($headers)); + curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, self::DEFAULT_CONNECT_TIMEOUT); + curl_setopt($curl, CURLOPT_TIMEOUT, self::DEFAULT_TIMEOUT); + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true); + curl_setopt($curl, CURLOPT_CAINFO, CaBundle::getBundledCaBundlePath()); + + switch ($httpMethod) { + case MollieApiClient::HTTP_POST: + curl_setopt($curl, CURLOPT_POST, true); + curl_setopt($curl, CURLOPT_POSTFIELDS, $httpBody); + + break; + case MollieApiClient::HTTP_GET: + break; + case MollieApiClient::HTTP_PATCH: + curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PATCH'); + curl_setopt($curl, CURLOPT_POSTFIELDS, $httpBody); + + break; + case MollieApiClient::HTTP_DELETE: + curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE'); + curl_setopt($curl, CURLOPT_POSTFIELDS, $httpBody); + + break; + default: + throw new \InvalidArgumentException("Invalid http method: ". $httpMethod); + } + + $response = curl_exec($curl); + + if ($response === false) { + throw new ApiException("Curl error: " . curl_error($curl)); + } + + $statusCode = curl_getinfo($curl, CURLINFO_RESPONSE_CODE); + + curl_close($curl); + + return $this->parseResponseBody($response, $statusCode, $httpBody); + } + + /** + * The version number for the underlying http client, if available. + * @example Guzzle/6.3 + * + * @return string|null + */ + public function versionString() + { + return 'Curl/*'; + } + + /** + * @param string $response + * @param int $statusCode + * @param string $httpBody + * @return \stdClass|null + * @throws \Mollie\Api\Exceptions\ApiException + */ + protected function parseResponseBody($response, $statusCode, $httpBody) + { + if (empty($response)) { + if ($statusCode === self::HTTP_NO_CONTENT) { + return null; + } + + throw new ApiException("No response body found."); + } + + $body = @json_decode($response); + + // GUARDS + if (json_last_error() !== JSON_ERROR_NONE) { + throw new ApiException("Unable to decode Mollie response: '{$response}'."); + } + + if (isset($body->error)) { + throw new ApiException($body->error->message); + } + + if ($statusCode >= 400) { + $message = "Error executing API call ({$body->status}: {$body->title}): {$body->detail}"; + + $field = null; + + if (! empty($body->field)) { + $field = $body->field; + } + + if (isset($body->_links, $body->_links->documentation)) { + $message .= ". Documentation: {$body->_links->documentation->href}"; + } + + if ($httpBody) { + $message .= ". Request body: {$httpBody}"; + } + + throw new ApiException($message, $statusCode, $field); + } + + return $body; + } + + protected function parseHeaders($headers) + { + $result = []; + + foreach ($headers as $key => $value) { + $result[] = $key .': ' . $value; + } + + return $result; + } +} diff --git a/src/HttpAdapter/Guzzle6And7MollieHttpAdapter.php b/src/HttpAdapter/Guzzle6And7MollieHttpAdapter.php new file mode 100644 index 00000000..b5f7597d --- /dev/null +++ b/src/HttpAdapter/Guzzle6And7MollieHttpAdapter.php @@ -0,0 +1,146 @@ +httpClient = $httpClient; + } + + /** + * Instantiate a default adapter with sane configuration for Guzzle 6 or 7. + * + * @return static + */ + public static function createDefault() + { + $retryMiddlewareFactory = new Guzzle6And7RetryMiddlewareFactory; + $handlerStack = HandlerStack::create(); + $handlerStack->push($retryMiddlewareFactory->retry()); + + $client = new Client([ + GuzzleRequestOptions::VERIFY => CaBundle::getBundledCaBundlePath(), + GuzzleRequestOptions::TIMEOUT => self::DEFAULT_TIMEOUT, + GuzzleRequestOptions::CONNECT_TIMEOUT => self::DEFAULT_CONNECT_TIMEOUT, + 'handler' => $handlerStack, + ]); + + return new Guzzle6And7MollieHttpAdapter($client); + } + + /** + * Send a request to the specified Mollie api url. + * + * @param $httpMethod + * @param $url + * @param $headers + * @param $httpBody + * @return \stdClass|null + * @throws \Mollie\Api\Exceptions\ApiException + */ + public function send($httpMethod, $url, $headers, $httpBody) + { + $request = new Request($httpMethod, $url, $headers, $httpBody); + + try { + $response = $this->httpClient->send($request, ['http_errors' => false]); + } catch (GuzzleException $e) { + + // Not all Guzzle Exceptions implement hasResponse() / getResponse() + if (method_exists($e, 'hasResponse') && method_exists($e, 'getResponse')) { + if ($e->hasResponse()) { + throw ApiException::createFromResponse($e->getResponse(), $request); + } + } + + throw new ApiException($e->getMessage(), $e->getCode(), null, $request, null); + } + + if (! $response) { + throw new ApiException("Did not receive API response.", 0, null, $request); + } + + return $this->parseResponseBody($response); + } + + /** + * Parse the PSR-7 Response body + * + * @param ResponseInterface $response + * @return \stdClass|null + * @throws ApiException + */ + private function parseResponseBody(ResponseInterface $response) + { + $body = (string) $response->getBody(); + if (empty($body)) { + if ($response->getStatusCode() === self::HTTP_NO_CONTENT) { + return null; + } + + throw new ApiException("No response body found."); + } + + $object = @json_decode($body); + + if (json_last_error() !== JSON_ERROR_NONE) { + throw new ApiException("Unable to decode Mollie response: '{$body}'."); + } + + if ($response->getStatusCode() >= 400) { + throw ApiException::createFromResponse($response, null); + } + + return $object; + } + + /** + * The version number for the underlying http client, if available. This is used to report the UserAgent to Mollie, + * for convenient support. + * @example Guzzle/6.3 + * + * @return string|null + */ + public function versionString() + { + if (defined('\GuzzleHttp\ClientInterface::MAJOR_VERSION')) { // Guzzle 7 + return "Guzzle/" . ClientInterface::MAJOR_VERSION; + } elseif (defined('\GuzzleHttp\ClientInterface::VERSION')) { // Before Guzzle 7 + return "Guzzle/" . ClientInterface::VERSION; + } + + return null; + } +} diff --git a/src/Guzzle/RetryMiddlewareFactory.php b/src/HttpAdapter/Guzzle6And7RetryMiddlewareFactory.php similarity index 96% rename from src/Guzzle/RetryMiddlewareFactory.php rename to src/HttpAdapter/Guzzle6And7RetryMiddlewareFactory.php index 5e28867e..1b5f6875 100644 --- a/src/Guzzle/RetryMiddlewareFactory.php +++ b/src/HttpAdapter/Guzzle6And7RetryMiddlewareFactory.php @@ -1,6 +1,6 @@ guzzleIsDetected()) { + $guzzleVersion = $this->guzzleMajorVersionNumber(); + + if ($guzzleVersion && in_array($guzzleVersion, [6, 7])) { + return Guzzle6And7MollieHttpAdapter::createDefault(); + } + } + + return new CurlMollieHttpAdapter; + } + + if ($httpClient instanceof MollieHttpAdapterInterface) { + return $httpClient; + } + + if ($httpClient instanceof \GuzzleHttp\ClientInterface) { + return new Guzzle6And7MollieHttpAdapter($httpClient); + } + + throw new UnrecognizedClientException('The provided http client or adapter was not recognized.'); + } + + /** + * @return bool + */ + private function guzzleIsDetected() + { + return interface_exists("\GuzzleHttp\ClientInterface"); + } + + /** + * @return int|null + */ + private function guzzleMajorVersionNumber() + { + // Guzzle 7 + if (defined('\GuzzleHttp\ClientInterface::MAJOR_VERSION')) { + return (int) \GuzzleHttp\ClientInterface::MAJOR_VERSION; + } + + // Before Guzzle 7 + if (defined('\GuzzleHttp\ClientInterface::VERSION')) { + return (int) \GuzzleHttp\ClientInterface::VERSION[0]; + } + + return null; + } +} diff --git a/src/HttpAdapter/MollieHttpAdapterPickerInterface.php b/src/HttpAdapter/MollieHttpAdapterPickerInterface.php new file mode 100644 index 00000000..b91542d6 --- /dev/null +++ b/src/HttpAdapter/MollieHttpAdapterPickerInterface.php @@ -0,0 +1,13 @@ +httpClient = $httpClient; - - if (! $this->httpClient) { - $retryMiddlewareFactory = new RetryMiddlewareFactory; - $handlerStack = HandlerStack::create(); - $handlerStack->push($retryMiddlewareFactory->retry()); - - $this->httpClient = new Client([ - GuzzleRequestOptions::VERIFY => CaBundle::getBundledCaBundlePath(), - GuzzleRequestOptions::TIMEOUT => self::TIMEOUT, - GuzzleRequestOptions::CONNECT_TIMEOUT => self::CONNECT_TIMEOUT, - 'handler' => $handlerStack, - ]); - } + $httpAdapterPicker = $httpAdapterPicker ?: new MollieHttpAdapterPicker; + $this->httpClient = $httpAdapterPicker->pickHttpAdapter($httpClient); - $compatibilityChecker = new CompatibilityChecker(); + $compatibilityChecker = new CompatibilityChecker; $compatibilityChecker->checkCompatibility(); $this->initializeEndpoints(); @@ -313,10 +272,9 @@ public function __construct(ClientInterface $httpClient = null) $this->addVersionString("Mollie/" . self::CLIENT_VERSION); $this->addVersionString("PHP/" . phpversion()); - if (defined('\GuzzleHttp\ClientInterface::MAJOR_VERSION')) { // Guzzle 7 - $this->addVersionString("Guzzle/" . ClientInterface::MAJOR_VERSION); - } elseif (defined('\GuzzleHttp\ClientInterface::VERSION')) { // Before Guzzle 7 - $this->addVersionString("Guzzle/" . ClientInterface::VERSION); + $httpClientVersionString = $this->httpClient->versionString(); + if ($httpClientVersionString) { + $this->addVersionString($httpClientVersionString); } } @@ -369,6 +327,14 @@ public function getApiEndpoint() return $this->apiEndpoint; } + /** + * @return array + */ + public function getVersionStrings() + { + return $this->versionStrings; + } + /** * @param string $apiKey The Mollie API key, starting with 'test_' or 'live_' * @@ -437,7 +403,7 @@ public function addVersionString($versionString) * * @param string $httpMethod * @param string $apiMethod - * @param string|null|resource|StreamInterface $httpBody + * @param string|null $httpBody * * @return \stdClass * @throws ApiException @@ -459,7 +425,7 @@ public function performHttpCall($httpMethod, $apiMethod, $httpBody = null) * * @param string $httpMethod * @param string $url - * @param string|null|resource|StreamInterface $httpBody + * @param string|null $httpBody * * @return \stdClass|null * @throws ApiException @@ -488,50 +454,7 @@ public function performHttpCallToFullUrl($httpMethod, $url, $httpBody = null) $headers['X-Mollie-Client-Info'] = php_uname(); } - $request = new Request($httpMethod, $url, $headers, $httpBody); - - try { - $response = $this->httpClient->send($request, ['http_errors' => false]); - } catch (GuzzleException $e) { - throw ApiException::createFromGuzzleException($e, $request); - } - - if (! $response) { - throw new ApiException("Did not receive API response.", 0, null, $request); - } - - return $this->parseResponseBody($response); - } - - /** - * Parse the PSR-7 Response body - * - * @param ResponseInterface $response - * @return \stdClass|null - * @throws ApiException - */ - private function parseResponseBody(ResponseInterface $response) - { - $body = (string) $response->getBody(); - if (empty($body)) { - if ($response->getStatusCode() === self::HTTP_NO_CONTENT) { - return null; - } - - throw new ApiException("No response body found."); - } - - $object = @json_decode($body); - - if (json_last_error() !== JSON_ERROR_NONE) { - throw new ApiException("Unable to decode Mollie response: '{$body}'."); - } - - if ($response->getStatusCode() >= 400) { - throw ApiException::createFromResponse($response, null); - } - - return $object; + return $this->httpClient->send($httpMethod, $url, $headers, $httpBody); } /** @@ -555,8 +478,7 @@ public function __sleep() /** * When unserializing a collection or a resource, this class should restore itself. * - * Note that if you use a custom GuzzleClient, this client is lost. You can't re set the Client, so you should - * probably not use this feature. + * Note that if you have set an HttpAdapter, this adapter is lost on wakeup and reset to the default one. * * @throws IncompatiblePlatform If suddenly unserialized on an incompatible platform. */ diff --git a/tests/Mollie/API/Exceptions/ApiExceptionTest.php b/tests/Mollie/API/Exceptions/ApiExceptionTest.php index 0daa3917..9a05833f 100644 --- a/tests/Mollie/API/Exceptions/ApiExceptionTest.php +++ b/tests/Mollie/API/Exceptions/ApiExceptionTest.php @@ -2,7 +2,6 @@ namespace Tests\Mollie\API\Exceptions; -use GuzzleHttp\Exception\RequestException; use GuzzleHttp\Psr7\Request; use GuzzleHttp\Psr7\Response; use Mollie\Api\Exceptions\ApiException; @@ -13,86 +12,6 @@ class ApiExceptionTest extends TestCase { use LinkObjectTestHelpers; - public function testCreateFromGuzzleException() - { - $response = new Response( - 422, - [], - '{ - "status": 422, - "title": "Unprocessable Entity", - "detail": "Can not enable Credit card via the API. Please go to the dashboard to enable this payment method.", - "_links": { - "dashboard": { - "href": "https://www.mollie.com/dashboard/settings/profiles/pfl_v9hTwCvYqw/payment-methods", - "type": "text/html" - }, - "documentation": { - "href": "https://docs.mollie.com/guides/handling-errors", - "type": "text/html" - } - } - }' - ); - - $guzzleException = new RequestException( - 'Something went wrong...', - new Request( - 'POST', - 'https://api.mollie.com/v2/profiles/pfl_v9hTwCvYqw/methods/bancontact', - [], - '{ "foo": "bar" }' - ), - $response - ); - - $exception = ApiException::createFromGuzzleException($guzzleException); - - $this->assertInstanceOf(ApiException::class, $exception); - $this->assertInstanceOf(Response::class, $exception->getResponse()); - - $this->assertEquals($response, $exception->getResponse()); - $this->assertTrue($exception->hasResponse()); - - $this->assertTrue($exception->hasLink('dashboard')); - $this->assertTrue($exception->hasLink('documentation')); - $this->assertFalse($exception->hasLink('foo')); - - $this->assertLinkObject( - 'https://www.mollie.com/dashboard/settings/profiles/pfl_v9hTwCvYqw/payment-methods', - 'text/html', - $exception->getLink('dashboard') - ); - - $this->assertEquals( - 'https://www.mollie.com/dashboard/settings/profiles/pfl_v9hTwCvYqw/payment-methods', - $exception->getUrl('dashboard') - ); - - $this->assertEquals( - 'https://www.mollie.com/dashboard/settings/profiles/pfl_v9hTwCvYqw/payment-methods', - $exception->getDashboardUrl() - ); - - $this->assertLinkObject( - 'https://docs.mollie.com/guides/handling-errors', - 'text/html', - $exception->getLink('documentation') - ); - - $this->assertEquals( - 'https://docs.mollie.com/guides/handling-errors', - $exception->getDocumentationUrl() - ); - - $this->assertNull($exception->getLink('foo')); - $this->assertNull($exception->getUrl('foo')); - - $this->assertInstanceOf(\DateTimeInterface::class, $exception->getRaisedAt()); - - $this->assertNull($exception->getRequest()); - } - public function testCanGetRequestBodyIfRequestIsSet() { $response = new Response( @@ -124,13 +43,7 @@ public function testCanGetRequestBodyIfRequestIsSet() '{ "foo": "bar" }' ); - $guzzleException = new RequestException( - 'Something went wrong...', - $request, - $response - ); - - $exception = ApiException::createFromGuzzleException($guzzleException, $request); + $exception = ApiException::createFromResponse($response, $request); $this->assertJsonStringEqualsJsonString(/** @lang JSON */'{ "foo": "bar" }', $exception->getRequest()->getBody()->__toString()); $this->assertStringEndsWith('Error executing API call (422: Unprocessable Entity): Can not enable Credit card via the API. Please go to the dashboard to enable this payment method.. Documentation: https://docs.mollie.com/guides/handling-errors. Request body: { "foo": "bar" }', $exception->getMessage()); diff --git a/tests/Mollie/API/HttpAdapter/MockMollieHttpAdapter.php b/tests/Mollie/API/HttpAdapter/MockMollieHttpAdapter.php new file mode 100644 index 00000000..cf480b8b --- /dev/null +++ b/tests/Mollie/API/HttpAdapter/MockMollieHttpAdapter.php @@ -0,0 +1,22 @@ + 'bar']; + } + + /** + * @inheritDoc + */ + public function versionString() + { + return 'mock-client/1.0'; + } +} diff --git a/tests/Mollie/API/HttpAdapter/MollieHttpAdapterPickerTest.php b/tests/Mollie/API/HttpAdapter/MollieHttpAdapterPickerTest.php new file mode 100644 index 00000000..42e7523d --- /dev/null +++ b/tests/Mollie/API/HttpAdapter/MollieHttpAdapterPickerTest.php @@ -0,0 +1,55 @@ +pickHttpAdapter(null); + + $this->assertInstanceOf(Guzzle6And7MollieHttpAdapter::class, $adapter); + } + + /** @test */ + public function returnsTheAdapterThatWasPassedIn() + { + $picker = new MollieHttpAdapterPicker; + $mockAdapter = new MockMollieHttpAdapter; + + $adapter = $picker->pickHttpAdapter($mockAdapter); + + $this->assertInstanceOf(MockMollieHttpAdapter::class, $adapter); + $this->assertEquals($mockAdapter, $adapter); + } + + /** @test */ + public function wrapsAGuzzleClientIntoAnAdapter() + { + $picker = new MollieHttpAdapterPicker; + $guzzleClient = new GuzzleClient; + + $adapter = $picker->pickHttpAdapter($guzzleClient); + + $this->assertInstanceOf(Guzzle6And7MollieHttpAdapter::class, $adapter); + } + + /** @test */ + public function throwsAnExceptionWhenReceivingAnUnrecognizedClient() + { + $this->expectExceptionObject(new UnrecognizedClientException('The provided http client or adapter was not recognized')); + $picker = new MollieHttpAdapterPicker; + $unsupportedClient = (object) ['foo' => 'bar']; + + $picker->pickHttpAdapter($unsupportedClient); + } +} diff --git a/tests/Mollie/API/MollieApiClientTest.php b/tests/Mollie/API/MollieApiClientTest.php index 107dc09b..800ecf32 100644 --- a/tests/Mollie/API/MollieApiClientTest.php +++ b/tests/Mollie/API/MollieApiClientTest.php @@ -6,6 +6,7 @@ use GuzzleHttp\ClientInterface; use GuzzleHttp\Psr7\Response; use Mollie\Api\Exceptions\ApiException; +use Mollie\Api\HttpAdapter\Guzzle6And7MollieHttpAdapter; use Mollie\Api\MollieApiClient; class MollieApiClientTest extends \PHPUnit\Framework\TestCase @@ -122,7 +123,7 @@ public function testCanBeSerializedAndUnserialized() $client_copy = Liberator::liberate(unserialize($serialized)); $this->assertEmpty($client_copy->apiKey, "API key should not have been remembered"); - $this->assertInstanceOf(ClientInterface::class, $client_copy->httpClient, "A Guzzle client should have been set."); + $this->assertInstanceOf(Guzzle6And7MollieHttpAdapter::class, $client_copy->httpClient, "A Guzzle client should have been set."); $this->assertNull($client_copy->usesOAuth()); $this->assertEquals("https://mymollieproxy.local", $client_copy->getApiEndpoint(), "The API endpoint should be remembered"); diff --git a/tests/Mollie/Guzzle/RetryMiddlewareFactoryTest.php b/tests/Mollie/Guzzle/RetryMiddlewareFactoryTest.php index 9b3514fc..1ee85e71 100644 --- a/tests/Mollie/Guzzle/RetryMiddlewareFactoryTest.php +++ b/tests/Mollie/Guzzle/RetryMiddlewareFactoryTest.php @@ -8,14 +8,14 @@ use GuzzleHttp\HandlerStack; use GuzzleHttp\Psr7\Request; use GuzzleHttp\Psr7\Response; -use Mollie\Api\Guzzle\RetryMiddlewareFactory; +use Mollie\Api\HttpAdapter\Guzzle6And7RetryMiddlewareFactory; use PHPUnit\Framework\TestCase; class RetryMiddlewareFactoryTest extends TestCase { public function testRetriesConnectException() { - $middlewareFactory = new RetryMiddlewareFactory; + $middlewareFactory = new Guzzle6And7RetryMiddlewareFactory; $mock = new MockHandler( [ @@ -35,7 +35,7 @@ public function testRetriesConnectException() public function testRetryLimit() { - $middlewareFactory = new RetryMiddlewareFactory; + $middlewareFactory = new Guzzle6And7RetryMiddlewareFactory; $mock = new MockHandler( [ @@ -60,7 +60,7 @@ public function testRetryLimit() public function testRetryDelay() { - $middlewareFactory = new RetryMiddlewareFactory; + $middlewareFactory = new Guzzle6And7RetryMiddlewareFactory; $mock = new MockHandler( [