diff --git a/CHANGELOG.md b/CHANGELOG.md index f4c9652..0cc12bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,12 @@ See [GitHub releases](https://github.com/mll-lab/laravel-utils/releases). ## Unreleased +## v11.0.0 + +### Changed + +- Execute transitions when repeatedly setting the same state https://github.com/mll-lab/laravel-utils/pull/34 + ## v10.9.0 ### Added diff --git a/app/ModelStates/ModelStates/ModelState.php b/app/ModelStates/ModelStates/ModelState.php index 7c84f61..b128106 100644 --- a/app/ModelStates/ModelStates/ModelState.php +++ b/app/ModelStates/ModelStates/ModelState.php @@ -4,6 +4,7 @@ use App\ModelStates\StateManager; use App\ModelStates\Transitions\CustomInvalidTransition; +use App\ModelStates\Transitions\TransitionWithException; use MLL\LaravelUtils\ModelStates\State; use MLL\LaravelUtils\ModelStates\StateConfig; @@ -13,6 +14,7 @@ public static function config(): StateConfig { return (new StateConfig()) ->allowTransition(StateA::class, StateB::class) + ->allowTransition(StateA::class, StateA::class, TransitionWithException::class) ->allowTransition([StateA::class, StateB::class], StateC::class) ->allowTransition(StateA::class, StateD::class) ->allowTransition(StateC::class, StateA::class) diff --git a/app/ModelStates/Transitions/TransitionWithException.php b/app/ModelStates/Transitions/TransitionWithException.php new file mode 100644 index 0000000..4af4d3f --- /dev/null +++ b/app/ModelStates/Transitions/TransitionWithException.php @@ -0,0 +1,23 @@ +manage(); + + throw new \Exception('This is a exception thrown by TransitionWithException.'); + } +} diff --git a/src/ModelStates/HasStateManager.php b/src/ModelStates/HasStateManager.php index b7fa6f4..9fb2b7c 100644 --- a/src/ModelStates/HasStateManager.php +++ b/src/ModelStates/HasStateManager.php @@ -57,11 +57,6 @@ public function getStateAttribute(): State /** @param State|class-string $newState */ public function setStateAttribute(State|string $newState): void { - // if the old and new state are the same, do not perform a "transition" - if ($this->state::name() === $newState::name()) { - return; - } - $this->stateMachine() ->transitionTo($newState); } diff --git a/tests/ModelStates/StateTest.php b/tests/ModelStates/StateTest.php index 0f8644f..89ffad8 100644 --- a/tests/ModelStates/StateTest.php +++ b/tests/ModelStates/StateTest.php @@ -35,15 +35,16 @@ public function testModelWillBeCreatedWithDefault(): void self::assertSame(StateA::name(), $model->stateManager->state_name); } - public function testIfOldAndNewStateAreIdenticalNoTransitionNotAllowedExceptionWillBeThrown(): void + public function testTransitionIsBeingCalledIfOldAndNewStateAreIdentical(): void { // A -> A $model1 = new TestModel(); $model1->save(); self::assertSame('STATE_A', StateA::name()); self::assertSame(StateA::name(), $model1->stateManager->state_name); + + self::expectExceptionObject(new \Exception('This is a exception thrown by TransitionWithException.')); $model1->state = new StateA(); - self::assertSame(StateA::name(), $model1->stateManager->state_name); } public function testCanTransitionToAllowedStates(): void @@ -116,6 +117,7 @@ public function testReturnsListOfPossibleNextStates(): void StateB::class => new StateB(), StateC::class => new StateC(), StateD::class => new StateD(), + StateA::class => new StateA(), ]), $model->stateManager->canTransitionTo); $model->state = new StateB(); @@ -218,6 +220,7 @@ public function testGenerateMermaidGraph(): void STATE_A-->FOO_BAR; STATE_A-->STATE_C; STATE_A-->STATE_D; + STATE_A-->|"TransitionWithException"|STATE_A; STATE_C-->STATE_A; STATE_D-->|"CustomInvalidTransition"|STATE_A;