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 */ 016package org.kuali.rice.kew.actions; 017 018 019import static org.junit.Assert.assertEquals; 020import static org.junit.Assert.assertFalse; 021import static org.junit.Assert.assertNotNull; 022import static org.junit.Assert.assertTrue; 023import static org.junit.Assert.fail; 024 025import java.util.Collection; 026import java.util.Iterator; 027import java.util.List; 028 029import mocks.MockEmailNotificationService; 030 031import org.junit.Test; 032import org.kuali.rice.core.api.delegation.DelegationType; 033import org.kuali.rice.kew.actionrequest.ActionRequestValue; 034import org.kuali.rice.kew.actionrequest.service.ActionRequestService; 035import org.kuali.rice.kew.api.WorkflowDocument; 036import org.kuali.rice.kew.api.WorkflowDocumentFactory; 037import org.kuali.rice.kew.api.action.InvalidActionTakenException; 038import org.kuali.rice.kew.engine.node.RouteNodeInstance; 039import org.kuali.rice.kew.engine.node.service.RouteNodeService; 040import org.kuali.rice.kew.service.KEWServiceLocator; 041import org.kuali.rice.kew.test.KEWTestCase; 042import org.kuali.rice.kew.test.TestUtilities; 043import org.kuali.rice.kew.api.KewApiConstants; 044import org.kuali.rice.test.BaselineTestCase.BaselineMode; 045import org.kuali.rice.test.BaselineTestCase.Mode; 046 047@BaselineMode(Mode.CLEAR_DB) 048public 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}