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