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