1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kew.docsearch;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.joda.time.DateTime;
20 import org.joda.time.Days;
21 import org.joda.time.Years;
22 import org.junit.Test;
23 import org.kuali.rice.kew.api.KewApiConstants;
24 import org.kuali.rice.kew.api.WorkflowDocument;
25 import org.kuali.rice.kew.api.WorkflowDocumentFactory;
26 import org.kuali.rice.kew.api.action.RequestedActions;
27 import org.kuali.rice.kew.api.document.Document;
28 import org.kuali.rice.kew.api.document.DocumentStatus;
29 import org.kuali.rice.kew.api.document.DocumentStatusCategory;
30 import org.kuali.rice.kew.api.document.search.DocumentSearchCriteria;
31 import org.kuali.rice.kew.api.document.search.DocumentSearchResult;
32 import org.kuali.rice.kew.api.document.search.DocumentSearchResults;
33 import org.kuali.rice.kew.api.document.search.RouteNodeLookupLogic;
34 import org.kuali.rice.kew.docsearch.service.DocumentSearchService;
35 import org.kuali.rice.kew.doctype.bo.DocumentType;
36 import org.kuali.rice.kew.doctype.service.DocumentTypeService;
37 import org.kuali.rice.kew.engine.node.RouteNode;
38 import org.kuali.rice.kew.service.KEWServiceLocator;
39 import org.kuali.rice.kew.test.KEWTestCase;
40 import org.kuali.rice.kew.useroptions.UserOptions;
41 import org.kuali.rice.kew.useroptions.UserOptionsService;
42 import org.kuali.rice.kim.api.identity.Person;
43 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
44 import org.kuali.rice.test.BaselineTestCase;
45 import org.kuali.rice.test.TestHarnessServiceLocator;
46 import org.springframework.jdbc.core.JdbcTemplate;
47
48 import java.util.Arrays;
49 import java.util.Collection;
50 import java.util.HashMap;
51 import java.util.Iterator;
52 import java.util.List;
53 import java.util.Map;
54 import java.util.Set;
55
56 import static org.junit.Assert.*;
57
58 @BaselineTestCase.BaselineMode(BaselineTestCase.Mode.CLEAR_DB)
59 public class DocumentSearchTest extends KEWTestCase {
60 private static final String KREW_DOC_HDR_T = "KREW_DOC_HDR_T";
61 private static final String INITIATOR_COL = "INITR_PRNCPL_ID";
62
63 DocumentSearchService docSearchService;
64 UserOptionsService userOptionsService;
65
66 @Override
67 protected void loadTestData() throws Exception {
68 loadXmlFile("SearchAttributeConfig.xml");
69 }
70
71 @Override
72 protected void setUpAfterDataLoad() throws Exception {
73 docSearchService = (DocumentSearchService)KEWServiceLocator.getDocumentSearchService();
74 userOptionsService = (UserOptionsService)KEWServiceLocator.getUserOptionsService();
75 }
76
77
78 @Test public void testDocSearch() throws Exception {
79 Person user = KimApiServiceLocator.getPersonService().getPersonByPrincipalName("bmcgough");
80 DocumentSearchCriteria.Builder criteria = DocumentSearchCriteria.Builder.create();
81 DocumentSearchResults results = null;
82 criteria.setTitle("*IN");
83 criteria.setSaveName("bytitle");
84 results = docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
85 criteria = DocumentSearchCriteria.Builder.create();
86 criteria.setTitle("*IN-CFSG");
87 criteria.setSaveName("for in accounts");
88 results = docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
89 criteria = DocumentSearchCriteria.Builder.create();
90 criteria.setDateApprovedFrom(new DateTime(2004, 9, 16, 0, 0));
91 results = docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
92 criteria = DocumentSearchCriteria.Builder.create();
93 user = KimApiServiceLocator.getPersonService().getPersonByPrincipalName("bmcgough");
94 DocumentSearchCriteria savedCriteria = docSearchService.getNamedSearchCriteria(user.getPrincipalId(), "bytitle");
95 assertNotNull(savedCriteria);
96 assertEquals("bytitle", savedCriteria.getSaveName());
97 savedCriteria = docSearchService.getNamedSearchCriteria(user.getPrincipalId(), "for in accounts");
98 assertNotNull(savedCriteria);
99 assertEquals("for in accounts", savedCriteria.getSaveName());
100 }
101
102
103 @Test public void testDocSearchDocumentResult() throws Exception {
104 String[] docIds = routeTestDocs();
105 Person user = KimApiServiceLocator.getPersonService().getPersonByPrincipalName("bmcgough");
106 DocumentSearchCriteria.Builder criteria = DocumentSearchCriteria.Builder.create();
107 DocumentSearchResults results = docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
108 assertEquals(3, results.getSearchResults().size());
109 DocumentSearchResult result = results.getSearchResults().get(0);
110 Document doc = result.getDocument();
111
112
113 assertNotNull(doc.getApplicationDocumentStatus());
114 assertNotNull(doc.getApplicationDocumentStatusDate());
115 assertNotNull(doc.getDateApproved());
116 assertNotNull(doc.getDateCreated());
117 assertNotNull(doc.getDateFinalized());
118 assertNotNull(doc.getDocumentId());
119 assertNotNull(doc.getDocumentTypeName());
120 assertNotNull(doc.getApplicationDocumentId());
121 assertNotNull(doc.getDateLastModified());
122 assertNotNull(doc.getDocumentHandlerUrl());
123 assertNotNull(doc.getDocumentTypeId());
124 assertNotNull(doc.getInitiatorPrincipalId());
125 assertNotNull(doc.getRoutedByPrincipalId());
126 assertNotNull(doc.getStatus());
127 assertNotNull(doc.getTitle());
128
129 assertTrue(doc.getVariables().isEmpty());
130 }
131
132 @Test public void testDocSearch_appDocStatuses() throws Exception {
133 String[] docIds = routeTestDocs();
134
135 DateTime now = DateTime.now();
136 DateTime before = now.minusDays(2);
137 DateTime after = now.plusDays(2);
138
139 String principalId = getPrincipalId("bmcgough");
140
141
142
143 List<String> appDocStatusSearch = Arrays.asList("Submitted", "Pending");
144 DocumentSearchResults results = doAppStatusDocSearch(principalId, appDocStatusSearch, null, null);
145
146 assertEquals("should have matched one doc for each status", 2, results.getSearchResults().size());
147
148 for (DocumentSearchResult result : results.getSearchResults()) {
149 assertTrue("app doc status should be in " + StringUtils.join(appDocStatusSearch, ", "),
150 appDocStatusSearch.contains(result.getDocument().getApplicationDocumentStatus()));
151 }
152
153
154
155
156
157 appDocStatusSearch = Arrays.asList("Submitted", "Pending", "Completed");
158 results = doAppStatusDocSearch(principalId, appDocStatusSearch, before, after);
159
160 assertEquals("all docs are in the date range, should have matched them all", 3, results.getSearchResults().size());
161
162 for (DocumentSearchResult result : results.getSearchResults()) {
163 assertTrue("app doc status should be in " + StringUtils.join(appDocStatusSearch, ", "),
164 appDocStatusSearch.contains(result.getDocument().getApplicationDocumentStatus()));
165 }
166
167
168
169 appDocStatusSearch = Arrays.asList("Submitted", "Pending");
170
171 results = doAppStatusDocSearch(principalId, appDocStatusSearch, before, after);
172 assertEquals("should have matched one doc for each status", 2, results.getSearchResults().size());
173
174 for (DocumentSearchResult result : results.getSearchResults()) {
175 assertTrue("app doc status should be in " + StringUtils.join(appDocStatusSearch, ", "),
176 appDocStatusSearch.contains(result.getDocument().getApplicationDocumentStatus()));
177 }
178
179
180
181 appDocStatusSearch = Arrays.asList("Submitted", "Pending", "Completed");
182
183 results = doAppStatusDocSearch(principalId, appDocStatusSearch, after, after.plusDays(1));
184 assertEquals("none of the docs should be in the date range", 0, results.getSearchResults().size());
185
186
187
188 DocumentSearchCriteria.Builder criteria = DocumentSearchCriteria.Builder.create();
189 criteria.setDocumentTypeName("SearchDocType");
190 criteria.setApplicationDocumentStatus("Submitted");
191
192 results = docSearchService.lookupDocuments(principalId, criteria.build());
193 assertEquals("legacy style app doc status search should have matched one document",
194 1, results.getSearchResults().size());
195 assertTrue("app doc status should match the search criteria",
196 "Submitted".equals(results.getSearchResults().get(0).getDocument().getApplicationDocumentStatus()));
197 }
198
199 private DocumentSearchResults doAppStatusDocSearch(String principalId, List<String> appDocStatuses,
200 DateTime appStatusChangedFrom, DateTime appStatusChangedTo) {
201 DocumentSearchCriteria.Builder criteria = DocumentSearchCriteria.Builder.create();
202 criteria.setDocumentTypeName("SearchDocType");
203 criteria.setApplicationDocumentStatuses(appDocStatuses);
204 criteria.setDateApplicationDocumentStatusChangedFrom(appStatusChangedFrom);
205 criteria.setDateApplicationDocumentStatusChangedTo(appStatusChangedTo);
206 return docSearchService.lookupDocuments(principalId, criteria.build());
207 }
208
209 @Test public void testDocSearch_maxResults() throws Exception {
210 String[] docIds = routeTestDocs();
211
212 String principalId = getPrincipalId("bmcgough");
213
214 DocumentSearchCriteria.Builder criteria = DocumentSearchCriteria.Builder.create();
215 criteria.setDocumentTypeName("SearchDocType");
216 criteria.setMaxResults(5);
217 DocumentSearchResults results = docSearchService.lookupDocuments(principalId, criteria.build());
218 assertEquals(3, results.getSearchResults().size());
219 criteria.setMaxResults(2);
220 results = docSearchService.lookupDocuments(principalId, criteria.build());
221 assertEquals(2, results.getSearchResults().size());
222
223
224
225 assertEquals("_blank", results.getSearchResults().get(0).getDocument().getDocumentHandlerUrl());
226 }
227
228 @Test public void testDocSearch_maxResultsIsNull() throws Exception {
229 String[] docIds = routeTestDocs();
230
231 String principalId = getPrincipalId("bmcgough");
232
233 DocumentSearchCriteria.Builder criteria = DocumentSearchCriteria.Builder.create();
234 criteria.setDocumentTypeName("SearchDocType");
235 criteria.setMaxResults(5);
236 DocumentSearchResults results = docSearchService.lookupDocuments(principalId, criteria.build());
237 assertEquals(3, results.getSearchResults().size());
238 criteria.setMaxResults(null);
239 results = docSearchService.lookupDocuments(principalId, criteria.build());
240 assertEquals(3, results.getSearchResults().size());
241 }
242
243 @Test public void testDocSearch_maxResultsIsZero() throws Exception {
244 String[] docIds = routeTestDocs();
245
246 String principalId = getPrincipalId("bmcgough");
247
248 DocumentSearchCriteria.Builder criteria = DocumentSearchCriteria.Builder.create();
249 criteria.setDocumentTypeName("SearchDocType");
250 criteria.setMaxResults(5);
251 DocumentSearchResults results = docSearchService.lookupDocuments(principalId, criteria.build());
252 assertEquals(3, results.getSearchResults().size());
253 criteria.setMaxResults(0);
254 results = docSearchService.lookupDocuments(principalId, criteria.build());
255 assertEquals(0, results.getSearchResults().size());
256 }
257
258 @Test public void testDocSearch_startAtIndex() throws Exception {
259 String[] docIds = routeTestDocs();
260
261 String principalId = getPrincipalId("bmcgough");
262
263 DocumentSearchCriteria.Builder criteria = DocumentSearchCriteria.Builder.create();
264 criteria.setDocumentTypeName("SearchDocType");
265 criteria.setMaxResults(5);
266 DocumentSearchResults results = docSearchService.lookupDocuments(principalId, criteria.build());
267 assertEquals(3, results.getSearchResults().size());
268 criteria.setStartAtIndex(1);
269 results = docSearchService.lookupDocuments(principalId, criteria.build());
270 assertEquals(2, results.getSearchResults().size());
271 }
272
273 @Test public void testDocSearch_startAtIndexMoreThanResuls() throws Exception {
274 String[] docIds = routeTestDocs();
275
276 String principalId = getPrincipalId("bmcgough");
277
278 DocumentSearchCriteria.Builder criteria = DocumentSearchCriteria.Builder.create();
279 criteria.setDocumentTypeName("SearchDocType");
280 criteria.setMaxResults(5);
281 DocumentSearchResults results = docSearchService.lookupDocuments(principalId, criteria.build());
282 assertEquals(3, results.getSearchResults().size());
283 criteria.setStartAtIndex(5);
284 results = docSearchService.lookupDocuments(principalId, criteria.build());
285 assertEquals(0, results.getSearchResults().size());
286
287 }
288
289 @Test public void testDocSearch_startAtIndexNegative() throws Exception {
290 String[] docIds = routeTestDocs();
291
292 String principalId = getPrincipalId("bmcgough");
293
294 DocumentSearchCriteria.Builder criteria = DocumentSearchCriteria.Builder.create();
295 criteria.setDocumentTypeName("SearchDocType");
296 criteria.setMaxResults(5);
297 DocumentSearchResults results = docSearchService.lookupDocuments(principalId, criteria.build());
298 assertEquals(3, results.getSearchResults().size());
299 criteria.setStartAtIndex(-1);
300 results = docSearchService.lookupDocuments(principalId, criteria.build());
301 assertEquals(0, results.getSearchResults().size());
302
303 }
304
305 @Test public void testDocSearch_startAtIndexZero() throws Exception {
306 String[] docIds = routeTestDocs();
307
308 String principalId = getPrincipalId("bmcgough");
309
310 DocumentSearchCriteria.Builder criteria = DocumentSearchCriteria.Builder.create();
311 criteria.setDocumentTypeName("SearchDocType");
312 criteria.setMaxResults(5);
313 DocumentSearchResults results = docSearchService.lookupDocuments(principalId, criteria.build());
314 assertEquals(3, results.getSearchResults().size());
315 criteria.setStartAtIndex(0);
316 results = docSearchService.lookupDocuments(principalId, criteria.build());
317 assertEquals(3, results.getSearchResults().size());
318
319 }
320
321
322
323
324 @Test public void testUnnamedDocSearchPersistence() throws Exception {
325 Person user = KimApiServiceLocator.getPersonService().getPersonByPrincipalName("bmcgough");
326 Collection<UserOptions> allUserOptions_before = userOptionsService.findByWorkflowUser(user.getPrincipalId());
327 List<UserOptions> namedSearches_before = userOptionsService.findByUserQualified(user.getPrincipalId(), "DocSearch.NamedSearch.%");
328
329 assertEquals(0, namedSearches_before.size());
330 assertEquals(0, allUserOptions_before.size());
331
332 DocumentSearchCriteria.Builder criteria = DocumentSearchCriteria.Builder.create();
333 criteria.setTitle("*IN");
334 criteria.setDateCreatedFrom(DateTime.now().minus(Years.ONE));
335 DocumentSearchCriteria c1 = criteria.build();
336 DocumentSearchResults results = docSearchService.lookupDocuments(user.getPrincipalId(), c1);
337
338 Collection<UserOptions> allUserOptions_after = userOptionsService.findByWorkflowUser(user.getPrincipalId());
339 List<UserOptions> namedSearches_after = userOptionsService.findByUserQualified(user.getPrincipalId(), "DocSearch.NamedSearch.%");
340
341
342
343 assertEquals(allUserOptions_before.size() + 2, allUserOptions_after.size());
344 assertEquals(namedSearches_before.size(), namedSearches_after.size());
345
346 assertEquals("DocSearch.LastSearch.Holding0", userOptionsService.findByOptionId("DocSearch.LastSearch.Order".toString(), user.getPrincipalId()).getOptionVal());
347 assertEquals(marshall(c1), userOptionsService.findByOptionId("DocSearch.LastSearch.Holding0", user.getPrincipalId()).getOptionVal());
348
349
350
351 criteria = DocumentSearchCriteria.Builder.create();
352 criteria.setTitle("*IN-CFSG*");
353 criteria.setDateCreatedFrom(DateTime.now().minus(Years.ONE));
354 DocumentSearchCriteria c2 = criteria.build();
355 results = docSearchService.lookupDocuments(user.getPrincipalId(), c2);
356
357
358 assertEquals(allUserOptions_before.size() + 2, allUserOptions_after.size());
359 assertEquals(namedSearches_before.size(), namedSearches_after.size());
360
361 assertEquals("DocSearch.LastSearch.Holding1,DocSearch.LastSearch.Holding0", userOptionsService.findByOptionId("DocSearch.LastSearch.Order", user.getPrincipalId()).getOptionVal());
362 assertEquals(marshall(c1), userOptionsService.findByOptionId("DocSearch.LastSearch.Holding0", user.getPrincipalId()).getOptionVal());
363 assertEquals(marshall(c2), userOptionsService.findByOptionId("DocSearch.LastSearch.Holding1", user.getPrincipalId()).getOptionVal());
364 }
365
366
367
368
369 @Test public void testNamedDocSearchPersistence() throws Exception {
370 Person user = KimApiServiceLocator.getPersonService().getPersonByPrincipalName("bmcgough");
371 Collection<UserOptions> allUserOptions_before = userOptionsService.findByWorkflowUser(user.getPrincipalId());
372 List<UserOptions> namedSearches_before = userOptionsService.findByUserQualified(user.getPrincipalId(), "DocSearch.NamedSearch.%");
373
374 DocumentSearchCriteria.Builder criteria = DocumentSearchCriteria.Builder.create();
375 criteria.setTitle("*IN");
376 criteria.setSaveName("bytitle");
377 criteria.setDateCreatedFrom(DateTime.now().minus(Years.ONE));
378 DocumentSearchCriteria c1 = criteria.build();
379 DocumentSearchResults results = docSearchService.lookupDocuments(user.getPrincipalId(), c1);
380
381 Collection<UserOptions> allUserOptions_after = userOptionsService.findByWorkflowUser(user.getPrincipalId());
382 List<UserOptions> namedSearches_after = userOptionsService.findByUserQualified(user.getPrincipalId(), "DocSearch.NamedSearch.%");
383
384 assertEquals(allUserOptions_before.size() + 1, allUserOptions_after.size());
385 assertEquals(namedSearches_before.size() + 1, namedSearches_after.size());
386
387 assertEquals(marshall(c1), userOptionsService.findByOptionId("DocSearch.NamedSearch." + criteria.getSaveName(), user.getPrincipalId()).getOptionVal());
388
389
390 criteria = DocumentSearchCriteria.Builder.create();
391 criteria.setTitle("*IN");
392 criteria.setSaveName("bytitle2");
393 criteria.setDateCreatedFrom(DateTime.now().minus(Years.ONE));
394 DocumentSearchCriteria c2 = criteria.build();
395 results = docSearchService.lookupDocuments(user.getPrincipalId(), c2);
396
397 allUserOptions_after = userOptionsService.findByWorkflowUser(user.getPrincipalId());
398 namedSearches_after = userOptionsService.findByUserQualified(user.getPrincipalId(), "DocSearch.NamedSearch.%");
399
400
401 assertEquals(allUserOptions_before.size() + 2, allUserOptions_after.size());
402 assertEquals(namedSearches_before.size() + 2, namedSearches_after.size());
403
404 assertEquals(marshall(c2), userOptionsService.findByOptionId("DocSearch.NamedSearch." + criteria.getSaveName(), user.getPrincipalId()).getOptionVal());
405
406 }
407
408 protected static String marshall(DocumentSearchCriteria criteria) throws Exception {
409 return DocumentSearchInternalUtils.marshalDocumentSearchCriteria(criteria);
410 }
411
412 @Test
413 public void testDocSearch_criteriaModified() throws Exception {
414 String principalId = getPrincipalId("ewestfal");
415
416
417 DocumentSearchCriteria.Builder criteria = DocumentSearchCriteria.Builder.create();
418 DocumentSearchResults results = docSearchService.lookupDocuments(principalId, criteria.build());
419 assertTrue("criteria should have been modified", results.isCriteriaModified());
420 assertNull("original date created from should have been null", criteria.getDateCreatedFrom());
421 assertNotNull("modified date created from should be non-null", results.getCriteria().getDateCreatedFrom());
422 assertEquals("Criteria date minus today's date should equal the constant value",
423 KewApiConstants.DOCUMENT_SEARCH_NO_CRITERIA_CREATE_DATE_DAYS_AGO.intValue(),
424 getDifferenceInDays(results.getCriteria().getDateCreatedFrom()));
425
426
427
428 criteria.setMaxResults(new Integer(50));
429 criteria.setSaveName("myRadSearch");
430 results = docSearchService.lookupDocuments(principalId, criteria.build());
431 assertTrue("criteria should have been modified", results.isCriteriaModified());
432 assertNotNull("modified date created from should be non-null", results.getCriteria().getDateCreatedFrom());
433
434
435 criteria.setTitle("My rad title search!");
436 results = docSearchService.lookupDocuments(principalId, criteria.build());
437 assertTrue("criteria should have been modified", results.isCriteriaModified());
438 assertNotNull("modified date created from should be non-null", results.getCriteria().getDateCreatedFrom());
439 assertEquals("Criteria date minus today's date should equal the constant value",
440 Math.abs(KewApiConstants.DOCUMENT_SEARCH_DOC_TITLE_CREATE_DATE_DAYS_AGO.intValue()),
441 getDifferenceInDays(results.getCriteria().getDateCreatedFrom()));
442
443
444 criteria.setApplicationDocumentId("12345");
445 results = docSearchService.lookupDocuments(principalId, criteria.build());
446 assertFalse("criteria should *not* have been modified", results.isCriteriaModified());
447 assertNull("modified date created from should still be null", results.getCriteria().getDateCreatedFrom());
448 assertEquals("both criterias should be equal", criteria.build(), results.getCriteria());
449 }
450
451
452
453
454
455
456
457 @Test public void testDocSearch_MissingInitiator() throws Exception {
458 String documentTypeName = "SearchDocType";
459 DocumentType docType = ((DocumentTypeService)KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_TYPE_SERVICE)).findByName(documentTypeName);
460 String userNetworkId = "arh14";
461
462 WorkflowDocument workflowDocument = WorkflowDocumentFactory.createDocument(getPrincipalId(userNetworkId), documentTypeName);
463 workflowDocument.setTitle("testDocSearch_MissingInitiator");
464 workflowDocument.route("routing this document.");
465
466
467 workflowDocument = WorkflowDocumentFactory.loadDocument(getPrincipalId("jhopf"),workflowDocument.getDocumentId());
468 assertTrue(workflowDocument.isEnroute());
469 assertTrue(workflowDocument.isApprovalRequested());
470
471
472 new JdbcTemplate(TestHarnessServiceLocator.getDataSource()).execute("update " + KREW_DOC_HDR_T + " set " + INITIATOR_COL + " = 'bogus user' where DOC_HDR_ID = " + workflowDocument.getDocumentId());
473
474
475 Person user = KimApiServiceLocator.getPersonService().getPersonByPrincipalName("jhopf");
476 DocumentSearchCriteria.Builder criteria = DocumentSearchCriteria.Builder.create();
477 criteria.setDocumentTypeName(documentTypeName);
478 DocumentSearchResults results = docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
479 assertEquals("Search returned invalid number of documents", 1, results.getSearchResults().size());
480 }
481
482
483
484
485
486 @Test public void testDocSearch_SearchOnMissingInitiator() throws Exception {
487 String documentTypeName = "SearchDocType";
488 DocumentType docType = ((DocumentTypeService)KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_TYPE_SERVICE)).findByName(documentTypeName);
489 String userNetworkId = "arh14";
490
491 WorkflowDocument workflowDocument = WorkflowDocumentFactory.createDocument(getPrincipalId(userNetworkId), documentTypeName);
492 workflowDocument.setTitle("testDocSearch_MissingInitiator");
493 workflowDocument.route("routing this document.");
494
495
496 workflowDocument = WorkflowDocumentFactory.loadDocument(getPrincipalId("jhopf"),workflowDocument.getDocumentId());
497 assertTrue(workflowDocument.isEnroute());
498 assertTrue(workflowDocument.isApprovalRequested());
499
500
501 new JdbcTemplate(TestHarnessServiceLocator.getDataSource()).execute("update " + KREW_DOC_HDR_T + " set " + INITIATOR_COL + " = 'bogus user' where DOC_HDR_ID = " + workflowDocument.getDocumentId());
502
503
504 Person user = KimApiServiceLocator.getPersonService().getPersonByPrincipalName("jhopf");
505 DocumentSearchCriteria.Builder criteria = DocumentSearchCriteria.Builder.create();
506 criteria.setInitiatorPrincipalName("bogus user");
507
508 DocumentSearchResults results = docSearchService.lookupDocuments(user.getPrincipalId(),
509 criteria.build());
510 int size = results.getSearchResults().size();
511 assertTrue("Searching by an invalid initiator should return nothing", size == 0);
512
513 }
514
515 @Test public void testDocSearch_RouteNodeName() throws Exception {
516 loadXmlFile("DocSearchTest_RouteNode.xml");
517 String documentTypeName = "SearchDocType_RouteNodeTest";
518 DocumentType docType = ((DocumentTypeService)KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_TYPE_SERVICE)).findByName(documentTypeName);
519 String userNetworkId = "rkirkend";
520
521
522 WorkflowDocument workflowDocument = WorkflowDocumentFactory.createDocument(getPrincipalId(userNetworkId), documentTypeName);
523 workflowDocument.setTitle("Routing style");
524 workflowDocument.route("routing this document.");
525
526 workflowDocument = WorkflowDocumentFactory.loadDocument(getPrincipalId("jhopf"),workflowDocument.getDocumentId());
527 assertTrue(workflowDocument.isEnroute());
528 assertTrue(workflowDocument.isApprovalRequested());
529 workflowDocument.approve("");
530 workflowDocument = WorkflowDocumentFactory.loadDocument(getPrincipalId("jhopf"),workflowDocument.getDocumentId());
531 assertTrue(workflowDocument.isFinal());
532 workflowDocument = WorkflowDocumentFactory.createDocument(getPrincipalId(userNetworkId), documentTypeName);
533 workflowDocument.setTitle("Routing style");
534 workflowDocument.route("routing this document.");
535
536 workflowDocument = WorkflowDocumentFactory.loadDocument(getPrincipalId("jhopf"),workflowDocument.getDocumentId());
537 assertTrue(workflowDocument.isEnroute());
538 assertTrue(workflowDocument.isApprovalRequested());
539
540
541 Person user = KimApiServiceLocator.getPersonService().getPersonByPrincipalName(userNetworkId);
542 DocumentSearchCriteria.Builder criteria = DocumentSearchCriteria.Builder.create();
543 criteria.setDocumentTypeName(documentTypeName);
544 DocumentSearchResults results = docSearchService.lookupDocuments(user.getPrincipalId(),
545 criteria.build());
546 assertEquals("Search returned invalid number of documents", 2, results.getSearchResults().size());
547
548 criteria.setRouteNodeName(getRouteNodeForSearch(documentTypeName,workflowDocument.getNodeNames()));
549 criteria.setRouteNodeLookupLogic(RouteNodeLookupLogic.EXACTLY);
550 results = docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
551 assertEquals("Search returned invalid number of documents", 1, results.getSearchResults().size());
552
553
554 loadXmlFile("DocSearchTest_RouteNode.xml");
555
556 workflowDocument = WorkflowDocumentFactory.loadDocument(getPrincipalId("jhopf"),workflowDocument.getDocumentId());
557 assertTrue(workflowDocument.isEnroute());
558 assertTrue(workflowDocument.isApprovalRequested());
559 criteria.setRouteNodeName(getRouteNodeForSearch(documentTypeName, workflowDocument.getNodeNames()));
560 results = docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
561 assertEquals("Search returned invalid number of documents", 1, results.getSearchResults().size());
562
563 }
564
565 private String getRouteNodeForSearch(String documentTypeName, Set<String> nodeNames) {
566 assertEquals(1, nodeNames.size());
567 String expectedNodeName = nodeNames.iterator().next();
568 List routeNodes = KEWServiceLocator.getRouteNodeService().getFlattenedNodes(KEWServiceLocator.getDocumentTypeService().findByName(documentTypeName), true);
569 for (Iterator iterator = routeNodes.iterator(); iterator.hasNext();) {
570 RouteNode node = (RouteNode) iterator.next();
571 if (expectedNodeName.equals(node.getRouteNodeName())) {
572 return node.getRouteNodeName();
573 }
574 }
575 return null;
576 }
577
578 @Test public void testGetNamedDocSearches() throws Exception {
579 List namedSearches = docSearchService.getNamedSearches(getPrincipalId("bmcgough"));
580 assertNotNull(namedSearches);
581 }
582
583 private static int getDifferenceInDays(DateTime compareDate) {
584 return Days.daysBetween(compareDate, new DateTime()).getDays();
585 }
586
587
588
589
590
591 @Test public void testDocSearchWithAttributes() throws Exception {
592 String[] docIds = routeTestDocs();
593
594 String principalId = getPrincipalId("bmcgough");
595 DocumentSearchCriteria.Builder builder = DocumentSearchCriteria.Builder.create();
596 builder.setDocumentTypeName("SearchDocType");
597 builder.setSaveName("testDocSearchWithAttributes");
598 Map<String, List<String>> docAttrs = new HashMap<String, List<String>>();
599 docAttrs.put(TestXMLSearchableAttributeString.SEARCH_STORAGE_KEY, Arrays.asList(new String[]{TestXMLSearchableAttributeString.SEARCH_STORAGE_VALUE}));
600 builder.setDocumentAttributeValues(docAttrs);
601
602 DocumentSearchResults results = docSearchService.lookupDocuments(principalId, builder.build());
603 assertEquals(docIds.length, results.getSearchResults().size());
604
605 DocumentSearchCriteria loaded = docSearchService.getNamedSearchCriteria(principalId, builder.getSaveName());
606 assertNotNull(loaded);
607 assertEquals(docAttrs, loaded.getDocumentAttributeValues());
608
609
610 results = docSearchService.lookupDocuments(principalId, loaded);
611 assertEquals(docIds.length, results.getSearchResults().size());
612 }
613
614
615
616
617
618 @Test public void testDocSearch_WildcardsOnRegularAttributes() throws Exception {
619
620
621
622 String[] docIds = routeTestDocs();
623
624 String principalId = getPrincipalId("bmcgough");
625 DocumentSearchCriteria.Builder criteria = null;
626 DocumentSearchResults results = null;
627
628
629
630
631
632 String[] searchStrings = {"!quickstart", "!quickstart&&!rkirkend", "!admin", "user1", "quickstart|bmcgough",
633 "admin|rkirkend", ">bmcgough", ">=rkirkend", "<bmcgough", "<=quickstart", ">bmcgough&&<=rkirkend", "<rkirkend&&!bmcgough",
634 "?mc?oug?", "*t", "*i?k*", "*", "!quick*", "!*g*&&!*k*", "quickstart..rkirkend"};
635 int[] expectedResults = {2, 1, 3, 0, 2, 1, 2, 1, 0, 2, 2, 1, 1, 1, 2, 3, 2, 0, 2};
636 for (int i = 0; i < searchStrings.length; i++) {
637 criteria = DocumentSearchCriteria.Builder.create();
638 criteria.setInitiatorPrincipalName(searchStrings[i]);
639 results = docSearchService.lookupDocuments(principalId, criteria.build());
640 assertEquals("Initiator search at index " + i + " retrieved the wrong number of documents.", expectedResults[i], results.getSearchResults().size());
641 }
642
643
644 searchStrings = new String[] {"jhopf","!jhopf", ">jhopf", "<jjopf", ">=quickstart", "<=jhopf", "jhope..jhopg", "?hopf", "*i*", "!*f", "j*"};
645 expectedResults = new int[] {1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1};
646 for (int i = 0; i < searchStrings.length; i++) {
647 criteria = DocumentSearchCriteria.Builder.create();
648 criteria.setApproverPrincipalName(searchStrings[i]);
649 results = docSearchService.lookupDocuments(principalId, criteria.build());
650 assertEquals("Approver search at index " + i + " retrieved the wrong number of documents.", expectedResults[i], results.getSearchResults().size());
651 }
652
653
654 searchStrings = new String[] {"jhopf","!jhopf", ">jhopf", "<jjopf", ">=quickstart", "<=jhopf", "jhope..jhopg", "?hopf", "*i*", "!*f", "j*"};
655 expectedResults = new int[] {3, 0, 0, 3, 0, 3, 3, 3, 0, 0, 3};
656 for (int i = 0; i < searchStrings.length; i++) {
657 criteria = DocumentSearchCriteria.Builder.create();
658 criteria.setViewerPrincipalName(searchStrings[i]);
659 results = docSearchService.lookupDocuments(principalId, criteria.build());
660 if(expectedResults[i] != results.getSearchResults().size()){
661 assertEquals("Viewer search at index " + i + " retrieved the wrong number of documents.", expectedResults[i], results.getSearchResults().size());
662 }
663 }
664
665
666
667
668
669
670 searchStrings = new String[] {"!"+docIds[0], docIds[1]+"|"+docIds[2], "<="+docIds[1], ">="+docIds[2], "<"+docIds[0]+"&&>"+docIds[2],
671 ">"+docIds[1], "<"+docIds[2]+"&&!"+docIds[0], docIds[0]+".."+docIds[2], "?"+docIds[1]+"*", "?"+docIds[1].substring(1)+"*", "?9*7abc"};
672 expectedResults = new int[] {2, 2, 2, 1, 0, 1, 1, 3, 0, 1, 0};
673 for (int i = 0; i < searchStrings.length; i++) {
674 criteria = DocumentSearchCriteria.Builder.create();
675 criteria.setDocumentId(searchStrings[i]);
676 results = docSearchService.lookupDocuments(principalId, criteria.build());
677 assertEquals("Doc ID search at index " + i + " retrieved the wrong number of documents.", expectedResults[i], results.getSearchResults().size());
678 }
679
680
681 searchStrings = new String[] {"6543", "5432|4321", ">4321", "<=5432", ">=6543", "<3210", "!3210", "!5432", "!4321!5432", ">4321&&!6543",
682 "*5?3*", "*", "?3?1", "!*43*", "!???2", ">43*1", "<=5432&&!?32?", "5432..6543"};
683 expectedResults = new int[] {1, 2, 2, 2, 1, 0, 3, 2, 1, 1, 2, 3, 1, 0, 2, 3, 1, 2};
684 for (int i = 0; i < searchStrings.length; i++) {
685 criteria = DocumentSearchCriteria.Builder.create();
686 criteria.setApplicationDocumentId(searchStrings[i]);
687 results = docSearchService.lookupDocuments(principalId, criteria.build());
688 if(expectedResults[i] != results.getSearchResults().size()){
689 assertEquals("App doc ID search at index " + i + " retrieved the wrong number of documents.", expectedResults[i], results.getSearchResults().size());
690 }
691 }
692
693
694 searchStrings = new String[] {"Some New Document", "Document Number 2|The New Doc", "!The New Doc", "!Some New Document!Document Number 2",
695 "!The New Doc&&!Some New Document", ">Document Number 2", "<=Some New Document", ">=The New Doc&&<Some New Document", ">A New Doc",
696 "<Some New Document|The New Doc", ">=Document Number 2&&!Some New Document", "*Docu??nt*", "*New*", "The ??? Doc", "*Doc*", "*Number*",
697 "Some New Document..The New Doc", "Document..The", "*New*&&!*Some*", "!The ??? Doc|!*New*"};
698 expectedResults = new int[] {1, 2, 2, 1, 1, 2, 2, 0, 3, 2, 2, 2, 2, 1, 3, 1, 2, 2, 1, 2};
699 for (int i = 0; i < searchStrings.length; i++) {
700 criteria = DocumentSearchCriteria.Builder.create();
701 criteria.setTitle(searchStrings[i]);
702 results = docSearchService.lookupDocuments(principalId, criteria.build());
703 if(expectedResults[i] != results.getSearchResults().size()){
704 assertEquals("Doc title search at index " + i + " retrieved the wrong number of documents.", expectedResults[i], results.getSearchResults().size());
705 }
706 }
707
708 }
709
710 @Test public void testAdditionalDocumentTypesCriteria() throws Exception {
711 String[] docIds = routeTestDocs();
712 String docId2 = routeTestDoc2();
713
714 String principalId = getPrincipalId("bmcgough");
715
716 DocumentSearchCriteria.Builder criteria = DocumentSearchCriteria.Builder.create();
717 criteria.setDocumentTypeName("SearchDocType");
718
719
720 DocumentSearchResults results = docSearchService.lookupDocuments(principalId, criteria.build());
721 assertEquals(3, results.getSearchResults().size());
722
723 criteria.setDocumentTypeName("SearchDocType2");
724 results = docSearchService.lookupDocuments(principalId, criteria.build());
725 assertEquals(1, results.getSearchResults().size());
726
727 criteria.getAdditionalDocumentTypeNames().add("SearchDocType");
728 results = docSearchService.lookupDocuments(principalId, criteria.build());
729 assertEquals(4, results.getSearchResults().size());
730 }
731
732
733
734
735 @Test public void testDocumentStatusSearching() {
736 String dt = "SearchDocType";
737 String pid = getPrincipalIdForName("quickstart");
738 WorkflowDocument initiated = WorkflowDocumentFactory.createDocument(pid, dt);
739 WorkflowDocument saved = WorkflowDocumentFactory.createDocument(pid, dt);
740 saved.saveDocument("saved");
741 assertEquals(DocumentStatus.SAVED, saved.getStatus());
742
743 WorkflowDocument enroute = WorkflowDocumentFactory.createDocument(pid, dt);
744 enroute.route("routed");
745 assertEquals(DocumentStatus.ENROUTE, enroute.getStatus());
746
747 WorkflowDocument exception = WorkflowDocumentFactory.createDocument(pid, dt);
748 exception.route("routed");
749 exception.placeInExceptionRouting("placed in exception routing");
750 assertEquals(DocumentStatus.EXCEPTION, exception.getStatus());
751
752
753
754
755
756 WorkflowDocument finl = WorkflowDocumentFactory.createDocument(pid, dt);
757 finl.route("routed");
758 finl.switchPrincipal(getPrincipalId("jhopf"));
759 finl.approve("approved");
760 assertEquals(DocumentStatus.FINAL, finl.getStatus());
761
762 WorkflowDocument canceled = WorkflowDocumentFactory.createDocument(pid, dt);
763 canceled.cancel("canceled");
764 assertEquals(DocumentStatus.CANCELED, canceled.getStatus());
765
766 WorkflowDocument disapproved = WorkflowDocumentFactory.createDocument(pid, dt);
767 disapproved.route("routed");
768 disapproved.switchPrincipal(getPrincipalId("jhopf"));
769 RequestedActions ra = disapproved.getRequestedActions();
770 disapproved.disapprove("disapproved");
771 assertEquals(DocumentStatus.DISAPPROVED, disapproved.getStatus());
772
773 assertDocumentStatuses(dt, pid, 1, 1, 1, 1, 0, 1, 1, 1);
774 }
775
776
777
778
779
780 protected void assertDocumentStatuses(String documentType, String principalId, int initiated, int saved, int enroute, int exception,
781 int processed, int finl, int canceled, int disapproved) {
782 assertDocumentStatus(documentType, principalId, DocumentStatus.INITIATED, initiated);
783 assertDocumentStatus(documentType, principalId, DocumentStatus.SAVED, saved);
784 assertDocumentStatus(documentType, principalId, DocumentStatus.ENROUTE, enroute);
785 assertDocumentStatus(documentType, principalId, DocumentStatus.EXCEPTION, exception);
786
787 assertDocumentStatusCategory(documentType, principalId, DocumentStatusCategory.PENDING,
788 initiated + saved + enroute + exception);
789
790 assertDocumentStatus(documentType, principalId, DocumentStatus.PROCESSED, processed);
791 assertDocumentStatus(documentType, principalId, DocumentStatus.FINAL, finl);
792
793 assertDocumentStatusCategory(documentType, principalId, DocumentStatusCategory.SUCCESSFUL, processed + finl);
794
795 assertDocumentStatus(documentType, principalId, DocumentStatus.CANCELED, canceled);
796 assertDocumentStatus(documentType, principalId, DocumentStatus.DISAPPROVED, finl);
797
798 assertDocumentStatusCategory(documentType, principalId, DocumentStatusCategory.UNSUCCESSFUL,
799 canceled + disapproved);
800 }
801
802
803
804
805 protected void assertDocumentStatus(String documentType, String principalId, DocumentStatus status, int num) {
806 DocumentSearchCriteria.Builder criteria = DocumentSearchCriteria.Builder.create();
807 criteria.setDocumentTypeName(documentType);
808 criteria.setDocumentStatuses(Arrays.asList(new DocumentStatus[] { status }));
809 DocumentSearchResults result = docSearchService.lookupDocuments(principalId, criteria.build());
810 assertEquals("Expected " + num + " documents in status " + status, num, result.getSearchResults().size());
811 }
812
813
814
815
816 protected void assertDocumentStatusCategory(String documentType, String principalId, DocumentStatusCategory status, int num) {
817 DocumentSearchCriteria.Builder criteria = DocumentSearchCriteria.Builder.create();
818 criteria.setDocumentTypeName(documentType);
819 criteria.setDocumentStatusCategories(Arrays.asList(new DocumentStatusCategory[]{status}));
820 DocumentSearchResults result = docSearchService.lookupDocuments(principalId, criteria.build());
821 assertEquals("Expected " + num + " documents in status category " + status, num,
822 result.getSearchResults().size());
823 }
824
825 private static final class TestDocData {
826 private TestDocData() { throw new IllegalStateException("leave me alone"); }
827
828 static String docTypeName = "SearchDocType";
829 static String[] principalNames = {"bmcgough", "quickstart", "rkirkend"};
830 static String[] titles = {"The New Doc", "Document Number 2", "Some New Document"};
831 static String[] appDocIds = {"6543", "5432", "4321"};
832 static String[] appDocStatuses = {"Submitted", "Pending", "Completed"};
833 static String[] approverNames = {null, "jhopf", null};
834 }
835
836
837
838
839
840 protected String[] routeTestDocs() {
841
842 String[] docIds = new String[TestDocData.titles.length];
843
844 for (int i = 0; i < TestDocData.titles.length; i++) {
845 WorkflowDocument workflowDocument = WorkflowDocumentFactory.createDocument(
846 getPrincipalId(TestDocData.principalNames[i]), TestDocData.docTypeName);
847 workflowDocument.setTitle(TestDocData.titles[i]);
848 workflowDocument.setApplicationDocumentId(TestDocData.appDocIds[i]);
849 workflowDocument.route("routing this document.");
850
851 docIds[i] = workflowDocument.getDocumentId();
852
853 if (TestDocData.approverNames[i] != null) {
854 workflowDocument.switchPrincipal(getPrincipalId(TestDocData.approverNames[i]));
855 workflowDocument.approve("approving this document.");
856 }
857
858 workflowDocument.setApplicationDocumentStatus(TestDocData.appDocStatuses[i]);
859 workflowDocument.saveDocumentData();
860 }
861
862 return docIds;
863 }
864
865
866
867
868 protected String routeTestDoc2() {
869
870 String docTypeName = "SearchDocType2";
871 WorkflowDocument workflowDocument = WorkflowDocumentFactory.createDocument(getPrincipalId("ewestfal"), docTypeName);
872 workflowDocument.setTitle("Search Doc Type 2!");
873 workflowDocument.saveDocument("saving the document");
874 return workflowDocument.getDocumentId();
875 }
876
877 private String getPrincipalId(String principalName) {
878 return KimApiServiceLocator.getIdentityService().getPrincipalByPrincipalName(principalName).getPrincipalId();
879 }
880
881 @Test
882 public void testDocSearch_maxResultsCap() throws Exception {
883 DocumentSearchCriteria.Builder criteria = DocumentSearchCriteria.Builder.create();
884 criteria.setDocumentTypeName("SearchDocType");
885 int maxResultsCap = docSearchService.getMaxResultCap(criteria.build());
886 assertEquals(500, maxResultsCap);
887
888 criteria.setMaxResults(5);
889 int maxResultsCap1 = docSearchService.getMaxResultCap(criteria.build());
890 assertEquals(5, maxResultsCap1);
891
892 criteria.setMaxResults(2);
893 int maxResultsCap2 = docSearchService.getMaxResultCap(criteria.build());
894 assertEquals(2, maxResultsCap2);
895 }
896
897 @Test
898 public void testDocSearch_fetchMoreIterationLimit() throws Exception {
899 DocumentSearchCriteria.Builder criteria = DocumentSearchCriteria.Builder.create();
900 criteria.setDocumentTypeName("SearchDocType");
901 int fetchIterationLimit = docSearchService.getFetchMoreIterationLimit();
902 assertEquals(10, fetchIterationLimit);
903
904 }
905 }