mirror of
https://github.com/notrab/dumbo.git
synced 2025-01-17 06:08:31 +01:00
116 lines
3.9 KiB
PHP
116 lines
3.9 KiB
PHP
|
<?php
|
||
|
|
||
|
namespace Dumbo\Tests;
|
||
|
|
||
|
use Dumbo\Context;
|
||
|
use Dumbo\Middleware\CacheMiddleware;
|
||
|
use GuzzleHttp\Psr7\Response;
|
||
|
use PHPUnit\Framework\TestCase;
|
||
|
use Psr\Http\Message\ServerRequestInterface;
|
||
|
use Psr\Http\Message\UriInterface;
|
||
|
|
||
|
class CacheMiddlewareTest extends TestCase
|
||
|
{
|
||
|
private function createMockContext($method = 'GET', $headers = [], $path = '/', $queryParams = []): Context
|
||
|
{
|
||
|
$request = $this->createMock(ServerRequestInterface::class);
|
||
|
$request->method('getMethod')->willReturn($method);
|
||
|
|
||
|
$uri = $this->createMock(UriInterface::class);
|
||
|
$uri->method('getPath')->willReturn($path);
|
||
|
$request->method('getUri')->willReturn($uri);
|
||
|
|
||
|
$request->method('getHeader')
|
||
|
->willReturnCallback(function ($headerName) use ($headers) {
|
||
|
return $headers[$headerName] ?? [];
|
||
|
});
|
||
|
|
||
|
$request->method('getHeaders')->willReturn($headers);
|
||
|
|
||
|
$request->method('getQueryParams')->willReturn($queryParams);
|
||
|
|
||
|
return new Context($request, [], $path);
|
||
|
}
|
||
|
|
||
|
public function testHeadersAreModifiedByMiddleware()
|
||
|
{
|
||
|
$middleware = CacheMiddleware::withHeaders('public', true, 60);
|
||
|
$context = $this->createMockContext();
|
||
|
|
||
|
$next = function ($ctx) {
|
||
|
return new Response(200, [], 'Response body');
|
||
|
};
|
||
|
|
||
|
$response = $middleware($context, $next);
|
||
|
|
||
|
$this->assertEquals(200, $response->getStatusCode());
|
||
|
$this->assertEquals('public, max-age=60, must-revalidate', $response->getHeaderLine('Cache-Control'));
|
||
|
$this->assertNotEmpty($response->getHeaderLine('ETag'));
|
||
|
$this->assertNotEmpty($response->getHeaderLine('Last-Modified'));
|
||
|
}
|
||
|
|
||
|
public function testReturns304WhenETagMatches()
|
||
|
{
|
||
|
$etag = 'W/"' . md5('/') . '"';
|
||
|
$middleware = CacheMiddleware::withHeaders('public', true, 60);
|
||
|
$context = $this->createMockContext('GET', ['If-None-Match' => [$etag]]);
|
||
|
|
||
|
$next = function ($ctx) {
|
||
|
return new Response(200, [], 'Response body');
|
||
|
};
|
||
|
|
||
|
$response = $middleware($context, $next);
|
||
|
|
||
|
$this->assertEquals(304, $response->getStatusCode());
|
||
|
$this->assertEquals($etag, $response->getHeaderLine('ETag'));
|
||
|
}
|
||
|
|
||
|
public function testReturns304WhenIfModifiedSinceMatches()
|
||
|
{
|
||
|
$lastModified = gmdate('D, d M Y H:i:s') . ' GMT';
|
||
|
$middleware = CacheMiddleware::withHeaders('public', true, 60);
|
||
|
$context = $this->createMockContext('GET', ['If-Modified-Since' => [$lastModified]]);
|
||
|
|
||
|
$next = function ($ctx) use ($lastModified) {
|
||
|
return (new Response(200, [], 'Response body'))
|
||
|
->withHeader('Last-Modified', $lastModified);
|
||
|
};
|
||
|
|
||
|
$response = $middleware($context, $next);
|
||
|
|
||
|
$this->assertEquals(304, $response->getStatusCode());
|
||
|
$this->assertEquals($lastModified, $response->getHeaderLine('Last-Modified'));
|
||
|
}
|
||
|
|
||
|
public function testDoesNotCacheNonGetRequests()
|
||
|
{
|
||
|
$middleware = CacheMiddleware::withHeaders('public', true, 60);
|
||
|
$context = $this->createMockContext('POST');
|
||
|
|
||
|
$next = function ($ctx) {
|
||
|
return new Response(200, [], 'Response body');
|
||
|
};
|
||
|
|
||
|
$response = $middleware($context, $next);
|
||
|
|
||
|
$this->assertEquals(200, $response->getStatusCode());
|
||
|
$this->assertEmpty($response->getHeaderLine('Cache-Control'));
|
||
|
}
|
||
|
|
||
|
public function testGeneratesCorrectETagForStrictMode()
|
||
|
{
|
||
|
$middleware = CacheMiddleware::withHeaders('public', true, 60, true);
|
||
|
|
||
|
$context = $this->createMockContext('GET', [], '/test', ['name' => 'Dumbo']);
|
||
|
|
||
|
$next = function ($ctx) {
|
||
|
return new Response(200, [], 'Response body');
|
||
|
};
|
||
|
|
||
|
$expectedEtag = 'W/"' . md5('GET/test' . serialize(['name' => 'Dumbo'])) . '"';
|
||
|
|
||
|
$response = $middleware($context, $next);
|
||
|
|
||
|
$this->assertEquals($expectedEtag, $response->getHeaderLine('ETag'));
|
||
|
}
|
||
|
}
|