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;
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.List;
25  
26  import org.junit.Test;
27  import org.kuali.rice.kew.api.WorkflowDocument;
28  import org.kuali.rice.kew.api.WorkflowDocumentFactory;
29  import org.kuali.rice.kew.engine.node.DynamicNode;
30  import org.kuali.rice.kew.engine.node.DynamicResult;
31  import org.kuali.rice.kew.engine.node.NodeState;
32  import org.kuali.rice.kew.engine.node.RouteNode;
33  import org.kuali.rice.kew.engine.node.RouteNodeInstance;
34  import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
35  import org.kuali.rice.kew.service.KEWServiceLocator;
36  import org.kuali.rice.kew.test.KEWTestCase;
37  
38  
39  public class DynamicRoutingTest extends KEWTestCase {
40  
41      private static final String SEQ_DOC_TYPE_NAME = "DynSeqDocType";
42      private static final String INIT = "Initial";
43      private static final String FIRST = "First";
44      private static final String DYNAMIC_SEQ = "DynSeq";
45      private static final String SUB_REQUESTS = "SubRequests";
46      private static final String LAST = "Last";
47  
48      @Override
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          List<RouteNodeInstance> nodeInstances = KEWServiceLocator.getRouteNodeService().getActiveNodeInstances(document.getDocumentId());
59          assertEquals("Wrong number of active nodes.", 1, nodeInstances.size());
60          assertEquals("Wrong active node.", INIT, 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<RouteNodeInstance> initial = document.getInitialRouteNodeInstances();
94          assertEquals(1, initial.size());
95          RouteNodeInstance init = initial.get(0);
96          assertEquals(INIT, init.getRouteNode().getRouteNodeName());
97          assertEquals(0, init.getPreviousNodeInstances().size());
98  
99          List<RouteNodeInstance> next = init.getNextNodeInstances();
100         assertEquals(1, next.size());
101         RouteNodeInstance first = 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 = 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 = 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 = 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 = 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         @Override
144         public DynamicResult transitioningInto(RouteContext context, RouteNodeInstance process, RouteHelper helper) throws Exception {
145             RouteNodeInstance routeNodeInstance = context.getNodeInstance();
146             RouteNode dynamicRequestNode = helper.getNodeFactory().getRouteNode(context, SUB_REQUESTS);
147             RouteNodeInstance dynamicRequestNodeInstance1 = helper.getNodeFactory().createRouteNodeInstance(context.getDocument().getDocumentId(), dynamicRequestNode);
148             dynamicRequestNodeInstance1.addNodeState(new NodeState("role", "pmckown"));
149             RouteNodeInstance dynamicRequestNodeInstance2 = helper.getNodeFactory().createRouteNodeInstance(context.getDocument().getDocumentId(), dynamicRequestNode);
150             dynamicRequestNodeInstance2.addNodeState(new NodeState("role", "temay"));
151             RouteNodeInstance dynamicRequestNodeInstance3 = helper.getNodeFactory().createRouteNodeInstance(context.getDocument().getDocumentId(), dynamicRequestNode);
152             dynamicRequestNodeInstance3.addNodeState(new NodeState("role", "jhopf"));
153             dynamicRequestNodeInstance1.addNextNodeInstance(dynamicRequestNodeInstance2);
154             dynamicRequestNodeInstance2.addNextNodeInstance(dynamicRequestNodeInstance3);
155             routeNodeInstance.addNodeState(new NodeState("beenHere", "val"));
156             return new DynamicResult(true, dynamicRequestNodeInstance1);
157         }
158 
159         @Override
160         public DynamicResult transitioningOutOf(RouteContext context, RouteHelper helper) throws Exception {
161             return new DynamicResult(true, null);
162         }
163     }
164 }