001 /**
002 * Copyright 2005-2011 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.kuali.rice.kew.actions;
017
018
019 import static org.junit.Assert.assertEquals;
020 import static org.junit.Assert.assertFalse;
021 import static org.junit.Assert.assertNotNull;
022 import static org.junit.Assert.assertTrue;
023 import static org.junit.Assert.fail;
024
025 import java.util.Collection;
026 import java.util.Iterator;
027 import java.util.List;
028
029 import mocks.MockEmailNotificationService;
030
031 import org.junit.Test;
032 import org.kuali.rice.core.api.delegation.DelegationType;
033 import org.kuali.rice.kew.actionrequest.ActionRequestValue;
034 import org.kuali.rice.kew.actionrequest.service.ActionRequestService;
035 import org.kuali.rice.kew.api.WorkflowDocument;
036 import org.kuali.rice.kew.api.WorkflowDocumentFactory;
037 import org.kuali.rice.kew.api.action.InvalidActionTakenException;
038 import org.kuali.rice.kew.engine.node.RouteNodeInstance;
039 import org.kuali.rice.kew.engine.node.service.RouteNodeService;
040 import org.kuali.rice.kew.service.KEWServiceLocator;
041 import org.kuali.rice.kew.test.KEWTestCase;
042 import org.kuali.rice.kew.test.TestUtilities;
043 import org.kuali.rice.kew.api.KewApiConstants;
044 import org.kuali.rice.test.BaselineTestCase.BaselineMode;
045 import org.kuali.rice.test.BaselineTestCase.Mode;
046
047 @BaselineMode(Mode.CLEAR_DB)
048 public class BlanketApproveTest extends KEWTestCase {
049
050 @Override
051 protected void loadTestData() throws Exception {
052 loadXmlFile("ActionsConfig.xml");
053 }
054
055 /**
056 * When a user is not in the blanket approver workgroup an exception should be thrown and
057 * it should have a good message.
058 *
059 * @throws Exception
060 */
061 @Test public void testBlanketApproverNotInBlanketApproverWorkgroup() throws Exception {
062 WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("user1"), SequentialSetup.DOCUMENT_TYPE_NAME);
063 try {
064 document.blanketApprove("");
065 fail("InvalidActionTakenException should have been thrown");
066 } catch (InvalidActionTakenException iate) {
067 assertEquals("Exception on message is incorrent", "User is not authorized to BlanketApprove document", iate.getMessage());
068 }
069
070 }
071
072 /**
073 * When a user is in the blanket approve workgroup but the user is not the initiator an exception
074 * should be thrown.
075 */
076 @Test public void testBlanketApproverNotInitiator() throws Exception {
077 WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("user1"), SequentialSetup.DOCUMENT_TYPE_NAME);
078 WorkflowDocument newDocument = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("ewestfal"), document.getDocumentId());
079 try {
080 newDocument.blanketApprove("");
081 fail("Exception should have been thrown when non-initiator user attempts blanket approve on default blanket approve policy document");
082 } catch (Exception e) {
083 e.printStackTrace();
084 }
085 }
086
087 @SuppressWarnings("deprecation")
088 @Test public void testBlanketApproveSequential() throws Exception {
089 WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), SequentialSetup.DOCUMENT_TYPE_NAME);
090 document.blanketApprove("");
091 document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("ewestfal"), document.getDocumentId());
092 assertTrue("Document should be processed.", document.isProcessed());
093 Collection nodeInstances = getRouteNodeService().getActiveNodeInstances(document.getDocumentId());
094 // once the document is processed there are no active nodes
095 assertEquals("Wrong number of active nodes.", 0, nodeInstances.size());
096 nodeInstances = getRouteNodeService().getTerminalNodeInstances(document.getDocumentId());
097 assertEquals("Wrong number of active nodes.", 1, nodeInstances.size());
098 RouteNodeInstance ackNodeInstance = (RouteNodeInstance)nodeInstances.iterator().next();
099 assertEquals("At wrong node.", SequentialSetup.ACKNOWLEDGE_2_NODE, ackNodeInstance.getRouteNode().getRouteNodeName());
100 assertTrue("Node should be complete.", ackNodeInstance.isComplete());
101 List actionRequests = KEWServiceLocator.getActionRequestService().findPendingByDoc(document.getDocumentId());
102 assertEquals("Wrong number of pending action requests.", 5, actionRequests.size());
103 boolean isNotification1 = false;
104 boolean isNotification2 = false;
105 boolean isNotification3 = false;
106 boolean isAck1 = false;
107 boolean isAck2 = false;
108 for (Iterator iterator = actionRequests.iterator(); iterator.hasNext();) {
109 ActionRequestValue actionRequest = (ActionRequestValue) iterator.next();
110 assertEquals("Should only be acknowledges.", KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ, actionRequest.getActionRequested());
111 RouteNodeInstance nodeInstance = actionRequest.getNodeInstance();
112 assertNotNull(nodeInstance);
113 String nodeName = nodeInstance.getRouteNode().getRouteNodeName();
114 if (actionRequest.getPrincipalId().equals(getPrincipalIdForName("bmcgough"))) {
115 isNotification1 = true;
116 assertEquals(SequentialSetup.WORKFLOW_DOCUMENT_NODE, nodeName);
117 assertEquals(KewApiConstants.MACHINE_GENERATED_RESPONSIBILITY_ID, actionRequest.getResponsibilityId());
118 } else if (actionRequest.getPrincipalId().equals(getPrincipalIdForName("rkirkend"))) {
119 isNotification2 = true;
120 assertEquals(SequentialSetup.WORKFLOW_DOCUMENT_NODE, nodeName);
121 assertEquals(KewApiConstants.MACHINE_GENERATED_RESPONSIBILITY_ID, actionRequest.getResponsibilityId());
122 } else if (actionRequest.getPrincipalId().equals(getPrincipalIdForName("pmckown"))) {
123 isNotification3 = true;
124 assertEquals(SequentialSetup.WORKFLOW_DOCUMENT_2_NODE, nodeName);
125 assertEquals(KewApiConstants.MACHINE_GENERATED_RESPONSIBILITY_ID, actionRequest.getResponsibilityId());
126 } else if (actionRequest.getPrincipalId().equals(getPrincipalIdForName("temay"))) {
127 isAck1 = true;
128 assertEquals(SequentialSetup.ACKNOWLEDGE_1_NODE, nodeName);
129 assertFalse(KewApiConstants.MACHINE_GENERATED_RESPONSIBILITY_ID.equals(actionRequest.getResponsibilityId()));
130 } else if (actionRequest.getPrincipalId().equals(getPrincipalIdForName("jhopf"))) {
131 isAck2 = true;
132 assertEquals(SequentialSetup.ACKNOWLEDGE_2_NODE, nodeName);
133 assertFalse(KewApiConstants.MACHINE_GENERATED_RESPONSIBILITY_ID.equals(actionRequest.getResponsibilityId()));
134 }
135 }
136 assertTrue(isNotification1);
137 assertTrue(isNotification2);
138 assertTrue(isNotification3);
139 assertTrue(isAck1);
140 assertTrue(isAck2);
141 document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("bmcgough"), document.getDocumentId());
142 assertTrue(document.isProcessed());
143 assertTrue(document.isAcknowledgeRequested());
144 assertEquals("bmcgough should not have been sent an approve email", 0, getMockEmailService().immediateReminderEmailsSent("bmcgough", document.getDocumentId(), KewApiConstants.ACTION_REQUEST_APPROVE_REQ));
145 assertEquals("bmcgough should not have been sent an ack email", 1, getMockEmailService().immediateReminderEmailsSent("bmcgough", document.getDocumentId(), KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ));
146 document.acknowledge("");
147
148 document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("rkirkend"), document.getDocumentId());
149 assertTrue(document.isProcessed());
150 assertTrue(document.isAcknowledgeRequested());
151 assertEquals("rkirkend should not have been sent an approve email", 0, getMockEmailService().immediateReminderEmailsSent("rkirkend", document.getDocumentId(), KewApiConstants.ACTION_REQUEST_APPROVE_REQ));
152 assertEquals("rkirkend should not have been sent an ack email", 1, getMockEmailService().immediateReminderEmailsSent("rkirkend", document.getDocumentId(), KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ));
153 document.acknowledge("");
154
155 document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("pmckown"), document.getDocumentId());
156 assertTrue(document.isProcessed());
157 assertTrue(document.isAcknowledgeRequested());
158 assertEquals("pmckown should not have been sent an approve email", 0, getMockEmailService().immediateReminderEmailsSent("pmckown", document.getDocumentId(), KewApiConstants.ACTION_REQUEST_APPROVE_REQ));
159 assertEquals("pmckown should not have been sent an ack email", 1, getMockEmailService().immediateReminderEmailsSent("pmckown", document.getDocumentId(), KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ));
160 document.acknowledge("");
161
162 document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("temay"), document.getDocumentId());
163 assertTrue(document.isProcessed());
164 assertTrue(document.isAcknowledgeRequested());
165 assertEquals("rkirkend should have been sent an temay", 1, getMockEmailService().immediateReminderEmailsSent("temay", document.getDocumentId(), KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ));
166 document.acknowledge("");
167
168 document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("jhopf"), document.getDocumentId());
169 assertTrue(document.isProcessed());
170 assertTrue(document.isAcknowledgeRequested());
171 assertEquals("rkirkend should have been sent an jhopf", 1, getMockEmailService().immediateReminderEmailsSent("jhopf", document.getDocumentId(), KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ));
172 document.acknowledge("");
173
174 document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("ewestfal"), document.getDocumentId());
175 assertTrue(document.isFinal());
176
177 document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), SequentialSetup.DOCUMENT_TYPE_NAME);
178 document.blanketApprove("", SequentialSetup.WORKFLOW_DOCUMENT_2_NODE);
179 assertTrue("Document should be enroute.", document.isEnroute());
180 nodeInstances = getRouteNodeService().getActiveNodeInstances(document.getDocumentId());
181 assertEquals("Should be one active node.", 1, nodeInstances.size());
182 RouteNodeInstance 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 = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("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 = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("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 = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), SequentialSetup.DOCUMENT_TYPE_NAME);
205 document.route("");
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 = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("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 = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), ParallelSetup.DOCUMENT_TYPE_NAME);
221 document.blanketApprove("");
222 document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("ewestfal"), document.getDocumentId());
223 assertTrue("Document should be processed.", document.isProcessed());
224 Collection nodeInstances = getRouteNodeService().getActiveNodeInstances(document.getDocumentId());
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.getDocumentId());
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.getDocumentId());
233 assertEquals("Wrong number of pending action requests.", 10, actionRequests.size());
234
235 }
236
237 @Test public void testBlanketApproveIntoBranch() throws Exception {
238 WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), ParallelSetup.DOCUMENT_TYPE_NAME);
239 document.blanketApprove("", ParallelSetup.WORKFLOW_DOCUMENT_2_B1_NODE);
240 List actionRequests = KEWServiceLocator.getActionRequestService().findPendingByDoc(document.getDocumentId());
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.getDocumentId());
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 = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("ewestfal"), document.getDocumentId());
264 assertTrue("Document should be processed.", document.isProcessed());
265 actionRequests = KEWServiceLocator.getActionRequestService().findPendingByDoc(document.getDocumentId());
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 = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("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.getDocumentId());
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.getDocumentId());
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 = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("ewestfal"), document.getDocumentId());
298 assertTrue("Document should be processed.", document.isProcessed());
299 actionRequests = KEWServiceLocator.getActionRequestService().findPendingByDoc(document.getDocumentId());
300 assertEquals("Wrong number of pending action requests.", 10, actionRequests.size());
301 }
302
303 @Test public void testBlanketApproveToJoin() throws Exception {
304
305 WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), ParallelSetup.DOCUMENT_TYPE_NAME);
306 document.blanketApprove("", ParallelSetup.JOIN_NODE);
307 assertTrue("Document should still be enroute.", document.isEnroute());
308
309 // document should now be at the workflow document final node
310 Collection activeNodes = getRouteNodeService().getActiveNodeInstances(document.getDocumentId());
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 = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("xqi"), document.getDocumentId());
316 assertTrue("Should have approve request.", document.isApprovalRequested());
317 document.blanketApprove("", ParallelSetup.ACKNOWLEDGE_1_NODE);
318
319 activeNodes = getRouteNodeService().getActiveNodeInstances(document.getDocumentId());
320 assertEquals("Wrong number of active nodes.", 0, activeNodes.size());
321 Collection terminalNodes = getRouteNodeService().getTerminalNodeInstances(document.getDocumentId());
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 = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), ParallelSetup.DOCUMENT_TYPE_NAME);
331 document.blanketApprove("", ParallelSetup.ACKNOWLEDGE_1_NODE);
332 assertTrue("Document should be processed.", document.isProcessed());
333
334 // document should now be terminal
335 Collection activeNodes = getRouteNodeService().getActiveNodeInstances(document.getDocumentId());
336 assertEquals("Wrong number of active nodes.", 0, activeNodes.size());
337 Collection terminalNodes = getRouteNodeService().getTerminalNodeInstances(document.getDocumentId());
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 = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("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 = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("ewestfal"), document.getDocumentId());
354 assertTrue("Document should be in exception routing.", document.isException());
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 = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), NotifySetup.DOCUMENT_TYPE_NAME);
363 document.blanketApprove("");
364 ActionRequestService arService = KEWServiceLocator.getActionRequestService();
365 List actionRequests = arService.getRootRequests(arService.findPendingByDoc(document.getDocumentId()));
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().getName(): getPrincipalNameForId(childRequest.getPrincipalId()));
394 if ("temay".equals(childId)) {
395 foundTemayDelegate = true;
396 assertEquals("Should be primary delegation.", DelegationType.PRIMARY, childRequest.getDelegationType());
397 } else if ("pmckown".equals(childId)) {
398 foundPmckownDelegate = true;
399 assertEquals("Should be secondary delegation.", DelegationType.SECONDARY, childRequest.getDelegationType());
400 } else if ("NonSIT".equals(childId)) {
401 foundNonSITWGDelegate = true;
402 assertEquals("Should be primary delegation.", DelegationType.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", DelegationType.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 = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), "BlanketApproveMandatoryNodeTest");
465 document.blanketApprove("");
466 assertTrue("Document should be processed.", document.isProcessed());
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 = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("user1"), "BlanketApproveThroughRoleAndWorkgroupTest");
476 document.saveDocument("");
477 assertTrue(document.isSaved());
478 TestUtilities.assertNotInActionList(jitruePrincipalId, document.getDocumentId());
479 document.blanketApprove("");
480
481 // document should now be processed
482 document = WorkflowDocumentFactory.loadDocument(jitruePrincipalId, document.getDocumentId());
483 assertTrue(document.isProcessed());
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.getDocumentId());
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.getDocumentId());
492
493 // acknowledge as a member of the workgroup who is not jitrue
494 document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("ewestfal"), document.getDocumentId());
495 assertTrue(document.isAcknowledgeRequested());
496 document.acknowledge("");
497
498 // document should still be processed
499 document = WorkflowDocumentFactory.loadDocument(jitruePrincipalId, document.getDocumentId());
500 assertTrue(document.isProcessed());
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.getDocumentId());
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.getDocumentId());
509 document.acknowledge("");
510
511 // document should now be final
512 assertTrue(document.isFinal());
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 }