View Javadoc
1   /**
2    * Copyright 2005-2011 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;
17  
18  
19  import static org.junit.Assert.assertEquals;
20  import static org.junit.Assert.assertNotNull;
21  import static org.junit.Assert.assertNull;
22  import static org.junit.Assert.assertTrue;
23  
24  import java.util.Collection;
25  import java.util.List;
26  
27  import org.junit.Test;
28  import org.kuali.rice.kew.api.WorkflowDocument;
29  import org.kuali.rice.kew.api.WorkflowDocumentFactory;
30  import org.kuali.rice.kew.engine.node.DynamicNode;
31  import org.kuali.rice.kew.engine.node.DynamicResult;
32  import org.kuali.rice.kew.engine.node.NodeState;
33  import org.kuali.rice.kew.engine.node.RouteNode;
34  import org.kuali.rice.kew.engine.node.RouteNodeInstance;
35  import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
36  import org.kuali.rice.kew.service.KEWServiceLocator;
37  import org.kuali.rice.kew.test.KEWTestCase;
38  
39  
40  public class DynamicRoutingTest extends KEWTestCase {
41  
42      private static final String SEQ_DOC_TYPE_NAME = "DynSeqDocType";
43      private static final String INIT = "Initial";
44      private static final String FIRST = "First";
45      private static final String DYNAMIC_SEQ = "DynSeq";
46      private static final String SUB_REQUESTS = "SubRequests";
47      private static final String LAST = "Last";
48  
49      protected void loadTestData() throws Exception {
50          loadXmlFile("EngineConfig.xml");
51      }
52  
53      @Test public void testDynamicParallelRoute() throws Exception {
54          WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), SEQ_DOC_TYPE_NAME);
55          document.saveDocumentData();
56          assertTrue("Document should be initiated", document.isInitiated());
57          assertEquals("Should be no action requests.", 0, document.getRootActionRequests().size());
58          Collection nodeInstances = KEWServiceLocator.getRouteNodeService().getActiveNodeInstances(document.getDocumentId());
59          assertEquals("Wrong number of active nodes.", 1, nodeInstances.size());
60          assertEquals("Wrong active node.", INIT, ((RouteNodeInstance) nodeInstances.iterator().next()).getRouteNode().getRouteNodeName());
61          document.route("");
62  
63          document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("bmcgough"), document.getDocumentId());
64          assertTrue("Approve should be requested.", document.isApprovalRequested());
65          document.approve("");
66  
67          nodeInstances = KEWServiceLocator.getRouteNodeService().getActiveNodeInstances(document.getDocumentId());
68          assertEquals("Wrong number of active nodes.", 1, nodeInstances.size());
69          document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("pmckown"), document.getDocumentId());
70          assertTrue("Approve should be requested.", document.isApprovalRequested());
71          document.approve("");
72  
73          document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("temay"), document.getDocumentId());
74          assertTrue("Approve should be requested.", document.isApprovalRequested());
75          document.approve("");
76  
77          document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("jhopf"), document.getDocumentId());
78          assertTrue("Approve should be requested.", document.isApprovalRequested());
79          document.approve("");
80  
81          document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("rkirkend"), document.getDocumentId());
82          assertTrue("Approve should be requested.", document.isApprovalRequested());
83          document.approve("");
84  
85          //        document = WorkflowDocumentFactory.loadDocument(new NetworkIdVO("ewestfal"), document.getDocumentId());
86          //        assertTrue("Document should be final.", document.isFinal());
87  
88          verifyRoutingPath(document.getDocumentId());
89      }
90  
91      private void verifyRoutingPath(String documentId) {
92          DocumentRouteHeaderValue document = KEWServiceLocator.getRouteHeaderService().getRouteHeader(documentId);
93          List initial = document.getInitialRouteNodeInstances();
94          assertEquals(1, initial.size());
95          RouteNodeInstance init = (RouteNodeInstance) initial.get(0);
96          assertEquals(INIT, init.getRouteNode().getRouteNodeName());
97          assertEquals(0, init.getPreviousNodeInstances().size());
98  
99          List next = init.getNextNodeInstances();
100         assertEquals(1, next.size());
101         RouteNodeInstance first = (RouteNodeInstance) next.get(0);
102         assertEquals(FIRST, first.getRouteNode().getRouteNodeName());
103         assertEquals(1, first.getPreviousNodeInstances().size());
104 
105         next = first.getNextNodeInstances();
106         assertEquals(1, next.size());
107         RouteNodeInstance pmckownNode = (RouteNodeInstance) next.get(0);
108         assertEquals(SUB_REQUESTS, pmckownNode.getRouteNode().getRouteNodeName());
109         assertEquals(1, pmckownNode.getPreviousNodeInstances().size());
110         assertInSubProcess(pmckownNode);
111 
112         next = pmckownNode.getNextNodeInstances();
113         assertEquals(1, next.size());
114         RouteNodeInstance temayNode = (RouteNodeInstance) next.get(0);
115         assertEquals(SUB_REQUESTS, temayNode.getRouteNode().getRouteNodeName());
116         assertEquals(1, temayNode.getPreviousNodeInstances().size());
117         assertInSubProcess(temayNode);
118 
119         next = temayNode.getNextNodeInstances();
120         assertEquals(1, next.size());
121         RouteNodeInstance jhopfNode = (RouteNodeInstance) next.get(0);
122         assertEquals(SUB_REQUESTS, jhopfNode.getRouteNode().getRouteNodeName());
123         assertEquals(1, jhopfNode.getPreviousNodeInstances().size());
124         assertInSubProcess(jhopfNode);
125 
126         next = jhopfNode.getNextNodeInstances();
127         assertEquals(1, next.size());
128         RouteNodeInstance last = (RouteNodeInstance) next.get(0);
129         assertNull(last.getProcess());
130         assertEquals(LAST, last.getRouteNode().getRouteNodeName());
131         assertEquals(1, last.getPreviousNodeInstances().size());
132         assertEquals(0, last.getNextNodeInstances().size());
133     }
134 
135     private void assertInSubProcess(RouteNodeInstance nodeInstance) {
136         RouteNodeInstance subProcess = nodeInstance.getProcess();
137         assertNotNull(subProcess);
138         assertEquals(DYNAMIC_SEQ, subProcess.getRouteNode().getRouteNodeName());
139     }
140 
141     public static class MockSequentialDynamicNode implements DynamicNode {
142 
143         public DynamicResult transitioningInto(RouteContext context, RouteNodeInstance process, RouteHelper helper) throws Exception {
144             RouteNodeInstance routeNodeInstance = context.getNodeInstance();
145             RouteNode dynamicRequestNode = helper.getNodeFactory().getRouteNode(context, SUB_REQUESTS);
146             RouteNodeInstance dynamicRequestNodeInstance1 = helper.getNodeFactory().createRouteNodeInstance(context.getDocument().getDocumentId(), dynamicRequestNode);
147             dynamicRequestNodeInstance1.addNodeState(new NodeState("role", "pmckown"));
148             RouteNodeInstance dynamicRequestNodeInstance2 = helper.getNodeFactory().createRouteNodeInstance(context.getDocument().getDocumentId(), dynamicRequestNode);
149             dynamicRequestNodeInstance2.addNodeState(new NodeState("role", "temay"));
150             RouteNodeInstance dynamicRequestNodeInstance3 = helper.getNodeFactory().createRouteNodeInstance(context.getDocument().getDocumentId(), dynamicRequestNode);
151             dynamicRequestNodeInstance3.addNodeState(new NodeState("role", "jhopf"));
152             dynamicRequestNodeInstance1.addNextNodeInstance(dynamicRequestNodeInstance2);
153             dynamicRequestNodeInstance2.addNextNodeInstance(dynamicRequestNodeInstance3);
154             routeNodeInstance.addNodeState(new NodeState("beenHere", "val"));
155             return new DynamicResult(true, dynamicRequestNodeInstance1);
156         }
157 
158         public DynamicResult transitioningOutOf(RouteContext context, RouteHelper helper) throws Exception {
159             return new DynamicResult(true, null);
160         }
161     }
162 }