From ab1526270c0144d4c26c7fc7cc6cc0979de6f53b Mon Sep 17 00:00:00 2001 From: Grzegorz Rajchman Date: Wed, 15 May 2024 10:10:27 +0100 Subject: [PATCH] Migrate to guzzlehttp/guzzle (#8) --- .circleci/config.yml | 4 +-- composer.json | 13 +++++---- src/SRU/Client.php | 56 +++++++++++++++++++-------------------- tests/unit/ClientTest.php | 44 +++++++++++++++++++++++++++++- 4 files changed, 79 insertions(+), 38 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 768e953..a68ab0b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -42,5 +42,5 @@ workflows: php_version: - '7.3' - '7.4' - # - '8.0' - # - '8.3' + - '8.0' + - '8.3' diff --git a/composer.json b/composer.json index d71c6c3..816e970 100644 --- a/composer.json +++ b/composer.json @@ -5,24 +5,23 @@ "homepage": "https://github.com/talis/SRUclient-php", "type": "library", "license": "MIT", - "authors":[ + "authors": [ { - "name":"Ross Singer", + "name": "Ross Singer", "email": "rxs@talis.com", - "homepage":"http://engineering.talis.com" + "homepage": "http://engineering.talis.com" } ], - "require":{ + "require": { "php": ">=7.3", - "monolog/monolog": ">=1.5.0", - "guzzle/guzzle":"~3.7" + "guzzlehttp/guzzle": "^6.5.8 || ^7.4.5" }, "require-dev": { "squizlabs/php_codesniffer": "3.*", "phpunit/phpunit": "^8.5.38", "pear/file_marc": "1.1.2" }, - "autoload":{ + "autoload": { "psr-4": { "SRU\\": "src/SRU/" } diff --git a/src/SRU/Client.php b/src/SRU/Client.php index de97907..79e8c7f 100644 --- a/src/SRU/Client.php +++ b/src/SRU/Client.php @@ -2,6 +2,8 @@ namespace SRU; +use GuzzleHttp\RequestOptions; + class Client { /** @@ -35,7 +37,7 @@ class Client private $defaultSRUVersion = "1.1"; /** - * @var \Guzzle\Http\Client + * @var \GuzzleHttp\Client */ private $httpClient; @@ -71,13 +73,14 @@ public function explain($raw = false) $explainResponse = $this->fetch( ['version' => $this->getDefaultSRUVersion(), 'operation' => 'explain'] ); + $body = (string) $explainResponse->getBody(); if ($raw) { - $explain = $explainResponse->getBody(); - } else { - $explain = new \DOMDocument(); - $explain->loadXML($explainResponse->getBody()); + return $body; } + $explain = new \DOMDocument(); + $explain->loadXML($body); + return $explain; } @@ -118,15 +121,16 @@ public function searchRetrieve($query, $options = [], $raw = false) $searchRetrieveResponse = $this->fetch( array_merge($defaultOptions, $options, ['operation' => 'searchRetrieve', 'query' => $query]) ); + $body = (string) $searchRetrieveResponse->getBody(); if ($raw) { - $searchRetrieve = $searchRetrieveResponse->getBody(); - } else { - $searchXML = new \DOMDocument(); - $searchXML->loadXML($searchRetrieveResponse->getBody()); - - $searchRetrieve = new SearchRetrieveResponse($searchXML); + return $body; } + $searchXML = new \DOMDocument(); + $searchXML->loadXML($body); + + $searchRetrieve = new SearchRetrieveResponse($searchXML); + return $searchRetrieve; } @@ -149,11 +153,12 @@ public function scan($scanClause, $options = [], $raw = false) $scanResponse = $this->fetch( array_merge($defaultOptions, $options, ['operation' => 'scan', 'scanClause' => $scanClause]) ); + $body = (string) $scanResponse->getBody(); if ($raw) { - $scan = $scanResponse->getBody(); - } else { - $scan = new ScanResponse($scanResponse->getBody()); + return $body; } + + $scan = new ScanResponse($body); return $scan; } @@ -211,10 +216,9 @@ public function indexes() /** * Performs the HTTP request based on the defined request method * @param array $args - * @param array $options - * @return \Guzzle\Http\Message\Response + * @return \Psr\Http\Message\ResponseInterface */ - protected function fetch(array $args = null, array $options = []) + protected function fetch(array $args = []) { $client = $this->getHttpClient(); @@ -225,16 +229,12 @@ protected function fetch(array $args = null, array $options = []) $url = $this->getBaseUrl() . '?' . http_build_query($args); } - $request = $client->get($url, $args, $options); - $response = $request->send(); - - return $response; - } else { - $request = $client->post($this->getBaseUrl(), array(), $args, $options); - $response = $request->send(); - - return $response; + return $client->get($url); } + + return $client->post($this->getBaseUrl(), [ + RequestOptions::FORM_PARAMS => $args, + ]); } /** @@ -314,12 +314,12 @@ public function setDefaultHttpMethod($defaultHttpMethod) /** * Lazy loader for the GuzzleClient - * @return \Guzzle\Http\Client + * @return \GuzzleHttp\Client */ protected function getHttpClient() { if (!$this->httpClient) { - $this->httpClient = new \Guzzle\Http\Client(); + $this->httpClient = new \GuzzleHttp\Client(); } return $this->httpClient; } diff --git a/tests/unit/ClientTest.php b/tests/unit/ClientTest.php index f6af170..77c5600 100644 --- a/tests/unit/ClientTest.php +++ b/tests/unit/ClientTest.php @@ -2,8 +2,10 @@ namespace SRU\tests; -use SRU\Client; +use GuzzleHttp\Exception\ClientException; +use GuzzleHttp\Exception\ServerException; use PHPUnit\Framework\TestCase; +use SRU\Client; class ClientTest extends TestCase { @@ -113,4 +115,44 @@ public function scanDataProvider(): iterable yield 'Override default maximumTerms' => ['GET', ['maximumRecords' => '42']]; yield 'Call options' => ['GET', ['version' => '2.0'], ['version' => '3.0', 'responsePosition' => 5]]; } + + /** + * @dataProvider clientErrorStatusProvider + */ + public function testThrowsClientException(int $status) + { + $this->expectException(ClientException::class); + $this->expectExceptionCode($status); + + $client = new Client(self::$httpbinHost . '/status/' . $status); + $client->explain(true); + } + + public function clientErrorStatusProvider(): iterable + { + yield 'Bad Request' => [400]; + yield 'Unauthorized' => [401]; + yield 'Forbidden' => [403]; + yield 'Not Found' => [404]; + } + + /** + * @dataProvider serverErrorStatusProvider + */ + public function testThrowsServerException(int $status) + { + $this->expectException(ServerException::class); + $this->expectExceptionCode($status); + + $client = new Client(self::$httpbinHost . '/status/' . $status); + $client->explain(true); + } + + public function serverErrorStatusProvider(): iterable + { + yield 'Internal Server Error' => [500]; + yield 'Bad Gateway' => [502]; + yield 'Service Unavailable' => [503]; + yield 'Gateway Timeout' => [504]; + } }