Passed
Pull Request — master (#204)
by
unknown
02:18
created

RateLimiterMiddlewareTest.php$0 ➔ createRequest()   A

Complexity

Conditions 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Yiisoft\Yii\Web\Tests\RateLimiter;
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\Cache\ArrayCache;
13
use Yiisoft\Http\Method;
14
use Yiisoft\Yii\Web\RateLimiter\Counter;
15
use Yiisoft\Yii\Web\RateLimiter\RateLimiterMiddleware;
16
17
final class RateLimiterMiddlewareTest extends TestCase
18
{
19
    /**
20
     * @test
21
     */
22
    public function singleRequestWorksAsExpected(): void
23
    {
24
        $middleware = $this->createRateLimiter($this->getCounter(1000));
25
        $response = $middleware->process($this->createRequest(), $this->createRequestHandler());
26
        $this->assertEquals(200, $response->getStatusCode());
27
        $this->assertSame(
28
            [
29
                'X-Rate-Limit-Limit' => ['1000'],
30
                'X-Rate-Limit-Remaining' => ['999'],
31
                'X-Rate-Limit-Reset' => ['4']
32
            ],
33
            $response->getHeaders()
34
        );
35
    }
36
37
    /**
38
     * @test
39
     */
40
    public function limitingIsStartedWhenExpected(): void
41
    {
42
        $middleware = $this->createRateLimiter($this->getCounter(10));
43
44
        for ($i = 0; $i < 8; $i++) {
45
            $middleware->process($this->createRequest(), $this->createRequestHandler());
46
        }
47
48
        // last allowed request
49
        $response = $middleware->process($this->createRequest(), $this->createRequestHandler());
50
        $this->assertEquals(200, $response->getStatusCode());
51
        $this->assertSame(
52
            [
53
                'X-Rate-Limit-Limit' => ['10'],
54
                'X-Rate-Limit-Remaining' => ['1'],
55
                'X-Rate-Limit-Reset' => ['3240']
56
            ],
57
            $response->getHeaders()
58
        );
59
60
        // first denied request
61
        $response = $middleware->process($this->createRequest(), $this->createRequestHandler());
62
        $this->assertEquals(429, $response->getStatusCode());
63
        $this->assertSame(
64
            [
65
                'X-Rate-Limit-Limit' => ['10'],
66
                'X-Rate-Limit-Remaining' => ['0'],
67
                'X-Rate-Limit-Reset' => ['3600']
68
            ],
69
            $response->getHeaders()
70
        );
71
    }
72
73
    /**
74
     * @test
75
     */
76
    public function counterIdCouldBeSet(): void
77
    {
78
        $cache = new ArrayCache();
79
        $counter = new Counter(100, 3600, $cache);
80
81
        $middleware = $this->createRateLimiter($counter)->withCounterId('custom-id');
82
        $middleware->process($this->createRequest(), $this->createRequestHandler());
83
84
        $this->assertTrue($cache->has($counter->getCacheKey()));
85
    }
86
87
    /**
88
     * @test
89
     */
90
    public function counterIdCouldBeSetWithCallback(): void
91
    {
92
        $cache = new ArrayCache();
93
        $counter = new Counter(100, 3600, $cache);
94
95
        $middleware = $this->createRateLimiter($counter)->withCounterIdCallback(
96
            static function (ServerRequestInterface $request) {
97
                return $request->getMethod();
98
            }
99
        );
100
101
        $middleware->process($this->createRequest(), $this->createRequestHandler());
102
        $this->assertTrue($cache->has($counter->getCacheKey()));
103
    }
104
105
    private function getCounter(int $limit): Counter
106
    {
107
        return new Counter($limit, 3600, new ArrayCache());
108
    }
109
110
    private function createRequestHandler(): RequestHandlerInterface
111
    {
112
        return new class implements RequestHandlerInterface {
113
            public function handle(ServerRequestInterface $request): ResponseInterface
114
            {
115
                return new Response(200);
116
            }
117
        };
118
    }
119
120
    private function createRequest(string $method = Method::GET, string $uri = '/'): ServerRequestInterface
121
    {
122
        return new ServerRequest($method, $uri);
123
    }
124
125
    private function createRateLimiter(Counter $counter): RateLimiterMiddleware
126
    {
127
        return new RateLimiterMiddleware($counter, new Psr17Factory());
128
    }
129
}
130