diff --git a/composer.json b/composer.json index 8c04d02e..9af33b15 100644 --- a/composer.json +++ b/composer.json @@ -20,7 +20,8 @@ "laravel/framework": "^6.0|^7.0", "orchestra/testbench-browser-kit": "^4.0|^5.0", "league/flysystem-aws-s3-v3": "~1.0", - "doctrine/dbal": "^2.10" + "doctrine/dbal": "^2.10", + "spatie/valuestore": "^1.2" }, "autoload": { "psr-4": { diff --git a/src/Events/Listeners/JobPipeline.php b/src/Events/Listeners/JobPipeline.php index 4b344f6b..fff58473 100644 --- a/src/Events/Listeners/JobPipeline.php +++ b/src/Events/Listeners/JobPipeline.php @@ -8,7 +8,7 @@ use Illuminate\Contracts\Queue\ShouldQueue; class JobPipeline implements ShouldQueue { /** @var bool */ - public static $shouldQueueByDefault = true; + public static $shouldBeQueuedByDefault = false; /** @var callable[]|string[] */ public $jobs; @@ -22,16 +22,16 @@ class JobPipeline implements ShouldQueue public $passable; /** @var bool */ - public $shouldQueue; + public $shouldBeQueued; - public function __construct($jobs, callable $send = null, bool $shouldQueue = null) + public function __construct($jobs, callable $send = null, bool $shouldBeQueued = null) { $this->jobs = $jobs; $this->send = $send ?? function ($event) { // If no $send callback is set, we'll just pass the event through the jobs. return $event; }; - $this->shouldQueue = $shouldQueue ?? static::$shouldQueueByDefault; + $this->shouldBeQueued = $shouldBeQueued ?? static::$shouldBeQueuedByDefault; } /** @param callable[]|string[] $jobs */ @@ -47,15 +47,11 @@ class JobPipeline implements ShouldQueue return $this; } - public function shouldQueue(bool $shouldQueue = null) + public function shouldBeQueued(bool $shouldBeQueued) { - if ($shouldQueue !== null) { - $this->shouldQueue = $shouldQueue; + $this->shouldBeQueued = $shouldBeQueued; - return $this; - } - - return $this->shouldQueue; + return $this; } public function handle(): void @@ -71,14 +67,20 @@ class JobPipeline implements ShouldQueue public function toListener(): Closure { return function (...$args) { - dispatch($this->queueFriendly($args)); + $executable = $this->executable($args); + + if ($this->shouldBeQueued) { + dispatch($executable); + } else { + dispatch_now($executable); + } }; } /** * Return a serializable version of the current object. */ - public function queueFriendly($listenerArgs): self + public function executable($listenerArgs): self { $clone = clone $this; diff --git a/tests/v3/JobPipelineTest.php b/tests/v3/JobPipelineTest.php index f5b3c6a3..79f51ea9 100644 --- a/tests/v3/JobPipelineTest.php +++ b/tests/v3/JobPipelineTest.php @@ -4,26 +4,43 @@ namespace Stancl\Tenancy\Tests\v3; use Illuminate\Support\Facades\Event; use Illuminate\Support\Facades\Queue; +use Spatie\Valuestore\Valuestore; use Stancl\Tenancy\Database\Models\Tenant; use Stancl\Tenancy\Events\Listeners\JobPipeline; use Stancl\Tenancy\Events\TenantCreated; use Stancl\Tenancy\Tests\TestCase; -// todo the shouldQueue() doesnt make sense? test if it really works or if its just because of sync queue driver class JobPipelineTest extends TestCase { + public $mockConsoleOutput = false; + + /** @var Valuestore */ + protected $valuestore; + + public function setUp(): void + { + parent::setUp(); + + config(['queue.default' => 'redis']); + + file_put_contents(__DIR__ . '/../Etc/tmp/jobpipelinetest.json', '{}'); + $this->valuestore = Valuestore::make(__DIR__ . '/../Etc/tmp/jobpipelinetest.json')->flush(); + } + /** @test */ public function job_pipeline_can_listen_to_any_event() { Event::listen(TenantCreated::class, JobPipeline::make([ FooJob::class, - ])->toListener()); + ])->send(function () { + return $this->valuestore; + })->toListener()); - $this->assertFalse(app()->bound('foo')); + $this->assertFalse($this->valuestore->has('foo')); Tenant::create(); - $this->assertSame('bar', app('foo')); + $this->assertSame('bar', $this->valuestore->get('foo')); } /** @test */ @@ -33,12 +50,14 @@ class JobPipelineTest extends TestCase Event::listen(TenantCreated::class, JobPipeline::make([ FooJob::class, - ])->shouldQueue(true)->toListener()); + ])->send(function () { + return $this->valuestore; + })->shouldBeQueued(true)->toListener()); Queue::assertNothingPushed(); Tenant::create(); - $this->assertFalse(app()->bound('foo')); + $this->assertFalse($this->valuestore->has('foo')); Queue::pushed(JobPipeline::class, function (JobPipeline $pipeline) { $this->assertSame([FooJob::class], $pipeline->jobs); @@ -52,43 +71,94 @@ class JobPipelineTest extends TestCase FirstJob::class, SecondJob::class, ])->send(function (TenantCreated $event) { - return $event->tenant; + return [$event->tenant, $this->valuestore]; })->toListener()); - $this->assertFalse(app()->bound('foo')); + $this->assertFalse($this->valuestore->has('foo')); Tenant::create(); - $this->assertSame('first job changed property', app('foo')); + $this->assertSame('first job changed property', $this->valuestore->get('foo')); } /** @test */ public function send_can_return_multiple_arguments() { - // todo + Event::listen(TenantCreated::class, JobPipeline::make([ + JobWithMultipleArguments::class + ])->send(function () { + return ['a', 'b']; + })->toListener()); + + $this->assertFalse(app()->bound('test_args')); + + Tenant::create(); + + $this->assertSame(['a', 'b'], app('test_args')); } } class FooJob { + protected $valuestore; + + public function __construct(Valuestore $valuestore) + { + $this->valuestore = $valuestore; + } + public function handle() { - app()->instance('foo', 'bar'); + $this->valuestore->put('foo', 'bar'); } }; class FirstJob { - public function handle(Tenant $tenant) + public $tenant; + + public function __construct(Tenant $tenant) { - $tenant->foo = 'first job changed property'; + $this->tenant = $tenant; + } + + public function handle() + { + $this->tenant->foo = 'first job changed property'; } } class SecondJob { - public function handle(Tenant $tenant) + public $tenant; + + protected $valuestore; + + public function __construct(Tenant $tenant, Valuestore $valuestore) { - app()->instance('foo', $tenant->foo); + $this->tenant = $tenant; + $this->valuestore = $valuestore; + } + + public function handle() + { + $this->valuestore->put('foo', $this->tenant->foo); + } +} + +class JobWithMultipleArguments +{ + protected $first; + protected $second; + + public function __construct($first, $second) + { + $this->first = $first; + $this->second = $second; + } + + public function handle() + { + app()->instance('test_args', [$this->first, $this->second]); } }