1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kew.routeheader;
17
18 import org.joda.time.DateTime;
19 import org.junit.Test;
20 import org.kuali.rice.kew.api.KewApiConstants;
21 import org.kuali.rice.kew.api.KewApiServiceLocator;
22 import org.kuali.rice.kew.api.WorkflowDocument;
23 import org.kuali.rice.kew.api.WorkflowDocumentFactory;
24 import org.kuali.rice.kew.api.WorkflowRuntimeException;
25 import org.kuali.rice.kew.api.action.ActionRequest;
26 import org.kuali.rice.kew.api.action.ActionRequestType;
27 import org.kuali.rice.kew.api.action.AdHocToPrincipal;
28 import org.kuali.rice.kew.api.action.RequestedActions;
29 import org.kuali.rice.kew.api.document.Document;
30 import org.kuali.rice.kew.api.document.search.DocumentSearchCriteria;
31 import org.kuali.rice.kew.api.document.search.DocumentSearchResults;
32 import org.kuali.rice.kew.doctype.bo.DocumentType;
33 import org.kuali.rice.kew.impl.document.WorkflowDocumentImpl;
34 import org.kuali.rice.kew.impl.document.WorkflowDocumentPrototype;
35 import org.kuali.rice.kew.service.KEWServiceLocator;
36 import org.kuali.rice.kew.test.KEWTestCase;
37 import org.kuali.rice.kim.api.identity.Person;
38 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
39 import org.kuali.rice.krad.util.KRADUtils;
40
41 import java.util.List;
42 import java.util.Set;
43
44 import static org.junit.Assert.*;
45
46 public class AppDocStatusTest extends KEWTestCase {
47
48 protected void loadTestData() throws Exception {
49 super.loadTestData();
50 loadXmlFile("AppDocStatusTestConfig.xml");
51 }
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66 @Test public void testValidAppDocStatus() throws Exception {
67
68 WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), "TestAppDocStatusDoc2");
69 document.saveDocumentData();
70 assertNotNull(document.getDocumentId());
71 assertTrue("Document should be initiatied", document.isInitiated());
72 assertTrue("Invalid route level.", document.getNodeNames().contains("Initiated"));
73
74
75 document.route("Test Routing.");
76 String appDocStatus = document.getDocument().getApplicationDocumentStatus();
77 assertTrue("Application Document Status:" + appDocStatus +" is invalid", "Approval in Progress".equalsIgnoreCase(appDocStatus));
78
79
80 document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("bmcgough"), document.getDocumentId());
81 assertTrue("Document should be enroute", document.isEnroute());
82 Set<String> nodeNames = document.getNodeNames();
83 assertEquals("Wrong number of node names.", 1, nodeNames.size());
84 assertTrue("Wrong node name.", document.getNodeNames().contains("DestinationApproval"));
85
86
87 List<ActionRequest> requests = document.getRootActionRequests();
88 assertEquals(1, requests.size());
89 ActionRequest request = requests.get(0);
90 assertEquals(getPrincipalIdForName("bmcgough"), request.getPrincipalId());
91 assertEquals(ActionRequestType.APPROVE, request.getActionRequested());
92 assertEquals("DestinationApproval", request.getNodeName());
93 assertTrue(document.isApprovalRequested());
94
95
96 document.approve("Test approve by bmcgough");
97
98
99 document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("temay"), document.getDocumentId());
100 Document rh = document.getDocument();
101 appDocStatus = rh.getApplicationDocumentStatus();
102 assertTrue("Application Document Status:" + appDocStatus +" is invalid", "Submitted".equalsIgnoreCase(appDocStatus));
103
104
105 assertTrue("Document should be enroute", document.isEnroute());
106 nodeNames = document.getNodeNames();
107 assertEquals("Wrong number of node names.", 1, nodeNames.size());
108 assertTrue("Wrong node name.", nodeNames.contains("TravelerApproval"));
109 document.approve("Test approve by temay");
110
111
112 document.setApplicationDocumentStatus("Completed");
113 document.saveDocumentData();
114
115
116 document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("temay"), document.getDocumentId());
117
118 rh = document.getDocument();
119 appDocStatus = rh.getApplicationDocumentStatus();
120 assertTrue("Application Document Status:" + appDocStatus +" is invalid", "Completed".equalsIgnoreCase(appDocStatus));
121
122
123 List<org.kuali.rice.kew.api.document.DocumentStatusTransition> history = KewApiServiceLocator.getWorkflowDocumentService().getDocumentStatusTransitionHistory(
124 document.getDocumentId());
125
126 assertEquals(3, history.size());
127 assertTrue("First History record has incorrect status", "Approval In Progress".equalsIgnoreCase(history.get(0).getNewStatus()));
128 assertTrue("Second History record has incorrect old status", "Approval In Progress".equalsIgnoreCase(
129 history.get(1).getOldStatus()));
130 assertTrue("Second History record has incorrect new status", "Submitted".equalsIgnoreCase(history.get(1).getNewStatus()));
131 assertTrue("Third History record has incorrect old status", "Submitted".equalsIgnoreCase(history.get(2).getOldStatus()));
132 assertTrue("Third History record has incorrect new status", "Completed".equalsIgnoreCase(history.get(2).getNewStatus()));
133
134
135 document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("ewestfal"), document.getDocumentId());
136 assertTrue("Document should be final.", document.isFinal());
137 }
138
139
140
141
142
143
144
145
146 @Test public void testAppDocStatusValuesNotDefined() throws Exception {
147
148 WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), "TestAppDocStatusDoc1");
149 document.saveDocumentData();
150 assertNotNull(document.getDocumentId());
151 assertTrue("Document should be initiatied", document.isInitiated());
152 assertTrue("Invalid route level.", document.getNodeNames().contains("Initiated"));
153
154
155 document.route("Test Routing.");
156 Document rh = document.getDocument();
157 String appDocStatus = rh.getApplicationDocumentStatus();
158 assertTrue("Application Document Status:" + appDocStatus +" is invalid", "Approval in Progress".equalsIgnoreCase(appDocStatus));
159
160
161 document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("bmcgough"), document.getDocumentId());
162 assertTrue("Document should be enroute", document.isEnroute());
163 Set<String> nodeNames = document.getNodeNames();
164 assertEquals("Wrong number of node names.", 1, nodeNames.size());
165 assertTrue("Wrong node name.", nodeNames.contains("step1"));
166
167
168 List<ActionRequest> requests = document.getRootActionRequests();
169 assertEquals(1, requests.size());
170 ActionRequest request = requests.get(0);
171 assertEquals(getPrincipalIdForName("bmcgough"), request.getPrincipalId());
172 assertEquals(ActionRequestType.APPROVE, request.getActionRequested());
173 assertEquals("step1", request.getNodeName());
174 assertTrue(document.isApprovalRequested());
175
176
177 document.approve("Test approve by bmcgough");
178
179
180 document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("temay"), document.getDocumentId());
181 rh = document.getDocument();
182 appDocStatus = rh.getApplicationDocumentStatus();
183 assertTrue("Application Document Status:" + appDocStatus +" is invalid", "Submitted".equalsIgnoreCase(appDocStatus));
184
185
186 assertTrue("Document should be enroute", document.isEnroute());
187 nodeNames = document.getNodeNames();
188 assertEquals("Wrong number of node names.", 1, nodeNames.size());
189 assertTrue("Wrong node name.", nodeNames.contains("step2"));
190 document.approve("Test approve by temay");
191
192
193 document.setApplicationDocumentStatus("Some Random Value");
194 document.saveDocumentData();
195
196
197 document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("temay"), document.getDocumentId());
198
199 rh = document.getDocument();
200 appDocStatus = rh.getApplicationDocumentStatus();
201 assertTrue("Application Document Status:" + appDocStatus +" is invalid", "Some Random Value".equalsIgnoreCase(appDocStatus));
202
203
204 List<org.kuali.rice.kew.api.document.DocumentStatusTransition> history = KewApiServiceLocator.getWorkflowDocumentService().getDocumentStatusTransitionHistory(
205 document.getDocumentId());
206
207 assertEquals(3, history.size());
208 assertTrue("First History record has incorrect status", "Approval In Progress".equalsIgnoreCase(history.get(0)
209 .getNewStatus()));
210 assertTrue("Second History record has incorrect old status", "Approval In Progress".equalsIgnoreCase(
211 history.get(1).getOldStatus()));
212 assertTrue("Second History record has incorrect new status", "Submitted".equalsIgnoreCase(history.get(1)
213 .getNewStatus()));
214 assertTrue("Third History record has incorrect old status", "Submitted".equalsIgnoreCase(history.get(2).getOldStatus()));
215 assertTrue("Third History record has incorrect new status", "Some Random Value".equalsIgnoreCase(history.get(2)
216 .getNewStatus()));
217
218
219 document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("ewestfal"), document.getDocumentId());
220 assertTrue("Document should be final.", document.isFinal());
221 }
222
223
224
225
226
227
228
229
230
231 @Test public void testInvalidAppDocStatusValue() throws Exception {
232 WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), "TestAppDocStatusDoc2");
233 document.saveDocumentData();
234 assertNotNull(document.getDocumentId());
235 assertTrue("Document should be initiatied", document.isInitiated());
236 assertTrue("Invalid route level.", document.getNodeNames().contains("Initiated"));
237
238
239 boolean gotException = false;
240 try {
241 document.setApplicationDocumentStatus("BAD STATUS");
242 document.saveDocumentData();
243 } catch (Throwable t){
244 gotException = true;
245 WorkflowRuntimeException ex = new WorkflowRuntimeException();
246 assertEquals("WrongExceptionType", t.getClass(), ex.getClass());
247 } finally {
248 assertTrue("Expected WorkflowRuntimeException not thrown.", gotException);
249
250 }
251 }
252
253
254
255
256
257
258
259
260 @Test public void testValidInheritedAppDocStatus() throws Exception {
261
262 WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), "TestAppDocStatusDoc3");
263 document.saveDocumentData();
264 assertNotNull(document.getDocumentId());
265 assertTrue("Document should be initiatied", document.isInitiated());
266 assertTrue("Invalid route level.", document.getNodeNames().contains("Initiated"));
267 DocumentType documentType = KEWServiceLocator.getDocumentTypeService().findByName("TestAppDocStatusDoc3");
268 assertTrue(KRADUtils.isNotNull(documentType));
269 assertTrue(KRADUtils.isNotNull(documentType.getValidApplicationStatuses()));
270 assertEquals(6,documentType.getValidApplicationStatuses().size());
271 LOG.info("valid application status size: " + documentType.getValidApplicationStatuses().size());
272 assertTrue(KRADUtils.isNotNull(documentType.getApplicationStatusCategories()));
273 assertEquals(0,documentType.getApplicationStatusCategories().size());
274 }
275
276
277
278
279
280
281
282 @Test public void testValidInheritedAppDocStatusWithCategories() throws Exception {
283
284 WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), "TestAppDocStatusDoc5");
285 document.saveDocumentData();
286 assertNotNull(document.getDocumentId());
287 assertTrue("Document should be initiatied", document.isInitiated());
288 assertTrue("Invalid route level.", document.getNodeNames().contains("Initiated"));
289 DocumentType documentType = KEWServiceLocator.getDocumentTypeService().findByName("TestAppDocStatusDoc5");
290 assertTrue(KRADUtils.isNotNull(documentType));
291 assertTrue(KRADUtils.isNotNull(documentType.getValidApplicationStatuses()));
292 LOG.info("valid application status size: " + documentType.getValidApplicationStatuses().size());
293 assertEquals(6,documentType.getValidApplicationStatuses().size());
294 assertTrue(KRADUtils.isNotNull(documentType.getApplicationStatusCategories()));
295 assertEquals(2,documentType.getApplicationStatusCategories().size());
296 }
297
298
299
300
301
302
303
304 @Test public void testInheritedAppDocStatusWithKEWStatus() throws Exception {
305
306 WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), "TestAppDocStatusDoc6");
307 document.saveDocumentData();
308 assertNotNull(document.getDocumentId());
309 assertTrue("Document should be initiatied", document.isInitiated());
310 assertTrue("Invalid route level.", document.getNodeNames().contains("Initiated"));
311 DocumentType documentType = KEWServiceLocator.getDocumentTypeService().findByName("TestAppDocStatusDoc6");
312 assertTrue(KRADUtils.isNotNull(documentType));
313 assertTrue(KRADUtils.isNotNull(documentType.getValidApplicationStatuses()));
314 assertEquals(0,documentType.getValidApplicationStatuses().size());
315 LOG.info("valid application status size: " + documentType.getValidApplicationStatuses().size());
316 assertTrue(KRADUtils.isNotNull(documentType.getApplicationStatusCategories()));
317 assertEquals(0,documentType.getApplicationStatusCategories().size());
318 }
319
320 @Test public void testSearching() throws InterruptedException {
321 String documentTypeName = "TestAppDocStatusDoc1";
322
323 String initiatorNetworkId = "rkirkend";
324 Person initiator = KimApiServiceLocator.getPersonService().getPersonByPrincipalName(initiatorNetworkId);
325 String approverNetworkId = "bmcgough";
326 Person approver = KimApiServiceLocator.getPersonService().getPersonByPrincipalName(approverNetworkId);
327 String travelerNetworkId = "temay";
328 Person traveler = KimApiServiceLocator.getPersonService().getPersonByPrincipalName(travelerNetworkId);
329
330 WorkflowDocument workflowDocument = WorkflowDocumentFactory.createDocument(initiator.getPrincipalId(), documentTypeName);
331 workflowDocument.setTitle("Routing style");
332
333
334 assertAppDocStatuses(workflowDocument.getDocumentId(), new String [] { });
335 assertSearchStatus(documentTypeName, initiator, "Approval in Progress", 0, 0);
336 assertSearchStatus(documentTypeName, initiator, "Submitted", 0, 0);
337
338 workflowDocument.route("routing this document.");
339
340 DocumentRouteHeaderValue drhv = KEWServiceLocator.getRouteHeaderService().getRouteHeader(workflowDocument.getDocumentId());
341
342
343 assertAppDocStatuses(workflowDocument.getDocumentId(), new String [] { "Approval in Progress" });
344 assertSearchStatus(documentTypeName, initiator, "Approval in Progress", 1, 0);
345 assertSearchStatus(documentTypeName, initiator, "Approval in Progress", 1, drhv.getRouteStatusDate().getTime());
346 assertSearchStatus(documentTypeName, initiator, "Submitted", 0, 0);
347
348
349 workflowDocument = WorkflowDocumentFactory.loadDocument(approver.getPrincipalId(), workflowDocument.getDocumentId());
350 RequestedActions actions = workflowDocument.getRequestedActions();
351 assertTrue(actions.isApproveRequested());
352 workflowDocument.approve("destination approval");
353
354 assertAppDocStatuses(workflowDocument.getDocumentId(), new String [] { "Approval in Progress", "Submitted" });
355 assertSearchStatus(documentTypeName, approver, "Approval in Progress", 0, 0);
356 assertSearchStatus(documentTypeName, approver, "Approval in Progress", 1, drhv.getRouteStatusDate().getTime());
357 assertSearchStatus(documentTypeName, approver, "Submitted", 1, 0);
358 assertSearchStatus(documentTypeName, approver, "Submitted", 1, drhv.getDateLastModified().getMillis());
359
360
361 workflowDocument = WorkflowDocumentFactory.loadDocument(traveler.getPrincipalId(), workflowDocument.getDocumentId());
362 actions = workflowDocument.getRequestedActions();
363 assertTrue(actions.isApproveRequested());
364 workflowDocument.approve("travel approval");
365
366
367 assertAppDocStatuses(workflowDocument.getDocumentId(), new String [] { "Approval in Progress", "Submitted" });
368 assertSearchStatus(documentTypeName, traveler, "Approval in Progress", 0, 0);
369 assertSearchStatus(documentTypeName, traveler, "Approval in Progress", 1, drhv.getRouteStatusDate().getTime());
370 assertSearchStatus(documentTypeName, traveler, "Submitted", 1, 0);
371 assertSearchStatus(documentTypeName, traveler, "Submitted", 1, drhv.getDateLastModified().getMillis());
372 }
373
374 @Test public void testAppDocResetAfterAdHoc() throws Exception {
375 String documentTypeName = "TestAppDocStatusDoc1";
376
377 String initiatorNetworkId = "rkirkend";
378 String approverNetworkId = "bmcgough";
379 String travelerNetworkId = "temay";
380
381 Person initiator = KimApiServiceLocator.getPersonService().getPersonByPrincipalName(initiatorNetworkId);
382 Person approver = KimApiServiceLocator.getPersonService().getPersonByPrincipalName(approverNetworkId);
383 Person traveler = KimApiServiceLocator.getPersonService().getPersonByPrincipalName(travelerNetworkId);
384
385 WorkflowDocument workflowDocument = WorkflowDocumentFactory.createDocument(initiator.getPrincipalId(), documentTypeName);
386 workflowDocument.setTitle("Routing style");
387 workflowDocument.route("routing this document.");
388
389
390
391
392 assertAppDocStatuses(workflowDocument.getDocumentId(), new String [] { "Approval in Progress" });
393
394
395
396 workflowDocument = WorkflowDocumentFactory.loadDocument(approver.getPrincipalId(), workflowDocument.getDocumentId());
397 Document staleWorkflowDocument = KewApiServiceLocator.getWorkflowDocumentService().getDocument(workflowDocument.getDocumentId());
398
399 assertEquals( "app doc status incorrect before final approval: " + staleWorkflowDocument, "Approval in Progress", staleWorkflowDocument.getApplicationDocumentStatus() );
400
401 RequestedActions actions = workflowDocument.getRequestedActions();
402 assertTrue(actions.isApproveRequested());
403 workflowDocument.approve("destination approval");
404
405
406
407 workflowDocument = WorkflowDocumentFactory.loadDocument(traveler.getPrincipalId(), workflowDocument.getDocumentId());
408 assertEquals( "current app doc status incorrect after 1st approval", "Submitted", workflowDocument.getApplicationDocumentStatus() );
409
410 actions = workflowDocument.getRequestedActions();
411 assertTrue(actions.isApproveRequested());
412 workflowDocument.approve("travel approval");
413
414 workflowDocument = WorkflowDocumentFactory.loadDocument(traveler.getPrincipalId(), workflowDocument.getDocumentId());
415
416 assertEquals( "app doc status in 'stale' WorkflowDocument retrieved before approval should still have original status", "Approval in Progress", staleWorkflowDocument.getApplicationDocumentStatus() );
417
418 Document newWorkflowDocument = KewApiServiceLocator.getWorkflowDocumentService().getDocument(workflowDocument.getDocumentId());
419
420 assertEquals( "current API app doc status incorrect after 2nd approval", "Submitted", newWorkflowDocument.getApplicationDocumentStatus() );
421
422 WorkflowDocumentPrototype prototype = KEWServiceLocator.getWorkflowDocumentPrototype();
423 prototype.init(traveler.getPrincipalId(), staleWorkflowDocument);
424 prototype.setTitle(prototype.getTitle());
425 prototype.adHocToPrincipal(AdHocToPrincipal.Builder.create(ActionRequestType.FYI, null, initiator.getPrincipalId()).build(), "FYI to initiator");
426
427 workflowDocument = WorkflowDocumentFactory.loadDocument(traveler.getPrincipalId(), workflowDocument.getDocumentId());
428
429 assertEquals( "current app doc status incorrect after adhoc", "Submitted", workflowDocument.getApplicationDocumentStatus() );
430 }
431
432
433
434
435
436
437
438
439
440 protected void assertSearchStatus(String documentTypeName, Person user, String appDocStatus, int expected, long changed) {
441 DocumentSearchCriteria.Builder criteria = DocumentSearchCriteria.Builder.create();
442 criteria.setDocumentTypeName(documentTypeName);
443 criteria.setApplicationDocumentStatus(appDocStatus);
444 if (changed != 0) {
445 criteria.setDateApplicationDocumentStatusChangedFrom(new DateTime(changed - 200));
446 criteria.setDateApplicationDocumentStatusChangedTo(new DateTime(changed + 200));
447 }
448 DocumentSearchResults results = KEWServiceLocator.getDocumentSearchService().lookupDocuments(user.getPrincipalId(), criteria.build());
449 assertEquals("Search results should have " + expected + " documents.", expected, results.getSearchResults().size());
450 }
451
452
453
454
455
456
457 protected void assertAppDocStatuses(String documentId, String[] appDocStatuses) {
458 DocumentRouteHeaderValue drhv = KEWServiceLocator.getRouteHeaderService().getRouteHeader(documentId);
459
460 String curStatus = KewApiConstants.UNKNOWN_STATUS;
461 if (appDocStatuses.length > 0) {
462 curStatus = appDocStatuses[appDocStatuses.length - 1];
463 }
464 assertEquals(curStatus, drhv.getAppDocStatus());
465
466 List<DocumentStatusTransition> transitions = drhv.getAppDocStatusHistory();
467 assertEquals(appDocStatuses.length, transitions.size());
468 for (int i = 0; i < appDocStatuses.length; i++) {
469 DocumentStatusTransition trans = transitions.get(i);
470 assertEquals(appDocStatuses[i], trans.getNewAppDocStatus());
471 String prevStatus = null;
472 if (i > 0) {
473 prevStatus = appDocStatuses[i - 1];
474 }
475 assertEquals(prevStatus, trans.getOldAppDocStatus());
476 }
477 }
478 }