diff --git a/CHANGELOG.md b/CHANGELOG.md index 638fb9b..6c03c9f 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 + ## v10.5.0 ### Added diff --git a/app/ModelStates/ModelStates/ModelState.php b/app/ModelStates/ModelStates/ModelState.php index dd7b426..fb15060 100644 --- a/app/ModelStates/ModelStates/ModelState.php +++ b/app/ModelStates/ModelStates/ModelState.php @@ -3,6 +3,7 @@ namespace App\ModelStates\ModelStates; use App\ModelStates\StateManager; +use App\ModelStates\Transitions\TransitionWithException; use MLL\LaravelUtils\ModelStates\State; use MLL\LaravelUtils\ModelStates\StateConfig; @@ -12,6 +13,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); } 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 b539e7f..ec197cf 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(); @@ -206,6 +208,7 @@ public function testGenerateMermaidGraph(): void STATE_A-->FOO_BAR; STATE_A-->STATE_C; STATE_A-->STATE_D; + STATE_A-->|"TransitionWithException"|STATE_A; linkStyle default interpolate basis; MERMAID;