/
githubmirror
/
framework
Обзор
Документация
Войти
/
githubmirror
/
framework
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
13.x
tests/Integration/Queue/RateLimitedWithRedisTest.php
236 строк
6 KB
Jason McCreary
[13.x] Mockery cleanup (#61117)
10 авг 2026, 20:23
Не верифицирован
10 авг 2026, 20:23
2ee40ee
Код
Авторство
О чём код?
<?php namespace Illuminate\Tests\Integration\Queue; use Illuminate\Bus\Dispatcher; use Illuminate\Bus\Queueable; use Illuminate\Cache\RateLimiter; use Illuminate\Cache\RateLimiting\Limit; use Illuminate\Contracts\Queue\Job; use Illuminate\Contracts\Redis\Connection; use Illuminate\Foundation\Testing\Concerns\InteractsWithRedis; use Illuminate\Queue\CallQueuedHandler; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\Middleware\RateLimitedWithRedis; use Illuminate\Support\Str; use Mockery; use Orchestra\Testbench\Attributes\RequiresEnv; use Orchestra\Testbench\TestCase; use PHPUnit\Framework\Attributes\RequiresPhpExtension; #[RequiresEnv('REDIS_CLIENT')] #[RequiresPhpExtension('redis')] class RateLimitedWithRedisTest extends TestCase { use InteractsWithRedis; protected function setUp(): void { parent::setUp(); $this->setUpRedis(); } protected function tearDown(): void { $this->tearDownRedis(); parent::tearDown(); } public function testUnlimitedJobsAreExecuted() { $rateLimiter = $this->app->make(RateLimiter::class); $testJob = new RedisRateLimitedTestJob; $rateLimiter->for($testJob->key, function ($job) { return Limit::none(); }); $this->assertJobRanSuccessfully($testJob); $this->assertJobRanSuccessfully($testJob); } public function testRateLimitedJobsAreNotExecutedOnLimitReached() { $rateLimiter = $this->app->make(RateLimiter::class); $testJob = new RedisRateLimitedTestJob; $rateLimiter->for($testJob->key, function ($job) { return Limit::perMinute(1); }); $this->assertJobRanSuccessfully($testJob); $this->assertJobWasReleased($testJob); } public function testRateLimitedJobsCanBeSkippedOnLimitReached() { $rateLimiter = $this->app->make(RateLimiter::class); $testJob = new RedisRateLimitedDontReleaseTestJob; $rateLimiter->for($testJob->key, function ($job) { return Limit::perMinute(1); }); $this->assertJobRanSuccessfully($testJob); $this->assertJobWasSkipped($testJob); } public function testJobsCanHaveConditionalRateLimits() { $rateLimiter = $this->app->make(RateLimiter::class); $adminJob = new RedisAdminTestJob; $rateLimiter->for($adminJob->key, function ($job) { if ($job->isAdmin()) { return Limit::none(); } return Limit::perMinute(1); }); $this->assertJobRanSuccessfully($adminJob); $this->assertJobRanSuccessfully($adminJob); $nonAdminJob = new RedisNonAdminTestJob; $rateLimiter->for($nonAdminJob->key, function ($job) { if ($job->isAdmin()) { return Limit::none(); } return Limit::perMinute(1); }); $this->assertJobRanSuccessfully($nonAdminJob); $this->assertJobWasReleased($nonAdminJob); } public function testMiddlewareSerialization() { $rateLimited = new RateLimitedWithRedis('limiterName', 'default'); $rateLimited->shouldRelease = false; $restoredRateLimited = unserialize(serialize($rateLimited)); $fetch = (function (string $name) { return $this->{$name}; })->bindTo($restoredRateLimited, RateLimitedWithRedis::class); $this->assertFalse($restoredRateLimited->shouldRelease); $this->assertSame('limiterName', $fetch('limiterName')); $this->assertSame('default', $fetch('connectionName')); $this->assertInstanceOf(RateLimiter::class, $fetch('limiter')); // $this->assertInstanceOf(Connection::class, $fetch('redis')); } protected function assertJobRanSuccessfully($testJob) { $testJob::$handled = false; $instance = new CallQueuedHandler(new Dispatcher($this->app), $this->app); $job = Mockery::mock(Job::class); $job->expects('hasFailed')->andReturn(false); $job->expects('isReleased')->times(2)->andReturn(false); $job->expects('isDeletedOrReleased')->andReturn(false); $job->expects('delete'); $instance->call($job, [ 'command' => serialize($testJob), ]); $this->assertTrue($testJob::$handled); } protected function assertJobWasReleased($testJob) { $testJob::$handled = false; $instance = new CallQueuedHandler(new Dispatcher($this->app), $this->app); $job = Mockery::mock(Job::class); $job->expects('hasFailed')->andReturn(false); $job->expects('release'); $job->expects('isReleased')->times(2)->andReturn(true); $job->expects('isDeletedOrReleased')->andReturn(true); $instance->call($job, [ 'command' => serialize($testJob), ]); $this->assertFalse($testJob::$handled); } protected function assertJobWasSkipped($testJob) { $testJob::$handled = false; $instance = new CallQueuedHandler(new Dispatcher($this->app), $this->app); $job = Mockery::mock(Job::class); $job->expects('hasFailed')->andReturn(false); $job->expects('isReleased')->times(2)->andReturn(false); $job->expects('isDeletedOrReleased')->andReturn(false); $job->expects('delete'); $instance->call($job, [ 'command' => serialize($testJob), ]); $this->assertFalse($testJob::$handled); } } class RedisRateLimitedTestJob { use InteractsWithQueue, Queueable; public $key; public static $handled = false; public function __construct() { $this->key = Str::random(10); } public function handle() { static::$handled = true; } public function middleware() { return [new RateLimitedWithRedis($this->key)]; } } class RedisAdminTestJob extends RedisRateLimitedTestJob { public function isAdmin() { return true; } } class RedisNonAdminTestJob extends RedisRateLimitedTestJob { public function isAdmin() { return false; } } class RedisRateLimitedDontReleaseTestJob extends RedisRateLimitedTestJob { public function middleware() { return [(new RateLimitedWithRedis($this->key))->dontRelease()]; } }