/** * Finalize the workflow * * @return Workflow Constructed workflow */ public function build() { // Build the workflow $workflow = new Workflow($this->workflowName, $this->contextClass); // Set the limits if they exist if ($this->activeLimit !== null) { $workflow->setActiveInstanceLimit($this->activeLimit); } if ($this->totalLimit !== null) { $workflow->setTotalInstanceLimit($this->totalLimit); } // Construct the map of states $stateMap = array(); foreach ($this->stateBuilders as $stateName => $stateBuilder) { $stateMap[$stateName] = $stateBuilder->getUnbuiltState(); } // Build each state foreach ($this->stateBuilders as $stateBuilder) { $workflow->addState($stateBuilder->build($stateMap)); } // Set the Initial state if (!array_key_exists($this->initialStateName, $stateMap)) { throw new StateNotFoundException($this->initialStateName, array_keys($stateMap)); } $workflow->setInitialState($stateMap[$this->initialStateName]); // Return the completed workflow return $workflow; }
/** * @expectedException \TyHand\WorkflowBundle\Exceptions\WorkflowNotFoundException * @expectedExceptionMessage Workflow with name "unicorn" was not found. Names found are [ "manager_test" ] */ public function testWorkflowNotFoundException() { // Create a dummy definition $workflow = new Workflow('manager_test', 'TyHand\\WorkflowBundle\\Tests\\DummyContext'); $stateA = new State('A'); $workflow->addState($stateA); $workflow->setInitialState($stateA); $mockBuilder = $this->getMockBuilder('TyHand\\WorkflowBundle\\Workflow\\Builder\\WorkflowBuilder')->disableOriginalConstructor()->setMethods(array('build'))->getMock(); $mockBuilder->expects($this->any())->method('build')->will($this->returnValue($workflow)); $mockDefinition = $this->getMockBuilder('TyHand\\WorkflowBundle\\Workflow\\AbstractWorkflowDefinition')->setMethods(array('getName', 'getContextClass', 'build'))->getMock(); $mockDefinition->expects($this->any())->method('getName')->will($this->returnValue('manager_test')); $mockDefinition->expects($this->any())->method('getContextClass')->will($this->returnValue('TyHand\\WorkflowBundle\\Tests\\DummyContext')); $mockDefinition->expects($this->any())->method('build')->will($this->returnValue($mockBuilder)); // Create the new manager $manager = new WorkflowManager(); $manager->addWorkflowDefinition($mockDefinition); // Get a non-existent workflow $workflow = $manager->getWorkflow('unicorn'); }
public function testOnWorkflowEvent() { // Create a test workflow $workflow = new Workflow('test', 'TyHand\\WorkflowBundle\\Tests\\DummyContext'); $stateA = new State('A'); $stateB = new State('B'); $stateC = new State('C'); $triggerA1 = new EventTrigger('go', 'B'); $triggerA1->setState($stateB); $triggerA2 = new EventTrigger('skip', 'C'); $triggerA2->setState($stateC); $triggerB1 = new EventTrigger('go', 'C'); $triggerB1->setState($stateC); $stateA->addEventTrigger($triggerA1); $stateA->addEventTrigger($triggerA2); $stateB->addEventTrigger($triggerB1); $workflow->addState($stateA); $workflow->addState($stateB); $workflow->addState($stateC); $workflow->setInitialState($stateA); // Create a mock workflow manager $mockManager = $this->getMockBuilder('TyHand\\WorkflowBundle\\Workflow\\WorkflowManager')->disableOriginalConstructor()->setMethods(array('getWorkflow'))->getMock(); $mockManager->expects($this->any())->method('getWorkflow')->with($this->equalTo('test'))->will($this->returnValue($workflow)); // create a mock object manager $mockObjectManager = $this->getMockBuilder('Doctrine\\ORM\\EntityManager')->disableOriginalConstructor()->setMethods(array('flush'))->getMock(); $mockObjectManager->expects($this->any())->method('flush')->will($this->returnValue(true)); // create the listener $listener = new WorkflowEventListener($mockManager, $mockObjectManager); // Test 1 (A -> B -> C) $dummyContext = new DummyContext(); $instance = $workflow->start($dummyContext); $this->assertEquals('A', $instance->getStateName()); $event = new WorkflowEvent($dummyContext, 'test', 'go'); $listener->onWorkflowEvent($event); $this->assertEquals('B', $instance->getStateName()); $event = new WorkflowEvent($dummyContext, 'test', 'go'); $listener->onWorkflowEvent($event); $this->assertEquals('C', $instance->getStateName()); // Test 2 (A -> C) $dummyContext = new DummyContext(); $instance = $workflow->start($dummyContext); $this->assertEquals('A', $instance->getStateName()); $event = new WorkflowEvent($dummyContext, 'test', 'skip'); $listener->onWorkflowEvent($event); $this->assertEquals('C', $instance->getStateName()); // Test 3 (A -> B -> C & A -> B) $dummyContext = new DummyContext(); $instance = $workflow->start($dummyContext); $this->assertEquals('A', $instance->getStateName()); $event = new WorkflowEvent($dummyContext, 'test', 'go'); $listener->onWorkflowEvent($event); $this->assertEquals('B', $instance->getStateName()); $instance2 = $workflow->start($dummyContext); $this->assertEquals('A', $instance2->getStateName()); $event = new WorkflowEvent($dummyContext, 'test', 'go'); $listener->onWorkflowEvent($event); $this->assertEquals('C', $instance->getStateName()); $this->assertEquals('B', $instance2->getStateName()); // Test 4 (A -> B -> B) $dummyContext = new DummyContext(); $instance = $workflow->start($dummyContext); $this->assertEquals('A', $instance->getStateName()); $event = new WorkflowEvent($dummyContext, 'test', 'go'); $listener->onWorkflowEvent($event); $this->assertEquals('B', $instance->getStateName()); $event = new WorkflowEvent($dummyContext, 'test', 'skip'); $listener->onWorkflowEvent($event); $this->assertEquals('B', $instance->getStateName()); // Test 5 (A -> A) $dummyContext = new DummyContext(); $instance = $workflow->start($dummyContext); $this->assertEquals('A', $instance->getStateName()); $event = new WorkflowEvent($dummyContext, 'test', 'jump'); $listener->onWorkflowEvent($event); $this->assertEquals('A', $instance->getStateName()); }
/** * @expectedException \TyHand\WorkflowBundle\Exceptions\ContextOverWorkflowLimitException * @expectedExceptionMessage This workflow only allows a context to have 2 active instances */ public function testStartContextWorkflowActiveLimitException() { $dummy = new DummyContext(); $workflow = new Workflow('test', 'TyHand\\WorkflowBundle\\Tests\\DummyContext'); $stateA = new State('A'); $stateB = new State('B'); $trigger = new EventTrigger('go', 'B'); $trigger->setState($stateB); $stateA->addEventTrigger($trigger); $workflow->addState($stateA); $workflow->addState($stateB); $workflow->setInitialState($stateA); $workflow->setActiveInstanceLimit(2); $instance = $workflow->start($dummy); // Mark instance 1 to be complete to test that only active is being checked $instance->setIsComplete(false); $instance2 = $workflow->start($dummy); $instance3 = $workflow->start($dummy); $this->assertTrue(true); // Checkpoint check $instance4 = $workflow->start($dummy); }