View Javadoc
1   /**
2    * Copyright 2005-2014 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.kew.engine.node;
17  
18  import static org.junit.Assert.assertEquals;
19  import static org.junit.Assert.assertNotNull;
20  import static org.junit.Assert.assertTrue;
21  import static org.junit.Assert.fail;
22  
23  import java.util.ArrayList;
24  import java.util.Iterator;
25  import java.util.List;
26  import java.util.Set;
27  
28  import org.junit.Test;
29  import org.kuali.rice.kew.api.WorkflowDocument;
30  import org.kuali.rice.kew.api.WorkflowDocumentFactory;
31  import org.kuali.rice.kew.engine.node.service.RouteNodeService;
32  import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
33  import org.kuali.rice.kew.service.KEWServiceLocator;
34  import org.kuali.rice.kew.test.KEWTestCase;
35  import org.kuali.rice.kew.test.TestUtilities;
36  
37  public class RouteNodeServiceTest extends KEWTestCase {
38  
39      private RouteNodeService routeNodeService;
40      
41      protected void setUpAfterDataLoad() throws Exception {
42          routeNodeService = KEWServiceLocator.getRouteNodeService();
43      }
44  
45      protected void loadTestData() throws Exception {
46          loadXmlFile("NodeConfig.xml");
47      }
48      
49      @Test public void testGetFlattenedNodeInstances() throws Exception {
50          WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), "SeqDocType");
51          document.saveDocument("");
52          
53          DocumentRouteHeaderValue serverDocument = KEWServiceLocator.getRouteHeaderService().getRouteHeader(document.getDocumentId());
54          List routeNodeInstances = routeNodeService.getFlattenedNodeInstances(serverDocument, true);
55          assertEquals(1, routeNodeInstances.size());
56          assertEquals("AdHoc", ((RouteNodeInstance)routeNodeInstances.get(0)).getName());
57          
58          document.blanketApprove("");
59          assertTrue(document.isProcessed());
60          
61          serverDocument = KEWServiceLocator.getRouteHeaderService().getRouteHeader(document.getDocumentId());
62          routeNodeInstances = routeNodeService.getFlattenedNodeInstances(serverDocument, true);
63          assertEquals(4, routeNodeInstances.size());
64          assertEquals("AdHoc", ((RouteNodeInstance)routeNodeInstances.get(0)).getName());
65          assertEquals("WorkflowDocument", ((RouteNodeInstance)routeNodeInstances.get(1)).getName());
66          assertEquals("Acknowledge1", ((RouteNodeInstance)routeNodeInstances.get(2)).getName());
67          assertEquals("Acknowledge2", ((RouteNodeInstance)routeNodeInstances.get(3)).getName());
68      }
69  
70      @Test public void testSearchNodeGraphSequentailBackward() throws Exception {
71      	WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), "SeqDocType");
72      	document.blanketApprove("", "WorkflowDocument");
73      	List activeNodeInstances = routeNodeService.getActiveNodeInstances(document.getDocumentId());
74      	NodeGraphSearchCriteria criteria = new NodeGraphSearchCriteria(NodeGraphSearchCriteria.SEARCH_DIRECTION_BACKWARD, activeNodeInstances, "AdHoc");
75      	NodeGraphSearchResult result = routeNodeService.searchNodeGraph(criteria);
76      	assertEquals("Path should have two nodes.", 2, result.getPath().size());
77      	RouteNodeInstance resultNodeInstance = result.getResultNodeInstance();
78      	assertNotNull("Should have a resulting node instance.", resultNodeInstance);
79      	assertEquals("Result node should be the adhoc node.", "AdHoc", resultNodeInstance.getName());
80      	
81      	// take it to the end
82      	document.blanketApprove("");
83      	assertTrue("Document should be processed.", document.isProcessed());
84      	List terminalNodeInstances = routeNodeService.getTerminalNodeInstances(document.getDocumentId());
85      	criteria = new NodeGraphSearchCriteria(NodeGraphSearchCriteria.SEARCH_DIRECTION_BACKWARD, terminalNodeInstances, "AdHoc");
86      	result = routeNodeService.searchNodeGraph(criteria);
87      	assertEquals("Path should have 4 nodes.", 4, result.getPath().size());
88      	resultNodeInstance = result.getResultNodeInstance();
89      	assertNotNull("Should have a resulting node instance.", resultNodeInstance);
90      	assertEquals("Result node should be the adhoc node.", "AdHoc", resultNodeInstance.getName());
91      	
92      	// now try searching from the Ack1 node for the WorkflowDocument node
93      	RouteNodeInstance ack1NodeInstance = null;
94      	for (Iterator iterator = result.getPath().iterator(); iterator.hasNext(); ) {
95  			RouteNodeInstance nodeInstance = (RouteNodeInstance) iterator.next();
96  			if (nodeInstance.getName().equals("Acknowledge1")) {
97  				ack1NodeInstance = nodeInstance;
98  				break;
99  			}
100 		}
101     	assertNotNull("Could not locate the Acknowledge1 node in the path.", ack1NodeInstance);
102     	List<RouteNodeInstance> startNodes = new ArrayList<RouteNodeInstance>();
103     	startNodes.add(ack1NodeInstance);
104     	criteria = new NodeGraphSearchCriteria(NodeGraphSearchCriteria.SEARCH_DIRECTION_BACKWARD, startNodes, "WorkflowDocument");
105     	result = routeNodeService.searchNodeGraph(criteria);
106     	// since we started at 'Acknowledge1' there should just be 'Acknowledge1' and 'WorkflowDocument' in the path
107     	assertEquals("Path should have 2 nodes.", 2, result.getPath().size());
108     	resultNodeInstance = result.getResultNodeInstance();
109     	assertNotNull("Should have a resulting node instance.", resultNodeInstance);
110     	assertEquals("Result node should be the workflow document node.", "WorkflowDocument", resultNodeInstance.getName());
111     }
112     
113     @Test public void testSearchNodeGraphParallelBackward() throws Exception {
114     	WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), "ParallelDocType");
115     	document.blanketApprove("", new String[] { "WorkflowDocument2", "WorkflowDocument3" });
116     	List activeNodeInstances = routeNodeService.getActiveNodeInstances(document.getDocumentId());
117     	assertEquals("Should be 2 active nodes.", 2, activeNodeInstances.size());
118     	Set<? extends String> nodeNames = TestUtilities.createNodeInstanceNameSet(activeNodeInstances);
119     	assertTrue("Should be at WorkflowDocument2 node.", nodeNames.contains("WorkflowDocument2"));
120     	assertTrue("Should be at the WorkflowDocument3 node.", nodeNames.contains("WorkflowDocument3"));
121     	
122     	
123     	// search backward to the adhoc node
124     	NodeGraphSearchCriteria criteria = new NodeGraphSearchCriteria(NodeGraphSearchCriteria.SEARCH_DIRECTION_BACKWARD, activeNodeInstances, "AdHoc");
125     	NodeGraphSearchResult result = routeNodeService.searchNodeGraph(criteria);
126     	assertEquals("Path should have eight nodes.", 8, result.getPath().size());
127     	RouteNodeInstance resultNodeInstance = result.getResultNodeInstance();
128     	assertNotNull("Should have a resulting node instance.", resultNodeInstance);
129     	assertEquals("Result node should be the adhoc node.", "AdHoc", resultNodeInstance.getName());
130     	nodeNames = TestUtilities.createNodeInstanceNameSet(result.getPath());
131     	// the following nodes should be in the list of 8
132     	assertTrue(nodeNames.contains("WorkflowDocument3"));
133     	assertTrue(nodeNames.contains("WorkflowDocument5"));
134     	assertTrue(nodeNames.contains("WorkflowDocument2"));
135     	assertTrue(nodeNames.contains("Acknowledge1"));
136     	assertTrue(nodeNames.contains("WorkflowDocument4"));
137     	assertTrue(nodeNames.contains("Split"));
138     	assertTrue(nodeNames.contains("WorkflowDocument"));
139     	assertTrue(nodeNames.contains("AdHoc"));
140     	
141     	// extract our active node instances
142     	RouteNodeInstance workflowDocument2Node = null;
143     	RouteNodeInstance workflowDocument3Node = null;
144     	for (Iterator iterator = activeNodeInstances.iterator(); iterator.hasNext(); ) {
145 			RouteNodeInstance nodeInstance = (RouteNodeInstance) iterator.next();
146 			if (nodeInstance.getName().equals("WorkflowDocument2")) {
147 				workflowDocument2Node = nodeInstance;
148 			} else if (nodeInstance.getName().equals("WorkflowDocument3")) {
149 				workflowDocument3Node = nodeInstance;
150 			}
151 		}
152     	assertNotNull("Could not locate WorkflowDocument2 node.", workflowDocument2Node);
153     	assertNotNull("Could not locate WorkflowDocument3 node.", workflowDocument3Node);
154     	
155     	// now try searching backward for WorkflowDocument4 from WorkflowDocument2, this should keep us on the branch
156     	List<RouteNodeInstance> startNodeInstances = new ArrayList<RouteNodeInstance>();
157     	startNodeInstances.add(workflowDocument2Node);
158     	criteria = new NodeGraphSearchCriteria(NodeGraphSearchCriteria.SEARCH_DIRECTION_BACKWARD, activeNodeInstances, "WorkflowDocument4");
159     	result = routeNodeService.searchNodeGraph(criteria);
160     	assertEquals("Path should have three nodes.", 3, result.getPath().size());
161     	resultNodeInstance = result.getResultNodeInstance();
162     	assertEquals("Result node should be the WorkflowDocument4 node.", "WorkflowDocument4", resultNodeInstance.getName());
163     	nodeNames = TestUtilities.createNodeInstanceNameSet(result.getPath());
164     	// the following nodes should be in the list of 3
165     	assertTrue(nodeNames.contains("WorkflowDocument2"));
166     	assertTrue(nodeNames.contains("Acknowledge1"));
167     	assertTrue(nodeNames.contains("WorkflowDocument4"));
168     	
169     	// try searching backward for WorkflowDocument5
170     	startNodeInstances = new ArrayList<RouteNodeInstance>();
171     	startNodeInstances.add(workflowDocument3Node);
172     	criteria = new NodeGraphSearchCriteria(NodeGraphSearchCriteria.SEARCH_DIRECTION_BACKWARD, activeNodeInstances, "WorkflowDocument5");
173     	result = routeNodeService.searchNodeGraph(criteria);
174     	assertEquals("Path should have two nodes.", 2, result.getPath().size());
175     	resultNodeInstance = result.getResultNodeInstance();
176     	assertEquals("Result node should be the WorkflowDocument5 node.", "WorkflowDocument5", resultNodeInstance.getName());
177     	nodeNames = TestUtilities.createNodeInstanceNameSet(result.getPath());
178     	// the following nodes should be in the list of 2
179     	assertTrue(nodeNames.contains("WorkflowDocument3"));
180     	assertTrue(nodeNames.contains("WorkflowDocument5"));
181     }
182     
183     /**
184      * currently searching forward does not work and needs to be implemented, we'll stub in a test
185      * that shows it throws an UnsupportedOperationException and then this test can be modified when the
186      * functionality is implemented.
187      */
188     @Test public void testSearchNodeGraphForward() throws Exception {
189     	WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), "SeqDocType");
190     	document.route("");
191     	List initialNodeInstances = KEWServiceLocator.getRouteNodeService().getInitialNodeInstances(document.getDocumentId());
192     	NodeGraphSearchCriteria criteria = new NodeGraphSearchCriteria(NodeGraphSearchCriteria.SEARCH_DIRECTION_FORWARD, initialNodeInstances, "WorkflowDocument");
193     	try {
194     		routeNodeService.searchNodeGraph(criteria);
195     		fail("Should have thrown UnsupportedOperationException");
196     	} catch (UnsupportedOperationException e) {
197     	}
198     }
199 
200 }