Skip to content

Commit

Permalink
Merge pull request #12 from Sammyjo20/fix/allow-body-to-be-used-in-ca…
Browse files Browse the repository at this point in the history
…che-key

Fix | Allow body to be used in cache key
  • Loading branch information
Sammyjo20 authored Apr 2, 2023
2 parents 330ba77 + 9ae8ae1 commit a5d85b0
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 28 deletions.
5 changes: 1 addition & 4 deletions .github/workflows/php-cs-fixer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
28 changes: 12 additions & 16 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd"
bootstrap="vendor/autoload.php"
colors="true"
>
<testsuites>
<testsuite name="Test Suite">
<directory suffix="Test.php">./tests</directory>
</testsuite>
</testsuites>
<coverage processUncoveredFiles="true">
<include>
<directory suffix=".php">./app</directory>
<directory suffix=".php">./src</directory>
</include>
</coverage>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.0/phpunit.xsd" bootstrap="vendor/autoload.php" colors="true" cacheDirectory=".phpunit.cache">
<testsuites>
<testsuite name="Test Suite">
<directory suffix="Test.php">./tests</directory>
</testsuite>
</testsuites>
<coverage>
<include>
<directory suffix=".php">./app</directory>
<directory suffix=".php">./src</directory>
</include>
</coverage>
</phpunit>
4 changes: 2 additions & 2 deletions src/Http/Middleware/CacheMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public function __construct(
protected Driver $driver,
protected int $ttl,
protected ?string $cacheKey,
protected bool $invalidate = false,
protected bool $invalidate = false,
) {
//
}
Expand All @@ -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();
}
Expand Down
15 changes: 10 additions & 5 deletions src/Traits/HasCaching.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
}

/**
Expand Down
32 changes: 32 additions & 0 deletions tests/Feature/CacheTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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']),
Expand Down
48 changes: 48 additions & 0 deletions tests/Fixtures/Requests/BodyCacheKeyRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

declare(strict_types=1);

namespace Saloon\CachePlugin\Tests\Fixtures\Requests;

use Saloon\Enums\Method;
use Saloon\Http\Request;
use League\Flysystem\Filesystem;
use Saloon\Contracts\Body\HasBody;
use Saloon\Traits\Body\HasJsonBody;
use Saloon\Contracts\PendingRequest;
use Saloon\CachePlugin\Contracts\Driver;
use Saloon\CachePlugin\Traits\HasCaching;
use Saloon\CachePlugin\Contracts\Cacheable;
use Saloon\CachePlugin\Drivers\FlysystemDriver;
use League\Flysystem\Local\LocalFilesystemAdapter;
use Saloon\CachePlugin\Tests\Fixtures\Connectors\TestConnector;

class BodyCacheKeyRequest extends Request implements Cacheable, HasBody
{
use HasCaching;
use HasJsonBody;

protected ?string $connector = TestConnector::class;

protected Method $method = Method::GET;

public function resolveEndpoint(): string
{
return '/user';
}

public function resolveCacheDriver(): Driver
{
return new FlysystemDriver(new Filesystem(new LocalFilesystemAdapter(cachePath())));
}

public function cacheExpiryInSeconds(): int
{
return 60;
}

protected function cacheKey(PendingRequest $pendingRequest): ?string
{
return (string)$pendingRequest->body()->all();
}
}

0 comments on commit a5d85b0

Please sign in to comment.