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