Passed
Pull Request — master (#199)
by Rustam
13:42
created

HttpCacheTest::testNotModifiedResultWithEtag()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 7
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 10
rs 10
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\ResponseInterface;
10
use Psr\Http\Message\ServerRequestInterface;
11
use Psr\Http\Server\RequestHandlerInterface;
12
use Yiisoft\Http\Method;
13
use Yiisoft\Yii\Web\Middleware\HttpCache;
14
15
class HttpCacheTest extends TestCase
16
{
17
    public function testNotCacheableMethods(): void
18
    {
19
        $time = \time();
20
        $middleware = $this->createMiddlewareWithLastModified($time + 1);
21
        $response = $middleware->process($this->createServerRequest(Method::PATCH), $this->createRequestHandler());
22
        $this->assertEquals(200, $response->getStatusCode());
23
        $this->assertFalse($response->hasHeader('Last-Modified'));
24
    }
25
26
    public function testModifiedResultWithLastModified(): void
27
    {
28
        $time = \time();
29
        $middleware = $this->createMiddlewareWithLastModified($time + 1);
30
        $headers = [
31
            'If-Modified-Since' => gmdate('D, d M Y H:i:s', $time) . 'GMT',
32
        ];
33
        $response = $middleware->process($this->createServerRequest(Method::GET, $headers), $this->createRequestHandler());
34
        $this->assertEquals(200, $response->getStatusCode());
35
    }
36
37
    public function testModifiedResultWithEtag(): void
38
    {
39
        $etag = 'test-etag';
40
        $middleware = $this->createMiddlewareWithETag($etag);
41
        $headers = [
42
            'If-None-Match' => implode(',', [$etag]),
43
        ];
44
        $response = $middleware->process($this->createServerRequest(Method::GET, $headers), $this->createRequestHandler());
45
        $this->assertEquals(200, $response->getStatusCode());
46
        $this->assertEquals($response->getHeaderLine('Etag'), $this->generateEtag($etag));
47
    }
48
49
    public function testNotModifiedResultWithLastModified(): void
50
    {
51
        $time = \time();
52
        $middleware = $this->createMiddlewareWithLastModified($time - 1);
53
        $headers = [
54
            'If-Modified-Since' => gmdate('D, d M Y H:i:s', $time) . 'GMT',
55
        ];
56
        $response = $middleware->process($this->createServerRequest(Method::GET, $headers), $this->createRequestHandler());
57
        $this->assertEquals(304, $response->getStatusCode());
58
        $this->assertEmpty((string)$response->getBody());
59
        $this->assertEquals(gmdate('D, d M Y H:i:s', $time - 1) . ' GMT', $response->getHeaderLine('Last-Modified'));
60
    }
61
62
    public function testNotModifiedResultWithEtag(): void
63
    {
64
        $etag = 'test-etag';
65
        $middleware = $this->createMiddlewareWithETag($etag);
66
        $headers = [
67
            'If-None-Match' => implode(',', [$this->generateEtag($etag)]),
68
        ];
69
        $response = $middleware->process($this->createServerRequest(Method::GET, $headers), $this->createRequestHandler());
70
        $this->assertEquals(304, $response->getStatusCode());
71
        $this->assertEmpty((string)$response->getBody());
72
    }
73
74
    private function createMiddlewareWithLastModified(int $lastModified): HttpCache
75
    {
76
        $middleware = new HttpCache(new Psr17Factory());
77
        $middleware->setLastModified(static function (ServerRequestInterface $request, $params) use ($lastModified) {
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

77
        $middleware->setLastModified(static function (/** @scrutinizer ignore-unused */ ServerRequestInterface $request, $params) use ($lastModified) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $params is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

77
        $middleware->setLastModified(static function (ServerRequestInterface $request, /** @scrutinizer ignore-unused */ $params) use ($lastModified) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
78
            return $lastModified;
79
        });
80
        return $middleware;
81
    }
82
83
    private function createMiddlewareWithETag(string $etag): HttpCache
84
    {
85
        $middleware = new HttpCache(new Psr17Factory());
86
        $middleware->setEtagSeed(static function (ServerRequestInterface $request, $params) use ($etag) {
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

86
        $middleware->setEtagSeed(static function (/** @scrutinizer ignore-unused */ ServerRequestInterface $request, $params) use ($etag) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $params is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

86
        $middleware->setEtagSeed(static function (ServerRequestInterface $request, /** @scrutinizer ignore-unused */ $params) use ($etag) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
87
            return $etag;
88
        });
89
        return $middleware;
90
    }
91
92
    private function createRequestHandler(): RequestHandlerInterface
93
    {
94
        return new class implements RequestHandlerInterface {
95
            public function handle(ServerRequestInterface $request): ResponseInterface
96
            {
97
                return new Response(200);
98
            }
99
        };
100
    }
101
102
    private function createServerRequest(string $method = Method::GET, $headers = []): ServerRequestInterface
103
    {
104
        return new ServerRequest($method, '/', $headers);
105
    }
106
107
    private function generateEtag(string $seed, ?string $weakEtag = null): string
108
    {
109
        $etag = '"' . rtrim(base64_encode(sha1($seed, true)), '=') . '"';
110
        return $weakEtag ? 'W/' . $etag : $etag;
111
    }
112
}
113