From 3e650171e4d2ce4376bb5ce990d34a1d5e1a3331 Mon Sep 17 00:00:00 2001 From: Kennedy Tedesco Date: Wed, 4 Sep 2024 11:12:02 -0300 Subject: [PATCH 1/3] [11.x] Add `Skip` middleware for Queue Jobs --- src/Illuminate/Queue/Middleware/Skip.php | 45 ++++++ .../Integration/Queue/SkipMiddlewareTest.php | 132 ++++++++++++++++++ 2 files changed, 177 insertions(+) create mode 100644 src/Illuminate/Queue/Middleware/Skip.php create mode 100644 tests/Integration/Queue/SkipMiddlewareTest.php diff --git a/src/Illuminate/Queue/Middleware/Skip.php b/src/Illuminate/Queue/Middleware/Skip.php new file mode 100644 index 000000000000..7c72ad195efc --- /dev/null +++ b/src/Illuminate/Queue/Middleware/Skip.php @@ -0,0 +1,45 @@ +skip) { + return false; + } + + return $next($job); + } +} diff --git a/tests/Integration/Queue/SkipMiddlewareTest.php b/tests/Integration/Queue/SkipMiddlewareTest.php new file mode 100644 index 000000000000..121ca3a16b10 --- /dev/null +++ b/tests/Integration/Queue/SkipMiddlewareTest.php @@ -0,0 +1,132 @@ +assertJobWasSkipped($job); + } + + public function testJobIsSkippedWhenConditionIsTrueUsingClosure() + { + $job = new SkipTestJob(skip: new SerializableClosure(fn () => true)); + + $this->assertJobWasSkipped($job); + } + + public function testJobIsNotSkippedWhenConditionIsFalse() + { + $job = new SkipTestJob(skip: false); + + $this->assertJobRanSuccessfully($job); + } + + public function testJobIsNotSkippedWhenConditionIsFalseUsingClosure() + { + $job = new SkipTestJob(skip: new SerializableClosure(fn () => false)); + + $this->assertJobRanSuccessfully($job); + } + + public function testJobIsNotSkippedWhenConditionIsTrueWithUnless() + { + $job = new SkipTestJob(skip: true, useUnless: true); + + $this->assertJobRanSuccessfully($job); + } + + public function testJobIsNotSkippedWhenConditionIsTrueWithUnlessUsingClosure() + { + $job = new SkipTestJob(skip: new SerializableClosure(fn () => true), useUnless: true); + + $this->assertJobRanSuccessfully($job); + } + + public function testJobIsSkippedWhenConditionIsFalseWithUnless() + { + $job = new SkipTestJob(skip: false, useUnless: true); + + $this->assertJobWasSkipped($job); + } + + public function testJobIsSkippedWhenConditionIsFalseWithUnlessUsingClosure() + { + $job = new SkipTestJob(skip: new SerializableClosure(fn () => false), useUnless: true); + + $this->assertJobWasSkipped($job); + } + + protected function assertJobRanSuccessfully(SkipTestJob $class) + { + $this->assertJobHandled(class: $class, expectedHandledValue: true); + } + + protected function assertJobWasSkipped(SkipTestJob $class) + { + $this->assertJobHandled(class: $class, expectedHandledValue: false); + } + + protected function assertJobHandled(SkipTestJob $class, bool $expectedHandledValue) + { + $class::$handled = false; + $instance = new CallQueuedHandler(new Dispatcher($this->app), $this->app); + + $job = m::mock(Job::class); + + $job->shouldReceive('hasFailed')->andReturn(false); + $job->shouldReceive('isReleased')->andReturn(false); + $job->shouldReceive('isDeletedOrReleased')->andReturn(false); + $job->shouldReceive('delete')->once(); + + $instance->call($job, [ + 'command' => serialize($class), + ]); + + $this->assertEquals($expectedHandledValue, $class::$handled); + } +} + +class SkipTestJob +{ + use InteractsWithQueue, Queueable; + + public static $handled = false; + + public function __construct( + protected bool|SerializableClosure $skip, + protected bool $useUnless = false, + ) { + } + + public function handle(): void + { + static::$handled = true; + } + + public function middleware(): array + { + $skip = $this->skip instanceof SerializableClosure + ? $this->skip->getClosure() + : $this->skip; + + if ($this->useUnless) { + return [Skip::unless($skip)]; + } + + return [Skip::if($skip)]; + } +} From 65774e5a6c0ebeac27902f61e5650548ad373bb4 Mon Sep 17 00:00:00 2001 From: Kennedy Tedesco Date: Wed, 4 Sep 2024 11:30:11 -0300 Subject: [PATCH 2/3] CS Fixes --- src/Illuminate/Queue/Middleware/Skip.php | 4 ++-- tests/Integration/Queue/SkipMiddlewareTest.php | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Illuminate/Queue/Middleware/Skip.php b/src/Illuminate/Queue/Middleware/Skip.php index 7c72ad195efc..d95b749fe977 100644 --- a/src/Illuminate/Queue/Middleware/Skip.php +++ b/src/Illuminate/Queue/Middleware/Skip.php @@ -13,7 +13,7 @@ public function __construct(protected bool $skip = false) /** * Apply the middleware if the given condition is truthy. * - * @param bool|Closure(): bool $condition + * @param bool|Closure(): bool $condition */ public static function if(bool|Closure $condition): self { @@ -25,7 +25,7 @@ public static function if(bool|Closure $condition): self /** * Apply the middleware unless the given condition is truthy. * - * @param bool|Closure(): bool $condition + * @param bool|Closure(): bool $condition */ public static function unless(bool|Closure $condition): self { diff --git a/tests/Integration/Queue/SkipMiddlewareTest.php b/tests/Integration/Queue/SkipMiddlewareTest.php index 121ca3a16b10..83fc848ad853 100644 --- a/tests/Integration/Queue/SkipMiddlewareTest.php +++ b/tests/Integration/Queue/SkipMiddlewareTest.php @@ -2,15 +2,15 @@ namespace Illuminate\Tests\Integration\Queue; -use Illuminate\Bus\Queueable; -use Illuminate\Queue\Middleware\Skip; use Illuminate\Bus\Dispatcher; +use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\Job; use Illuminate\Queue\CallQueuedHandler; use Illuminate\Queue\InteractsWithQueue; +use Illuminate\Queue\Middleware\Skip; +use Laravel\SerializableClosure\SerializableClosure; use Mockery as m; use Orchestra\Testbench\TestCase; -use Laravel\SerializableClosure\SerializableClosure; class SkipMiddlewareTest extends TestCase { From 2f5acb53ecbe4f3f9a096035453057df158eef1e Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Fri, 6 Sep 2024 15:48:04 -0500 Subject: [PATCH 3/3] formatting --- src/Illuminate/Queue/Middleware/Skip.php | 15 +++++++-------- tests/Integration/Queue/SkipMiddlewareTest.php | 2 +- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/Illuminate/Queue/Middleware/Skip.php b/src/Illuminate/Queue/Middleware/Skip.php index d95b749fe977..37fc91d5949f 100644 --- a/src/Illuminate/Queue/Middleware/Skip.php +++ b/src/Illuminate/Queue/Middleware/Skip.php @@ -15,11 +15,9 @@ public function __construct(protected bool $skip = false) * * @param bool|Closure(): bool $condition */ - public static function if(bool|Closure $condition): self + public static function when(Closure|bool $condition): self { - $condition = $condition instanceof Closure ? $condition() : $condition; - - return new self($condition); + return new self(value($condition)); } /** @@ -27,13 +25,14 @@ public static function if(bool|Closure $condition): self * * @param bool|Closure(): bool $condition */ - public static function unless(bool|Closure $condition): self + public static function unless(Closure|bool $condition): self { - $condition = $condition instanceof Closure ? $condition() : $condition; - - return new self(! $condition); + return new self(! value($condition)); } + /** + * Handle the job. + */ public function handle(mixed $job, callable $next): mixed { if ($this->skip) { diff --git a/tests/Integration/Queue/SkipMiddlewareTest.php b/tests/Integration/Queue/SkipMiddlewareTest.php index 83fc848ad853..14bd1809b194 100644 --- a/tests/Integration/Queue/SkipMiddlewareTest.php +++ b/tests/Integration/Queue/SkipMiddlewareTest.php @@ -127,6 +127,6 @@ public function middleware(): array return [Skip::unless($skip)]; } - return [Skip::if($skip)]; + return [Skip::when($skip)]; } }