View Javadoc

1   /*
2    * Copyright 2005-2007 The Kuali Foundation
3    * 
4    * 
5    * Licensed under the Educational Community License, Version 2.0 (the "License");
6    * you may not use this file except in compliance with the License.
7    * You may obtain a copy of the License at
8    * 
9    * http://www.opensource.org/licenses/ecl2.php
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.kuali.rice.kew.actions;
18  
19  
20  import java.util.Collection;
21  import java.util.Iterator;
22  import java.util.List;
23  
24  import mocks.MockEmailNotificationService;
25  
26  import org.junit.Test;
27  import org.kuali.rice.kew.actionrequest.ActionRequestValue;
28  import org.kuali.rice.kew.actionrequest.service.ActionRequestService;
29  import org.kuali.rice.kew.dto.NetworkIdDTO;
30  import org.kuali.rice.kew.engine.node.RouteNodeInstance;
31  import org.kuali.rice.kew.engine.node.service.RouteNodeService;
32  import org.kuali.rice.kew.exception.InvalidActionTakenException;
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  import org.kuali.rice.kew.test.TestUtilities;
37  import org.kuali.rice.kew.util.KEWConstants;
38  
39  
40  public class BlanketApproveTest extends KEWTestCase {
41  
42  	@Override
43      protected void loadTestData() throws Exception {
44          loadXmlFile("ActionsConfig.xml");
45      }
46      
47      /**
48       * When a user is not in the blanket approver workgroup an exception should be thrown and 
49       * it should have a good message.
50       * 
51       * @throws Exception
52       */
53      @Test public void testBlanketApproverNotInBlanketApproverWorkgroup() throws Exception  {
54      	WorkflowDocument document = new WorkflowDocument(new NetworkIdDTO("user1"), SequentialSetup.DOCUMENT_TYPE_NAME);
55      	try {
56      		document.blanketApprove("");
57      		fail("InvalidActionTakenException should have been thrown");
58      	} catch (InvalidActionTakenException iate) {
59      		assertEquals("Exception on message is incorrent", "User is not authorized to BlanketApprove document", iate.getMessage());
60      	}
61          
62      }
63      
64      /**
65       * When a user is in the blanket approve workgroup but the user is not the initiator an exception
66       * should be thrown.
67       */
68      @Test public void testBlanketApproverNotInitiator() throws Exception  {
69          WorkflowDocument document = new WorkflowDocument(new NetworkIdDTO("user1"), SequentialSetup.DOCUMENT_TYPE_NAME);
70          WorkflowDocument newDocument = new WorkflowDocument(new NetworkIdDTO("ewestfal"), document.getRouteHeaderId());
71          try {
72              newDocument.blanketApprove("");
73              fail("Exception should have been thrown when non-initiator user attempts blanket approve on default blanket approve policy document");
74          } catch (Exception e) {
75              e.printStackTrace();
76          }
77      }
78      
79      @SuppressWarnings("deprecation")
80  	@Test public void testBlanketApproveSequential() throws Exception {
81          WorkflowDocument document = new WorkflowDocument(new NetworkIdDTO("ewestfal"), SequentialSetup.DOCUMENT_TYPE_NAME);
82          document.blanketApprove("");
83          document = new WorkflowDocument(new NetworkIdDTO("ewestfal"), document.getRouteHeaderId());
84          assertTrue("Document should be processed.", document.stateIsProcessed());
85          Collection nodeInstances = getRouteNodeService().getActiveNodeInstances(document.getRouteHeaderId());
86          // once the document is processed there are no active nodes
87          assertEquals("Wrong number of active nodes.", 0, nodeInstances.size());
88          nodeInstances = getRouteNodeService().getTerminalNodeInstances(document.getRouteHeaderId());
89          assertEquals("Wrong number of active nodes.", 1, nodeInstances.size());
90          RouteNodeInstance ackNodeInstance = (RouteNodeInstance)nodeInstances.iterator().next();
91          assertEquals("At wrong node.", SequentialSetup.ACKNOWLEDGE_2_NODE, ackNodeInstance.getRouteNode().getRouteNodeName());
92          assertTrue("Node should be complete.", ackNodeInstance.isComplete());
93          List actionRequests = KEWServiceLocator.getActionRequestService().findPendingByDoc(document.getRouteHeaderId());
94          assertEquals("Wrong number of pending action requests.", 5, actionRequests.size());
95          boolean isNotification1 = false;
96          boolean isNotification2 = false;
97          boolean isNotification3 = false;
98          boolean isAck1 = false;
99          boolean isAck2 = false;
100         for (Iterator iterator = actionRequests.iterator(); iterator.hasNext();) {
101             ActionRequestValue actionRequest = (ActionRequestValue) iterator.next();
102             assertEquals("Should only be acknowledges.", KEWConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ, actionRequest.getActionRequested());
103             RouteNodeInstance nodeInstance = actionRequest.getNodeInstance();
104             assertNotNull(nodeInstance);
105             String nodeName = nodeInstance.getRouteNode().getRouteNodeName();
106             if (actionRequest.getPrincipalId().equals(getPrincipalIdForName("bmcgough"))) {
107                 isNotification1 = true;
108                 assertEquals(SequentialSetup.WORKFLOW_DOCUMENT_NODE, nodeName);
109                 assertEquals(KEWConstants.MACHINE_GENERATED_RESPONSIBILITY_ID, actionRequest.getResponsibilityId());
110             } else if (actionRequest.getPrincipalId().equals(getPrincipalIdForName("rkirkend"))) {
111                 isNotification2 = true;
112                 assertEquals(SequentialSetup.WORKFLOW_DOCUMENT_NODE, nodeName);
113                 assertEquals(KEWConstants.MACHINE_GENERATED_RESPONSIBILITY_ID, actionRequest.getResponsibilityId());
114             } else if (actionRequest.getPrincipalId().equals(getPrincipalIdForName("pmckown"))) {
115                 isNotification3 = true;
116                 assertEquals(SequentialSetup.WORKFLOW_DOCUMENT_2_NODE, nodeName);
117                 assertEquals(KEWConstants.MACHINE_GENERATED_RESPONSIBILITY_ID, actionRequest.getResponsibilityId());
118             } else if (actionRequest.getPrincipalId().equals(getPrincipalIdForName("temay"))) {
119                 isAck1 = true;
120                 assertEquals(SequentialSetup.ACKNOWLEDGE_1_NODE, nodeName);
121                 assertFalse(KEWConstants.MACHINE_GENERATED_RESPONSIBILITY_ID.equals(actionRequest.getResponsibilityId()));
122             } else if (actionRequest.getPrincipalId().equals(getPrincipalIdForName("jhopf"))) {
123                 isAck2 = true;
124                 assertEquals(SequentialSetup.ACKNOWLEDGE_2_NODE, nodeName);
125                 assertFalse(KEWConstants.MACHINE_GENERATED_RESPONSIBILITY_ID.equals(actionRequest.getResponsibilityId()));
126             }
127         }
128         assertTrue(isNotification1);
129         assertTrue(isNotification2);
130         assertTrue(isNotification3);
131         assertTrue(isAck1);
132         assertTrue(isAck2);
133         document = new WorkflowDocument(new NetworkIdDTO("bmcgough"), document.getRouteHeaderId());
134         assertTrue(document.stateIsProcessed());
135         assertTrue(document.isAcknowledgeRequested());
136         assertEquals("bmcgough should not have been sent an approve email", 0, getMockEmailService().immediateReminderEmailsSent("bmcgough", document.getRouteHeaderId(), KEWConstants.ACTION_REQUEST_APPROVE_REQ));
137         assertEquals("bmcgough should not have been sent an ack email", 1, getMockEmailService().immediateReminderEmailsSent("bmcgough", document.getRouteHeaderId(), KEWConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ));
138         document.acknowledge("");
139 
140         document = new WorkflowDocument(new NetworkIdDTO("rkirkend"), document.getRouteHeaderId());
141         assertTrue(document.stateIsProcessed());
142         assertTrue(document.isAcknowledgeRequested());
143         assertEquals("rkirkend should not have been sent an approve email", 0, getMockEmailService().immediateReminderEmailsSent("rkirkend", document.getRouteHeaderId(), KEWConstants.ACTION_REQUEST_APPROVE_REQ));        
144         assertEquals("rkirkend should not have been sent an ack email", 1, getMockEmailService().immediateReminderEmailsSent("rkirkend", document.getRouteHeaderId(), KEWConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ));
145         document.acknowledge("");
146         
147         document = new WorkflowDocument(new NetworkIdDTO("pmckown"), document.getRouteHeaderId());
148         assertTrue(document.stateIsProcessed());
149         assertTrue(document.isAcknowledgeRequested());
150         assertEquals("pmckown should not have been sent an approve email", 0, getMockEmailService().immediateReminderEmailsSent("pmckown", document.getRouteHeaderId(), KEWConstants.ACTION_REQUEST_APPROVE_REQ));
151         assertEquals("pmckown should not have been sent an ack email", 1, getMockEmailService().immediateReminderEmailsSent("pmckown", document.getRouteHeaderId(), KEWConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ));
152         document.acknowledge("");
153         
154         document = new WorkflowDocument(new NetworkIdDTO("temay"), document.getRouteHeaderId());
155         assertTrue(document.stateIsProcessed());
156         assertTrue(document.isAcknowledgeRequested());
157         assertEquals("rkirkend should have been sent an temay", 1, getMockEmailService().immediateReminderEmailsSent("temay", document.getRouteHeaderId(), KEWConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ));        
158         document.acknowledge("");
159         
160         document = new WorkflowDocument(new NetworkIdDTO("jhopf"), document.getRouteHeaderId());
161         assertTrue(document.stateIsProcessed());
162         assertTrue(document.isAcknowledgeRequested());
163         assertEquals("rkirkend should have been sent an jhopf", 1, getMockEmailService().immediateReminderEmailsSent("jhopf", document.getRouteHeaderId(), KEWConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ));
164         document.acknowledge("");
165         
166         document = new WorkflowDocument(new NetworkIdDTO("ewestfal"), document.getRouteHeaderId());
167         assertTrue(document.stateIsFinal());
168         
169         document = new WorkflowDocument(new NetworkIdDTO("ewestfal"), SequentialSetup.DOCUMENT_TYPE_NAME);
170         document.blanketApprove("", SequentialSetup.WORKFLOW_DOCUMENT_2_NODE);
171         assertTrue("Document should be enroute.", document.stateIsEnroute());
172         nodeInstances = getRouteNodeService().getActiveNodeInstances(document.getRouteHeaderId());
173         assertEquals("Should be one active node.", 1, nodeInstances.size());
174         RouteNodeInstance doc2Instance = (RouteNodeInstance)nodeInstances.iterator().next();
175         assertEquals("At wrong node.", SequentialSetup.WORKFLOW_DOCUMENT_2_NODE, doc2Instance.getRouteNode().getRouteNodeName());
176         
177         document = new WorkflowDocument(new NetworkIdDTO("ewestfal"), SequentialSetup.DOCUMENT_TYPE_NAME);
178         document.blanketApprove("", new Integer(2));
179         assertTrue("Document should be enroute.", document.stateIsEnroute());
180         nodeInstances = getRouteNodeService().getActiveNodeInstances(document.getRouteHeaderId());
181         assertEquals("Should be one active node.", 1, nodeInstances.size());
182         doc2Instance = (RouteNodeInstance)nodeInstances.iterator().next();
183         assertEquals("At wrong node.", SequentialSetup.WORKFLOW_DOCUMENT_2_NODE, doc2Instance.getRouteNode().getRouteNodeName());
184         
185     }
186     
187     @Test public void testBlanketApproveSequentialErrors() throws Exception {
188         // blanket approve to invalid node
189         WorkflowDocument document = new WorkflowDocument(new NetworkIdDTO("ewestfal"), SequentialSetup.DOCUMENT_TYPE_NAME);
190         try {
191             document.blanketApprove("", "TotallyInvalidNode");
192             fail("Should have thrown exception");
193         } catch (Exception e) {}
194         
195         // blanket approve backwards
196         document = new WorkflowDocument(new NetworkIdDTO("ewestfal"), SequentialSetup.DOCUMENT_TYPE_NAME);
197         document.blanketApprove("", SequentialSetup.WORKFLOW_DOCUMENT_2_NODE);
198         try {
199             document.blanketApprove("", SequentialSetup.WORKFLOW_DOCUMENT_NODE);
200             fail("Should have thrown exception");
201         } catch (Exception e) {}
202         
203         // blanket approve to current node
204         document = new WorkflowDocument(new NetworkIdDTO("ewestfal"), SequentialSetup.DOCUMENT_TYPE_NAME);
205         document.routeDocument("");
206         try {
207             document.blanketApprove("", SequentialSetup.WORKFLOW_DOCUMENT_NODE);
208             fail("Should have thrown exception");
209         } catch (Exception e) {}
210         
211         // blanket approve as user not in the blanket approve workgroup
212         document = new WorkflowDocument(new NetworkIdDTO("user1"), SequentialSetup.DOCUMENT_TYPE_NAME);
213         try {
214             document.blanketApprove("");
215             fail("Shouldn't be able to blanket approve if not in blanket approve workgroup");
216         } catch (Exception e) {}
217     }
218     
219     @Test public void testBlanketApproveParallel() throws Exception {
220         WorkflowDocument document = new WorkflowDocument(new NetworkIdDTO("ewestfal"), ParallelSetup.DOCUMENT_TYPE_NAME);
221         document.blanketApprove("");        
222         document = new WorkflowDocument(new NetworkIdDTO("ewestfal"), document.getRouteHeaderId());
223         assertTrue("Document should be processed.", document.stateIsProcessed());
224         Collection nodeInstances = getRouteNodeService().getActiveNodeInstances(document.getRouteHeaderId());
225         // once the document has gone processed there are no active nodes
226         assertEquals("Wrong number of active nodes.", 0, nodeInstances.size());
227         nodeInstances = getRouteNodeService().getTerminalNodeInstances(document.getRouteHeaderId());
228         assertEquals("Wrong number of terminal nodes.", 1, nodeInstances.size());
229         RouteNodeInstance ackNodeInstance = (RouteNodeInstance)nodeInstances.iterator().next();
230         assertEquals("At wrong node.", SequentialSetup.ACKNOWLEDGE_2_NODE, ackNodeInstance.getRouteNode().getRouteNodeName());
231         assertTrue("Node should be complete.", ackNodeInstance.isComplete());
232         List actionRequests = KEWServiceLocator.getActionRequestService().findPendingByDoc(document.getRouteHeaderId());
233         assertEquals("Wrong number of pending action requests.", 10, actionRequests.size());
234 
235     }
236     
237     @Test public void testBlanketApproveIntoBranch() throws Exception {
238         WorkflowDocument document = new WorkflowDocument(new NetworkIdDTO("ewestfal"), ParallelSetup.DOCUMENT_TYPE_NAME);
239         document.blanketApprove("", ParallelSetup.WORKFLOW_DOCUMENT_2_B1_NODE);
240         List actionRequests = KEWServiceLocator.getActionRequestService().findPendingByDoc(document.getRouteHeaderId());
241         assertEquals("Wrong number of pending action requests.", 5, actionRequests.size());
242         
243         // document should now be at the node we blanket approved to and the join node
244         Collection activeNodes = getRouteNodeService().getActiveNodeInstances(document.getRouteHeaderId());
245         assertEquals("Wrong number of active nodes.", 3, activeNodes.size());
246         boolean isAtWD2B1 = false;
247         boolean isAtJoin = false;
248         boolean isAtWD3B2 = false;
249         boolean isAtWD4B3 = false;
250         for (Iterator iterator = activeNodes.iterator(); iterator.hasNext();) {
251             RouteNodeInstance nodeInstance = (RouteNodeInstance) iterator.next();
252             isAtWD2B1 = isAtWD2B1 || nodeInstance.getName().equals(ParallelSetup.WORKFLOW_DOCUMENT_2_B1_NODE);
253             isAtWD3B2 = isAtWD3B2 || nodeInstance.getName().equals(ParallelSetup.WORKFLOW_DOCUMENT_3_B2_NODE);
254             isAtWD4B3 = isAtWD4B3 || nodeInstance.getName().equals(ParallelSetup.WORKFLOW_DOCUMENT_4_B3_NODE);
255             isAtJoin = isAtJoin || nodeInstance.getName().equals(ParallelSetup.JOIN_NODE);
256         }
257         assertTrue("Should be at blanket approved node.", isAtWD2B1);
258         assertTrue("Should be at blanket approved node WD3B2.", isAtWD3B2);
259         assertTrue("Should be at blanket approved node WD4B3.", isAtWD4B3);        
260         assertFalse("Should be at join node.", isAtJoin);
261         
262         document.blanketApprove("");
263         document = new WorkflowDocument(new NetworkIdDTO("ewestfal"), document.getRouteHeaderId());
264         assertTrue("Document should be processed.", document.stateIsProcessed());
265         actionRequests = KEWServiceLocator.getActionRequestService().findPendingByDoc(document.getRouteHeaderId());
266         
267         assertEquals("Wrong number of pending action requests.", 10, actionRequests.size());
268     }
269     
270     @Test public void testBlanketApproveToMultipleNodes() throws Exception {
271         
272         WorkflowDocument document = new WorkflowDocument(new NetworkIdDTO("ewestfal"), ParallelSetup.DOCUMENT_TYPE_NAME);
273         document.blanketApprove("", new String[] { ParallelSetup.WORKFLOW_DOCUMENT_2_B1_NODE, ParallelSetup.WORKFLOW_DOCUMENT_3_B2_NODE });
274         List actionRequests = KEWServiceLocator.getActionRequestService().findPendingByDoc(document.getRouteHeaderId());
275         assertEquals("Wrong number of pending action requests.", 5, actionRequests.size());
276         
277         // document should now be at both nodes we blanket approved to and the join node
278         Collection activeNodes = getRouteNodeService().getActiveNodeInstances(document.getRouteHeaderId());
279         assertEquals("Wrong number of active nodes.", 3, activeNodes.size());
280         boolean isAtWD2B1 = false;
281         boolean isAtWD3B2 = false;
282         boolean isAtJoin = false;
283         boolean isAtWD4B3 = false;
284         for (Iterator iterator = activeNodes.iterator(); iterator.hasNext();) {
285             RouteNodeInstance nodeInstance = (RouteNodeInstance) iterator.next();
286             isAtWD2B1 = isAtWD2B1 || nodeInstance.getName().equals(ParallelSetup.WORKFLOW_DOCUMENT_2_B1_NODE);
287             isAtWD3B2 = isAtWD3B2 || nodeInstance.getName().equals(ParallelSetup.WORKFLOW_DOCUMENT_3_B2_NODE);
288             isAtWD4B3 = isAtWD4B3 || nodeInstance.getName().equals(ParallelSetup.WORKFLOW_DOCUMENT_4_B3_NODE);
289             isAtJoin = isAtJoin || nodeInstance.getName().equals(ParallelSetup.JOIN_NODE);
290         }
291         assertTrue("Should be at blanket approved node WD2B1.", isAtWD2B1);
292         assertTrue("Should be at blanket approved node WD3B2.", isAtWD3B2);
293         assertTrue("Should be at blanket approved node WD4B3.", isAtWD4B3);
294         assertFalse("Should not be at join node.", isAtJoin);
295         
296         document.blanketApprove("");
297         document = new WorkflowDocument(new NetworkIdDTO("ewestfal"), document.getRouteHeaderId());
298         assertTrue("Document should be processed.", document.stateIsProcessed());
299         actionRequests = KEWServiceLocator.getActionRequestService().findPendingByDoc(document.getRouteHeaderId());
300         assertEquals("Wrong number of pending action requests.", 10, actionRequests.size());
301     }
302     
303     @Test public void testBlanketApproveToJoin() throws Exception {
304         
305         WorkflowDocument document = new WorkflowDocument(new NetworkIdDTO("ewestfal"), ParallelSetup.DOCUMENT_TYPE_NAME);
306         document.blanketApprove("", ParallelSetup.JOIN_NODE);
307         assertTrue("Document should still be enroute.", document.stateIsEnroute());
308 
309         // document should now be at the workflow document final node
310         Collection activeNodes = getRouteNodeService().getActiveNodeInstances(document.getRouteHeaderId());
311         assertEquals("Wrong number of active nodes.", 1, activeNodes.size());
312         RouteNodeInstance nodeInstance = (RouteNodeInstance)activeNodes.iterator().next();
313         assertEquals("Document at wrong node.", ParallelSetup.WORKFLOW_DOCUMENT_FINAL_NODE, nodeInstance.getName());
314         
315         document = new WorkflowDocument(new NetworkIdDTO("xqi"), document.getRouteHeaderId());
316         assertTrue("Should have approve request.", document.isApprovalRequested());
317         document.blanketApprove("", ParallelSetup.ACKNOWLEDGE_1_NODE);
318         
319         activeNodes = getRouteNodeService().getActiveNodeInstances(document.getRouteHeaderId());
320         assertEquals("Wrong number of active nodes.", 0, activeNodes.size());
321         Collection terminalNodes = getRouteNodeService().getTerminalNodeInstances(document.getRouteHeaderId());
322         assertEquals("Wrong number of terminal nodes.", 1, terminalNodes.size());
323         nodeInstance = (RouteNodeInstance)terminalNodes.iterator().next();
324         assertEquals("Document at wrong node.", ParallelSetup.ACKNOWLEDGE_2_NODE, nodeInstance.getName());
325         assertTrue("Final node not complete.", nodeInstance.isComplete());
326     }
327     
328     @Test public void testBlanketApproveToAcknowledge() throws Exception {
329         
330         WorkflowDocument document = new WorkflowDocument(new NetworkIdDTO("ewestfal"), ParallelSetup.DOCUMENT_TYPE_NAME);
331         document.blanketApprove("", ParallelSetup.ACKNOWLEDGE_1_NODE);
332         assertTrue("Document should be processed.", document.stateIsProcessed());
333 
334         // document should now be terminal
335         Collection activeNodes = getRouteNodeService().getActiveNodeInstances(document.getRouteHeaderId());
336         assertEquals("Wrong number of active nodes.", 0, activeNodes.size());
337         Collection terminalNodes = getRouteNodeService().getTerminalNodeInstances(document.getRouteHeaderId());
338         assertEquals("Wrong number of terminal nodes.", 1, terminalNodes.size());
339         RouteNodeInstance nodeInstance = (RouteNodeInstance)terminalNodes.iterator().next();
340         assertEquals("Document at wrong node.", ParallelSetup.ACKNOWLEDGE_2_NODE, nodeInstance.getName());
341         assertTrue("Final node not complete.", nodeInstance.isComplete());
342     }
343     
344     @Test public void testBlanketApproveToMultipleNodesErrors() throws Exception {
345         
346         WorkflowDocument document = new WorkflowDocument(new NetworkIdDTO("ewestfal"), ParallelSetup.DOCUMENT_TYPE_NAME);
347         try {
348             document.blanketApprove("", new String[] { ParallelSetup.WORKFLOW_DOCUMENT_2_B1_NODE, ParallelSetup.ACKNOWLEDGE_1_NODE });    
349             fail("document should have thrown exception");
350         } catch (Exception e) {
351             // Shouldn't be able to blanket approve past the join in conjunction with blanket approve within a branch
352         	TestUtilities.getExceptionThreader().join();
353         	document = new WorkflowDocument(new NetworkIdDTO("ewestfal"), document.getRouteHeaderId());
354             assertTrue("Document should be in exception routing.", document.stateIsException());            
355         }
356     }
357     
358     /**
359      * Tests that the notifications are generated properly on a blanket approve.  Works against the "NotificationTest" document type.
360      */
361     @Test public void testBlanketApproveNotification() throws Exception {
362         WorkflowDocument document = new WorkflowDocument(new NetworkIdDTO("ewestfal"), NotifySetup.DOCUMENT_TYPE_NAME);
363         document.blanketApprove("");
364         ActionRequestService arService = KEWServiceLocator.getActionRequestService(); 
365         List actionRequests = arService.getRootRequests(arService.findPendingByDoc(document.getRouteHeaderId()));
366         assertEquals("Should be 5 pending acknowledgements and 1 pending fyi", 6, actionRequests.size());
367         boolean foundJhopfNotification = false;
368         boolean foundRkirkendNotification = false;
369         boolean foundJitrueNotification = false;
370         boolean foundBmcgoughNotification = false;
371         boolean foundXqiAck = false;
372         boolean foundJthomasFYI = false;
373         for (Iterator iterator = actionRequests.iterator(); iterator.hasNext();) {
374             ActionRequestValue actionRequest = (ActionRequestValue) iterator.next();
375             RouteNodeInstance nodeInstance = actionRequest.getNodeInstance();
376             String netId = (actionRequest.getPrincipalId() == null ? null : getPrincipalNameForId(actionRequest.getPrincipalId()));
377             if ("jhopf".equals(netId)) {
378                 foundJhopfNotification = true;
379                 assertTrue("Action request should be an acknowledge.", actionRequest.isAcknowledgeRequest());
380                 assertEquals(NotifySetup.NOTIFY_FIRST_NODE, nodeInstance.getName());
381             } else if ("rkirkend".equals(netId)) {
382                 foundRkirkendNotification = true;
383                 assertTrue("Action request should be an acknowledge.", actionRequest.isAcknowledgeRequest());
384                 assertEquals(NotifySetup.NOTIFY_LEFT_NODE, nodeInstance.getName());
385                 assertEquals("Rkirkend should have three delegate acks.", 3, actionRequest.getChildrenRequests().size());
386                 assertTrue("Should be primary delegation.", actionRequest.isPrimaryDelegator());
387                 boolean foundTemayDelegate = false;
388                 boolean foundNonSITWGDelegate = false;
389                 boolean foundPmckownDelegate = false;
390                 for (Iterator iterator2 = actionRequest.getChildrenRequests().iterator(); iterator2.hasNext();) {
391                     ActionRequestValue childRequest = (ActionRequestValue) iterator2.next();
392                     assertTrue("Child request should be an acknowledge.", actionRequest.isAcknowledgeRequest());
393                     String childId = (childRequest.isGroupRequest() ? childRequest.getGroup().getGroupName(): getPrincipalNameForId(childRequest.getPrincipalId()));
394                     if ("temay".equals(childId)) {
395                         foundTemayDelegate = true;
396                         assertEquals("Should be primary delegation.", KEWConstants.DELEGATION_PRIMARY, childRequest.getDelegationType());
397                     } else if ("pmckown".equals(childId)) {
398                         foundPmckownDelegate = true;
399                         assertEquals("Should be secondary delegation.", KEWConstants.DELEGATION_SECONDARY, childRequest.getDelegationType());
400                     } else if ("NonSIT".equals(childId)) {
401                         foundNonSITWGDelegate = true;
402                         assertEquals("Should be primary delegation.", KEWConstants.DELEGATION_PRIMARY, childRequest.getDelegationType());
403                     }
404                 }
405                 assertTrue("Could not locate delegate request for temay.", foundTemayDelegate);
406                 assertTrue("Could not locate delegate request for NonSIT Group.", foundNonSITWGDelegate);
407                 assertTrue("Could not locate delegate request for pmckown.", foundPmckownDelegate);
408             } else if ("bmcgough".equals(netId)) {
409                 foundBmcgoughNotification = true;
410                 assertTrue("Action request should be an acknowledge.", actionRequest.isAcknowledgeRequest());
411                 assertEquals(NotifySetup.NOTIFY_FINAL_NODE, nodeInstance.getName());
412                 
413             } else if ("xqi".equals(netId)) {
414                 foundXqiAck = true;
415                 assertTrue("Action request should be an acknowledge.", actionRequest.isAcknowledgeRequest());
416                 assertEquals(NotifySetup.NOTIFY_FINAL_NODE, nodeInstance.getName());
417                 
418             } else if ("jthomas".equals(netId)) {
419                 foundJthomasFYI = true;
420                 assertTrue("Action request should be an FYI.", actionRequest.isFYIRequest());
421                 assertEquals(NotifySetup.NOTIFY_FINAL_NODE, nodeInstance.getName());
422             } else if (actionRequest.isRoleRequest()) {
423                List topLevelRequests = arService.getTopLevelRequests(actionRequest);
424                assertEquals(1, topLevelRequests.size());
425                actionRequest = (ActionRequestValue)topLevelRequests.get(0);
426                // this tests the notofication of the role to jitrue with delegates
427                assertEquals("Should be to jitrue.", "jitrue", getPrincipalNameForId(actionRequest.getPrincipalId()));
428                foundJitrueNotification = true;
429                List delegateRoleRequests = arService.getDelegateRequests(actionRequest);
430                assertEquals("Should be 1 delegate role requests", 1, delegateRoleRequests.size());
431                ActionRequestValue delegateRoleRequest = (ActionRequestValue)delegateRoleRequests.get(0);
432                assertEquals("Should be NotifyDelegate role", "NotifyDelegate", delegateRoleRequest.getRoleName());
433                assertEquals("Should be secondary delegation", KEWConstants.DELEGATION_SECONDARY, delegateRoleRequest.getDelegationType());
434                List delegateRequests = arService.getTopLevelRequests(delegateRoleRequest);
435                assertEquals("Should be 2 delegate requests", 2, delegateRequests.size());
436                boolean foundNatjohnsDelegate = false;
437                boolean foundShenlDelegate = false;
438                for (Iterator iterator2 = delegateRequests.iterator(); iterator2.hasNext();) {
439                    ActionRequestValue delegateRequest = (ActionRequestValue) iterator2.next();
440                    String delNetId = getPrincipalNameForId(delegateRequest.getPrincipalId());
441                    if ("natjohns".equals(delNetId)) {
442                        foundNatjohnsDelegate = true;
443                    } else if ("shenl".equals(delNetId)) {
444                        foundShenlDelegate = true;
445                    }
446                }
447                assertTrue("Could not locate natjohns role delegate request.", foundNatjohnsDelegate);
448                assertTrue("Could not locate shenl role delegate request.", foundShenlDelegate);
449             }
450         }
451         assertTrue("Could not locate notification for jhopf.", foundJhopfNotification);
452         assertTrue("Could not locate notification for rkirkend.", foundRkirkendNotification);
453         assertTrue("Could not locate notification for bmcgough.", foundBmcgoughNotification);
454         assertTrue("Could not locate acknowledgment for xqi.", foundXqiAck);
455         assertTrue("Could not locate FYI for jthomas.", foundJthomasFYI);
456         assertTrue("Could not locate notification for jitrue.", foundJitrueNotification);
457     }
458     
459     /**
460      * Tests that we can blanket approve past mandatory route nodes.
461      * Addresses issue http://fms.dfa.cornell.edu:8080/browse/KULWF-461
462      */
463     @Test public void testBlanketApprovePastMandatoryNode() throws Exception {
464         WorkflowDocument document = new WorkflowDocument(new NetworkIdDTO("ewestfal"), "BlanketApproveMandatoryNodeTest");
465         document.blanketApprove("");
466         assertTrue("Document should be processed.", document.stateIsProcessed());
467     }
468     
469     /**
470      * Tests the behavior of blanket approve through a role node and then through a node with a Workgroup including
471      * the individual(s) in the role.  Verifies that the Action List contains the proper entries in this case.
472      */
473     @Test public void testBlanketApproveThroughRoleAndWorkgroup() throws Exception {
474     	String jitruePrincipalId = getPrincipalIdForName("jitrue");
475     	WorkflowDocument document = new WorkflowDocument(new NetworkIdDTO("user1"), "BlanketApproveThroughRoleAndWorkgroupTest");
476     	document.saveDocument("");
477     	assertTrue(document.stateIsSaved());
478     	TestUtilities.assertNotInActionList(jitruePrincipalId, document.getRouteHeaderId());
479     	document.blanketApprove("");
480     	
481     	// document should now be processed
482     	document = new WorkflowDocument(jitruePrincipalId, document.getRouteHeaderId());
483     	assertTrue(document.stateIsProcessed());
484     	assertTrue(document.isAcknowledgeRequested());
485     	
486     	// there should be 3 root acknowledge requests, one to the WorkflowAdmin workgroup, one to jitrue in the Notify role and one to jitrue in the Notify2 role
487     	List actionRequests = KEWServiceLocator.getActionRequestService().findPendingRootRequestsByDocId(document.getRouteHeaderId());
488     	assertEquals("There should be 3 root requests.", 3, actionRequests.size());
489     	
490     	// now check that the document is in jitrue's action list
491     	TestUtilities.assertInActionList(jitruePrincipalId, document.getRouteHeaderId());
492     	
493     	// acknowledge as a member of the workgroup who is not jitrue
494     	document = new WorkflowDocument(new NetworkIdDTO("ewestfal"), document.getRouteHeaderId());
495     	assertTrue(document.isAcknowledgeRequested());
496     	document.acknowledge("");
497     	
498     	// document should still be processed
499     	document = new WorkflowDocument(jitruePrincipalId, document.getRouteHeaderId());
500     	assertTrue(document.stateIsProcessed());
501     	assertTrue(document.isAcknowledgeRequested());
502     	
503     	// there should now be 2 root acknowledge requests, one to jitrue in the Notify role and one to jitrue in the Notify2 role
504     	actionRequests = KEWServiceLocator.getActionRequestService().findPendingRootRequestsByDocId(document.getRouteHeaderId());
505     	assertEquals("There should be 2 root requests.", 2, actionRequests.size());
506     	
507     	// jitrue should still have this in his action list
508     	TestUtilities.assertInActionList(jitruePrincipalId, document.getRouteHeaderId());
509     	document.acknowledge("");
510     	
511     	// document should now be final
512     	assertTrue(document.stateIsFinal());
513     }
514     
515     private RouteNodeService getRouteNodeService() {
516         return KEWServiceLocator.getRouteNodeService();
517     }
518     
519     private class SequentialSetup {
520 
521         public static final String DOCUMENT_TYPE_NAME = "BlanketApproveSequentialTest";
522         public static final String ADHOC_NODE = "AdHoc";
523         public static final String WORKFLOW_DOCUMENT_NODE = "WorkflowDocument";
524         public static final String WORKFLOW_DOCUMENT_2_NODE = "WorkflowDocument2";
525         public static final String ACKNOWLEDGE_1_NODE = "Acknowledge1";
526         public static final String ACKNOWLEDGE_2_NODE = "Acknowledge2";
527         
528     }
529     
530     private class ParallelSetup {
531 
532         public static final String DOCUMENT_TYPE_NAME = "BlanketApproveParallelTest";
533         public static final String ADHOC_NODE = "AdHoc";
534         public static final String WORKFLOW_DOCUMENT_NODE = "WorkflowDocument";
535         public static final String WORKFLOW_DOCUMENT_2_B1_NODE = "WorkflowDocument2-B1";
536         public static final String WORKFLOW_DOCUMENT_2_B2_NODE = "WorkflowDocument2-B2";
537         public static final String WORKFLOW_DOCUMENT_3_B1_NODE = "WorkflowDocument3-B1";
538         public static final String WORKFLOW_DOCUMENT_3_B2_NODE = "WorkflowDocument3-B2";
539         public static final String WORKFLOW_DOCUMENT_4_B3_NODE = "WorkflowDocument4-B3";
540         public static final String ACKNOWLEDGE_1_NODE = "Acknowledge1";
541         public static final String ACKNOWLEDGE_2_NODE = "Acknowledge2";
542         public static final String JOIN_NODE = "Join";
543         public static final String SPLIT_NODE = "Split";
544         public static final String WORKFLOW_DOCUMENT_FINAL_NODE = "WorkflowDocumentFinal";
545         
546     }
547     
548     /*private class CycleSetup {
549 
550         public static final String DOCUMENT_TYPE_NAME = "BlanketApproveCycleTest";
551         public static final String ADHOC_NODE = "AdHoc";
552         public static final String WORKFLOW_DOCUMENT_NODE = "WorkflowDocument";
553         public static final String WORKFLOW_DOCUMENT_2_NODE = "WorkflowDocument2";
554         public static final String WORKFLOW_DOCUMENT_FINAL_NODE = "WorkflowDocumentFinal";
555         public static final String JOIN_NODE = "Join";
556         public static final String CUSTOM_CYCLE_SPLIT_NODE = "CustomCycleSplit";
557         
558     }*/
559     
560     public static class NotifySetup {
561 
562         public static final String DOCUMENT_TYPE_NAME = "NotificationTest";
563         public static final String ADHOC_NODE = "AdHoc";
564         public static final String NOTIFY_FIRST_NODE = "NotifyFirst";
565         public static final String NOTIFY_LEFT_NODE = "NotifyLeftBranch";
566         public static final String NOTIFY_RIGHT_NODE = "NotifyRightBranch";
567         public static final String NOTIFY_FINAL_NODE = "NotifyFinal";
568         public static final String SPLIT_NODE = "Split";
569         public static final String JOIN_NODE = "Join";
570         
571     }
572 
573     private MockEmailNotificationService getMockEmailService() {
574         return (MockEmailNotificationService)KEWServiceLocator.getActionListEmailService();
575     }
576     
577 }