xref: /webtrees/tests/app/Services/RateLimitServiceTest.php (revision 2ebcf907ed34213f816592af04e6c160335d6311)
1<?php
2
3/**
4 * webtrees: online genealogy
5 * Copyright (C) 2021 webtrees development team
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18declare(strict_types=1);
19
20namespace Fisharebest\Webtrees\Services;
21
22use Fisharebest\Webtrees\GuestUser;
23use Fisharebest\Webtrees\Http\Exceptions\HttpTooManyRequestsException;
24use Fisharebest\Webtrees\TestCase;
25use LogicException;
26
27use function explode;
28use function implode;
29use function range;
30use function time;
31
32/**
33 * Test harness for the class RateLimitService
34 */
35class RateLimitServiceTest extends TestCase
36{
37    /**
38     * @covers \Fisharebest\Webtrees\Services\RateLimitService
39     *
40     * @return void
41     */
42    public function testTooMuchHistory(): void
43    {
44        $rate_limit_service = new RateLimitService();
45
46        $user = new GuestUser();
47
48        $this->expectException(LogicException::class);
49
50        $rate_limit_service->limitRateForUser($user, 1000, 30, 'rate-limit');
51    }
52
53    /**
54     * @covers \Fisharebest\Webtrees\Services\RateLimitService
55     *
56     * @return void
57     */
58    public function testLimitNotReached(): void
59    {
60        $rate_limit_service = new RateLimitService();
61
62        $user = new GuestUser();
63
64        $rate_limit_service->limitRateForUser($user, 3, 30, 'rate-limit');
65        $history = $user->getPreference('rate-limit');
66        $this->assertCount(1, explode(',', $history));
67
68        $rate_limit_service->limitRateForUser($user, 3, 30, 'rate-limit');
69        $history = $user->getPreference('rate-limit');
70        $this->assertCount(2, explode(',', $history));
71
72        $rate_limit_service->limitRateForUser($user, 3, 30, 'rate-limit');
73        $history = $user->getPreference('rate-limit');
74        $this->assertCount(3, explode(',', $history));
75    }
76
77    /**
78     * @covers \Fisharebest\Webtrees\Services\RateLimitService
79     *
80     * @return void
81     */
82    public function testOldEventsIgnored(): void
83    {
84        $rate_limit_service = new RateLimitService();
85
86        $user = new GuestUser();
87
88        $history = implode(',', range(time() - 35, time() - 31));
89        $user->setPreference('rate-limit', $history);
90
91        $rate_limit_service->limitRateForUser($user, 5, 30, 'rate-limit');
92        $history = $user->getPreference('rate-limit');
93        $this->assertCount(6, explode(',', $history));
94    }
95
96    /**
97     * @covers \Fisharebest\Webtrees\Services\RateLimitService
98     *
99     * @return void
100     */
101    public function testLimitReached(): void
102    {
103        $rate_limit_service = new RateLimitService();
104
105        $user = new GuestUser();
106
107        $history = implode(',', range(time() - 5, time() - 1));
108        $user->setPreference('rate-limit', $history);
109
110        $this->expectException(HttpTooManyRequestsException::class);
111        $rate_limit_service->limitRateForUser($user, 5, 30, 'rate-limit');
112    }
113}
114