From 3c7164581cecc69c88e5ab1e864e45e4ff2ab169 Mon Sep 17 00:00:00 2001 From: "edgars.neimanis" Date: Mon, 3 Mar 2025 15:40:08 +0200 Subject: [PATCH] update timeout and middleware definition to allow per request usage --- README.md | 19 ++++++++++---- src/TmsApi.php | 28 +++++++++++--------- tests/Unit/TmsApiTest.php | 55 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 47e1bcc..cfabf45 100644 --- a/README.md +++ b/README.md @@ -77,28 +77,37 @@ TmsApi::createClient('default', new BearerAuthMethod($bearerToken)); // TmsApi::client('default')->run(...); ``` -### Configure Client +### Configure request -**Note:** This will override settings for upcoming requests on `default` client. +**Note:** These parameters will be present only for a single (upcoming) request and then will reset to defaults. #### `timeout` and `connectTimeout` ```php use Newman\LaravelTmsApiClient\Support\Facades\TmsApi; -TmsApi::client('default')->timeout(30)->connectTimeout(45); +TmsApi::client('default')->timeout(30)->connectTimeout(45)->run(...); ``` #### `withMiddleware` Append HTTP middleware to this client upcoming requests. -https://laravel.com/docs/9.x/http-client#guzzle-middleware +https://laravel.com/docs/12.x/http-client#guzzle-middleware ```php +use GuzzleHttp\Middleware; use Newman\LaravelTmsApiClient\Support\Facades\TmsApi; -TmsApi::client('default')->withMiddleware(...); +TmsApi::client('default') + ->withMiddleware( + Middleware::mapRequest(function (RequestInterface $request) { + $request = $request->withHeader('X-Example', 'Value'); + + return $request; + }) + ) + ->run(....); ``` ## Response diff --git a/src/TmsApi.php b/src/TmsApi.php index 63832c8..f99cb84 100644 --- a/src/TmsApi.php +++ b/src/TmsApi.php @@ -28,13 +28,13 @@ public function __construct(protected Application $app) {} */ public function client(string $name): ClientContract { - if (! isset($this->clients[$name])) { - $clientConfig = Config::get('tms-api.clients.'.$name); + $clientConfig = Config::get('tms-api.clients.'.$name); - if (! Config::has('tms-api.clients.'.$name) || ! is_array($clientConfig)) { - throw new InvalidTmsApiClientException('TMS Api client could\'nt be found.'); - } + if (! Config::has('tms-api.clients.'.$name) || ! is_array($clientConfig)) { + throw new InvalidTmsApiClientException('TMS Api client could\'nt be found.'); + } + if (! isset($this->clients[$name])) { if (! Arr::has($clientConfig, 'auth.username') || ! Arr::has($clientConfig, 'auth.password')) { throw new InvalidTmsApiClientException('TMS Api client auth credentials are not provided.'); } @@ -45,19 +45,21 @@ public function client(string $name): ClientContract $basicAuth = new BasicAuthMethod($clientUsername, $clientPassword); $this->clients[$name] = $this->makeClient($basicAuth); + } + + $pendingClient = clone $this->clients[$name]; - if (Arr::has($clientConfig, 'http')) { - if (Arr::has($clientConfig, 'http.timeout')) { - $this->clients[$name]->timeout(Config::integer('tms-api.clients.'.$name.'.http.timeout')); - } + if (Arr::has($clientConfig, 'http')) { + if (Arr::has($clientConfig, 'http.timeout')) { + $this->clients[$name]->timeout(Config::integer('tms-api.clients.'.$name.'.http.timeout')); + } - if (Arr::has($clientConfig, 'http.connect_timeout')) { - $this->clients[$name]->connectTimeout(Config::integer('tms-api.clients.'.$name.'.http.connect_timeout')); - } + if (Arr::has($clientConfig, 'http.connect_timeout')) { + $this->clients[$name]->connectTimeout(Config::integer('tms-api.clients.'.$name.'.http.connect_timeout')); } } - return $this->clients[$name]; + return $pendingClient; } /** diff --git a/tests/Unit/TmsApiTest.php b/tests/Unit/TmsApiTest.php index 66ad715..37f037e 100644 --- a/tests/Unit/TmsApiTest.php +++ b/tests/Unit/TmsApiTest.php @@ -5,11 +5,15 @@ namespace Newman\LaravelTmsApiClient\Tests\Unit; use Illuminate\Contracts\Config\Repository as ConfigRepository; +use Illuminate\Http\Client\Request; use Illuminate\Support\Arr; +use Illuminate\Support\Facades\Http; use Newman\LaravelTmsApiClient\Auth\ApiKeyAuthMethod; use Newman\LaravelTmsApiClient\Client; +use Newman\LaravelTmsApiClient\Contracts\ClientContract; use Newman\LaravelTmsApiClient\Exceptions\InvalidTmsApiClientException; use Newman\LaravelTmsApiClient\Support\Facades\TmsApi; +use Newman\LaravelTmsApiClient\Tests\Support\GetTestEndpoint; use Newman\LaravelTmsApiClient\Tests\TestCase; class TmsApiTest extends TestCase @@ -111,4 +115,55 @@ public function test_it_throws_exception_when_api_client_auth_config_is_not_prov TmsApi::client('ipsum'); } + + public function test_it_respects_individual_timeouts_on_client(): void + { + TmsApi::fake(); + + /** @var ConfigRepository $config */ + $config = $this->app->make(ConfigRepository::class); + + $config->set('tms-api.clients', [ + 'ipsum' => [ + 'auth' => [ + 'username' => 'lorem', + 'password' => 'ipsum', + ], + + 'http' => [ + 'timeout' => 1, + 'connect_timeout' => 1, + ], + ], + ]); + + $runClientTest = function (ClientContract $client, int $timeout, int $connection_timeout) { + $actualClientTimeout = null; + $actualClientConnectionTimeout = null; + + $clientHttpFactory = $client->buildHttpFactory(); + $clientHttpFactory->preventStrayRequests(); + $clientHttpFactory->fake(function (Request $request, array $options) use (&$actualClientTimeout, &$actualClientConnectionTimeout) { + $actualClientTimeout = $options['timeout']; + $actualClientConnectionTimeout = $options['connect_timeout']; + + if ($request->url() == 'https://api.cloudycdn.services/api/v5/Test?status=ingested') { + return Http::response(['msg' => '', 'code' => 0]); + } + + return Http::response('----', 404); + }); + + $client + ->timeout($timeout) + ->connectTimeout($connection_timeout) + ->run(new GetTestEndpoint); + + $this->assertEquals($timeout, $actualClientTimeout); + $this->assertEquals($connection_timeout, $actualClientConnectionTimeout); + }; + + $runClientTest(TmsApi::client('ipsum'), 15, 15); + $runClientTest(TmsApi::client('ipsum'), 20, 20); + } }