From 3c8dd3dc656d9cf7e98fbf6da2c292d57bc5cf6b Mon Sep 17 00:00:00 2001 From: A G Date: Wed, 1 Jan 2025 17:12:34 -0500 Subject: [PATCH] - Implement event to fire when file changes - Implement listener to capture aformentioned event and invoke pipeline - Implement 1 default pipeline step: restarting queue workers - Test case asserting pipeline is invoked - Test case asserting queue restart initiated --- config/nativephp.php | 4 +++ src/Events/App/ProjectFileChanged.php | 22 ++++++++++++ src/Listeners/ProjectFileChangedListener.php | 19 ++++++++++ src/NativeServiceProvider.php | 5 +++ .../RestartQueueWorkers.php | 26 ++++++++++++++ tests/Fixtures/Fakes/FakePipeline.php | 20 +++++++++++ .../ProjectFileChangedListenerTest.php | 35 +++++++++++++++++++ .../RestartQueueWorkersTest.php | 22 ++++++++++++ 8 files changed, 153 insertions(+) create mode 100644 src/Events/App/ProjectFileChanged.php create mode 100644 src/Listeners/ProjectFileChangedListener.php create mode 100644 src/Pipelines/ProjectFileChanged/RestartQueueWorkers.php create mode 100644 tests/Fixtures/Fakes/FakePipeline.php create mode 100644 tests/Listeners/ProjectFileChangedListenerTest.php create mode 100644 tests/Pipelines/ProjectFileChanged/RestartQueueWorkersTest.php diff --git a/config/nativephp.php b/config/nativephp.php index 5c6e7a8f..eb7a6e0d 100644 --- a/config/nativephp.php +++ b/config/nativephp.php @@ -122,4 +122,8 @@ 'timeout' => 60, ], ], + + 'on_php_file_change' => [ + \Native\Laravel\Pipelines\ProjectFileChanged\RestartQueueWorkers::class, + ], ]; diff --git a/src/Events/App/ProjectFileChanged.php b/src/Events/App/ProjectFileChanged.php new file mode 100644 index 00000000..43817e3c --- /dev/null +++ b/src/Events/App/ProjectFileChanged.php @@ -0,0 +1,22 @@ +through($pipelines)->thenReturn(); + } +} diff --git a/src/NativeServiceProvider.php b/src/NativeServiceProvider.php index 6ca8d626..e4932c45 100644 --- a/src/NativeServiceProvider.php +++ b/src/NativeServiceProvider.php @@ -3,6 +3,7 @@ namespace Native\Laravel; use Illuminate\Console\Application; +use Illuminate\Contracts\Events\Dispatcher; use Illuminate\Foundation\Application as Foundation; use Illuminate\Support\Arr; use Illuminate\Support\Facades\Artisan; @@ -20,9 +21,11 @@ use Native\Laravel\Contracts\QueueWorker as QueueWorkerContract; use Native\Laravel\Contracts\WindowManager as WindowManagerContract; use Native\Laravel\DTOs\QueueConfig; +use Native\Laravel\Events\App\ProjectFileChanged; use Native\Laravel\Events\EventWatcher; use Native\Laravel\Exceptions\Handler; use Native\Laravel\GlobalShortcut as GlobalShortcutImplementation; +use Native\Laravel\Listeners\ProjectFileChangedListener; use Native\Laravel\Logging\LogWatcher; use Native\Laravel\PowerMonitor as PowerMonitorImplementation; use Native\Laravel\Windows\WindowManager as WindowManagerImplementation; @@ -99,6 +102,8 @@ public function packageRegistered() public function bootingPackage() { + $this->app->make(Dispatcher::class)->listen(ProjectFileChanged::class, ProjectFileChangedListener::class); + if (config('nativephp-internal.running')) { $this->rewriteDatabase(); } diff --git a/src/Pipelines/ProjectFileChanged/RestartQueueWorkers.php b/src/Pipelines/ProjectFileChanged/RestartQueueWorkers.php new file mode 100644 index 00000000..8751537f --- /dev/null +++ b/src/Pipelines/ProjectFileChanged/RestartQueueWorkers.php @@ -0,0 +1,26 @@ +queueWorker->down($queueConfig->alias); + } + + return $next($event); + } +} diff --git a/tests/Fixtures/Fakes/FakePipeline.php b/tests/Fixtures/Fakes/FakePipeline.php new file mode 100644 index 00000000..99febf58 --- /dev/null +++ b/tests/Fixtures/Fakes/FakePipeline.php @@ -0,0 +1,20 @@ +handled = true; + $this->carry = $carry; + + return $next($carry); + } +} diff --git a/tests/Listeners/ProjectFileChangedListenerTest.php b/tests/Listeners/ProjectFileChangedListenerTest.php new file mode 100644 index 00000000..a3bdb382 --- /dev/null +++ b/tests/Listeners/ProjectFileChangedListenerTest.php @@ -0,0 +1,35 @@ +singleton(FakePipeline::class, fn () => $fake = new FakePipeline); + + config(['nativephp.on_php_file_change' => [ + FakePipeline::class, + ]]); + + app(Dispatcher::class)->dispatch(new ProjectFileChanged('some/file.php')); + + expect(app(FakePipeline::class)->handled)->toBeTrue(); + expect(app(FakePipeline::class)->carry)->toBeInstanceOf(ProjectFileChanged::class); +}); + +it('rejects nonexistent classes', function () { + config(['nativephp.on_php_file_change' => [ + 'definitely-not-a-class-fqcn', + ]]); + + try { + app(Dispatcher::class)->dispatch(new ProjectFileChanged('some/file.php')); + } catch (WebmozartInvalidArgumentException $e) { + expect($e->getMessage())->toBe('Class definitely-not-a-class-fqcn does not exist'); + + return; + } + + $this->fail('Expected an exception to be thrown'); +}); diff --git a/tests/Pipelines/ProjectFileChanged/RestartQueueWorkersTest.php b/tests/Pipelines/ProjectFileChanged/RestartQueueWorkersTest.php new file mode 100644 index 00000000..154c3285 --- /dev/null +++ b/tests/Pipelines/ProjectFileChanged/RestartQueueWorkersTest.php @@ -0,0 +1,22 @@ + [ + 'something' => [], + 'another' => [], + ]]); + + Pipeline::send(new ProjectFileChanged('some/file.php')) + ->through([RestartQueueWorkers::class]) + ->thenReturn(); + + QueueWorker::assertDown('something'); + QueueWorker::assertDown('another'); +});