From 5f9ff5f1f660d2efc53c26082a31fee6d79fa1a8 Mon Sep 17 00:00:00 2001 From: Chris Mellor Date: Sun, 20 Aug 2023 16:27:41 +0100 Subject: [PATCH 1/6] Add Events for state changes --- src/Events/ModelApproved.php | 14 ++++++++ src/Events/ModelRejected.php | 14 ++++++++ src/Events/ModelSetPending.php | 14 ++++++++ src/Models/Approval.php | 2 +- src/Scopes/ApprovalStateScope.php | 34 ++++++++++++------- .../Feature/Scopes/ApprovalStateScopeTest.php | 19 +++++++++++ 6 files changed, 84 insertions(+), 13 deletions(-) create mode 100644 src/Events/ModelApproved.php create mode 100644 src/Events/ModelRejected.php create mode 100644 src/Events/ModelSetPending.php diff --git a/src/Events/ModelApproved.php b/src/Events/ModelApproved.php new file mode 100644 index 0000000..9200565 --- /dev/null +++ b/src/Events/ModelApproved.php @@ -0,0 +1,14 @@ + ApprovalStatus::class, ]; - public static function booted() + public static function booted(): void { static::addGlobalScope(new ApprovalStateScope()); } diff --git a/src/Scopes/ApprovalStateScope.php b/src/Scopes/ApprovalStateScope.php index 43f7538..6b99c90 100644 --- a/src/Scopes/ApprovalStateScope.php +++ b/src/Scopes/ApprovalStateScope.php @@ -3,9 +3,13 @@ namespace Cjmellor\Approval\Scopes; use Cjmellor\Approval\Enums\ApprovalStatus; +use Cjmellor\Approval\Events\ModelApproved; +use Cjmellor\Approval\Events\ModelRejected; +use Cjmellor\Approval\Events\ModelSetPending; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Scope; +use Illuminate\Support\Facades\Event; class ApprovalStateScope implements Scope { @@ -107,6 +111,24 @@ protected function addApprove(Builder $builder): void }); } + /** + * A helper method for updating the approvals state. + */ + protected function updateApprovalState(Builder $builder, ApprovalStatus $state): int + { + match ($state) { + ApprovalStatus::Approved => Event::dispatch(new ModelApproved()), + ApprovalStatus::Pending => Event::dispatch(new ModelSetPending()), + ApprovalStatus::Rejected => Event::dispatch(new ModelRejected()), + }; + + return $builder + ->find(id: $builder->getModel()->id) + ->update([ + 'state' => $state, + ]); + } + /** * Set state as 'pending' (default). */ @@ -122,16 +144,4 @@ protected function addReject(Builder $builder): void { $builder->macro('reject', fn (Builder $builder): int => $this->updateApprovalState($builder, state: ApprovalStatus::Rejected)); } - - /** - * A helper method for updating the approvals state. - */ - protected function updateApprovalState(Builder $builder, $state): int - { - return $builder - ->find(id: $builder->getModel()->id) - ->update([ - 'state' => $state, - ]); - } } diff --git a/tests/Feature/Scopes/ApprovalStateScopeTest.php b/tests/Feature/Scopes/ApprovalStateScopeTest.php index f3eadf5..5d211d8 100644 --- a/tests/Feature/Scopes/ApprovalStateScopeTest.php +++ b/tests/Feature/Scopes/ApprovalStateScopeTest.php @@ -1,8 +1,12 @@ fakeModelData = [ @@ -97,3 +101,18 @@ expect($modelOneApproval)->fresh()->state->toBe(expected: ApprovalStatus::Approved) ->and(Approval::find(id: 2))->state->toBe(expected: ApprovalStatus::Pending); }); + +test(description: 'An event is fired when a Model\'s state is changed', closure: function (string $state): void { + FakeModel::create($this->fakeModelData); + + Event::fake(); + + $approval = Approval::first(); + $approval->$state(); + + match ($state) { + 'approve' => Event::assertDispatched(ModelApproved::class), + 'reject' => Event::assertDispatched(ModelRejected::class), + 'postpone' => Event::assertDispatched(ModelSetPending::class), + }; +})->with(['approve', 'reject', 'postpone']); From 834048cc96d435c0fa6bc32bf71c02ad61dfec84 Mon Sep 17 00:00:00 2001 From: Chris Mellor Date: Sun, 20 Aug 2023 16:28:35 +0100 Subject: [PATCH 2/6] Upgrade to Pest v2 --- composer.json | 8 ++++---- phpunit.xml.dist | 37 ++++++------------------------------- phpunit.xml.dist.bak | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 35 deletions(-) create mode 100644 phpunit.xml.dist.bak diff --git a/composer.json b/composer.json index a7ee97a..d8f8e51 100644 --- a/composer.json +++ b/composer.json @@ -22,11 +22,11 @@ }, "require-dev": { "laravel/pint": "^1.0", - "nunomaduro/collision": "^6.0", + "nunomaduro/collision": "^7.0", "orchestra/testbench": "^7.0|^8.0", - "pestphp/pest": "^1.21", - "pestphp/pest-plugin-laravel": "^1.1", - "phpunit/phpunit": "^9.5" + "pestphp/pest": "^2.0", + "pestphp/pest-plugin-laravel": "^2.0", + "pestphp/pest-plugin-type-coverage": "^2.0" }, "autoload": { "psr-4": { diff --git a/phpunit.xml.dist b/phpunit.xml.dist index d557761..eb5ce8c 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,39 +1,14 @@ - + - - tests + + ./tests - + + ./src - - - - - - - - - + diff --git a/phpunit.xml.dist.bak b/phpunit.xml.dist.bak new file mode 100644 index 0000000..d557761 --- /dev/null +++ b/phpunit.xml.dist.bak @@ -0,0 +1,39 @@ + + + + + tests + + + + + ./src + + + + + + + + + + + From 85c200443750c47c888c308ed83c590ae8d71b7b Mon Sep 17 00:00:00 2001 From: Chris Mellor Date: Sun, 20 Aug 2023 16:33:18 +0100 Subject: [PATCH 3/6] Mention the Events in the docs --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 8db4b4a..7d58bd5 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,16 @@ Approval::where('id', 3)->postpone(); In the event you need to reset a state, you can use the `withAnyState` helper. +### Events + +Once a Model's state has been changed, an event will be fired. + +```php +ModelApproved::class +ModelPostponed::class +ModelRejected::class +``` + ### Persisting data By default, once you approve a Model, it will be inserted into the database. From a24760ecab7e6262cf1b2f528a32338fb2296daa Mon Sep 17 00:00:00 2001 From: Chris Mellor Date: Sun, 20 Aug 2023 16:36:56 +0100 Subject: [PATCH 4/6] Remove unnecessary plugin --- composer.json | 1 - 1 file changed, 1 deletion(-) diff --git a/composer.json b/composer.json index d8f8e51..b5b6dd7 100644 --- a/composer.json +++ b/composer.json @@ -25,7 +25,6 @@ "nunomaduro/collision": "^7.0", "orchestra/testbench": "^7.0|^8.0", "pestphp/pest": "^2.0", - "pestphp/pest-plugin-laravel": "^2.0", "pestphp/pest-plugin-type-coverage": "^2.0" }, "autoload": { From 1fed3be93eee384dd2869a4f6b5df2d6d3f2a5f7 Mon Sep 17 00:00:00 2001 From: Chris Mellor Date: Sun, 20 Aug 2023 16:45:41 +0100 Subject: [PATCH 5/6] Update test runner --- .github/workflows/run-pest.yml | 37 ++++++++++++++++++++++ .github/workflows/run-tests.yml | 54 --------------------------------- 2 files changed, 37 insertions(+), 54 deletions(-) create mode 100644 .github/workflows/run-pest.yml delete mode 100644 .github/workflows/run-tests.yml diff --git a/.github/workflows/run-pest.yml b/.github/workflows/run-pest.yml new file mode 100644 index 0000000..8509649 --- /dev/null +++ b/.github/workflows/run-pest.yml @@ -0,0 +1,37 @@ +name: "Run Pest" + +on: pull_request + +jobs: + tests: + runs-on: ubuntu-latest + strategy: + fail-fast: true + matrix: + php: [ 8.1, 8.2 ] + stability: [ prefer-lowest, prefer-stable ] + + name: "PHP: v${{ matrix.php }}" + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + tools: composer:v2 + coverage: none + + - name: Setup problem matchers + run: | + echo "::add-matcher::${{ runner.tool_cache }}/php.json" + echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" + + - name: Install dependencies + run: | + composer update --${{ matrix.stability }} --prefer-dist --no-interaction + + - name: Execute tests + run: vendor/bin/pest diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml deleted file mode 100644 index 18284af..0000000 --- a/.github/workflows/run-tests.yml +++ /dev/null @@ -1,54 +0,0 @@ -name: "Run Tests" - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - -jobs: - test: - runs-on: ${{ matrix.os }} - strategy: - fail-fast: true - matrix: - os: [ ubuntu-latest ] - php: [ 8.2, 8.1 ] - laravel: [ 9.*, 10.* ] - stability: [ prefer-stable ] - include: - - laravel: 10.* - testbench: 8.* - carbon: ^2.63 - - laravel: 9.* - testbench: 7.* - carbon: ^2.63 - - name: P${{ matrix.php }} - L${{ matrix.laravel }} - - steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php }} - extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv, imagick, fileinfo - coverage: none - - - name: Setup problem matchers - run: | - echo "::add-matcher::${{ runner.tool_cache }}/php.json" - echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" - - - name: Install dependencies - run: | - composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" "nesbot/carbon:${{ matrix.carbon }}" --no-interaction --no-update - composer update --${{ matrix.stability }} --prefer-dist --no-interaction - - - name: List Installed Dependencies - run: composer show -D - - - name: Execute tests - run: vendor/bin/pest From 6b0b9fcd2997d494e413188487cb1b3ca56b56b9 Mon Sep 17 00:00:00 2001 From: Chris Mellor Date: Sun, 20 Aug 2023 16:48:00 +0100 Subject: [PATCH 6/6] Change runner output --- .github/workflows/run-pest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run-pest.yml b/.github/workflows/run-pest.yml index 8509649..97328a2 100644 --- a/.github/workflows/run-pest.yml +++ b/.github/workflows/run-pest.yml @@ -11,7 +11,7 @@ jobs: php: [ 8.1, 8.2 ] stability: [ prefer-lowest, prefer-stable ] - name: "PHP: v${{ matrix.php }}" + name: "PHP: v${{ matrix.php }} [${{ matrix.stability }}]" steps: - name: Checkout