public function testReturnReportWithEventsOnEnterWorkflow() { $model = new Item04(); $model->on(WorkflowEvent::beforeEnterStatus('Item04Workflow/A'), function ($event) { $event->invalidate('my error message'); }); $report = $model->getNextStatuses(false, true); $this->assertCount(1, $report); $this->assertArrayHasKey('Item04Workflow/A', $report); $this->assertInstanceOf('raoul2000\\workflow\\base\\Status', $report['Item04Workflow/A']['status']); $this->assertCount(3, $report['Item04Workflow/A']['event']); $this->assertEquals([0 => ['name' => SimpleWorkflowBehavior::EVENT_BEFORE_CHANGE_STATUS, 'success' => null], 1 => ['name' => 'beforeEnterWorkflow{Item04Workflow}', 'success' => null], 2 => ['name' => 'beforeEnterStatus{Item04Workflow/A}', 'success' => false, 'messages' => [0 => 'my error message']]], $report['Item04Workflow/A']['event']); $this->assertEquals(false, $report['Item04Workflow/A']['isValid']); }
public function testNoPropagateErrorToModel() { // prepare item instance $item = new Item00(); $item->attachBehavior('workflow', ['class' => SimpleWorkflowBehavior::className(), 'defaultWorkflowId' => 'Item04Workflow', 'propagateErrorsToModel' => false]); $item->on(WorkflowEvent::beforeEnterStatus('Item04Workflow/B'), [$this, 'invalidateEvent']); $item->sendToStatus('Item04Workflow/A'); verify('item is in status A', $item->getWorkflowStatus()->getId())->equals('Item04Workflow/A'); verify('item has no error', $item->hasErrors())->false(); // send to B $item->sendToStatus('B'); expect('status is still A', $item->getWorkflowStatus()->getId())->equals('Item04Workflow/A'); expect('item has no error', $item->hasErrors())->false(); }
public function testOnEnterWorkflowError() { $this->model->on(WorkflowEvent::beforeEnterWorkflow('Item04Workflow'), function ($event) { $this->eventsBefore[] = $event; $event->isValid = false; }); $this->model->on(WorkflowEvent::afterEnterWorkflow('Item04Workflow'), function ($event) { $this->eventsAfter[] = $event; }); verify('event handler handlers have been called', count($this->eventsBefore) == 0 && count($this->eventsAfter) == 0)->true(); $this->model->enterWorkflow(); verify('current status is not set', $this->model->hasWorkflowStatus())->false(); expect('beforeChangeStatus handler has been called', count($this->eventsBefore))->equals(1); expect('afterChangeStatus handler has not been called', count($this->eventsAfter))->equals(0); }
public function testChangeStatusEventOnSaveFails() { $this->model->on(WorkflowEvent::beforeChangeStatus('Item04Workflow/A', 'Item04Workflow/B'), function ($event) { $this->eventsBefore[] = $event; $event->isValid = false; }); $this->model->on(WorkflowEvent::afterChangeStatus('Item04Workflow/A', 'Item04Workflow/B'), function ($event) { $this->eventsAfter[] = $event; }); $this->model->enterWorkflow(); verify('current status is set', $this->model->hasWorkflowStatus())->true(); verify('event handlers have never been called', count($this->eventsBefore) == 0 && count($this->eventsAfter) == 0)->true(); $this->model->status = 'Item04Workflow/B'; verify('save fails', $this->model->save())->false(); expect('model has not changed status', $this->model->getWorkflowStatus()->getId())->equals('Item04Workflow/A'); expect('beforeChangeStatus handler has been called', count($this->eventsBefore))->equals(1); expect('afterChangeStatus handler has not been called', count($this->eventsAfter))->equals(0); }
public function testStopOnFirstInvalidEventFalse() { // prepare item instance $item = new Item00(); $item->attachBehavior('workflowBehavior', ['class' => SimpleWorkflowBehavior::className(), 'defaultWorkflowId' => 'Item04Workflow', 'propagateErrorsToModel' => true, 'stopOnFirstInvalidEvent' => false]); $item->on(WorkflowEvent::beforeLeaveStatus('Item04Workflow/A'), [$this, 'invalidateEvent1']); $item->on(WorkflowEvent::beforeEnterStatus('Item04Workflow/B'), [$this, 'invalidateEvent2']); verify('stopOnFirstInvalidEvent is true', $item->stopOnFirstInvalidEvent)->false(); $item->sendToStatus('Item04Workflow/A'); verify('item is in status A', $item->getWorkflowStatus()->getId())->equals('Item04Workflow/A'); verify('item has no error', $item->hasErrors())->false(); // send to B $item->sendToStatus('B'); expect('status is still A', $item->getWorkflowStatus()->getId())->equals('Item04Workflow/A'); expect('item has error', $item->hasErrors())->true(); expect('1 error message is set for attribute "status"', count($item->getErrors('status')))->equals(2); $errorMessages = $item->getErrors('status'); expect('First error message is "err_message_1" ', $errorMessages[0])->equals("err_message_1"); expect('Second error message is "err_message_2" ', $errorMessages[1])->equals("err_message_2"); }
public function events() { return [WorkflowEvent::beforeEnterStatus('Item06Workflow/new') => "beforeNew", WorkflowEvent::afterEnterStatus('Item06Workflow/new') => "afterNew", WorkflowEvent::afterEnterStatus('Item06Workflow/correction') => "postToCorrect", WorkflowEvent::beforeLeaveStatus('Item06Workflow/correction') => "postCorrected", WorkflowEvent::beforeEnterStatus('Item06Workflow/published') => "checkCanBePublished", WorkflowEvent::beforeChangeStatus('Item06Workflow/published', 'Item06Workflow/archive') => "canBeArchived", WorkflowEvent::beforeLeaveWorkflow('Item06Workflow') => 'beforeLeaveWorkflow', WorkflowEvent::afterLeaveWorkflow('Item06Workflow') => 'afterLeaveWorkflow']; }
/** * Produces the following event sequence when a model changes from status A to status B. * * - beforeLeaveStatus(*) * - beforeLeaveStatus(A) * - beforeChangeStatusFrom(A)to(B) * - beforeEnterStatus(*) * - beforeEnterStatus(B) * * - afterLeaveStatus(*) * - afterLeaveStatus(A) * - afterChangeStatusFrom(A)to(B) * - afterEnterStatus(*) * - afterEnterStatus(B) * @see \raoul2000\workflow\events\IEventSequence::createChangeStatusSequence() */ public function createChangeStatusSequence($transition, $sender) { return ['before' => [new WorkflowEvent(WorkflowEvent::beforeLeaveStatus(), ['start' => $transition->getStartStatus(), 'sender' => $sender]), new WorkflowEvent(WorkflowEvent::beforeLeaveStatus($transition->getStartStatus()->getId()), ['start' => $transition->getStartStatus(), 'sender' => $sender]), new WorkflowEvent(WorkflowEvent::beforeChangeStatus($transition->getStartStatus()->getId(), $transition->getEndStatus()->getId()), ['start' => $transition->getStartStatus(), 'end' => $transition->getEndStatus(), 'transition' => $transition, 'sender' => $sender]), new WorkflowEvent(WorkflowEvent::beforeEnterStatus(), ['end' => $transition->getEndStatus(), 'sender' => $sender]), new WorkflowEvent(WorkflowEvent::beforeEnterStatus($transition->getEndStatus()->getId()), ['end' => $transition->getEndStatus(), 'sender' => $sender])], 'after' => [new WorkflowEvent(WorkflowEvent::afterLeaveStatus(), ['start' => $transition->getStartStatus(), 'sender' => $sender]), new WorkflowEvent(WorkflowEvent::afterLeaveStatus($transition->getStartStatus()->getId()), ['start' => $transition->getStartStatus(), 'sender' => $sender]), new WorkflowEvent(WorkflowEvent::afterChangeStatus($transition->getStartStatus()->getId(), $transition->getEndStatus()->getId()), ['start' => $transition->getStartStatus(), 'end' => $transition->getEndStatus(), 'transition' => $transition, 'sender' => $sender]), new WorkflowEvent(WorkflowEvent::afterEnterStatus(), ['end' => $transition->getEndStatus(), 'sender' => $sender]), new WorkflowEvent(WorkflowEvent::afterEnterStatus($transition->getEndStatus()->getId()), ['end' => $transition->getEndStatus(), 'sender' => $sender])]]; }
/** * Produces the following sequence when a model changes from status A to status B: * * - beforeChangeStatus(A,B) * - afterChangeStatus(A,B) * * @see \raoul2000\workflow\events\IEventSequence::createChangeStatusSequence() */ public function createChangeStatusSequence($transition, $sender) { $config = ['start' => $transition->getStartStatus(), 'end' => $transition->getEndStatus(), 'transition' => $transition, 'sender' => $sender]; return ['before' => [new WorkflowEvent(WorkflowEvent::beforeChangeStatus($transition->getStartStatus()->getId(), $transition->getEndStatus()->getId()), $config)], 'after' => [new WorkflowEvent(WorkflowEvent::afterChangeStatus($transition->getStartStatus()->getId(), $transition->getEndStatus()->getId()), $config)]]; }