/
githubmirror
/
framework
Обзор
Документация
Войти
/
githubmirror
/
framework
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
13.x
tests/Cache/CacheRateLimiterTest.php
230 строк
8 KB
Jason McCreary
[13.x] Mockery cleanup (#61117)
10 авг 2026, 20:23
Не верифицирован
10 авг 2026, 20:23
2ee40ee
Код
Авторство
О чём код?
<?php namespace Illuminate\Tests\Cache; use Illuminate\Cache\ArrayStore; use Illuminate\Cache\RateLimiter; use Illuminate\Contracts\Cache\Repository as Cache; use Illuminate\Support\Carbon; use Mockery; use PHPUnit\Framework\TestCase; class CacheRateLimiterTest extends TestCase { public function testTooManyAttemptsReturnTrueIfAlreadyLockedOut() { $cache = Mockery::mock(Cache::class); $cache->expects('get')->with('key', 0)->andReturn(1); $cache->expects('has')->with('key:timer')->andReturn(true); $cache->shouldReceive('add')->never(); $cache->expects('getStore')->andReturn(new ArrayStore); $rateLimiter = new RateLimiter($cache); $this->assertTrue($rateLimiter->tooManyAttempts('key', 1)); } public function testHitProperlyIncrementsAttemptCount() { $cache = Mockery::mock(Cache::class); $cache->expects('add')->with('key:timer', Mockery::type('int'), 1)->andReturn(true); $cache->expects('add')->with('key', 0, 1)->andReturn(true); $cache->expects('increment')->with('key', 1)->andReturn(1); $cache->expects('getStore')->andReturn(new ArrayStore); $rateLimiter = new RateLimiter($cache); $rateLimiter->hit('key', 1); } public function testIncrementProperlyIncrementsAttemptCount() { $cache = Mockery::mock(Cache::class); $cache->expects('add')->with('key:timer', Mockery::type('int'), 1)->andReturn(true); $cache->expects('add')->with('key', 0, 1)->andReturn(true); $cache->expects('increment')->with('key', 5)->andReturn(5); $cache->expects('getStore')->andReturn(new ArrayStore); $rateLimiter = new RateLimiter($cache); $rateLimiter->increment('key', 1, 5); } public function testDecrementProperlyDecrementsAttemptCount() { $cache = Mockery::mock(Cache::class); $cache->expects('add')->with('key:timer', Mockery::type('int'), 1)->andReturn(true); $cache->expects('add')->with('key', 0, 1)->andReturn(true); $cache->expects('increment')->with('key', -5)->andReturn(-5); $cache->expects('getStore')->andReturn(new ArrayStore); $rateLimiter = new RateLimiter($cache); $rateLimiter->decrement('key', 1, 5); } public function testHitHasNoMemoryLeak() { $cache = Mockery::mock(Cache::class); $cache->expects('add')->with('key:timer', Mockery::type('int'), 1)->andReturn(true); $cache->expects('add')->with('key', 0, 1)->andReturn(false); $cache->expects('increment')->with('key', 1)->andReturn(1); $cache->expects('put')->with('key', 1, 1); $cache->expects('getStore')->times(2)->andReturn(new ArrayStore); $rateLimiter = new RateLimiter($cache); $rateLimiter->hit('key', 1); } public function testIncrementWithCustomAmountHasNoMemoryLeak() { $cache = Mockery::mock(Cache::class); $cache->expects('add')->with('key:timer', Mockery::type('int'), 60)->andReturn(true); $cache->expects('add')->with('key', 0, 60)->andReturn(false); $cache->expects('increment')->with('key', 2)->andReturn(2); $cache->expects('put')->with('key', 2, 60); $cache->expects('getStore')->times(2)->andReturn(new ArrayStore); $rateLimiter = new RateLimiter($cache); $rateLimiter->increment('key', 60, 2); } public function testRemainingIsNotNegative(): void { $cache = Mockery::mock(Cache::class); $cache->expects('get')->times(2)->with('key', 0)->andReturn(5); $cache->expects('getStore')->times(2)->andReturn(new ArrayStore); $rateLimiter = new RateLimiter($cache); $this->assertSame(0, $rateLimiter->remaining('key', 3)); $this->assertSame(0, $rateLimiter->retriesLeft('key', 3)); } public function testRetriesLeftReturnsCorrectCount() { $cache = Mockery::mock(Cache::class); $cache->expects('get')->with('key', 0)->andReturn(3); $cache->expects('getStore')->andReturn(new ArrayStore); $rateLimiter = new RateLimiter($cache); $this->assertEquals(2, $rateLimiter->retriesLeft('key', 5)); } public function testClearClearsTheCacheKeys() { $cache = Mockery::mock(Cache::class); $cache->expects('forget')->with('key'); $cache->expects('forget')->with('key:timer'); $cache->shouldReceive('getStore')->andReturn(new ArrayStore); $rateLimiter = new RateLimiter($cache); $rateLimiter->clear('key'); } public function testAvailableInReturnsPositiveValues() { $cache = Mockery::mock(Cache::class); $cache->expects('get')->times(2)->andReturn(Carbon::now()->subMinute()->getTimestamp(), null); $rateLimiter = new RateLimiter($cache); $this->assertTrue($rateLimiter->availableIn('key:timer') >= 0); $this->assertTrue($rateLimiter->availableIn('key:timer') >= 0); } public function testAttemptsCallbackReturnsTrue() { $cache = Mockery::mock(Cache::class); $cache->expects('get')->with('key', 0)->andReturn(0); $cache->expects('add')->with('key:timer', Mockery::type('int'), 1); $cache->expects('add')->with('key', 0, 1)->andReturns(1); $cache->expects('increment')->with('key', 1)->andReturn(1); $cache->expects('getStore')->times(2)->andReturn(new ArrayStore); $executed = false; $rateLimiter = new RateLimiter($cache); $rateLimiter->attempt('key', 1, function () use (&$executed) { $executed = true; }, 1); $this->assertTrue($executed); } public function testAttemptsCallbackReturnsCallbackReturn() { $cache = Mockery::mock(Cache::class); $cache->expects('get')->times(6)->with('key', 0)->andReturn(0); $cache->expects('add')->times(6)->with('key:timer', Mockery::type('int'), 1); $cache->expects('add')->times(6)->with('key', 0, 1)->andReturns(1); $cache->expects('increment')->times(6)->with('key', 1)->andReturn(1); $cache->expects('getStore')->times(12)->andReturn(new ArrayStore); $rateLimiter = new RateLimiter($cache); $this->assertSame('foo', $rateLimiter->attempt('key', 1, function () { return 'foo'; }, 1)); $this->assertFalse($rateLimiter->attempt('key', 1, function () { return false; }, 1)); $this->assertSame([], $rateLimiter->attempt('key', 1, function () { return []; }, 1)); $this->assertSame(0, $rateLimiter->attempt('key', 1, function () { return 0; }, 1)); $this->assertSame(0.0, $rateLimiter->attempt('key', 1, function () { return 0.0; }, 1)); $this->assertSame('', $rateLimiter->attempt('key', 1, function () { return ''; }, 1)); } public function testAttemptsCallbackReturnsFalse() { $cache = Mockery::mock(Cache::class); $cache->expects('get')->with('key', 0)->andReturn(2); $cache->expects('has')->with('key:timer')->andReturn(true); $cache->expects('getStore')->andReturn(new ArrayStore); $executed = false; $rateLimiter = new RateLimiter($cache); $this->assertFalse($rateLimiter->attempt('key', 1, function () use (&$executed) { $executed = true; }, 1)); $this->assertFalse($executed); } public function testKeysAreSanitizedFromUnicodeCharacters() { $cache = Mockery::mock(Cache::class); $cache->expects('get')->with('john', 0)->andReturn(1); $cache->expects('has')->with('john:timer')->andReturn(true); $cache->shouldReceive('add')->never(); $cache->expects('getStore')->andReturn(new ArrayStore); $rateLimiter = new RateLimiter($cache); $this->assertTrue($rateLimiter->tooManyAttempts('jôhn', 1)); } public function testKeyIsSanitizedOnlyOnce() { $cache = Mockery::mock(Cache::class); $rateLimiter = new RateLimiter($cache); $key = "john'doe"; $cleanedKey = $rateLimiter->cleanRateLimiterKey($key); $cache->expects('get')->with($cleanedKey, 0)->andReturn(1); $cache->expects('has')->with("$cleanedKey:timer")->andReturn(true); $cache->shouldReceive('add')->never(); $cache->expects('getStore')->andReturn(new ArrayStore); $this->assertTrue($rateLimiter->tooManyAttempts($key, 1)); } }