1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kew.actions;
17
18 import mocks.MockEmailNotificationService;
19 import org.apache.cxf.common.util.StringUtils;
20 import org.junit.Ignore;
21 import org.junit.Test;
22 import org.kuali.rice.core.api.delegation.DelegationType;
23 import org.kuali.rice.kew.actionrequest.ActionRequestValue;
24 import org.kuali.rice.kew.actionrequest.service.ActionRequestService;
25 import org.kuali.rice.kew.api.KewApiConstants;
26 import org.kuali.rice.kew.api.WorkflowDocument;
27 import org.kuali.rice.kew.api.WorkflowDocumentFactory;
28 import org.kuali.rice.kew.api.action.InvalidActionTakenException;
29 import org.kuali.rice.kew.api.document.DocumentContentUpdate;
30 import org.kuali.rice.kew.api.document.PropertyDefinition;
31 import org.kuali.rice.kew.api.document.attribute.WorkflowAttributeDefinition;
32 import org.kuali.rice.kew.engine.node.RouteNodeInstance;
33 import org.kuali.rice.kew.engine.node.service.RouteNodeService;
34 import org.kuali.rice.kew.framework.postprocessor.DocumentRouteStatusChange;
35 import org.kuali.rice.kew.framework.postprocessor.ProcessDocReport;
36 import org.kuali.rice.kew.postprocessor.DefaultPostProcessor;
37 import org.kuali.rice.kew.rule.GenericWorkflowAttribute;
38 import org.kuali.rice.kew.service.KEWServiceLocator;
39 import org.kuali.rice.kew.test.KEWTestCase;
40 import org.kuali.rice.kew.test.TestUtilities;
41 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
42 import org.kuali.rice.test.BaselineTestCase.BaselineMode;
43 import org.kuali.rice.test.BaselineTestCase.Mode;
44
45 import java.util.Collection;
46 import java.util.HashMap;
47 import java.util.Iterator;
48 import java.util.List;
49 import java.util.Map;
50
51 import static org.junit.Assert.*;
52
53 @BaselineMode(Mode.CLEAR_DB)
54 public class BlanketApproveTest extends KEWTestCase {
55
56 public static String TEST_USER_EWESTFAL = "ewestfal";
57 public static String TEST_USER_USER1 = "user1";
58 public static String TEST_USER_USER2 = "user2";
59 public static String TEST_USER_TEMAY = "temay";
60 public static String TEST_USER_JHOPF = "jhopf";
61 public static String TEST_USER_JITRUE = "jitrue";
62 public static String TEST_USER_JTHOMAS = "jthomas";
63 public static String TEST_USER_BMCGOUGH = "bmcgough";
64 public static String TEST_USER_RKIRKEND = "rkirkend";
65 public static String TEST_USER_PMCKOWN = "pmckown";
66 public static String TEST_USER_XQI = "xqi";
67
68 @Override
69 protected void loadTestData() throws Exception {
70 loadXmlFile("ActionsConfig.xml");
71 }
72
73
74
75
76
77
78
79 @Test public void testBlanketApproverNotInBlanketApproverWorkgroup() throws Exception {
80 WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName(TEST_USER_USER1), SequentialSetup.DOCUMENT_TYPE_NAME);
81 try {
82 document.blanketApprove("");
83 fail("InvalidActionTakenException should have been thrown");
84 } catch (InvalidActionTakenException iate) {
85 assertEquals("Exception on message is incorrent", "User is not authorized to BlanketApprove document", iate.getMessage());
86 }
87
88 }
89
90
91
92
93
94 @Test public void testBlanketApproverNotInitiator() throws Exception {
95 WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName(TEST_USER_USER1), SequentialSetup.DOCUMENT_TYPE_NAME);
96 WorkflowDocument newDocument = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName(TEST_USER_EWESTFAL), document.getDocumentId());
97 try {
98 newDocument.blanketApprove("");
99 fail("Exception should have been thrown when non-initiator user attempts blanket approve on default blanket approve policy document");
100 } catch (Exception e) {
101 e.printStackTrace();
102 }
103 }
104
105 @SuppressWarnings("deprecation")
106 @Test public void testBlanketApproveSequential() throws Exception {
107 WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName(TEST_USER_EWESTFAL), SequentialSetup.DOCUMENT_TYPE_NAME);
108 document.blanketApprove("");
109 document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName(TEST_USER_EWESTFAL), document.getDocumentId());
110 assertTrue("Document should be processed.", document.isProcessed());
111 Collection nodeInstances = getRouteNodeService().getActiveNodeInstances(document.getDocumentId());
112
113 assertEquals("Wrong number of active nodes.", 0, nodeInstances.size());
114 nodeInstances = getRouteNodeService().getTerminalNodeInstances(document.getDocumentId());
115 assertEquals("Wrong number of active nodes.", 1, nodeInstances.size());
116 RouteNodeInstance ackNodeInstance = (RouteNodeInstance)nodeInstances.iterator().next();
117 assertEquals("At wrong node.", SequentialSetup.ACKNOWLEDGE_2_NODE, ackNodeInstance.getRouteNode().getRouteNodeName());
118 assertTrue("Node should be complete.", ackNodeInstance.isComplete());
119 List actionRequests = KEWServiceLocator.getActionRequestService().findPendingByDoc(document.getDocumentId());
120 assertEquals("Wrong number of pending action requests.", 5, actionRequests.size());
121 boolean isNotification1 = false;
122 boolean isNotification2 = false;
123 boolean isNotification3 = false;
124 boolean isAck1 = false;
125 boolean isAck2 = false;
126 for (Iterator iterator = actionRequests.iterator(); iterator.hasNext();) {
127 ActionRequestValue actionRequest = (ActionRequestValue) iterator.next();
128 assertEquals("Should only be acknowledges.", KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ, actionRequest.getActionRequested());
129 RouteNodeInstance nodeInstance = actionRequest.getNodeInstance();
130 assertNotNull(nodeInstance);
131 String nodeName = nodeInstance.getRouteNode().getRouteNodeName();
132 if (actionRequest.getPrincipalId().equals(getPrincipalIdForName(TEST_USER_BMCGOUGH))) {
133 isNotification1 = true;
134 assertEquals(SequentialSetup.WORKFLOW_DOCUMENT_NODE, nodeName);
135 assertEquals(KewApiConstants.MACHINE_GENERATED_RESPONSIBILITY_ID, actionRequest.getResponsibilityId());
136 } else if (actionRequest.getPrincipalId().equals(getPrincipalIdForName(TEST_USER_RKIRKEND))) {
137 isNotification2 = true;
138 assertEquals(SequentialSetup.WORKFLOW_DOCUMENT_NODE, nodeName);
139 assertEquals(KewApiConstants.MACHINE_GENERATED_RESPONSIBILITY_ID, actionRequest.getResponsibilityId());
140 } else if (actionRequest.getPrincipalId().equals(getPrincipalIdForName(TEST_USER_PMCKOWN))) {
141 isNotification3 = true;
142 assertEquals(SequentialSetup.WORKFLOW_DOCUMENT_2_NODE, nodeName);
143 assertEquals(KewApiConstants.MACHINE_GENERATED_RESPONSIBILITY_ID, actionRequest.getResponsibilityId());
144 } else if (actionRequest.getPrincipalId().equals(getPrincipalIdForName(TEST_USER_TEMAY))) {
145 isAck1 = true;
146 assertEquals(SequentialSetup.ACKNOWLEDGE_1_NODE, nodeName);
147 assertFalse(KewApiConstants.MACHINE_GENERATED_RESPONSIBILITY_ID.equals(actionRequest.getResponsibilityId()));
148 } else if (actionRequest.getPrincipalId().equals(getPrincipalIdForName(TEST_USER_JHOPF))) {
149 isAck2 = true;
150 assertEquals(SequentialSetup.ACKNOWLEDGE_2_NODE, nodeName);
151 assertFalse(KewApiConstants.MACHINE_GENERATED_RESPONSIBILITY_ID.equals(actionRequest.getResponsibilityId()));
152 }
153 }
154 assertTrue(isNotification1);
155 assertTrue(isNotification2);
156 assertTrue(isNotification3);
157 assertTrue(isAck1);
158 assertTrue(isAck2);
159 document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName(TEST_USER_BMCGOUGH), document.getDocumentId());
160 assertTrue(document.isProcessed());
161 assertTrue(document.isAcknowledgeRequested());
162 assertEquals("bmcgough should not have been sent an approve email", 0, getMockEmailService().immediateReminderEmailsSent(TEST_USER_BMCGOUGH, document.getDocumentId(), KewApiConstants.ACTION_REQUEST_APPROVE_REQ));
163 assertEquals("bmcgough should not have been sent an ack email", 1, getMockEmailService().immediateReminderEmailsSent(TEST_USER_BMCGOUGH, document.getDocumentId(), KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ));
164 document.acknowledge("");
165
166 document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName(TEST_USER_RKIRKEND), document.getDocumentId());
167 assertTrue(document.isProcessed());
168 assertTrue(document.isAcknowledgeRequested());
169 assertEquals("rkirkend should not have been sent an approve email", 0, getMockEmailService().immediateReminderEmailsSent("rkirkend", document.getDocumentId(), KewApiConstants.ACTION_REQUEST_APPROVE_REQ));
170 assertEquals("rkirkend should not have been sent an ack email", 1, getMockEmailService().immediateReminderEmailsSent("rkirkend", document.getDocumentId(), KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ));
171 document.acknowledge("");
172
173 document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName(TEST_USER_PMCKOWN), document.getDocumentId());
174 assertTrue(document.isProcessed());
175 assertTrue(document.isAcknowledgeRequested());
176 assertEquals("pmckown should not have been sent an approve email", 0, getMockEmailService().immediateReminderEmailsSent("pmckown", document.getDocumentId(), KewApiConstants.ACTION_REQUEST_APPROVE_REQ));
177 assertEquals("pmckown should not have been sent an ack email", 1, getMockEmailService().immediateReminderEmailsSent("pmckown", document.getDocumentId(), KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ));
178 document.acknowledge("");
179
180 document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName(TEST_USER_TEMAY), document.getDocumentId());
181 assertTrue(document.isProcessed());
182 assertTrue(document.isAcknowledgeRequested());
183 assertEquals("rkirkend should have been sent an temay", 1, getMockEmailService().immediateReminderEmailsSent(TEST_USER_TEMAY, document.getDocumentId(), KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ));
184 document.acknowledge("");
185
186 document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName(TEST_USER_JHOPF), document.getDocumentId());
187 assertTrue(document.isProcessed());
188 assertTrue(document.isAcknowledgeRequested());
189 assertEquals("rkirkend should have been sent an jhopf", 1, getMockEmailService().immediateReminderEmailsSent(TEST_USER_JHOPF, document.getDocumentId(), KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ));
190 document.acknowledge("");
191
192 document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName(TEST_USER_EWESTFAL), document.getDocumentId());
193 assertTrue(document.isFinal());
194
195 document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName(TEST_USER_EWESTFAL), SequentialSetup.DOCUMENT_TYPE_NAME);
196 document.blanketApprove("", SequentialSetup.WORKFLOW_DOCUMENT_2_NODE);
197 assertTrue("Document should be enroute.", document.isEnroute());
198 nodeInstances = getRouteNodeService().getActiveNodeInstances(document.getDocumentId());
199 assertEquals("Should be one active node.", 1, nodeInstances.size());
200 RouteNodeInstance doc2Instance = (RouteNodeInstance)nodeInstances.iterator().next();
201 assertEquals("At wrong node.", SequentialSetup.WORKFLOW_DOCUMENT_2_NODE, doc2Instance.getRouteNode().getRouteNodeName());
202
203 }
204
205 @Test public void testBlanketApproveSequentialErrors() throws Exception {
206
207 WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName(TEST_USER_EWESTFAL), SequentialSetup.DOCUMENT_TYPE_NAME);
208 try {
209 document.blanketApprove("", "TotallyInvalidNode");
210 fail("Should have thrown exception");
211 } catch (Exception e) {}
212
213
214 document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName(TEST_USER_EWESTFAL), SequentialSetup.DOCUMENT_TYPE_NAME);
215 document.blanketApprove("", SequentialSetup.WORKFLOW_DOCUMENT_2_NODE);
216 try {
217 document.blanketApprove("", SequentialSetup.WORKFLOW_DOCUMENT_NODE);
218 fail("Should have thrown exception");
219 } catch (Exception e) {}
220
221
222 document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName(TEST_USER_EWESTFAL), SequentialSetup.DOCUMENT_TYPE_NAME);
223 document.route("");
224 try {
225 document.blanketApprove("", SequentialSetup.WORKFLOW_DOCUMENT_NODE);
226 fail("Should have thrown exception");
227 } catch (Exception e) {}
228
229
230 document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName(TEST_USER_USER1), SequentialSetup.DOCUMENT_TYPE_NAME);
231 try {
232 document.blanketApprove("");
233 fail("Shouldn't be able to blanket approve if not in blanket approve workgroup");
234 } catch (Exception e) {}
235 }
236
237 @Test public void testBlanketApproveParallel() throws Exception {
238 WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName(TEST_USER_EWESTFAL), ParallelSetup.DOCUMENT_TYPE_NAME);
239 document.blanketApprove("");
240 document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName(TEST_USER_EWESTFAL), document.getDocumentId());
241 assertTrue("Document should be processed.", document.isProcessed());
242 Collection nodeInstances = getRouteNodeService().getActiveNodeInstances(document.getDocumentId());
243
244 assertEquals("Wrong number of active nodes.", 0, nodeInstances.size());
245 nodeInstances = getRouteNodeService().getTerminalNodeInstances(document.getDocumentId());
246 assertEquals("Wrong number of terminal nodes.", 1, nodeInstances.size());
247 RouteNodeInstance ackNodeInstance = (RouteNodeInstance)nodeInstances.iterator().next();
248 assertEquals("At wrong node.", SequentialSetup.ACKNOWLEDGE_2_NODE, ackNodeInstance.getRouteNode().getRouteNodeName());
249 assertTrue("Node should be complete.", ackNodeInstance.isComplete());
250 List actionRequests = KEWServiceLocator.getActionRequestService().findPendingByDoc(document.getDocumentId());
251 assertEquals("Wrong number of pending action requests.", 10, actionRequests.size());
252
253 }
254
255
256
257
258
259
260 @Ignore
261 @Test
262 public void testChainedBlanketApproval() throws Exception {
263
264 WorkflowDocument childDocument = WorkflowDocumentFactory.createDocument(getPrincipalIdForName(TEST_USER_EWESTFAL), ChainedChildSetup.DOCUMENT_TYPE_NAME);
265 WorkflowAttributeDefinition.Builder childDocAttribute = WorkflowAttributeDefinition.Builder.create(ChainedParentSetup.CHILD_DOC_ATTRIBUTE);
266 PropertyDefinition docIdProperty = PropertyDefinition.create(
267 ChainedParentSetup.DOC_ID_PROPERTY, childDocument.getDocumentId());
268 childDocAttribute.addPropertyDefinition(docIdProperty);
269
270
271 WorkflowDocument parentDocument = WorkflowDocumentFactory.createDocument(getPrincipalIdForName(TEST_USER_EWESTFAL), ChainedParentSetup.DOCUMENT_TYPE_NAME);
272
273
274
275
276 String fullContent = parentDocument.getDocumentContent().getFullContent();
277 String newContent = "<documentContent><attributeContent><documentId>" + childDocument.getDocumentId() + "</documentId></attributeContent></documentContent>";
278 DocumentContentUpdate.Builder documentContentUpdateBuilder = DocumentContentUpdate.Builder.create();
279 documentContentUpdateBuilder.setAttributeContent(newContent);
280 parentDocument.updateDocumentContent(documentContentUpdateBuilder.build());
281 parentDocument.saveDocumentData();
282
283 parentDocument.blanketApprove("");
284 parentDocument = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName(TEST_USER_EWESTFAL), parentDocument.getDocumentId());
285 assertTrue("Parent Document should be processed.", parentDocument.isProcessed());
286
287 childDocument = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName(TEST_USER_EWESTFAL), childDocument.getDocumentId());
288 assertTrue("Child Document should be processed.", childDocument.isProcessed());
289
290 }
291
292 @Test public void testBlanketApproveIntoBranch() throws Exception {
293 WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName(TEST_USER_EWESTFAL), ParallelSetup.DOCUMENT_TYPE_NAME);
294 document.blanketApprove("", ParallelSetup.WORKFLOW_DOCUMENT_2_B1_NODE);
295 List actionRequests = KEWServiceLocator.getActionRequestService().findPendingByDoc(document.getDocumentId());
296 assertEquals("Wrong number of pending action requests.", 5, actionRequests.size());
297
298
299 Collection activeNodes = getRouteNodeService().getActiveNodeInstances(document.getDocumentId());
300 assertEquals("Wrong number of active nodes.", 3, activeNodes.size());
301 boolean isAtWD2B1 = false;
302 boolean isAtJoin = false;
303 boolean isAtWD3B2 = false;
304 boolean isAtWD4B3 = false;
305 for (Iterator iterator = activeNodes.iterator(); iterator.hasNext();) {
306 RouteNodeInstance nodeInstance = (RouteNodeInstance) iterator.next();
307 isAtWD2B1 = isAtWD2B1 || nodeInstance.getName().equals(ParallelSetup.WORKFLOW_DOCUMENT_2_B1_NODE);
308 isAtWD3B2 = isAtWD3B2 || nodeInstance.getName().equals(ParallelSetup.WORKFLOW_DOCUMENT_3_B2_NODE);
309 isAtWD4B3 = isAtWD4B3 || nodeInstance.getName().equals(ParallelSetup.WORKFLOW_DOCUMENT_4_B3_NODE);
310 isAtJoin = isAtJoin || nodeInstance.getName().equals(ParallelSetup.JOIN_NODE);
311 }
312 assertTrue("Should be at blanket approved node.", isAtWD2B1);
313 assertTrue("Should be at blanket approved node WD3B2.", isAtWD3B2);
314 assertTrue("Should be at blanket approved node WD4B3.", isAtWD4B3);
315 assertFalse("Should be at join node.", isAtJoin);
316
317 document.blanketApprove("");
318 document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName(TEST_USER_EWESTFAL), document.getDocumentId());
319 assertTrue("Document should be processed.", document.isProcessed());
320 actionRequests = KEWServiceLocator.getActionRequestService().findPendingByDoc(document.getDocumentId());
321
322 assertEquals("Wrong number of pending action requests.", 10, actionRequests.size());
323 }
324
325 @Test public void testBlanketApproveToMultipleNodes() throws Exception {
326
327 WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName(TEST_USER_EWESTFAL), ParallelSetup.DOCUMENT_TYPE_NAME);
328 document.blanketApprove("", new String[] { ParallelSetup.WORKFLOW_DOCUMENT_2_B1_NODE, ParallelSetup.WORKFLOW_DOCUMENT_3_B2_NODE });
329 List actionRequests = KEWServiceLocator.getActionRequestService().findPendingByDoc(document.getDocumentId());
330 assertEquals("Wrong number of pending action requests.", 5, actionRequests.size());
331
332
333 Collection activeNodes = getRouteNodeService().getActiveNodeInstances(document.getDocumentId());
334 assertEquals("Wrong number of active nodes.", 3, activeNodes.size());
335 boolean isAtWD2B1 = false;
336 boolean isAtWD3B2 = false;
337 boolean isAtJoin = false;
338 boolean isAtWD4B3 = false;
339 for (Iterator iterator = activeNodes.iterator(); iterator.hasNext();) {
340 RouteNodeInstance nodeInstance = (RouteNodeInstance) iterator.next();
341 isAtWD2B1 = isAtWD2B1 || nodeInstance.getName().equals(ParallelSetup.WORKFLOW_DOCUMENT_2_B1_NODE);
342 isAtWD3B2 = isAtWD3B2 || nodeInstance.getName().equals(ParallelSetup.WORKFLOW_DOCUMENT_3_B2_NODE);
343 isAtWD4B3 = isAtWD4B3 || nodeInstance.getName().equals(ParallelSetup.WORKFLOW_DOCUMENT_4_B3_NODE);
344 isAtJoin = isAtJoin || nodeInstance.getName().equals(ParallelSetup.JOIN_NODE);
345 }
346 assertTrue("Should be at blanket approved node WD2B1.", isAtWD2B1);
347 assertTrue("Should be at blanket approved node WD3B2.", isAtWD3B2);
348 assertTrue("Should be at blanket approved node WD4B3. https://jira.kuali.org/browse/KULRICE-8481 - "
349 + "BlanketApproveTest.testBlanketApproveToMultipleNodes fails in CI with Should be at blanket approved node WD4B3.", isAtWD4B3);
350 assertFalse("Should not be at join node.", isAtJoin);
351
352 document.blanketApprove("");
353 document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName(TEST_USER_EWESTFAL), document.getDocumentId());
354 assertTrue("Document should be processed.", document.isProcessed());
355 actionRequests = KEWServiceLocator.getActionRequestService().findPendingByDoc(document.getDocumentId());
356 assertEquals("Wrong number of pending action requests.", 10, actionRequests.size());
357 }
358
359 @Test public void testBlanketApproveToJoin() throws Exception {
360 WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName(TEST_USER_EWESTFAL), ParallelSetup.DOCUMENT_TYPE_NAME);
361 document.blanketApprove("", ParallelSetup.JOIN_NODE);
362 assertTrue("Document should still be enroute.", document.isEnroute());
363
364
365 Collection activeNodes = getRouteNodeService().getActiveNodeInstances(document.getDocumentId());
366 assertEquals("Wrong number of active nodes.", 1, activeNodes.size());
367 RouteNodeInstance nodeInstance = (RouteNodeInstance)activeNodes.iterator().next();
368 assertEquals("Document at wrong node.", ParallelSetup.WORKFLOW_DOCUMENT_FINAL_NODE, nodeInstance.getName());
369
370 document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName(TEST_USER_XQI), document.getDocumentId());
371 assertTrue("Should have approve request.", document.isApprovalRequested());
372 document.blanketApprove("", ParallelSetup.ACKNOWLEDGE_1_NODE);
373
374 activeNodes = getRouteNodeService().getActiveNodeInstances(document.getDocumentId());
375
376 assertEquals("Wrong number of active nodes.", 0, activeNodes.size());
377 Collection terminalNodes = getRouteNodeService().getTerminalNodeInstances(document.getDocumentId());
378 assertEquals("Wrong number of terminal nodes.", 1, terminalNodes.size());
379 nodeInstance = (RouteNodeInstance)terminalNodes.iterator().next();
380 assertEquals("Document at wrong node.", ParallelSetup.ACKNOWLEDGE_2_NODE, nodeInstance.getName());
381 assertTrue("Final node not complete.", nodeInstance.isComplete());
382 }
383
384 @Test public void testBlanketApproveToAcknowledge() throws Exception {
385
386 WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName(TEST_USER_EWESTFAL), ParallelSetup.DOCUMENT_TYPE_NAME);
387 document.blanketApprove("", ParallelSetup.ACKNOWLEDGE_1_NODE);
388 assertTrue("Document should be processed.", document.isProcessed());
389
390
391 Collection activeNodes = getRouteNodeService().getActiveNodeInstances(document.getDocumentId());
392 assertEquals("Wrong number of active nodes.", 0, activeNodes.size());
393 Collection terminalNodes = getRouteNodeService().getTerminalNodeInstances(document.getDocumentId());
394 assertEquals("Wrong number of terminal nodes.", 1, terminalNodes.size());
395 RouteNodeInstance nodeInstance = (RouteNodeInstance)terminalNodes.iterator().next();
396 assertEquals("Document at wrong node.", ParallelSetup.ACKNOWLEDGE_2_NODE, nodeInstance.getName());
397 assertTrue("Final node not complete.", nodeInstance.isComplete());
398 }
399
400 @Test public void testBlanketApproveToMultipleNodesErrors() throws Exception {
401
402 WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName(TEST_USER_EWESTFAL), ParallelSetup.DOCUMENT_TYPE_NAME);
403 try {
404 document.blanketApprove("", new String[] { ParallelSetup.WORKFLOW_DOCUMENT_2_B1_NODE, ParallelSetup.ACKNOWLEDGE_1_NODE });
405 fail("document should have thrown exception");
406 } catch (Exception e) {
407
408 TestUtilities.getExceptionThreader().join();
409 document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName(TEST_USER_EWESTFAL), document.getDocumentId());
410 assertTrue("Document should be in exception routing.", document.isException());
411 }
412 }
413
414
415
416
417 @Test public void testBlanketApproveNotification() throws Exception {
418 WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName(TEST_USER_EWESTFAL), NotifySetup.DOCUMENT_TYPE_NAME);
419 document.blanketApprove("");
420 ActionRequestService arService = KEWServiceLocator.getActionRequestService();
421 List actionRequests = arService.getRootRequests(arService.findPendingByDoc(document.getDocumentId()));
422 assertEquals("Should be 5 pending acknowledgements and 1 pending fyi", 6, actionRequests.size());
423 boolean foundJhopfNotification = false;
424 boolean foundRkirkendNotification = false;
425 boolean foundJitrueNotification = false;
426 boolean foundBmcgoughNotification = false;
427 boolean foundXqiAck = false;
428 boolean foundJthomasFYI = false;
429 for (Iterator iterator = actionRequests.iterator(); iterator.hasNext();) {
430 ActionRequestValue actionRequest = (ActionRequestValue) iterator.next();
431 RouteNodeInstance nodeInstance = actionRequest.getNodeInstance();
432 String netId = (actionRequest.getPrincipalId() == null ? null : getPrincipalNameForId(actionRequest.getPrincipalId()));
433 if (TEST_USER_JHOPF.equals(netId)) {
434 foundJhopfNotification = true;
435 assertTrue("Action request should be an acknowledge.", actionRequest.isAcknowledgeRequest());
436 assertEquals(NotifySetup.NOTIFY_FIRST_NODE, nodeInstance.getName());
437 } else if ("rkirkend".equals(netId)) {
438 foundRkirkendNotification = true;
439 assertTrue("Action request should be an acknowledge.", actionRequest.isAcknowledgeRequest());
440 assertEquals(NotifySetup.NOTIFY_LEFT_NODE, nodeInstance.getName());
441 assertEquals("Rkirkend should have three delegate acks.", 3, actionRequest.getChildrenRequests().size());
442 assertTrue("Should be primary delegation.", actionRequest.isPrimaryDelegator());
443 boolean foundTemayDelegate = false;
444 boolean foundNonSITWGDelegate = false;
445 boolean foundPmckownDelegate = false;
446 for (Iterator iterator2 = actionRequest.getChildrenRequests().iterator(); iterator2.hasNext();) {
447 ActionRequestValue childRequest = (ActionRequestValue) iterator2.next();
448 assertTrue("Child request should be an acknowledge.", actionRequest.isAcknowledgeRequest());
449 String childId = (childRequest.isGroupRequest() ? childRequest.getGroup().getName(): getPrincipalNameForId(childRequest.getPrincipalId()));
450 if (TEST_USER_TEMAY.equals(childId)) {
451 foundTemayDelegate = true;
452 assertEquals("Should be primary delegation.", DelegationType.PRIMARY, childRequest.getDelegationType());
453 } else if ("pmckown".equals(childId)) {
454 foundPmckownDelegate = true;
455 assertEquals("Should be secondary delegation.", DelegationType.SECONDARY, childRequest.getDelegationType());
456 } else if ("NonSIT".equals(childId)) {
457 foundNonSITWGDelegate = true;
458 assertEquals("Should be primary delegation.", DelegationType.PRIMARY, childRequest.getDelegationType());
459 }
460 }
461 assertTrue("Could not locate delegate request for temay.", foundTemayDelegate);
462 assertTrue("Could not locate delegate request for NonSIT Group.", foundNonSITWGDelegate);
463 assertTrue("Could not locate delegate request for pmckown.", foundPmckownDelegate);
464 } else if (TEST_USER_BMCGOUGH.equals(netId)) {
465 foundBmcgoughNotification = true;
466 assertTrue("Action request should be an acknowledge.", actionRequest.isAcknowledgeRequest());
467 assertEquals(NotifySetup.NOTIFY_FINAL_NODE, nodeInstance.getName());
468
469 } else if ("xqi".equals(netId)) {
470 foundXqiAck = true;
471 assertTrue("Action request should be an acknowledge.", actionRequest.isAcknowledgeRequest());
472 assertEquals(NotifySetup.NOTIFY_FINAL_NODE, nodeInstance.getName());
473
474 } else if (TEST_USER_JTHOMAS.equals(netId)) {
475 foundJthomasFYI = true;
476 assertTrue("Action request should be an FYI.", actionRequest.isFYIRequest());
477 assertEquals(NotifySetup.NOTIFY_FINAL_NODE, nodeInstance.getName());
478 } else if (actionRequest.isRoleRequest()) {
479 List topLevelRequests = arService.getTopLevelRequests(actionRequest);
480 assertEquals(1, topLevelRequests.size());
481 actionRequest = (ActionRequestValue)topLevelRequests.get(0);
482
483 assertEquals("Should be to jitrue.", TEST_USER_JITRUE, getPrincipalNameForId(actionRequest.getPrincipalId()));
484 foundJitrueNotification = true;
485 List delegateRoleRequests = arService.getDelegateRequests(actionRequest);
486 assertEquals("Should be 1 delegate role requests", 1, delegateRoleRequests.size());
487 ActionRequestValue delegateRoleRequest = (ActionRequestValue)delegateRoleRequests.get(0);
488 assertEquals("Should be NotifyDelegate role", "NotifyDelegate", delegateRoleRequest.getRoleName());
489 assertEquals("Should be secondary delegation", DelegationType.SECONDARY, delegateRoleRequest.getDelegationType());
490 List delegateRequests = arService.getTopLevelRequests(delegateRoleRequest);
491 assertEquals("Should be 2 delegate requests", 2, delegateRequests.size());
492 boolean foundNatjohnsDelegate = false;
493 boolean foundShenlDelegate = false;
494 for (Iterator iterator2 = delegateRequests.iterator(); iterator2.hasNext();) {
495 ActionRequestValue delegateRequest = (ActionRequestValue) iterator2.next();
496 String delNetId = getPrincipalNameForId(delegateRequest.getPrincipalId());
497 if ("natjohns".equals(delNetId)) {
498 foundNatjohnsDelegate = true;
499 } else if ("shenl".equals(delNetId)) {
500 foundShenlDelegate = true;
501 }
502 }
503 assertTrue("Could not locate natjohns role delegate request.", foundNatjohnsDelegate);
504 assertTrue("Could not locate shenl role delegate request.", foundShenlDelegate);
505 }
506 }
507 assertTrue("Could not locate notification for jhopf.", foundJhopfNotification);
508 assertTrue("Could not locate notification for rkirkend.", foundRkirkendNotification);
509 assertTrue("Could not locate notification for bmcgough.", foundBmcgoughNotification);
510 assertTrue("Could not locate acknowledgment for xqi.", foundXqiAck);
511 assertTrue("Could not locate FYI for jthomas.", foundJthomasFYI);
512 assertTrue("Could not locate notification for jitrue.", foundJitrueNotification);
513 }
514
515
516
517
518
519 @Test public void testBlanketApprovePastMandatoryNode() throws Exception {
520 WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName(TEST_USER_EWESTFAL), "BlanketApproveMandatoryNodeTest");
521 document.blanketApprove("");
522 assertTrue("Document should be processed.", document.isProcessed());
523 }
524
525
526
527
528
529 @Test public void testBlanketApproveThroughRoleAndWorkgroup() throws Exception {
530 String jitruePrincipalId = getPrincipalIdForName(TEST_USER_JITRUE);
531 WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName(TEST_USER_USER1), "BlanketApproveThroughRoleAndWorkgroupTest");
532 document.saveDocument("");
533 assertTrue(document.isSaved());
534 TestUtilities.assertNotInActionList(jitruePrincipalId, document.getDocumentId());
535
536 document.blanketApprove("");
537
538
539 document = WorkflowDocumentFactory.loadDocument(jitruePrincipalId, document.getDocumentId());
540 assertTrue(document.isProcessed());
541 assertTrue(document.isAcknowledgeRequested());
542
543
544 List actionRequests = KEWServiceLocator.getActionRequestService().findPendingRootRequestsByDocId(document.getDocumentId());
545 assertEquals("There should be 3 root requests.", 3, actionRequests.size());
546
547
548 TestUtilities.assertInActionList(jitruePrincipalId, document.getDocumentId());
549
550
551 document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName(TEST_USER_EWESTFAL), document.getDocumentId());
552 assertTrue(document.isAcknowledgeRequested());
553 document.acknowledge("");
554
555
556 document = WorkflowDocumentFactory.loadDocument(jitruePrincipalId, document.getDocumentId());
557 assertTrue(document.isProcessed());
558 assertTrue(document.isAcknowledgeRequested());
559
560
561 actionRequests = KEWServiceLocator.getActionRequestService().findPendingRootRequestsByDocId(document.getDocumentId());
562 assertEquals("There should be 2 root requests.", 2, actionRequests.size());
563
564
565 TestUtilities.assertInActionList(jitruePrincipalId, document.getDocumentId());
566 document.acknowledge("");
567
568
569 assertTrue(document.isFinal());
570 }
571
572 private RouteNodeService getRouteNodeService() {
573 return KEWServiceLocator.getRouteNodeService();
574 }
575
576 private class SequentialSetup {
577
578 public static final String DOCUMENT_TYPE_NAME = "BlanketApproveSequentialTest";
579 public static final String ADHOC_NODE = "AdHoc";
580 public static final String WORKFLOW_DOCUMENT_NODE = "WorkflowDocument";
581 public static final String WORKFLOW_DOCUMENT_2_NODE = "WorkflowDocument2";
582 public static final String ACKNOWLEDGE_1_NODE = "Acknowledge1";
583 public static final String ACKNOWLEDGE_2_NODE = "Acknowledge2";
584
585 }
586
587 private class ChainedParentSetup {
588 public static final String DOCUMENT_TYPE_NAME = "ChainedBlanketApproveTestParent";
589 public static final String CHILD_DOC_ATTRIBUTE = "ChildDocumentAttribute";
590 public static final String DOC_ID_PROPERTY = "documentId";
591 public static final String ADHOC_NODE = "AdHoc";
592 public static final String WORKFLOW_DOCUMENT_NODE = "WorkflowDocument";
593 public static final String WORKFLOW_DOCUMENT_2_NODE = "WorkflowDocument2";
594 public static final String ACKNOWLEDGE_1_NODE = "Acknowledge1";
595 public static final String ACKNOWLEDGE_2_NODE = "Acknowledge2";
596 }
597
598 private class ChainedChildSetup {
599 public static final String DOCUMENT_TYPE_NAME = "ChainedBlanketApproveTestChild";
600 public static final String ADHOC_NODE = "AdHoc";
601 public static final String WORKFLOW_DOCUMENT_NODE = "WorkflowDocument";
602 public static final String WORKFLOW_DOCUMENT_2_NODE = "WorkflowDocument2";
603 public static final String ACKNOWLEDGE_1_NODE = "Acknowledge1";
604 public static final String ACKNOWLEDGE_2_NODE = "Acknowledge2";
605 }
606
607 private class ParallelSetup {
608
609 public static final String DOCUMENT_TYPE_NAME = "BlanketApproveParallelTest";
610 public static final String ADHOC_NODE = "AdHoc";
611 public static final String WORKFLOW_DOCUMENT_NODE = "WorkflowDocument";
612 public static final String WORKFLOW_DOCUMENT_2_B1_NODE = "WorkflowDocument2-B1";
613 public static final String WORKFLOW_DOCUMENT_2_B2_NODE = "WorkflowDocument2-B2";
614 public static final String WORKFLOW_DOCUMENT_3_B1_NODE = "WorkflowDocument3-B1";
615 public static final String WORKFLOW_DOCUMENT_3_B2_NODE = "WorkflowDocument3-B2";
616 public static final String WORKFLOW_DOCUMENT_4_B3_NODE = "WorkflowDocument4-B3";
617 public static final String ACKNOWLEDGE_1_NODE = "Acknowledge1";
618 public static final String ACKNOWLEDGE_2_NODE = "Acknowledge2";
619 public static final String JOIN_NODE = "Join";
620 public static final String SPLIT_NODE = "Split";
621 public static final String WORKFLOW_DOCUMENT_FINAL_NODE = "WorkflowDocumentFinal";
622
623 }
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642 public static class ChainedApprovalPostProcessor extends DefaultPostProcessor {
643
644 public ProcessDocReport doRouteStatusChange(DocumentRouteStatusChange statusChangeEvent) throws Exception {
645
646 if (KewApiConstants.ROUTE_HEADER_PROCESSED_CD.equals(statusChangeEvent.getNewRouteStatus())) {
647
648 String principalId = KimApiServiceLocator
649 .getIdentityService().getPrincipalByPrincipalName(TEST_USER_EWESTFAL).getPrincipalId();
650 WorkflowDocument parentDocument = WorkflowDocumentFactory.loadDocument(principalId, statusChangeEvent.getDocumentId());
651 List<WorkflowAttributeDefinition> attributeDefinitions = parentDocument.getAttributeDefinitions();
652
653
654 String documentContent = parentDocument.getDocumentContent().getFullContent();
655 String documentId = StringUtils.split(documentContent, "\\<(\\/)?documentId\\>")[1];
656 WorkflowDocument childDocument = WorkflowDocumentFactory.loadDocument(principalId, documentId);
657 childDocument.blanketApprove("");
658
659
660 for(WorkflowAttributeDefinition attributeDefinition: parentDocument.getAttributeDefinitions()) {
661 if(ChainedParentSetup.CHILD_DOC_ATTRIBUTE.equals(attributeDefinition.getAttributeName())) {
662 String childDocumentId = attributeDefinition.getPropertyDefinitionsAsMap().get(ChainedParentSetup.DOC_ID_PROPERTY);
663 WorkflowDocument childDocumentItem = WorkflowDocumentFactory.loadDocument(principalId, childDocumentId);
664 childDocumentItem.blanketApprove("");
665 }
666 }
667 }
668
669 return new ProcessDocReport(true);
670 }
671
672 }
673
674 public class ChainedApprovalWorkflowAttribute extends GenericWorkflowAttribute {
675
676 public ChainedApprovalWorkflowAttribute() {
677
678 }
679
680 Map<String, String> propertiesMap = new HashMap<String, String>();
681
682 @Override
683 public Map<String, String> getProperties() {
684 return propertiesMap;
685 }
686 }
687
688
689 public static class NotifySetup {
690
691 public static final String DOCUMENT_TYPE_NAME = "NotificationTest";
692 public static final String ADHOC_NODE = "AdHoc";
693 public static final String NOTIFY_FIRST_NODE = "NotifyFirst";
694 public static final String NOTIFY_LEFT_NODE = "NotifyLeftBranch";
695 public static final String NOTIFY_RIGHT_NODE = "NotifyRightBranch";
696 public static final String NOTIFY_FINAL_NODE = "NotifyFinal";
697 public static final String SPLIT_NODE = "Split";
698 public static final String JOIN_NODE = "Join";
699
700 }
701
702 private MockEmailNotificationService getMockEmailService() {
703 return (MockEmailNotificationService)KEWServiceLocator.getActionListEmailService();
704 }
705
706 }