diff --git a/composer.json b/composer.json
index 9751450..7b9e021 100644
--- a/composer.json
+++ b/composer.json
@@ -42,6 +42,6 @@
"test-coverage" : "phpunit --log-junit tmp/coverage/unitreport.xml --coverage-html tmp/coverage --coverage-clover tmp/coverage/coverage.xml",
"phpstan": "vendor/bin/phpstan.phar analyse -c tests/phpstan.neon -l 7 src/",
"cs-check": "vendor/bin/phpcs --colors --standard=config/ruleset.xml -s -p --ignore=/config/Migrations/,/src/Dto/ src/ tests/ config/",
- "cs-fix": "vendor/bin/phpcbf --colors --standard=config/ruleset.xml -v --ignore=/config/Migrations/,/src/Dto/ src/ tests/ config/"
+ "cs-fix": "vendor/bin/phpcbf --colors --standard=config/ruleset.xml --ignore=/config/Migrations/,/src/Dto/ src/ tests/ config/"
}
}
diff --git a/src/Business/Logger/TransitionLog.php b/src/Business/Logger/TransitionLog.php
index 7d13cfc..0ba6259 100644
--- a/src/Business/Logger/TransitionLog.php
+++ b/src/Business/Logger/TransitionLog.php
@@ -47,11 +47,24 @@ public function __construct(
*/
public function setEvent(EventInterface $event): void
{
- $nameEvent = $event->getName();
- $nameEvent .= $event->getEventTypeLabel();
+ $eventName = $event->getName();
+ $eventName .= $event->getEventTypeLabel();
foreach ($this->logEntities as $logEntity) {
- $logEntity->event = $nameEvent;
+ $logEntity->event = $eventName;
+ }
+ }
+
+ /**
+ * @param \StateMachine\Dto\StateMachine\ItemDto $itemDto
+ * @param string $eventName
+ *
+ * @return void
+ */
+ public function setEventName(ItemDto $itemDto, string $eventName): void
+ {
+ foreach ($this->logEntities as $logEntity) {
+ $logEntity->event = $eventName;
}
}
diff --git a/src/Business/Logger/TransitionLogInterface.php b/src/Business/Logger/TransitionLogInterface.php
index a836792..69049b6 100644
--- a/src/Business/Logger/TransitionLogInterface.php
+++ b/src/Business/Logger/TransitionLogInterface.php
@@ -21,6 +21,14 @@ interface TransitionLogInterface
*/
public function setEvent(EventInterface $event): void;
+ /**
+ * @param \StateMachine\Dto\StateMachine\ItemDto $itemDto
+ * @param string $eventName
+ *
+ * @return void
+ */
+ public function setEventName(ItemDto $itemDto, string $eventName): void;
+
/**
* @param \StateMachine\Dto\StateMachine\ItemDto[] $stateMachineItems
*
diff --git a/src/Business/StateMachine/Trigger.php b/src/Business/StateMachine/Trigger.php
index e138854..c73111b 100644
--- a/src/Business/StateMachine/Trigger.php
+++ b/src/Business/StateMachine/Trigger.php
@@ -136,6 +136,7 @@ public function triggerEvent(string $eventName, array $stateMachineItems): int
$this->transitionLog->init($stateMachineItems);
$this->logSourceState($stateMachineItems);
+ $this->logEventName($stateMachineItems, $eventName);
$this->runCommand($eventName, $stateMachineItems, $processes);
@@ -384,6 +385,19 @@ protected function logSourceState(array $stateMachineItems): void
}
}
+ /**
+ * @param \StateMachine\Dto\StateMachine\ItemDto[] $stateMachineItems
+ * @param string $eventName
+ *
+ * @return void
+ */
+ protected function logEventName(array $stateMachineItems, string $eventName): void
+ {
+ foreach ($stateMachineItems as $itemDto) {
+ $this->transitionLog->setEventName($itemDto, $eventName);
+ }
+ }
+
/**
* @param string $commandString
* @param string $stateMachineName
diff --git a/src/Model/Table/StateMachineTransitionLogsTable.php b/src/Model/Table/StateMachineTransitionLogsTable.php
index a79ff98..492cb6e 100644
--- a/src/Model/Table/StateMachineTransitionLogsTable.php
+++ b/src/Model/Table/StateMachineTransitionLogsTable.php
@@ -170,7 +170,7 @@ public function afterSave(EventInterface $event, EntityInterface $entity, ArrayO
/**
* @param int $stateMachineItemId
*
- * @return array
+ * @return \StateMachine\Model\Entity\StateMachineTransitionLog[]
*/
public function getLogs(int $stateMachineItemId): array
{
diff --git a/tests/TestCase/Business/StateMachineFacadeTest.php b/tests/TestCase/Business/StateMachineFacadeTest.php
index 103054f..4781d04 100644
--- a/tests/TestCase/Business/StateMachineFacadeTest.php
+++ b/tests/TestCase/Business/StateMachineFacadeTest.php
@@ -12,21 +12,26 @@
use Cake\I18n\FrozenTime;
use Cake\ORM\TableRegistry;
use Cake\TestSuite\TestCase;
+use InvalidArgumentException;
use StateMachine\Business\StateMachineFacade;
use StateMachine\Business\StateMachineFacadeInterface;
use StateMachine\Dependency\StateMachineHandlerInterface;
use StateMachine\Dto\StateMachine\ItemDto;
use StateMachine\Dto\StateMachine\ProcessDto;
+use StateMachine\Model\Table\StateMachineItemsTable;
use StateMachine\Model\Table\StateMachineItemStateHistoryTable;
use StateMachine\Model\Table\StateMachineItemStatesTable;
use StateMachine\Model\Table\StateMachineProcessesTable;
use StateMachine\Model\Table\StateMachineTimeoutsTable;
+use StateMachine\Model\Table\StateMachineTransitionLogsTable;
class StateMachineFacadeTest extends TestCase
{
protected const TESTING_SM = 'TestingSm';
protected const TEST_PROCESS_NAME = 'TestProcess';
protected const TEST_PROCESS_WITH_LOOP_NAME = 'TestProcessWithLoop';
+ protected const TEST_PROCESS_WITH_ERROR_NAME = 'TestProcessWithError';
+ protected const TEST_PROCESS_WITH_COMMAND_ERROR_NAME = 'TestProcessWithCommandError';
/**
* @var \StateMachine\Model\Table\StateMachineItemStateHistoryTable
@@ -48,6 +53,11 @@ class StateMachineFacadeTest extends TestCase
*/
protected $StateMachineTimeouts;
+ /**
+ * @var \StateMachine\Model\Table\StateMachineTransitionLogsTable
+ */
+ protected $StateMachineTransitionLogs;
+
/**
* @var array
*/
@@ -81,6 +91,12 @@ public function setUp(): void
$config = TableRegistry::getTableLocator()->exists('StateMachineTimeouts') ? [] : ['className' => StateMachineTimeoutsTable::class];
$this->StateMachineTimeouts = TableRegistry::getTableLocator()->get('StateMachineTimeouts', $config);
+
+ $config = TableRegistry::getTableLocator()->exists('StateMachineTransitionLogs') ? [] : ['className' => StateMachineTransitionLogsTable::class];
+ $this->StateMachineTransitionLogs = TableRegistry::getTableLocator()->get('StateMachineTransitionLogs', $config);
+
+ $config = TableRegistry::getTableLocator()->exists('StateMachineItems') ? [] : ['className' => StateMachineItemsTable::class];
+ $this->StateMachineItems = TableRegistry::getTableLocator()->get('StateMachineItems', $config);
}
/**
@@ -211,6 +227,86 @@ public function testTriggerEventForItemWithManualEventShouldMoveToNextStateWithM
$this->assertSame($identifier, $itemDto->getIdentifier());
}
+ /**
+ * @return void
+ */
+ public function testTriggerEventConditionFailureLogsTransition(): void
+ {
+ $processName = static::TEST_PROCESS_WITH_ERROR_NAME;
+ $identifier = 1985;
+
+ $processDto = new ProcessDto();
+ $processDto->setProcessName($processName);
+ $processDto->setStateMachineName(static::TESTING_SM);
+
+ $stateMachineHandler = $this->createTestStateMachineHandler();
+ $stateMachineFacade = $this->createStateMachineFacade($stateMachineHandler);
+
+ $failed = false;
+ try {
+ $stateMachineFacade->triggerForNewStateMachineItem($processDto, $identifier);
+ } catch (InvalidArgumentException $exception) {
+ $failed = true;
+ }
+ $this->assertTrue($failed, 'Should have thrown exception');
+
+ $itemDto = $stateMachineHandler->getItemStateUpdated();
+ $this->assertSame('invoice sent', $itemDto->getStateName());
+ $this->assertSame($identifier, $itemDto->getIdentifier());
+
+ $stateMachineItem = $this->StateMachineItems->find()->where(['state_machine' => static::TESTING_SM, 'identifier' => $identifier])->firstOrFail();
+
+ $logs = $this->StateMachineTransitionLogs->getLogs($stateMachineItem->id);
+ $this->assertCount(3, $logs);
+
+ $lastLog = array_shift($logs);
+ $this->assertSame('export order (on enter)', $lastLog->event);
+ $this->assertSame('invoice sent', $lastLog->source_state);
+ $this->assertNull($lastLog->target_state);
+ $this->assertTrue($lastLog->is_error);
+ $this->assertContains('Test exception for identity', $lastLog->error_message);
+ }
+
+ /**
+ * @return void
+ */
+ public function testTriggerEventCommandFailureLogsTransition(): void
+ {
+ $processName = static::TEST_PROCESS_WITH_COMMAND_ERROR_NAME;
+ $identifier = 1985;
+
+ $processDto = new ProcessDto();
+ $processDto->setProcessName($processName);
+ $processDto->setStateMachineName(static::TESTING_SM);
+
+ $stateMachineHandler = $this->createTestStateMachineHandler();
+ $stateMachineFacade = $this->createStateMachineFacade($stateMachineHandler);
+
+ $failed = false;
+ try {
+ $stateMachineFacade->triggerForNewStateMachineItem($processDto, $identifier);
+ } catch (InvalidArgumentException $exception) {
+ $failed = true;
+ }
+ $this->assertTrue($failed, 'Should have thrown exception');
+
+ $itemDto = $stateMachineHandler->getItemStateUpdated();
+ $this->assertSame('invoice created', $itemDto->getStateName());
+ $this->assertSame($identifier, $itemDto->getIdentifier());
+
+ $stateMachineItem = $this->StateMachineItems->find()->where(['state_machine' => static::TESTING_SM, 'identifier' => $identifier])->firstOrFail();
+
+ $logs = $this->StateMachineTransitionLogs->getLogs($stateMachineItem->id);
+ $this->assertCount(2, $logs);
+
+ $lastLog = array_shift($logs);
+ $this->assertSame('send invoice', $lastLog->event);
+ $this->assertSame('invoice created', $lastLog->source_state);
+ $this->assertNull($lastLog->target_state);
+ $this->assertTrue($lastLog->is_error);
+ $this->assertContains('Test exception for identity', $lastLog->error_message);
+ }
+
/**
* @return void
*/
diff --git a/tests/test_app/src/StateMachine/Command/TestErrorCommand.php b/tests/test_app/src/StateMachine/Command/TestErrorCommand.php
new file mode 100644
index 0000000..2a94787
--- /dev/null
+++ b/tests/test_app/src/StateMachine/Command/TestErrorCommand.php
@@ -0,0 +1,29 @@
+getIdentifierOrFail());
+ }
+}
diff --git a/tests/test_app/src/StateMachine/Condition/TestErrorCondition.php b/tests/test_app/src/StateMachine/Condition/TestErrorCondition.php
new file mode 100644
index 0000000..aed9c8f
--- /dev/null
+++ b/tests/test_app/src/StateMachine/Condition/TestErrorCondition.php
@@ -0,0 +1,30 @@
+getIdentifierOrFail());
+ }
+}
diff --git a/tests/test_app/src/StateMachine/TestStateMachineHandler.php b/tests/test_app/src/StateMachine/TestStateMachineHandler.php
index 0adf7a2..eec31b0 100644
--- a/tests/test_app/src/StateMachine/TestStateMachineHandler.php
+++ b/tests/test_app/src/StateMachine/TestStateMachineHandler.php
@@ -8,6 +8,8 @@
namespace App\StateMachine;
use App\StateMachine\Command\TestCommand;
+use App\StateMachine\Command\TestErrorCommand;
+use App\StateMachine\Condition\TestErrorCondition;
use App\StateMachine\Condition\TestTrueCondition;
use StateMachine\Dependency\StateMachineHandlerInterface;
use StateMachine\Dto\StateMachine\ItemDto;
@@ -34,6 +36,7 @@ public function getCommands(): array
{
return [
'Test/Command' => TestCommand::class,
+ 'Test/ErrorCommand' => TestErrorCommand::class,
];
}
@@ -44,6 +47,7 @@ public function getConditions(): array
{
return [
'Test/Condition' => TestTrueCondition::class,
+ 'Test/ErrorCondition' => TestErrorCondition::class,
];
}
diff --git a/tests/test_files/TestingSm/TestProcessWithCommandError.xml b/tests/test_files/TestingSm/TestProcessWithCommandError.xml
new file mode 100644
index 0000000..bb95bf5
--- /dev/null
+++ b/tests/test_files/TestingSm/TestProcessWithCommandError.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+ Flag1
+
+
+ Flag1
+ Flag2
+
+
+
+
+
+ new
+ invoice created
+ create invoice
+
+
+
+ invoice created
+ invoice sent
+ send invoice
+
+
+
+
+
+
+
+
+
diff --git a/tests/test_files/TestingSm/TestProcessWithError.xml b/tests/test_files/TestingSm/TestProcessWithError.xml
new file mode 100644
index 0000000..3e1612e
--- /dev/null
+++ b/tests/test_files/TestingSm/TestProcessWithError.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+ Flag1
+
+
+ Flag1
+ Flag2
+
+
+
+
+
+
+ new
+ invoice created
+ create invoice
+
+
+
+ invoice created
+ invoice sent
+ send invoice
+
+
+
+ invoice sent
+ order exported
+ export order
+
+
+
+
+
+
+
+
+
+