diff --git a/.github/workflows/php-cs-fixer.yml b/.github/workflows/php-cs-fixer.yml index eb11d4e..7375fd9 100644 --- a/.github/workflows/php-cs-fixer.yml +++ b/.github/workflows/php-cs-fixer.yml @@ -18,10 +18,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v2 - with: - ref: ${{ github.head_ref }} - token: ${{ secrets.PHP_CS_FIXER }} + uses: actions/checkout@v3 - name: Run PHP CS Fixer uses: docker://oskarstark/php-cs-fixer-ga with: diff --git a/composer.json b/composer.json index d7a6193..449e6c4 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ }, "require-dev": { "friendsofphp/php-cs-fixer": "^3.13", - "pestphp/pest": "^1.21.2", + "pestphp/pest": "^2.3", "spatie/ray": "^1.34.2", "league/flysystem": "^3.12.2", "orchestra/testbench": "^8.0", diff --git a/phpunit.xml b/phpunit.xml index 8f4b58c..7b4f1a9 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,18 +1,14 @@ - - - - ./tests - - - - - ./app - ./src - - + + + + ./tests + + + + + ./app + ./src + + diff --git a/src/Http/Middleware/CacheMiddleware.php b/src/Http/Middleware/CacheMiddleware.php index 176cf06..4d10a20 100644 --- a/src/Http/Middleware/CacheMiddleware.php +++ b/src/Http/Middleware/CacheMiddleware.php @@ -26,7 +26,7 @@ public function __construct( protected Driver $driver, protected int $ttl, protected ?string $cacheKey, - protected bool $invalidate = false, + protected bool $invalidate = false, ) { // } @@ -53,7 +53,7 @@ public function __invoke(PendingRequest $pendingRequest): ?SimulatedResponsePayl // the SimulatedResponsePayload here. if ($this->invalidate === false && $cachedResponse->hasNotExpired()) { - $pendingRequest->middleware()->onResponse(fn (Response $response) => $response->setCached(true)); + $pendingRequest->middleware()->onResponse(fn (Response $response) => $response->setCached(true), true); return $cachedResponse->getSimulatedResponsePayload(); } diff --git a/src/Traits/HasCaching.php b/src/Traits/HasCaching.php index 068186d..650c6a6 100644 --- a/src/Traits/HasCaching.php +++ b/src/Traits/HasCaching.php @@ -58,12 +58,17 @@ public function bootHasCaching(PendingRequest $pendingRequest): void ? $request->cacheExpiryInSeconds() : $connector->cacheExpiryInSeconds(); - // Register a request middleware which wil handle the caching and recording - // of real responses for caching. + // Register a request middleware which wil handle the caching + // and recording of real responses for caching. - $pendingRequest->middleware()->onRequest( - callable: new CacheMiddleware($cacheDriver, $cacheExpiryInSeconds, $this->cacheKey($pendingRequest), $this->invalidateCache), - ); + $pendingRequest->middleware()->onRequest(function (PendingRequest $middlewarePendingRequest) use ($cacheDriver, $cacheExpiryInSeconds) { + // We'll call the cache middleware invokable class with the $middlewarePendingRequest + // because this $pendingRequest has everything loaded, unlike the instance that + // the plugin is provided. This allows us to have access to body and merged + // properties. + + return call_user_func(new CacheMiddleware($cacheDriver, $cacheExpiryInSeconds, $this->cacheKey($middlewarePendingRequest), $this->invalidateCache), $middlewarePendingRequest); + }); } /** diff --git a/tests/Feature/CacheTest.php b/tests/Feature/CacheTest.php index e0844e3..0c7002e 100644 --- a/tests/Feature/CacheTest.php +++ b/tests/Feature/CacheTest.php @@ -11,6 +11,7 @@ use Saloon\CachePlugin\Tests\Fixtures\Connectors\CachedConnector; use Saloon\CachePlugin\Tests\Fixtures\Requests\CachedPostRequest; use Saloon\CachePlugin\Tests\Fixtures\Requests\CachedUserRequest; +use Saloon\CachePlugin\Tests\Fixtures\Requests\BodyCacheKeyRequest; use Saloon\CachePlugin\Tests\Fixtures\Requests\CachedConnectorRequest; use Saloon\CachePlugin\Tests\Fixtures\Requests\AllowedCachedPostRequest; use Saloon\CachePlugin\Tests\Fixtures\Requests\CustomKeyCachedUserRequest; @@ -186,6 +187,37 @@ expect($responseC->isCached())->toBeFalse(); }); +test('body can be used in the cache key', function () { + $mockClient = new MockClient([ + MockResponse::make(['name' => 'Sam']), + MockResponse::make(['name' => 'Gareth']), + ]); + + $requestA = new BodyCacheKeyRequest; + $requestA->body()->set([ + 'name' => 'Sam', + 'expiry' => '10 hours', + ]); + + $responseA = TestConnector::make()->send($requestA, $mockClient); + + expect($responseA->isCached())->toBeFalse(); + expect($responseA->json())->toEqual(['name' => 'Sam']); + expect($responseA->status())->toEqual(200); + + $requestB = new BodyCacheKeyRequest; + $requestB->body()->set([ + 'name' => 'Sam', + 'expiry' => '10 hours', + ]); + + $responseB = TestConnector::make()->send($requestB, $mockClient); + + expect($responseB->isCached())->toBeTrue(); + expect($responseB->json())->toEqual(['name' => 'Sam']); + expect($responseB->status())->toEqual(200); +}); + test('you will not receive a cached response if the response has expired', function () { $mockClient = new MockClient([ MockResponse::make(['name' => 'Sam']), diff --git a/tests/Fixtures/Requests/BodyCacheKeyRequest.php b/tests/Fixtures/Requests/BodyCacheKeyRequest.php new file mode 100644 index 0000000..a7a38f8 --- /dev/null +++ b/tests/Fixtures/Requests/BodyCacheKeyRequest.php @@ -0,0 +1,48 @@ +body()->all(); + } +}