Passed
Pull Request — master (#257)
by Wilmer
25:21 queued 10:17
created

HttpCacheTest   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 96
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 50
dl 0
loc 96
rs 10
c 1
b 0
f 0
wmc 11
1
<?php
2
3
namespace Yiisoft\Yii\Web\Tests\Middleware;
4
5
use Nyholm\Psr7\Factory\Psr17Factory;
6
use Nyholm\Psr7\Response;
7
use Nyholm\Psr7\ServerRequest;
8
use PHPUnit\Framework\TestCase;
9
use Psr\Http\Message\ServerRequestInterface;
10
use Psr\Http\Server\RequestHandlerInterface;
11
use Yiisoft\Http\Method;
12
use Yiisoft\Yii\Web\Middleware\HttpCache;
13
14
class HttpCacheTest extends TestCase
15
{
16
    public function testNotCacheableMethods(): void
17
    {
18
        $time = \time();
19
        $middleware = $this->createMiddlewareWithLastModified($time + 1);
20
        $response = $middleware->process($this->createServerRequest(Method::PATCH), $this->createRequestHandler());
21
        $this->assertEquals(200, $response->getStatusCode());
22
        $this->assertFalse($response->hasHeader('Last-Modified'));
23
    }
24
25
    public function testModifiedResultWithLastModified(): void
26
    {
27
        $time = \time();
28
        $middleware = $this->createMiddlewareWithLastModified($time + 1);
29
        $headers = [
30
            'If-Modified-Since' => gmdate('D, d M Y H:i:s', $time) . 'GMT',
31
        ];
32
        $response = $middleware->process($this->createServerRequest(Method::GET, $headers), $this->createRequestHandler());
33
        $this->assertEquals(200, $response->getStatusCode());
34
    }
35
36
    public function testModifiedResultWithEtag(): void
37
    {
38
        $etag = 'test-etag';
39
        $middleware = $this->createMiddlewareWithETag($etag);
40
        $headers = [
41
            'If-None-Match' => $etag,
42
        ];
43
        $response = $middleware->process($this->createServerRequest(Method::GET, $headers), $this->createRequestHandler());
44
        $this->assertEquals(200, $response->getStatusCode());
45
        $this->assertEquals($response->getHeaderLine('Etag'), $this->generateEtag($etag));
46
    }
47
48
    public function testNotModifiedResultWithLastModified(): void
49
    {
50
        $time = \time();
51
        $middleware = $this->createMiddlewareWithLastModified($time - 1);
52
        $headers = [
53
            'If-Modified-Since' => gmdate('D, d M Y H:i:s', $time) . 'GMT',
54
        ];
55
        $response = $middleware->process($this->createServerRequest(Method::GET, $headers), $this->createRequestHandler());
56
        $this->assertEquals(304, $response->getStatusCode());
57
        $this->assertEmpty((string)$response->getBody());
58
        $this->assertEquals(gmdate('D, d M Y H:i:s', $time - 1) . ' GMT', $response->getHeaderLine('Last-Modified'));
59
    }
60
61
    public function testNotModifiedResultWithEtag(): void
62
    {
63
        $etag = 'test-etag';
64
        $middleware = $this->createMiddlewareWithETag($etag);
65
        $headers = [
66
            'If-None-Match' => $this->generateEtag($etag),
67
        ];
68
        $response = $middleware->process($this->createServerRequest(Method::GET, $headers), $this->createRequestHandler());
69
        $this->assertEquals(304, $response->getStatusCode());
70
        $this->assertEmpty((string)$response->getBody());
71
    }
72
73
    private function createMiddlewareWithLastModified(int $lastModified): HttpCache
74
    {
75
        $middleware = new HttpCache(new Psr17Factory());
76
        $middleware->setLastModified(static function (ServerRequestInterface $request, $params) use ($lastModified) {
77
            return $lastModified;
78
        });
79
        return $middleware;
80
    }
81
82
    private function createMiddlewareWithETag(string $etag): HttpCache
83
    {
84
        $middleware = new HttpCache(new Psr17Factory());
85
        $middleware->setEtagSeed(static function (ServerRequestInterface $request, $params) use ($etag) {
86
            return $etag;
87
        });
88
        return $middleware;
89
    }
90
91
    private function createRequestHandler(): RequestHandlerInterface
92
    {
93
        $requestHandler = $this->createMock(RequestHandlerInterface::class);
94
        $requestHandler
95
            ->method('handle')
96
            ->willReturn(new Response(200));
97
98
        return $requestHandler;
99
    }
100
101
    private function createServerRequest(string $method = Method::GET, $headers = []): ServerRequestInterface
102
    {
103
        return new ServerRequest($method, '/', $headers);
104
    }
105
106
    private function generateEtag(string $seed, ?string $weakEtag = null): string
107
    {
108
        $etag = '"' . rtrim(base64_encode(sha1($seed, true)), '=') . '"';
109
        return $weakEtag ? 'W/' . $etag : $etag;
110
    }
111
}
112