diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 9a3cf544..26a206ee 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -26,9 +26,11 @@ jobs: matrix: os: [ ubuntu-latest, windows-latest ] php: [ 8.2, 8.3, 8.4, 8.5 ] - stability: [ prefer-lowest, prefer-stable ] + guzzle: + - { constraint: '^7.6', stability: prefer-lowest } + - { constraint: '^8.0', stability: prefer-stable } - name: P${{ matrix.php }} - ${{ matrix.stability }} - ${{ matrix.os }} + name: P${{ matrix.php }} - Guzzle ${{ matrix.guzzle.constraint }} - ${{ matrix.os }} steps: - name: Checkout code @@ -47,7 +49,9 @@ jobs: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" - name: Install dependencies + shell: bash run: | - composer update --${{ matrix.stability }} --prefer-dist --no-interaction + composer require guzzlehttp/guzzle:${{ matrix.guzzle.constraint }} --no-update + composer update --${{ matrix.guzzle.stability }} --prefer-dist --no-interaction - name: Execute tests run: vendor/bin/pest -p diff --git a/composer.json b/composer.json index 4626f630..c6c78b1e 100644 --- a/composer.json +++ b/composer.json @@ -20,9 +20,9 @@ "homepage": "https://github.com/saloonphp/saloon", "require": { "php": "^8.2", - "guzzlehttp/guzzle": "^7.6", - "guzzlehttp/promises": "^1.5 || ^2.0", - "guzzlehttp/psr7": "^2.0", + "guzzlehttp/guzzle": "^7.6 || ^8.0", + "guzzlehttp/promises": "^1.5 || ^2.0 || ^3.0", + "guzzlehttp/psr7": "^2.0 || ^3.0", "psr/http-factory": "^1.0", "psr/http-message": "^1.1 || ^2.0" }, diff --git a/src/Http/Senders/GuzzleSender.php b/src/Http/Senders/GuzzleSender.php index 82c6a47e..b3c6870a 100644 --- a/src/Http/Senders/GuzzleSender.php +++ b/src/Http/Senders/GuzzleSender.php @@ -32,6 +32,8 @@ class GuzzleSender implements Sender /** * Guzzle's Handler Stack. + * + * @var HandlerStack): PromiseInterface> */ protected HandlerStack $handlerStack; @@ -84,6 +86,8 @@ protected function createGuzzleClient(): GuzzleClient /** * The default handler stack used by the underlying Guzzle client + * + * @return HandlerStack): PromiseInterface> */ protected function defaultHandlerStack(): HandlerStack { @@ -118,7 +122,7 @@ public function send(PendingRequest $pendingRequest): Response // Sometimes, Guzzle will throw a RequestException without a response. This // means that it was fatal, so we should still throw a fatal request exception. - $guzzleResponse = $exception->getResponse(); + $guzzleResponse = method_exists($exception, 'getResponse') ? $exception->getResponse() : null; if (is_null($guzzleResponse)) { throw new FatalRequestException($exception, $pendingRequest); @@ -166,7 +170,7 @@ function (TransferException $guzzleException) use ($pendingRequest, $psrRequest) // Sometimes, Guzzle will throw a RequestException without a response. This // means that it was fatal, so we should still throw a fatal request exception. - $guzzleResponse = $guzzleException->getResponse(); + $guzzleResponse = method_exists($guzzleException, 'getResponse') ? $guzzleException->getResponse() : null; if (is_null($guzzleResponse)) { throw new FatalRequestException($guzzleException, $pendingRequest); @@ -211,6 +215,8 @@ public function addMiddleware(callable $callable, string $name = ''): static /** * Overwrite the entire handler stack. * + * @param HandlerStack): PromiseInterface> $handlerStack + * * @return $this */ public function setHandlerStack(HandlerStack $handlerStack): static @@ -222,6 +228,8 @@ public function setHandlerStack(HandlerStack $handlerStack): static /** * Get the handler stack. + * + * @return HandlerStack): PromiseInterface> */ public function getHandlerStack(): HandlerStack { diff --git a/tests/Feature/Body/HasMultipartBodyTest.php b/tests/Feature/Body/HasMultipartBodyTest.php index ba9ea541..74ce4af0 100644 --- a/tests/Feature/Body/HasMultipartBodyTest.php +++ b/tests/Feature/Body/HasMultipartBodyTest.php @@ -74,7 +74,6 @@ expect((string)$guzzleRequest->getBody())->toContain( 'X-Saloon: Yee-haw!', 'Content-Disposition: form-data; name="nickname"; filename="user.txt"', - 'Content-Length: 3', 'Sam', ); @@ -135,7 +134,6 @@ expect($guzzleRequest->getBody()->getContents())->toContain( 'X-Saloon: Yee-haw!', 'Content-Disposition: form-data; name="nickname"; filename="user.txt"', - 'Content-Length: 3', 'Sam', 'Alfie', 'Tom', diff --git a/tests/Feature/GuzzleSenderTest.php b/tests/Feature/GuzzleSenderTest.php index a19c28b9..d6147eec 100644 --- a/tests/Feature/GuzzleSenderTest.php +++ b/tests/Feature/GuzzleSenderTest.php @@ -80,7 +80,7 @@ $saloonStack = invade($handlerStack)->stack; $defaultStack = invade(HandlerStack::create())->stack; - expect($saloonStack)->toHaveSameSize($defaultStack)->toHaveCount(4); + expect($saloonStack)->toHaveSameSize($defaultStack); expect($saloonStack[0][1])->toBe($defaultStack[0][1]); expect($saloonStack[1][1])->toBe($defaultStack[1][1]); @@ -116,7 +116,7 @@ $saloonStack = invade($saloonConfig['handler'])->stack; $defaultStack = invade($defaultConfig['handler'])->stack; - expect($saloonStack)->toHaveSameSize($defaultStack)->toHaveCount(4); + expect($saloonStack)->toHaveSameSize($defaultStack); }); test('you can set a custom handler stack on the guzzle sender', function () { diff --git a/tests/Feature/RetryConnectorTest.php b/tests/Feature/RetryConnectorTest.php index 0f5d4db5..1470b4e2 100644 --- a/tests/Feature/RetryConnectorTest.php +++ b/tests/Feature/RetryConnectorTest.php @@ -210,7 +210,7 @@ $connector = new RetryConnector(5, handleRetry: function (Exception $exception, Request $request) use (&$index) { $index++; - $request->headers()->add('X-Test-Index', $index); + $request->headers()->add('X-Test-Index', (string) $index); return true; }); @@ -230,7 +230,7 @@ $requestCount = 0; $connector = new RetryConnector(6, handleRetry: function (Exception $exception, Request $request) use (&$exceptions, &$index) { - $request->headers()->add('X-Yee-Haw', $index++); + $request->headers()->add('X-Yee-Haw', (string) $index++); return true; }); diff --git a/tests/Feature/RetryRequestTest.php b/tests/Feature/RetryRequestTest.php index 18c428f8..581c39b3 100644 --- a/tests/Feature/RetryRequestTest.php +++ b/tests/Feature/RetryRequestTest.php @@ -214,7 +214,7 @@ $response = $connector->send(new RetryUserRequest(5, handleRetry: function (Exception $exception, Request $request) use (&$index) { $index++; - $request->headers()->add('X-Test-Index', $index); + $request->headers()->add('X-Test-Index', (string) $index); return true; })); @@ -234,7 +234,7 @@ }); $request = new HeaderErrorRetryRequest(6, handleRetry: function (Exception $exception, Request $request) use (&$exceptions, &$index) { - $request->headers()->add('X-Yee-Haw', $index++); + $request->headers()->add('X-Yee-Haw', (string) $index++); return true; }); diff --git a/tests/Feature/SendAndRetryTest.php b/tests/Feature/SendAndRetryTest.php index bd477d96..ba6d8acf 100644 --- a/tests/Feature/SendAndRetryTest.php +++ b/tests/Feature/SendAndRetryTest.php @@ -235,7 +235,7 @@ $response = $connector->sendAndRetry(new UserRequest, 5, 0, function (Exception $exception, Request $request) use (&$index) { $index++; - $request->headers()->add('X-Test-Index', $index); + $request->headers()->add('X-Test-Index', (string) $index); return true; }); @@ -258,7 +258,7 @@ $index = 0; $response = $connector->sendAndRetry($request, 6, 0, function (Exception $exception, Request $request) use (&$exceptions, &$index) { - $request->headers()->add('X-Yee-Haw', $index++); + $request->headers()->add('X-Yee-Haw', (string) $index++); return true; }); diff --git a/tests/Fixtures/Senders/ArraySender.php b/tests/Fixtures/Senders/ArraySender.php index 44ee79f5..0802fa71 100644 --- a/tests/Fixtures/Senders/ArraySender.php +++ b/tests/Fixtures/Senders/ArraySender.php @@ -38,7 +38,7 @@ public function send(PendingRequest $pendingRequest): \Saloon\Http\Response /** @var class-string<\Saloon\Http\Response> $responseClass */ $responseClass = $pendingRequest->getResponseClass(); - return $responseClass::fromPsrResponse(new GuzzleResponse(200, ['X-Fake' => true], 'Default'), $pendingRequest, $pendingRequest->createPsrRequest()); + return $responseClass::fromPsrResponse(new GuzzleResponse(200, ['X-Fake' => 'true'], 'Default'), $pendingRequest, $pendingRequest->createPsrRequest()); } /**