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