the browser-facing portion of osu!
at master 2.5 kB view raw
1<?php 2 3// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the GNU Affero General Public License v3.0. 4// See the LICENCE file in the repository root for full licence text. 5 6declare(strict_types=1); 7 8namespace Tests\Middleware; 9 10use App\Http\Middleware\RequestCost; 11use App\Models\OAuth\Token; 12use App\Models\User; 13use Closure; 14use LaravelRedis; 15use Route; 16use Tests\TestCase; 17 18class ThrottleRequestsTest extends TestCase 19{ 20 const LIMIT = 60; 21 22 protected Token $token; 23 24 /** 25 * @dataProvider throttleDataProvider 26 */ 27 public function testThrottle(array $middlewares, int $remaining, ?Closure $action = null) 28 { 29 $action ??= (fn () => []); 30 31 Route::get('api/test-throttle', $action)->middleware(['api', 'require-scopes'])->middleware($middlewares); 32 33 $this->getJson('api/test-throttle') 34 ->assertHeader('X-Ratelimit-Limit', static::LIMIT) 35 ->assertHeader('X-Ratelimit-Remaining', $remaining); 36 } 37 38 public function testThrottleMultipleRequests() 39 { 40 Route::get('api/test-throttle', fn () => [])->middleware(['api', 'require-scopes'])->middleware('throttle:60,10'); 41 42 $this->getJson('api/test-throttle'); 43 $this->getJson('api/test-throttle') 44 ->assertHeader('X-Ratelimit-Limit', static::LIMIT) 45 ->assertHeader('X-Ratelimit-Remaining', 58); 46 } 47 48 public static function throttleDataProvider() 49 { 50 return [ 51 'throttle' => [['throttle:60,10'], 59], 52 'request-cost specified' => [['request-cost:5', 'throttle:60,10'], 55], 53 'request-cost after throttle order does not matter' => [['throttle:60,10', 'request-cost:5'], 55], 54 'setCost' => [['throttle:60,10'], 58, fn () => RequestCost::setCost(2)], 55 'setCost overrides default' => [['throttle:60,10', 'request-cost:5'], 58, fn () => RequestCost::setCost(2)], 56 ]; 57 } 58 59 protected function setUp(): void 60 { 61 parent::setUp(); 62 63 // Using token so we can get the key name and remove the keys from redis on cleanup. 64 $this->token = $this->createToken(User::factory()->create(), ['*']); 65 $this->actingWithToken($this->token); 66 } 67 68 protected function tearDown(): void 69 { 70 if ($GLOBALS['cfg']['cache']['default'] === 'redis') { 71 $key = $GLOBALS['cfg']['cache']['prefix'].':'.sha1($this->token->getKey()); 72 LaravelRedis::del($key); 73 LaravelRedis::del("{$key}:timer"); 74 } 75 76 parent::tearDown(); 77 } 78}