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