package ee.telekom.workflow.test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import java.util.LinkedList; import java.util.List; import java.util.Map; import org.junit.Before; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; import ee.telekom.workflow.api.WorkflowDefinition; import ee.telekom.workflow.api.WorkflowFactoryImpl; import ee.telekom.workflow.core.common.WorkflowEngineConfiguration; import ee.telekom.workflow.executor.plugin.WorkflowEnginePlugin; import ee.telekom.workflow.graph.BeanResolver; import ee.telekom.workflow.graph.Environment; import ee.telekom.workflow.graph.Graph; import ee.telekom.workflow.graph.GraphInstance; import ee.telekom.workflow.graph.GraphInstanceEventListener; import ee.telekom.workflow.graph.GraphWorkItem; import ee.telekom.workflow.graph.GraphWorkItemEventListener; import ee.telekom.workflow.graph.NewGraphInstanceCreator; import ee.telekom.workflow.graph.WorkItemStatus; import ee.telekom.workflow.graph.WorkflowException; import ee.telekom.workflow.graph.core.EnvironmentImpl; import ee.telekom.workflow.graph.core.GraphEngineImpl; import ee.telekom.workflow.graph.core.GraphRepositoryImpl; import ee.telekom.workflow.util.CallUtil; /** * Helper class for Workflow Unit tests * * @author Raido Türk */ public abstract class AbstractWorkflowApiTest{ @Spy @InjectMocks protected AdapterBeanResolver beanResolver = new AdapterBeanResolver(); GraphEngineImpl graphEngine; TestGraphEngineFactory factory; GraphInstance instance; @Mock private AdapterNewGraphInstanceCreator newGraphInstanceCreator; @Mock private AdapterEventListener listener; @Before public void setUpEngine(){ instance = null; graphEngine = new GraphEngineImpl(); graphEngine.setBeanResolver( beanResolver ); graphEngine.setRepository( new GraphRepositoryImpl() ); graphEngine.setNewGraphInstanceCreator( newGraphInstanceCreator ); graphEngine.registerInstanceEventListener( listener ); graphEngine.registerWorkItemEventListener( listener ); factory = new TestGraphEngineFactory( graphEngine, mock( WorkflowEngineConfiguration.class ), mock( WorkflowEnginePlugin.class ) ); } protected void addGraphAndStartInstance( WorkflowDefinition definition, Map<String, Object> inputAttributes ){ addGraph( definition ); instance = factory.getSingletonInstance().start( definition.getName(), definition.getVersion(), createEnvironment( inputAttributes ), 14l ); } protected void terminateTimer(){ GraphWorkItem item = findActiveTimer( instance ); graphEngine.complete( item ); } protected void sendSignal( String signal ){ GraphWorkItem item = findActiveSignal( instance, signal ); graphEngine.complete( item ); } protected void sendSignalWithResult( String signal, Object result ){ GraphWorkItem item = findActiveSignal( instance, signal ); item.setResult( result ); graphEngine.complete( item ); } protected void invokeAsyncCall(){ GraphWorkItem item = findActiveAsyncCall( instance ); Object returnValue = CallUtil.call( beanResolver.getBean( item.getBean() ), item.getMethod(), item.getTaskArguments() ); item.setResult( returnValue ); graphEngine.complete( item ); } protected void completeHumanTask(){ GraphWorkItem item = findActiveHumanTask( instance ); graphEngine.complete( item ); } protected void completeHumanTaskWithResult( Object result ){ GraphWorkItem item = findActiveHumanTask( instance ); item.setResult( result ); graphEngine.complete( item ); } protected void assertInstanceCompleted(){ assertTrue( instance.isCompleted() ); } protected void assertActiveWorkItemsCount( int count ){ assertEquals( count, getActiveWorkItems( instance ).size() ); } protected void assertEnvironmentContainsValues( Map<String, Object> expectedEnvironmentValues ){ Environment environment = instance.getEnvironment(); for( String key : expectedEnvironmentValues.keySet() ){ if( environment.containsAttribute( key ) ){ assertEquals( expectedEnvironmentValues.get( key ), environment.getAttribute( key ) ); } } } protected void verifyNewInstanceCreation( String instanceName ){ verify( newGraphInstanceCreator, times( 1 ) ).create( eq( instanceName ), anyInt(), anyString(), anyString(), any( Environment.class ) ); } private void addGraph( WorkflowDefinition definition ){ WorkflowFactoryImpl workflowFactory = new WorkflowFactoryImpl( definition.getName(), definition.getVersion() ); definition.configureWorkflowDefinition( workflowFactory ); Graph graph = workflowFactory.buildGraph(); factory.getSingletonInstance().getRepository().addGraph( graph ); } private List<GraphWorkItem> getActiveWorkItems( GraphInstance instance ){ List<GraphWorkItem> result = new LinkedList<>(); for( GraphWorkItem wi : instance.getWorkItems() ){ if( !WorkItemStatus.COMPLETED.equals( wi.getStatus() ) && !WorkItemStatus.CANCELLED.equals( wi.getStatus() ) ){ result.add( wi ); } } return result; } private GraphWorkItem findActiveSignal( GraphInstance graphInstance, String signal ){ for( GraphWorkItem workItem : getActiveWorkItems( graphInstance ) ){ if( signal != null && signal.equals( workItem.getSignal() ) ){ return workItem; } } throw new WorkflowException( "No active signal work item found" ); } private GraphWorkItem findActiveTimer( GraphInstance graphInstance ){ for( GraphWorkItem workItem : getActiveWorkItems( graphInstance ) ){ if( workItem.getDueDate() != null ){ return workItem; } } throw new WorkflowException( "No active timer work item found" ); } private GraphWorkItem findActiveAsyncCall( GraphInstance graphInstance ){ for( GraphWorkItem workItem : getActiveWorkItems( graphInstance ) ){ if( workItem.getBean() != null && workItem.getMethod() != null ){ return workItem; } } throw new WorkflowException( "No active async call work item found" ); } private GraphWorkItem findActiveHumanTask( GraphInstance graphInstance ){ for( GraphWorkItem workItem : getActiveWorkItems( graphInstance ) ){ if( workItem.getRole() != null || workItem.getUser() != null ){ return workItem; } } throw new WorkflowException( "No active human task work item found" ); } private EnvironmentImpl createEnvironment( Map<String, Object> inputAttributes ){ EnvironmentImpl environment = new EnvironmentImpl(); if( inputAttributes != null ){ for( String key : inputAttributes.keySet() ){ environment.setAttribute( key, inputAttributes.get( key ) ); } } return environment; } protected class AdapterBeanResolver implements BeanResolver{ @Override public Object getBean( String name ){ throw new IllegalStateException( "Bean '" + name + "' has not been mocked!" ); } } private class AdapterNewGraphInstanceCreator implements NewGraphInstanceCreator{ @Override public void create( String graphName, Integer graphVersion, String label1, String label2, Environment initialEnvironment ){ } } private class AdapterEventListener implements GraphInstanceEventListener, GraphWorkItemEventListener{ @Override public void onCreated( GraphInstance instance ){ } @Override public void onStarted( GraphInstance instance ){ } @Override public void onAborting( GraphInstance instance ){ } @Override public void onAborted( GraphInstance instance ){ } @Override public void onCompleted( GraphInstance instance ){ } @Override public void onCreated( GraphWorkItem workItem ){ } @Override public void onCancelled( GraphWorkItem workItem ){ } @Override public void onCompleted( GraphWorkItem workItem ){ } } }