View Javadoc

1   /*
2    * Copyright 2007 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.hierarchyrouting;
17  
18  import java.io.StringReader;
19  import java.util.List;
20  
21  import javax.xml.parsers.DocumentBuilderFactory;
22  
23  import org.junit.Test;
24  import org.kuali.rice.kew.dto.NetworkIdDTO;
25  import org.kuali.rice.kew.engine.node.hierarchyrouting.HierarchyProvider;
26  import org.kuali.rice.kew.engine.node.hierarchyrouting.HierarchyProvider.Stop;
27  import org.kuali.rice.kew.engine.node.hierarchyrouting.SimpleHierarchyProvider.SimpleStop;
28  import org.kuali.rice.kew.exception.WorkflowException;
29  import org.kuali.rice.kew.service.KEWServiceLocator;
30  import org.kuali.rice.kew.service.WorkflowDocument;
31  import org.kuali.rice.kew.test.KEWTestCase;
32  import org.kuali.rice.kew.test.TestUtilities;
33  import org.w3c.dom.Document;
34  import org.xml.sax.InputSource;
35  
36  
37  
38  /**
39   * Tests HeirarchyRoutingNode
40   * @author Kuali Rice Team (rice.collab@kuali.org)
41   *
42   */
43  public class HierarchyRoutingNodeTest extends KEWTestCase {
44  
45      private static final String HIERARCHY =
46      "<stop id=\"root\" type=\"user\" recipient=\"dewey\">" +
47        "<stop id=\"child1\" type=\"user\" recipient=\"user3\">" +
48          "<stop id=\"child1-1\" type=\"user\" recipient=\"user2\"/>" +
49          "<stop id=\"child1-2\" type=\"user\" recipient=\"user1\"/>" +
50        "</stop>" +
51        "<stop id=\"child2\" type=\"user\" recipient=\"quickstart\">" +
52          "<stop id=\"child2-1\" type=\"user\" recipient=\"temay\"/>" +
53          "<stop id=\"child2-2\" type=\"user\" recipient=\"jhopf\"/>" +
54        "</stop>" +
55      "</stop>";
56      private static final String HIERARCHY_UPDATED =
57      "<stop id=\"root\" type=\"user\" recipient=\"dewey\">" +
58        "<stop id=\"child1\" type=\"user\" recipient=\"user3\">" +
59          "<stop id=\"child1-1\" type=\"user\" recipient=\"user2\"/>" +
60          "<stop id=\"child1-2\" type=\"user\" recipient=\"user1\"/>" +
61          "<stop id=\"child1-3\" type=\"user\" recipient=\"delyea\"/>" +
62        "</stop>" +
63        "<stop id=\"child2\" type=\"user\" recipient=\"quickstart\">" +
64          "<stop id=\"child2-1\" type=\"user\" recipient=\"temay\"/>" +
65          "<stop id=\"child2-2\" type=\"user\" recipient=\"jhopf\"/>" +
66          "<stop id=\"child2-3\" type=\"user\" recipient=\"pzhang\"/>" +
67        "</stop>" +
68        "<stop id=\"child3\" type=\"user\" recipient=\"shenl\"/>" +
69      "</stop>";
70  
71      protected void assertStop(HierarchyProvider provider, String name, String parentName, String[] childNames) {
72          Stop stop = provider.getStopByIdentifier(name);
73          assertNotNull(stop);
74          if (parentName == null) {
75              assertNull(provider.getParent(stop));
76          } else {
77              Stop parent = provider.getStopByIdentifier(parentName);
78              assertNotNull(parent);
79              assertEquals(parent, ((SimpleStop) stop).parent);
80          }
81          assertEquals(childNames.length, ((SimpleStop) stop).children.size());
82          List<SimpleStop> children = ((SimpleStop) stop).children;
83          for (String childName: childNames) {
84              Stop child = provider.getStopByIdentifier(childName);
85              assertTrue(children.contains(child));
86          }
87      }
88  
89      @Test
90      public void testParseHierarchy() throws Exception {
91          Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(new StringReader(HIERARCHY)));
92          SimpleHierarchyProvider provider = new SimpleHierarchyProvider();
93          provider.init(doc.getDocumentElement());
94          
95          assertStop(provider, "root", null, new String[] { "child1", "child2" });
96          
97          assertStop(provider, "child1", "root", new String[] { "child1-1", "child1-2" });
98          assertStop(provider, "child1-1", "child1", new String[] { });
99          assertStop(provider, "child1-2", "child1", new String[] { });
100         
101         assertStop(provider, "child2", "root", new String[] { "child2-1", "child2-2" });
102         assertStop(provider, "child2-1", "child2", new String[] { });
103         assertStop(provider, "child2-2", "child2", new String[] { });
104         
105         List<Stop> leaves = provider.getLeafStops(null);
106         assertEquals(4, leaves.size());
107         assertTrue(leaves.contains(provider.getStopByIdentifier("child1-1")));
108         assertTrue(leaves.contains(provider.getStopByIdentifier("child1-2")));
109         assertTrue(leaves.contains(provider.getStopByIdentifier("child2-1")));
110         assertTrue(leaves.contains(provider.getStopByIdentifier("child2-2")));
111     }
112 
113     @Test
114     public void testHierarchyRoutingNode() throws WorkflowException {
115         loadXmlFile("HierarchyRoutingNodeConfig.xml");
116         
117         WorkflowDocument doc = new WorkflowDocument(new NetworkIdDTO("arh14"), "HierarchyDocType");
118         
119         
120         doc.getDocumentContent().setApplicationContent(HIERARCHY);
121         doc.routeDocument("initial route");
122         
123         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "user2", "user1", "temay", "jhopf" }, true);
124         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "user3", "quickstart", "dewey" }, false);
125         
126         doc = new WorkflowDocument(new NetworkIdDTO("user2"), doc.getRouteHeaderId());
127         doc.approve("approving as user2");
128         
129         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "user1", "temay", "jhopf" }, true);
130         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "user2", "user3", "quickstart", "dewey" }, false);
131         
132         doc = new WorkflowDocument(new NetworkIdDTO("jhopf"), doc.getRouteHeaderId());
133         doc.approve("approving as jhopf");
134         
135         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "user1", "temay" }, true);
136         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "jhopf", "user2", "user3", "quickstart", "dewey" }, false);
137         
138         doc = new WorkflowDocument(new NetworkIdDTO("user1"), doc.getRouteHeaderId());
139         doc.approve("approving as user1");
140         
141         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "user3", "temay" }, true);
142         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "user1", "jhopf", "user2", "quickstart", "dewey" }, false);
143         
144         doc = new WorkflowDocument(new NetworkIdDTO("temay"), doc.getRouteHeaderId());
145         doc.approve("approving as temay");
146         
147         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "user3", "quickstart" }, true);
148         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "temay", "user1", "jhopf", "user2", "dewey" }, false);
149         
150         doc = new WorkflowDocument(new NetworkIdDTO("user3"), doc.getRouteHeaderId());
151         doc.approve("approving as user3");
152         
153         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "quickstart" }, true);
154         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "user3", "temay", "user1", "jhopf", "user2", "dewey" }, false);
155         
156         doc = new WorkflowDocument(new NetworkIdDTO("quickstart"), doc.getRouteHeaderId());
157         doc.approve("approving as quickstart");
158         
159         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "dewey" }, true);
160         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "user3", "temay", "user1", "jhopf", "user2", "quickstart" }, false);
161         
162 
163         doc = new WorkflowDocument(new NetworkIdDTO("dewey"), doc.getRouteHeaderId());
164         doc.approve("approving as dewey");
165         
166         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "dewey", "user3", "temay", "user1", "jhopf", "user2", "quickstart" }, false);
167         
168         assertTrue(doc.stateIsFinal());
169     }
170     
171     @Test
172     public void testHierarchyRoutingNodeUnevenApproval() throws WorkflowException {
173         loadXmlFile("HierarchyRoutingNodeConfig.xml");
174         
175         WorkflowDocument doc = new WorkflowDocument(new NetworkIdDTO("arh14"), "HierarchyDocType");
176         
177         doc.getDocumentContent().setApplicationContent(HIERARCHY);
178         doc.routeDocument("initial route");
179         
180         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "user2", "user1", "temay", "jhopf" }, true);
181         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "user3", "quickstart", "dewey" }, false);
182         
183         doc = new WorkflowDocument(new NetworkIdDTO("user2"), doc.getRouteHeaderId());
184         doc.approve("approving as user2");
185         
186         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "user1", "temay", "jhopf" }, true);
187         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "user2", "user3", "quickstart", "dewey" }, false);
188         
189         doc = new WorkflowDocument(new NetworkIdDTO("jhopf"), doc.getRouteHeaderId());
190         doc.approve("approving as jhopf");
191         
192         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "user1", "temay" }, true);
193         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "jhopf", "user2", "user3", "quickstart", "dewey" }, false);
194         
195         doc = new WorkflowDocument(new NetworkIdDTO("user1"), doc.getRouteHeaderId());
196         doc.approve("approving as user1");
197         
198         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "user3", "temay" }, true);
199         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "user1", "jhopf", "user2", "quickstart", "dewey" }, false);
200         
201         doc = new WorkflowDocument(new NetworkIdDTO("user3"), doc.getRouteHeaderId());
202         doc.approve("approving as user3");
203         
204         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "temay" }, true);
205         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "user3", "user1", "jhopf", "user2", "dewey" }, false);
206         
207         doc = new WorkflowDocument(new NetworkIdDTO("temay"), doc.getRouteHeaderId());
208         doc.approve("approving as temay");
209         
210         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "quickstart" }, true);
211         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "user3", "temay", "user1", "jhopf", "user2", "dewey" }, false);
212         
213         doc = new WorkflowDocument(new NetworkIdDTO("quickstart"), doc.getRouteHeaderId());
214         doc.approve("approving as quickstart");
215         
216         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "dewey" }, true);
217         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "user3", "temay", "user1", "jhopf", "user2", "quickstart" }, false);
218 
219         doc = new WorkflowDocument(new NetworkIdDTO("dewey"), doc.getRouteHeaderId());
220         doc.approve("approving as dewey");
221         
222         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "dewey", "user3", "temay", "user1", "jhopf", "user2", "quickstart" }, false);
223         
224         assertTrue(doc.stateIsFinal());
225     }
226     
227     @Test
228     public void testHierarchyRoutingNodeUnevenApprovalExtraStops() throws WorkflowException {
229         loadXmlFile("HierarchyRoutingNodeConfig.xml");
230         
231         WorkflowDocument doc = new WorkflowDocument(new NetworkIdDTO("arh14"), "HierarchyDocType");
232         
233         doc.getDocumentContent().setApplicationContent(HIERARCHY);
234         doc.routeDocument("initial route");
235         
236         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "user2", "user1", "temay", "jhopf" }, true);
237         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "user3", "quickstart", "dewey" }, false);
238         
239         doc = new WorkflowDocument(new NetworkIdDTO("user2"), doc.getRouteHeaderId());
240         doc.approve("approving as user2");
241         
242         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "user1", "temay", "jhopf" }, true);
243         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "user2", "user3", "quickstart", "dewey" }, false);
244         
245         doc = new WorkflowDocument(new NetworkIdDTO("jhopf"), doc.getRouteHeaderId());
246         doc.approve("approving as jhopf");
247         
248         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "user1", "temay" }, true);
249         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "jhopf", "user2", "user3", "quickstart", "dewey" }, false);
250         
251         doc = new WorkflowDocument(new NetworkIdDTO("user1"), doc.getRouteHeaderId());
252         doc.setApplicationContent(HIERARCHY_UPDATED);
253         doc.approve("approving as user1");
254         
255         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "user3", "temay", "delyea", "pzhang", "shenl" }, true);
256         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "user1", "jhopf", "user2", "quickstart", "dewey" }, false);
257         
258         doc = new WorkflowDocument(new NetworkIdDTO("user3"), doc.getRouteHeaderId());
259         doc.approve("approving as user3");
260         
261         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "temay", "delyea", "pzhang", "shenl" }, true);
262         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "user3", "user1", "jhopf", "user2", "dewey" }, false);
263         
264         doc = new WorkflowDocument(new NetworkIdDTO("temay"), doc.getRouteHeaderId());
265         doc.approve("approving as temay");
266         
267         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "delyea", "pzhang", "shenl" }, true);
268         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "user3", "temay", "user1", "jhopf", "user2", "dewey", "quickstart" }, false);
269         
270         doc = new WorkflowDocument(new NetworkIdDTO("delyea"), doc.getRouteHeaderId());
271         doc.approve("approving as delyea");
272         
273         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "user3", "pzhang", "shenl" }, true);
274         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "delyea", "temay", "user1", "jhopf", "user2", "quickstart", "dewey" }, false);
275 
276         doc = new WorkflowDocument(new NetworkIdDTO("user3"), doc.getRouteHeaderId());
277         doc.approve("approving as user3");
278 
279         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "pzhang", "shenl" }, true);
280         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "delyea", "temay", "user1", "jhopf", "user2", "quickstart", "dewey" }, false);
281 
282         doc = new WorkflowDocument(new NetworkIdDTO("pzhang"), doc.getRouteHeaderId());
283         doc.approve("approving as pzhang");
284 
285         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "quickstart", "shenl" }, true);
286         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "pzhang", "delyea", "temay", "user1", "jhopf", "user2", "dewey" }, false);
287 
288         doc = new WorkflowDocument(new NetworkIdDTO("quickstart"), doc.getRouteHeaderId());
289         doc.approve("approving as quickstart");
290 
291         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "shenl" }, true);
292         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "pzhang", "delyea", "temay", "user1", "jhopf", "user2", "quickstart", "dewey" }, false);
293 
294         doc = new WorkflowDocument(new NetworkIdDTO("shenl"), doc.getRouteHeaderId());
295         doc.approve("approving as shenl");
296         
297         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "dewey" }, true);
298         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "pzhang", "delyea", "temay", "user1", "jhopf", "user2", "quickstart", "shenl" }, false);
299 
300         doc = new WorkflowDocument(new NetworkIdDTO("dewey"), doc.getRouteHeaderId());
301         doc.approve("approving as dewey");
302         
303         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "shenl", "dewey", "pzhang", "delyea", "user3", "temay", "user1", "jhopf", "user2", "quickstart" }, false);
304         
305         assertTrue(doc.stateIsFinal());
306     }
307 
308     @Test
309     public void testHierarchyRoutingNodeUnevenApprovalDisapprove() throws WorkflowException {
310         loadXmlFile("HierarchyRoutingNodeConfig.xml");
311         
312         WorkflowDocument doc = new WorkflowDocument(new NetworkIdDTO("arh14"), "HierarchyDocType");
313         
314         doc.getDocumentContent().setApplicationContent(HIERARCHY);
315         doc.routeDocument("initial route");
316         
317         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "user2", "user1", "temay", "jhopf" }, true);
318         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "user3", "quickstart", "dewey" }, false);
319         
320         doc = new WorkflowDocument(new NetworkIdDTO("user2"), doc.getRouteHeaderId());
321         doc.approve("approving as user2");
322         
323         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "user1", "temay", "jhopf" }, true);
324         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "user2", "user3", "quickstart", "dewey" }, false);
325         
326         doc = new WorkflowDocument(new NetworkIdDTO("jhopf"), doc.getRouteHeaderId());
327         doc.approve("approving as jhopf");
328         
329         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "user1", "temay" }, true);
330         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "jhopf", "user2", "user3", "quickstart", "dewey" }, false);
331         
332         doc = new WorkflowDocument(new NetworkIdDTO("user1"), doc.getRouteHeaderId());
333         doc.approve("approving as user1");
334         
335         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "user3", "temay" }, true);
336         TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "user1", "jhopf", "user2", "quickstart", "dewey" }, false);
337         
338         doc = new WorkflowDocument(new NetworkIdDTO("user3"), doc.getRouteHeaderId());
339         doc.disapprove("disapproving as user3");
340         
341         doc = new WorkflowDocument(new NetworkIdDTO("arh14"), doc.getRouteHeaderId());
342 
343         //TestUtilities.assertApprovals(doc.getRouteHeaderId(), new String[] { "user3", "temay", "user1", "jhopf", "user2", "quickstart", "dewey" }, false);
344 
345         assertTrue(doc.stateIsDisapproved());
346  
347         TestUtilities.logActionRequests(doc.getRouteHeaderId());
348 
349         // these are ok, these are the ACKs for the previous approvers
350         int numActionRequests = KEWServiceLocator.getActionRequestService().findPendingByDoc(doc.getRouteHeaderId()).size();
351         assertEquals("Incorrect number of action requests", 4, numActionRequests);
352         int numActionItems = KEWServiceLocator.getActionListService().findByRouteHeaderId(doc.getRouteHeaderId()).size();
353         assertEquals("Incorrect number of action items.", 4, numActionItems);
354         
355         doc = new WorkflowDocument(new NetworkIdDTO("user2"), doc.getRouteHeaderId());
356         doc.acknowledge("acknowledging disapproval as user2");
357         doc = new WorkflowDocument(new NetworkIdDTO("jhopf"), doc.getRouteHeaderId());
358         doc.acknowledge("acknowledging disapproval as jhopf");
359         doc = new WorkflowDocument(new NetworkIdDTO("user1"), doc.getRouteHeaderId());
360         doc.acknowledge("acknowledging disapproval as user1");
361         doc = new WorkflowDocument(new NetworkIdDTO("arh14"), doc.getRouteHeaderId());
362         doc.acknowledge("acknowledging disapproval as arh14");
363         
364         assertTrue(doc.stateIsDisapproved());
365 
366         numActionRequests = KEWServiceLocator.getActionRequestService().findPendingByDoc(doc.getRouteHeaderId()).size();
367         assertEquals("Incorrect number of action requests", 0, numActionRequests);
368         numActionItems = KEWServiceLocator.getActionListService().findByRouteHeaderId(doc.getRouteHeaderId()).size();
369         assertEquals("Incorrect number of action items.", 0, numActionItems);
370         
371     }
372 }