1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
86
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 }