View Javadoc

1   /*
2    * Copyright 2005-2007 The Kuali Foundation
3    *
4    *
5    * Licensed under the Educational Community License, Version 2.0 (the "License");
6    * you may not use this file except in compliance with the License.
7    * You may obtain a copy of the License at
8    *
9    * http://www.opensource.org/licenses/ecl2.php
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.kuali.rice.kew.docsearch.xml;
18  
19  import org.junit.Test;
20  import org.kuali.rice.kew.api.WorkflowDocument;
21  import org.kuali.rice.kew.api.WorkflowDocumentFactory;
22  import org.kuali.rice.kew.api.document.attribute.DocumentAttribute;
23  import org.kuali.rice.kew.api.document.attribute.WorkflowAttributeDefinition;
24  import org.kuali.rice.kew.api.document.lookup.DocumentLookupCriteria;
25  import org.kuali.rice.kew.api.document.lookup.DocumentLookupResult;
26  import org.kuali.rice.kew.api.document.lookup.DocumentLookupResults;
27  import org.kuali.rice.kew.docsearch.DocumentLookupInternalUtils;
28  import org.kuali.rice.kew.docsearch.DocumentSearchTestBase;
29  import org.kuali.rice.kew.docsearch.SearchableAttributeLongValue;
30  import org.kuali.rice.kew.docsearch.TestXMLSearchableAttributeDateTime;
31  import org.kuali.rice.kew.docsearch.TestXMLSearchableAttributeFloat;
32  import org.kuali.rice.kew.docsearch.TestXMLSearchableAttributeLong;
33  import org.kuali.rice.kew.docsearch.TestXMLSearchableAttributeString;
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.exception.WorkflowException;
38  import org.kuali.rice.kew.exception.WorkflowServiceErrorException;
39  import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
40  import org.kuali.rice.kew.service.KEWServiceLocator;
41  import org.kuali.rice.kew.test.TestUtilities;
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  
46  import java.sql.Timestamp;
47  
48  import static org.junit.Assert.*;
49  
50  
51  /**
52   * Tests the StandardGenericXMLSearchableAttribute.
53   *
54   * KULWF-654: Tests the resolution to this issue by configuring a CustomActionListAttribute as well as a
55   * searchable attribute.
56   */
57  @BaselineTestCase.BaselineMode(BaselineTestCase.Mode.NONE)
58  public class StandardGenericXMLSearchableAttributeTest extends DocumentSearchTestBase {
59  
60      protected void loadTestData() throws Exception {
61          loadXmlFile("XmlConfig.xml");
62      }
63  
64      @Test public void testXMLStandardSearchableAttributeWithInvalidValue() throws Exception {
65          String documentTypeName = "SearchDocTypeStandardSearchDataType";
66          String userNetworkId = "rkirkend";
67          WorkflowDocument workflowDocument = WorkflowDocumentFactory.createDocument(getPrincipalIdForName(userNetworkId), documentTypeName);
68  
69          /*
70           *   Below we are using the keys and values from the custom searchable attribute classes' static constants but
71           *   this is only for convenience as those should always be valid values to test for.
72           */
73          // adding string value in what should be a long searchable attribute
74          WorkflowAttributeDefinition.Builder longXMLDef = WorkflowAttributeDefinition.Builder.create("XMLSearchableAttributeStdLong");
75          longXMLDef.addPropertyDefinition(TestXMLSearchableAttributeLong.SEARCH_STORAGE_KEY, "123x23");
76          workflowDocument.addSearchableDefinition(longXMLDef.build());
77  
78          workflowDocument.setTitle("Routing style");
79          try {
80              workflowDocument.route("routing this document.");
81              fail("Document should be unroutable with invalid searchable attribute value");
82          } catch (Exception e) {
83              e.printStackTrace();
84          }
85          /*
86           * The call to TestUtilities below is needed because when exception routing spawns a new thread (see
87           * TestExceptionRoutingServiceImpl class) the next test will begin before the exception thread is complete and
88           * cause errors. This was originally discovered because the test method
89           * testXMLStandardSearchableAttributesWithDataType() would run and get errors loading xml data for workgroups
90           * perhaps because the exception thread was keeping the cache around and now allowing it to be cleared?
91           */
92          TestUtilities.waitForExceptionRouting();
93      }
94  
95      @Test public void testXMLStandardSearchableAttributesWithDataType() throws Exception {
96          String documentTypeName = "SearchDocTypeStandardSearchDataType";
97      	DocumentType docType = ((DocumentTypeService)KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_TYPE_SERVICE)).findByName(documentTypeName);
98          String userNetworkId = "rkirkend";
99          WorkflowDocument workflowDocument = WorkflowDocumentFactory.createDocument(getPrincipalIdForName(userNetworkId), documentTypeName);
100 
101         /*
102          *   Below we are using the keys and values from the custom searchable attribute classes' static constants but
103          *   this is only for convenience as those should always be valid values to test for.
104          */
105         int i = 0;
106         // adding string searchable attribute
107         i++;
108         WorkflowAttributeDefinition.Builder stringXMLDef = WorkflowAttributeDefinition.Builder.create("XMLSearchableAttribute");
109         stringXMLDef.addPropertyDefinition(TestXMLSearchableAttributeString.SEARCH_STORAGE_KEY, TestXMLSearchableAttributeString.SEARCH_STORAGE_VALUE);
110         workflowDocument.addSearchableDefinition(stringXMLDef.build());
111         // adding long searchable attribute
112         i++;
113         WorkflowAttributeDefinition.Builder longXMLDef = WorkflowAttributeDefinition.Builder.create("XMLSearchableAttributeStdLong");
114         longXMLDef.addPropertyDefinition(TestXMLSearchableAttributeLong.SEARCH_STORAGE_KEY, TestXMLSearchableAttributeLong.SEARCH_STORAGE_VALUE.toString());
115         workflowDocument.addSearchableDefinition(longXMLDef.build());
116         // adding float searchable attribute
117         i++;
118         WorkflowAttributeDefinition.Builder floatXMLDef = WorkflowAttributeDefinition.Builder.create("XMLSearchableAttributeStdFloat");
119         floatXMLDef.addPropertyDefinition(TestXMLSearchableAttributeFloat.SEARCH_STORAGE_KEY, TestXMLSearchableAttributeFloat.SEARCH_STORAGE_VALUE.toString());
120         workflowDocument.addSearchableDefinition(floatXMLDef.build());
121         // adding string searchable attribute
122         i++;
123         WorkflowAttributeDefinition.Builder dateXMLDef = WorkflowAttributeDefinition.Builder.create("XMLSearchableAttributeStdDateTime");
124         dateXMLDef.addPropertyDefinition(TestXMLSearchableAttributeDateTime.SEARCH_STORAGE_KEY, DocumentLookupInternalUtils
125                 .getDisplayValueWithDateOnly(TestXMLSearchableAttributeDateTime.SEARCH_STORAGE_VALUE));
126         workflowDocument.addSearchableDefinition(dateXMLDef.build());
127 
128         workflowDocument.setTitle("Routing style");
129         workflowDocument.route("routing this document.");
130 
131         workflowDocument = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName(userNetworkId), workflowDocument.getDocumentId());
132         DocumentRouteHeaderValue doc = KEWServiceLocator.getRouteHeaderService().getRouteHeader(workflowDocument.getDocumentId());
133 
134         DocumentSearchService docSearchService = (DocumentSearchService) KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_SEARCH_SERVICE);
135         Person user = KimApiServiceLocator.getPersonService().getPersonByPrincipalName(userNetworkId);
136 
137         DocumentLookupCriteria.Builder criteria = DocumentLookupCriteria.Builder.create();
138         criteria.setDocumentTypeName(documentTypeName);
139         addSearchableAttribute(criteria, TestXMLSearchableAttributeString.SEARCH_STORAGE_KEY,
140                 TestXMLSearchableAttributeString.SEARCH_STORAGE_VALUE);
141         DocumentLookupResults results = docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
142 
143         assertEquals("Search results should have one document.", 1, results.getLookupResults().size());
144 
145         DocumentLookupCriteria.Builder criteria2 = DocumentLookupCriteria.Builder.create();
146         criteria2.setDocumentTypeName(documentTypeName);
147         addSearchableAttribute(criteria2, TestXMLSearchableAttributeString.SEARCH_STORAGE_KEY, "fred");
148         DocumentLookupResults results2 = docSearchService.lookupDocuments(user.getPrincipalId(), criteria2.build());
149 
150         assertEquals("Search results should be empty.", 0, results2.getLookupResults().size());
151 
152         DocumentLookupCriteria.Builder criteria3 = DocumentLookupCriteria.Builder.create();
153         criteria3.setDocumentTypeName(documentTypeName);
154         addSearchableAttribute(criteria3, "fakeproperty", "doesntexist");
155         try {
156             docSearchService.lookupDocuments(user.getPrincipalId(), criteria3.build());
157             fail("Search results should be throwing a validation exception for use of non-existant searchable attribute");
158         } catch (WorkflowServiceErrorException e) {}
159 
160         criteria = null;
161         criteria = DocumentLookupCriteria.Builder.create();
162         criteria.setDocumentTypeName(documentTypeName);
163         addSearchableAttribute(criteria, TestXMLSearchableAttributeLong.SEARCH_STORAGE_KEY, TestXMLSearchableAttributeLong.SEARCH_STORAGE_VALUE.toString());
164         results = docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
165         assertEquals("Search results should have one document.", 1, results.getLookupResults().size());
166 
167         criteria2 = null;
168         criteria2 = DocumentLookupCriteria.Builder.create();
169         criteria2.setDocumentTypeName(documentTypeName);
170         addSearchableAttribute(criteria2, TestXMLSearchableAttributeLong.SEARCH_STORAGE_KEY, "1111111");
171         results2 = docSearchService.lookupDocuments(user.getPrincipalId(), criteria2.build());
172         assertEquals("Search results should be empty.", 0, results2.getLookupResults().size());
173 
174         criteria3 = null;
175         criteria3 = DocumentLookupCriteria.Builder.create();
176         criteria3.setDocumentTypeName(documentTypeName);
177         addSearchableAttribute(criteria3, "fakeymcfakefake", "99999999");
178         try {
179             docSearchService.lookupDocuments(user.getPrincipalId(), criteria3.build());
180             fail("Search results should be throwing a validation exception for use of non-existant searchable attribute");
181         } catch (WorkflowServiceErrorException e) {}
182 
183         criteria = null;
184         criteria = DocumentLookupCriteria.Builder.create();
185         criteria.setDocumentTypeName(documentTypeName);
186         addSearchableAttribute(criteria, TestXMLSearchableAttributeFloat.SEARCH_STORAGE_KEY,
187                 TestXMLSearchableAttributeFloat.SEARCH_STORAGE_VALUE.toString());
188         results = docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
189         assertEquals("Search results should have one document.", 1, results.getLookupResults().size());
190 
191         criteria2 = null;
192         criteria2 = DocumentLookupCriteria.Builder.create();
193         criteria2.setDocumentTypeName(documentTypeName);
194         addSearchableAttribute(criteria2, TestXMLSearchableAttributeFloat.SEARCH_STORAGE_KEY, "215.3548");
195         results2 = docSearchService.lookupDocuments(user.getPrincipalId(), criteria2.build());
196         assertEquals("Search results should be empty.", 0, results2.getLookupResults().size());
197 
198         criteria3 = null;
199         criteria3 = DocumentLookupCriteria.Builder.create();
200         criteria3.setDocumentTypeName(documentTypeName);
201         addSearchableAttribute(criteria3, "fakeylostington", "9999.9999");
202         try {
203             docSearchService.lookupDocuments(user.getPrincipalId(), criteria3.build());
204             fail("Search results should be throwing a validation exception for use of non-existant searchable attribute");
205         } catch (WorkflowServiceErrorException e) {}
206 
207         criteria = null;
208         criteria = DocumentLookupCriteria.Builder.create();
209         criteria.setDocumentTypeName(documentTypeName);
210         addSearchableAttribute(criteria, TestXMLSearchableAttributeDateTime.SEARCH_STORAGE_KEY,
211                 DocumentLookupInternalUtils.getDisplayValueWithDateOnly(new Timestamp(
212                         TestXMLSearchableAttributeDateTime.SEARCH_STORAGE_VALUE_IN_MILLS)));
213         results = docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
214         assertEquals("Search results should have one document.", 1, results.getLookupResults().size());
215 
216         criteria2 = null;
217         criteria2 = DocumentLookupCriteria.Builder.create();
218         criteria2.setDocumentTypeName(documentTypeName);
219         addSearchableAttribute(criteria2, TestXMLSearchableAttributeDateTime.SEARCH_STORAGE_KEY, "07/06/1979");
220         results2 = docSearchService.lookupDocuments(user.getPrincipalId(), criteria2.build());
221         assertEquals("Search results should be empty.", 0, results2.getLookupResults().size());
222 
223         criteria3 = null;
224         criteria3 = DocumentLookupCriteria.Builder.create();
225         criteria3.setDocumentTypeName(documentTypeName);
226         addSearchableAttribute(criteria3, "lastingsfakerson", "07/06/2007");
227         try {
228             docSearchService.lookupDocuments(user.getPrincipalId(), criteria3.build());
229             fail("Search results should be throwing a validation exception for use of non-existant searchable attribute");
230         } catch (WorkflowServiceErrorException e) {}
231     }
232 
233     @Test public void testRouteDocumentWithSearchableAttribute() throws Exception {
234     	String documentTypeName = "SearchDocType";
235     	String key = "givenname";
236     	DocumentType docType = ((DocumentTypeService)KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_TYPE_SERVICE)).findByName(documentTypeName);
237         WorkflowDocument workflowDocument = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("rkirkend"), documentTypeName);
238         WorkflowAttributeDefinition.Builder givennameXMLDef = WorkflowAttributeDefinition.Builder.create("XMLSearchableAttribute");
239 
240         workflowDocument.setApplicationContent("<test></test>");
241 
242         givennameXMLDef.addPropertyDefinition(key, "jack");
243         workflowDocument.addSearchableDefinition(givennameXMLDef.build());
244 
245         workflowDocument.setTitle("Routing style");
246         workflowDocument.route("routing this document.");
247 
248         DocumentSearchService docSearchService = (DocumentSearchService) KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_SEARCH_SERVICE);
249 
250         Person user = KimApiServiceLocator.getPersonService().getPersonByPrincipalName("rkirkend");
251         DocumentLookupCriteria.Builder criteria = DocumentLookupCriteria.Builder.create();
252         criteria.setDocumentTypeName(documentTypeName);
253         addSearchableAttribute(criteria, key, "jack");
254         DocumentLookupResults results = docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
255 
256         assertEquals("Search results should have one document.", 1, results.getLookupResults().size());
257 
258         criteria = null;
259         criteria = DocumentLookupCriteria.Builder.create();
260         criteria.setDocumentTypeName(documentTypeName);
261         addSearchableAttribute(criteria, key, "fred");
262         results = docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
263 
264         assertEquals("Search results should be empty.", 0, results.getLookupResults().size());
265 
266         criteria = null;
267         criteria = DocumentLookupCriteria.Builder.create();
268         criteria.setDocumentTypeName(documentTypeName);
269         addSearchableAttribute(criteria, "fakeproperty", "doesntexist");
270         try {
271             docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
272             fail("Search results should be throwing a validation exception for use of non-existant searchable attribute");
273         } catch (WorkflowServiceErrorException wsee) {}
274     }
275 
276     @Test public void testDocumentSearchAttributeWildcarding() throws Exception {
277         DocumentSearchService docSearchService = (DocumentSearchService) KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_SEARCH_SERVICE);
278 
279     	String documentTypeName = "SearchDocType";
280     	String key = "givenname";
281     	DocumentType docType = ((DocumentTypeService)KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_TYPE_SERVICE)).findByName(documentTypeName);
282         WorkflowDocument workflowDocument = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("rkirkend"), documentTypeName);
283         WorkflowAttributeDefinition.Builder givennameXMLDef = WorkflowAttributeDefinition.Builder.create("XMLSearchableAttribute");
284 
285         workflowDocument.setApplicationContent("<test></test>");
286 
287         givennameXMLDef.addPropertyDefinition(key, "jack");
288         workflowDocument.addSearchableDefinition(givennameXMLDef.build());
289 
290         workflowDocument.setTitle("Routing style");
291         workflowDocument.route("routing this document.");
292 
293         Person user = KimApiServiceLocator.getPersonService().getPersonByPrincipalName("rkirkend");
294         DocumentLookupCriteria.Builder criteria = DocumentLookupCriteria.Builder.create();
295         criteria.setDocumentTypeName(documentTypeName);
296         addSearchableAttribute(criteria, key, "jack");
297         DocumentLookupResults results = docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
298 
299         assertEquals("Search results should have one document.", 1, results.getLookupResults().size());
300 
301         criteria = DocumentLookupCriteria.Builder.create();
302         criteria.setDocumentTypeName(documentTypeName);
303         addSearchableAttribute(criteria, key, "ja*");
304         results = docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
305 
306         assertEquals("Search results should have one document.", 1, results.getLookupResults().size());
307 
308         criteria = DocumentLookupCriteria.Builder.create();
309         criteria.setDocumentTypeName(documentTypeName);
310         addSearchableAttribute(criteria, key, "ja");
311         results = docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
312 
313         assertEquals("Search results should have one document.", 0, results.getLookupResults().size());
314 
315         criteria = DocumentLookupCriteria.Builder.create();
316         criteria.setDocumentTypeName(documentTypeName);
317         addSearchableAttribute(criteria, key, "*ack");
318         results = docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
319 
320         assertEquals("Search results should have one document.", 1, results.getLookupResults().size());
321     }
322 
323     @Test public void testDocumentSearchAttributeWildcardingDisallow() throws Exception {
324         DocumentSearchService docSearchService = (DocumentSearchService) KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_SEARCH_SERVICE);
325 
326         String documentTypeName = "SearchDocTypeStandardSearchDataType";
327     	DocumentType docType = ((DocumentTypeService)KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_TYPE_SERVICE)).findByName(documentTypeName);
328         String userNetworkId = "rkirkend";
329         WorkflowDocument workflowDocument = WorkflowDocumentFactory.createDocument(getPrincipalIdForName(userNetworkId), documentTypeName);
330 
331         /*
332          *   Below we are using the keys and values from the custom searchable attribute classes' static constants but
333          *   this is only for convenience as those should always be valid values to test for.
334          */
335         WorkflowAttributeDefinition.Builder longXMLDef = WorkflowAttributeDefinition.Builder.create("XMLSearchableAttributeStdLong");
336         longXMLDef.addPropertyDefinition(TestXMLSearchableAttributeLong.SEARCH_STORAGE_KEY, TestXMLSearchableAttributeLong.SEARCH_STORAGE_VALUE.toString());
337         workflowDocument.addSearchableDefinition(longXMLDef.build());
338         workflowDocument.setTitle("Routing style");
339         workflowDocument.route("routing this document.");
340 
341         Person user = KimApiServiceLocator.getPersonService().getPersonByPrincipalName(userNetworkId);
342 
343         String validSearchValue = TestXMLSearchableAttributeLong.SEARCH_STORAGE_VALUE.toString();
344         DocumentLookupCriteria.Builder criteria = null;
345         DocumentLookupResults results = null;
346         criteria = DocumentLookupCriteria.Builder.create();
347         criteria.setDocumentTypeName(documentTypeName);
348         addSearchableAttribute(criteria, TestXMLSearchableAttributeLong.SEARCH_STORAGE_KEY, validSearchValue);
349         results = docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
350         assertEquals("Search results should have one document.", 1, results.getLookupResults().size());
351 
352         criteria = DocumentLookupCriteria.Builder.create();
353         criteria.setDocumentTypeName(documentTypeName);
354         addSearchableAttribute(criteria, TestXMLSearchableAttributeLong.SEARCH_STORAGE_KEY,
355                 "*" + validSearchValue.substring(2));
356 
357         if ((new SearchableAttributeLongValue()).allowsWildcards()) {
358             results = docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
359             assertEquals("Search results should be empty using wildcard '*' value.", 0, results.getLookupResults().size());
360         } else {
361             try {
362                 docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
363                 fail("Search results should be throwing a validation exception for use of the character '*' without allowing wildcards");
364             } catch (WorkflowServiceErrorException wsee) {}
365         }
366 
367         criteria = DocumentLookupCriteria.Builder.create();
368         criteria.setDocumentTypeName(documentTypeName);
369         addSearchableAttribute(criteria, TestXMLSearchableAttributeLong.SEARCH_STORAGE_KEY, validSearchValue.substring(
370                 0, (validSearchValue.length() - 2)));
371         results = docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
372         assertEquals("Search results should be empty trying to use assumed ending wildcard.", 0, results.getLookupResults().size());
373     }
374 
375     @Test public void testDocumentSearchAttributeCaseSensitivity() throws Exception {
376         DocumentSearchService docSearchService = (DocumentSearchService) KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_SEARCH_SERVICE);
377     	String documentTypeName = "SearchDocTypeCaseSensitivity";
378     	String networkId = "rkirkend";
379     	DocumentType docType = ((DocumentTypeService)KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_TYPE_SERVICE)).findByName(documentTypeName);
380 
381     	String key = "givenname";
382     	WorkflowDocument workflowDocument = WorkflowDocumentFactory.createDocument(getPrincipalIdForName(networkId), documentTypeName);
383         WorkflowAttributeDefinition.Builder givennameXMLDef = WorkflowAttributeDefinition.Builder.create("XMLSearchableAttribute");
384         givennameXMLDef.addPropertyDefinition(key, "jack");
385         workflowDocument.addSearchableDefinition(givennameXMLDef.build());
386         workflowDocument.setTitle("Routing style");
387         workflowDocument.route("routing this document.");
388 
389         Person user = KimApiServiceLocator.getPersonService().getPersonByPrincipalName(networkId);
390         DocumentLookupCriteria.Builder criteria = DocumentLookupCriteria.Builder.create();
391         criteria.setDocumentTypeName(documentTypeName);
392         addSearchableAttribute(criteria, key, "jack");
393         DocumentLookupResults results = docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
394         assertEquals("Search results should have one document.", 1, results.getLookupResults().size());
395 
396         criteria = DocumentLookupCriteria.Builder.create();
397         criteria.setDocumentTypeName(documentTypeName);
398         addSearchableAttribute(criteria, key, "JACK");
399         results =  docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
400         assertEquals("Search results should have one document.", 1, results.getLookupResults().size());
401 
402         criteria = DocumentLookupCriteria.Builder.create();
403         criteria.setDocumentTypeName(documentTypeName);
404         addSearchableAttribute(criteria, key, "jAck");
405         results =  docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
406         assertEquals("Search results should have one document.", 1, results.getLookupResults().size());
407 
408         criteria = DocumentLookupCriteria.Builder.create();
409         criteria.setDocumentTypeName(documentTypeName);
410         addSearchableAttribute(criteria, key, "jacK");
411         results =  docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
412         assertEquals("Search results should have one document.", 1, results.getLookupResults().size());
413 
414     	key = "givenname_nocase";
415         workflowDocument = WorkflowDocumentFactory.createDocument(getPrincipalIdForName(networkId), documentTypeName);
416         WorkflowAttributeDefinition.Builder givenname_nocaseXMLDef = WorkflowAttributeDefinition.Builder.create("XMLSearchableAttribute_CaseInsensitive");
417         givenname_nocaseXMLDef.addPropertyDefinition(key, "jaCk");
418         workflowDocument.addSearchableDefinition(givenname_nocaseXMLDef.build());
419         workflowDocument.setTitle("Routing style");
420         workflowDocument.route("routing this document.");
421 
422         criteria = DocumentLookupCriteria.Builder.create();
423         criteria.setDocumentTypeName(documentTypeName);
424         addSearchableAttribute(criteria, key, "jack");
425         results =  docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
426         assertEquals("Search results should have one document.", 1, results.getLookupResults().size());
427 
428         criteria = DocumentLookupCriteria.Builder.create();
429         criteria.setDocumentTypeName(documentTypeName);
430         addSearchableAttribute(criteria, key, "JACK");
431         results =  docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
432         assertEquals("Search results should have one document.", 1, results.getLookupResults().size());
433 
434         criteria = DocumentLookupCriteria.Builder.create();
435         criteria.setDocumentTypeName(documentTypeName);
436         addSearchableAttribute(criteria, key, "jaCk");
437         results =  docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
438         assertEquals("Search results should have one document.", 1, results.getLookupResults().size());
439 
440         criteria = DocumentLookupCriteria.Builder.create();
441         criteria.setDocumentTypeName(documentTypeName);
442         addSearchableAttribute(criteria, key, "jacK");
443         results =  docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
444         assertEquals("Search results should have one document.", 1, results.getLookupResults().size());
445 
446         criteria = DocumentLookupCriteria.Builder.create();
447         criteria.setDocumentTypeName(documentTypeName);
448         addSearchableAttribute(criteria, key, "jAc");
449         results =  docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
450         assertEquals("Search results should have one document.", 0, results.getLookupResults().size());
451 
452         criteria = DocumentLookupCriteria.Builder.create();
453         criteria.setDocumentTypeName(documentTypeName);
454         addSearchableAttribute(criteria, key, "jA*");
455         results =  docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
456         assertEquals("Search results should have one document.", 1, results.getLookupResults().size());
457 
458         criteria = DocumentLookupCriteria.Builder.create();
459         criteria.setDocumentTypeName(documentTypeName);
460         addSearchableAttribute(criteria, key, "*aCk");
461         results =  docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
462         assertEquals("Search results should have one document.", 1, results.getLookupResults().size());
463     }
464 
465     /**
466      * Tests searching with client-generated documentContent which is just malformed XML.
467      * @throws WorkflowException
468      */
469     @Test public void testRouteDocumentWithMalformedSearchableAttributeContent() throws WorkflowException {
470         WorkflowDocument workflowDocument = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("rkirkend"), "SearchDocType");
471 
472         workflowDocument.setApplicationContent("hey, <I'm Not ] Even & XML");
473 
474         workflowDocument.setTitle("Routing style");
475         try {
476             workflowDocument.route("routing this document.");
477             fail("routeDocument succeeded with malformed XML");
478         } catch (Exception we) {
479             // An exception is thrown in DTOConverter/XmlUtils.appendXml at the time of this writing
480             // so I will just assume that is the expected behavior
481         }
482         TestUtilities.waitForExceptionRouting();
483     }
484 
485     /**
486      * Tests searching with client-generated documentContent which will not match what the SearchableAttributeOld
487      * is configured to look for.  This should pass with zero search results, but should not throw an exception.
488      * @throws Exception
489      */
490     @Test public void testRouteDocumentWithInvalidSearchableAttributeContent() throws Exception {
491     	String documentTypeName = "SearchDocType";
492     	String key = "givenname";
493     	DocumentType docType = ((DocumentTypeService)KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_TYPE_SERVICE)).findByName(documentTypeName);
494         WorkflowDocument workflowDocument = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("rkirkend"), documentTypeName);
495 
496         workflowDocument.setApplicationContent("<documentContent><searchableContent><garbage>" +
497                                                "<blah>not going to match anything</blah>" +
498                                                "</garbage></searchableContent></documentContent>");
499 
500         workflowDocument.setTitle("Routing style");
501         workflowDocument.route("routing this document.");
502 
503         DocumentSearchService docSearchService = (DocumentSearchService) KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_SEARCH_SERVICE);
504 
505         Person user = KimApiServiceLocator.getPersonService().getPersonByPrincipalName("rkirkend");
506         DocumentLookupCriteria.Builder criteria = DocumentLookupCriteria.Builder.create();
507         criteria.setDocumentTypeName(documentTypeName);
508         addSearchableAttribute(criteria, key, "jack");
509         DocumentLookupResults results =  docSearchService.lookupDocuments(user.getPrincipalId(),
510                 criteria.build());
511 
512         assertEquals("Search results should be empty.", 0, results.getLookupResults().size());
513 
514         criteria = DocumentLookupCriteria.Builder.create();
515         criteria.setDocumentTypeName(documentTypeName);
516         addSearchableAttribute(criteria, key, "fred");
517         results =  docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
518 
519         assertEquals("Search results should be empty.", 0, results.getLookupResults().size());
520 
521         criteria = DocumentLookupCriteria.Builder.create();
522         criteria.setDocumentTypeName(documentTypeName);
523         addSearchableAttribute(criteria, "fakeproperty", "doesntexist");
524         try {
525             results = docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
526             fail("Search results should be throwing a validation exception for use of non-existant searchable attribute");
527         } catch (WorkflowServiceErrorException wsee) {}
528     }
529 
530     /**
531      * Tests searching with client-generated documentContent which will not match what the SearchableAttributeOld
532      * is configured to look for.  This should pass with zero search results, but should not throw an exception.
533      * @throws Exception
534      */
535     @Test public void testRouteDocumentWithMoreInvalidSearchableAttributeContent() throws Exception {
536     	String documentTypeName = "SearchDocType";
537     	String key = "givenname";
538     	DocumentType docType = ((DocumentTypeService)KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_TYPE_SERVICE)).findByName(documentTypeName);
539         WorkflowDocument workflowDocument = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("rkirkend"), documentTypeName);
540 
541         workflowDocument.setApplicationContent("<documentContent><NOTsearchableContent><garbage>" +
542                                                "<blah>not going to match anything</blah>" +
543                                                "</garbage></NOTsearchableContent></documentContent>");
544 
545         workflowDocument.setTitle("Routing style");
546         workflowDocument.route("routing this document.");
547 
548         DocumentSearchService docSearchService = (DocumentSearchService) KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_SEARCH_SERVICE);
549 
550         Person user = KimApiServiceLocator.getPersonService().getPersonByPrincipalName("rkirkend");
551         DocumentLookupCriteria.Builder criteria = DocumentLookupCriteria.Builder.create();
552         criteria.setDocumentTypeName(documentTypeName);
553         addSearchableAttribute(criteria, key, "jack");
554         DocumentLookupResults results =  docSearchService.lookupDocuments(user.getPrincipalId(),
555                 criteria.build());
556 
557         assertEquals("Search results should be empty.", 0, results.getLookupResults().size());
558 
559         criteria = DocumentLookupCriteria.Builder.create();
560         criteria.setDocumentTypeName(documentTypeName);
561         addSearchableAttribute(criteria, key, "fred");
562         results =  docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
563 
564         assertEquals("Search results should be empty.", 0, results.getLookupResults().size());
565 
566         criteria = DocumentLookupCriteria.Builder.create();
567         criteria.setDocumentTypeName(documentTypeName);
568         addSearchableAttribute(criteria, "fakeproperty", "doesntexist");
569         try {
570             results =  docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
571             fail("Search results should be throwing a validation exception for use of non-existant searchable attribute");
572         } catch (WorkflowServiceErrorException wsee) {}
573     }
574 
575     /*
576      * Test method for 'org.kuali.rice.kew.docsearch.xml.StandardGenericXMLSearchableAttribute.getSearchContent()'
577      */
578     /*
579 
580     TODO - Rice 2.0 - need to resurrect and rewrite this test
581 
582     @Test public void testGetSearchContent() throws Exception {
583         StandardGenericXMLSearchableAttribute attribute = getAttribute("XMLSearchableAttribute");
584         String keyName = "givenname";
585         String value = "jack";
586         Map paramMap = new HashMap();
587         paramMap.put(keyName, value);
588         attribute.setParamMap(paramMap);
589         //Filling in a random document type name... Revisit
590         String documentTypeName = "SearchDocType";
591         DocumentSearchContext context = DocSearchUtils.getDocumentSearchContext("", documentTypeName, "");
592         String searchContent = attribute.getSearchContent(context);
593         assertTrue("searchContent was not found.", searchContent != null && searchContent.length() > 0);
594         XPath xpath = XPathFactory.newInstance().newXPath();
595         Element foundDocContent = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(new BufferedReader(new StringReader(searchContent)))).getDocumentElement();
596         String findStuff = "//putWhateverWordsIwantInsideThisTag/" + keyName + "/value";
597         assertTrue("Search content does not contain correct value for field '" + keyName + "'.", value.equals(xpath.evaluate(findStuff, foundDocContent, XPathConstants.STRING)));
598 
599         attribute = getAttribute("XMLSearchableAttributeStdLong");
600         keyName = "testLongKey";
601         value = "123458";
602         paramMap = new HashMap();
603         paramMap.put(keyName, value);
604         attribute.setParamMap(paramMap);
605         searchContent = attribute.getSearchContent(context);
606         assertTrue("searchContent was not found.", searchContent != null && searchContent.length() > 0);
607         xpath = XPathFactory.newInstance().newXPath();
608         foundDocContent = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(new BufferedReader(new StringReader(searchContent)))).getDocumentElement();
609         findStuff = "//putWhateverWordsIwantInsideThisTag/" + keyName + "/value";
610         assertTrue("Search content does not contain correct value for field '" + keyName + "'.", value.equals(xpath.evaluate(findStuff, foundDocContent, XPathConstants.STRING)));
611 
612         attribute = getAttribute("XMLSearchableAttributeStdFloat");
613         keyName = "testFloatKey";
614         value = "2568.204";
615         paramMap = new HashMap();
616         paramMap.put(keyName, value);
617         attribute.setParamMap(paramMap);
618         searchContent = attribute.getSearchContent(context);
619         assertTrue("searchContent was not found.", searchContent != null && searchContent.length() > 0);
620         xpath = XPathFactory.newInstance().newXPath();
621         foundDocContent = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(new BufferedReader(new StringReader(searchContent)))).getDocumentElement();
622         findStuff = "//putWhateverWordsIwantInsideThisTag/" + keyName + "/value";
623         assertTrue("Search content does not contain correct value for field '" + keyName + "'.", value.equals(xpath.evaluate(findStuff, foundDocContent, XPathConstants.STRING)));
624 
625         attribute = getAttribute("XMLSearchableAttributeStdCurrency");
626         keyName = "testCurrencyKey";
627         value = "2248.20";
628         paramMap = new HashMap();
629         paramMap.put(keyName, value);
630         attribute.setParamMap(paramMap);
631         searchContent = attribute.getSearchContent(context);
632         assertTrue("searchContent was not found.", searchContent != null && searchContent.length() > 0);
633         xpath = XPathFactory.newInstance().newXPath();
634         foundDocContent = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(new BufferedReader(new StringReader(searchContent)))).getDocumentElement();
635         findStuff = "//putWhateverWordsIwantInsideThisTag/" + keyName + "/value";
636         assertTrue("Search content does not contain correct value for field '" + keyName + "'.", value.equals(xpath.evaluate(findStuff, foundDocContent, XPathConstants.STRING)));
637 
638         attribute = getAttribute("XMLSearchableAttributeStdDateTime");
639         keyName = "testDateTimeKey";
640         value = DocSearchUtils.getDisplayValueWithDateOnly(TestXMLSearchableAttributeDateTime.SEARCH_STORAGE_VALUE);
641         paramMap = new HashMap();
642         paramMap.put(keyName, value);
643         attribute.setParamMap(paramMap);
644         searchContent = attribute.getSearchContent(context);
645         assertTrue("searchContent was not found.", searchContent != null && searchContent.length() > 0);
646         xpath = XPathFactory.newInstance().newXPath();
647         foundDocContent = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(new BufferedReader(new StringReader(searchContent)))).getDocumentElement();
648         findStuff = "//putWhateverWordsIwantInsideThisTag/" + keyName + "/value";
649         assertTrue("Search content does not contain correct value for field '" + keyName + "'.", value.equals(xpath.evaluate(findStuff, foundDocContent, XPathConstants.STRING)));
650     }
651     */
652 
653     /*
654      * Test method for 'org.kuali.rice.kew.docsearch.xml.StandardGenericXMLSearchableAttribute.getSearchStorageValues(String)'
655      */
656     /*
657 
658     TODO - Rice 2.0 - need to resurrect and rewrite this test
659 
660     @Test public void testGetSearchStorageValues() {
661     	String attributeName = "XMLSearchableAttribute";
662     	String keyName = "givenname";
663     	String value = "jack";
664     	String documentcontent = "<documentContent>" + "<searchableContent>" + "<putWhateverWordsIwantInsideThisTag>" + "<" + keyName + ">" + "<value>" + value + "</value>" + "</" + keyName + ">" + "</putWhateverWordsIwantInsideThisTag>" + "</searchableContent>" + "</documentContent>";
665         StandardGenericXMLSearchableAttribute attribute = getAttribute(attributeName);
666         //Filling in a random document type name... Revisit
667         String documentTypeName = "SearchDocType";
668         DocumentSearchContext context = DocSearchUtils.getDocumentSearchContext("", documentTypeName, documentcontent);
669         List values = attribute.getSearchStorageValues(context);
670         assertEquals("Number of search attribute values is wrong",1,values.size());
671         for (Iterator iter = values.iterator(); iter.hasNext();) {
672             SearchableAttributeValue searchAttValue = (SearchableAttributeValue) iter.next();
673             assertEquals("Key of attribute is wrong",keyName,searchAttValue.getSearchableAttributeKey());
674             assertEquals("Value of attribute is wrong",value,searchAttValue.getSearchableAttributeDisplayValue());
675         }
676 
677         // test general operation
678         attributeName = "XMLSearchableAttributeStdLong";
679         keyName = "testLongKey";
680         value = "123458";
681         documentcontent = "<documentContent>" + "<searchableContent>" + "<putWhateverWordsIwantInsideThisTag>" + "<" + keyName + ">" + "<value>" + value + "</value>" + "</" + keyName + ">" + "</putWhateverWordsIwantInsideThisTag>" + "</searchableContent>" + "</documentContent>";
682         context = DocSearchUtils.getDocumentSearchContext("", documentTypeName, documentcontent);
683         attribute = getAttribute(attributeName);
684         values = attribute.getSearchStorageValues(context);
685         assertEquals("Number of search attribute values is wrong",1,values.size());
686         for (Iterator iter = values.iterator(); iter.hasNext();) {
687             SearchableAttributeValue searchAttValue = (SearchableAttributeValue) iter.next();
688             assertEquals("Key of attribute is wrong",keyName,searchAttValue.getSearchableAttributeKey());
689             assertEquals("Value of attribute is wrong",value,searchAttValue.getSearchableAttributeDisplayValue());
690         }
691 
692         // test operation with leading and trailing spaces in xml doc content
693         attributeName = "XMLSearchableAttributeStdLong";
694         keyName = "testLongKey";
695         value = "123458";
696         documentcontent = "<documentContent>" + "<searchableContent>" + "<putWhateverWordsIwantInsideThisTag>" + "<" + keyName + ">" + "<value>" + " " + value + " " + "</value>" + "</" + keyName + ">" + "</putWhateverWordsIwantInsideThisTag>" + "</searchableContent>" + "</documentContent>";
697         context = DocSearchUtils.getDocumentSearchContext("", documentTypeName, documentcontent);
698         attribute = getAttribute(attributeName);
699         values = attribute.getSearchStorageValues(context);
700         assertEquals("Number of search attribute values is wrong",1,values.size());
701         for (Iterator iter = values.iterator(); iter.hasNext();) {
702             SearchableAttributeValue searchAttValue = (SearchableAttributeValue) iter.next();
703             assertEquals("Key of attribute is wrong",keyName,searchAttValue.getSearchableAttributeKey());
704             assertEquals("Value of attribute is wrong",value,searchAttValue.getSearchableAttributeDisplayValue());
705         }
706 
707         attributeName = "XMLSearchableAttributeStdFloat";
708         keyName = "testFloatKey";
709         value = "2568.204154796";
710         documentcontent = "<documentContent>" + "<searchableContent>" + "<putWhateverWordsIwantInsideThisTag>" + "<" + keyName + ">" + "<value>" + value + "</value>" + "</" + keyName + ">" + "</putWhateverWordsIwantInsideThisTag>" + "</searchableContent>" + "</documentContent>";
711         context = DocSearchUtils.getDocumentSearchContext("", documentTypeName, documentcontent);
712         attribute = getAttribute(attributeName);
713         values = attribute.getSearchStorageValues(context);
714         assertEquals("Number of search attribute values is wrong",1,values.size());
715         for (Iterator iter = values.iterator(); iter.hasNext();) {
716             SearchableAttributeValue searchAttValue = (SearchableAttributeValue) iter.next();
717             assertEquals("Key of attribute is wrong",keyName,searchAttValue.getSearchableAttributeKey());
718             assertEquals("Value of attribute is wrong",insertCommasIfNeeded(value, 3),searchAttValue.getSearchableAttributeDisplayValue());
719         }
720 
721     	attributeName = "XMLSearchableAttributeStdDateTime";
722         keyName = "testDateTimeKey";
723         value = DocSearchUtils.getDisplayValueWithDateOnly(TestXMLSearchableAttributeDateTime.SEARCH_STORAGE_VALUE);
724         documentcontent = "<documentContent>" + "<searchableContent>" + "<putWhateverWordsIwantInsideThisTag>" + "<" + keyName + ">" + "<value>" + value + "</value>" + "</" + keyName + ">" + "</putWhateverWordsIwantInsideThisTag>" + "</searchableContent>" + "</documentContent>";
725         context = DocSearchUtils.getDocumentSearchContext("", documentTypeName, documentcontent);
726         attribute = getAttribute(attributeName);
727         values = attribute.getSearchStorageValues(context);
728         assertEquals("Number of search attribute values is wrong",1,values.size());
729         for (Iterator iter = values.iterator(); iter.hasNext();) {
730             SearchableAttributeValue searchAttValue = (SearchableAttributeValue) iter.next();
731             assertEquals("Key of attribute is wrong",keyName,searchAttValue.getSearchableAttributeKey());
732             assertEquals("Value of attribute is wrong",value,searchAttValue.getSearchableAttributeDisplayValue());
733         }
734 
735         // test for kuali xstream formatted dates
736         value = "02/20/2007";
737         String returnValue = "02/20/2007";
738         documentcontent = "<documentContent>" + "<searchableContent>" + "<putWhateverWordsIwantInsideThisTag>" + "<" + keyName + ">" + "<value>" + value + "</value>" + "</" + keyName + ">" + "</putWhateverWordsIwantInsideThisTag>" + "</searchableContent>" + "</documentContent>";
739         context = DocSearchUtils.getDocumentSearchContext("", documentTypeName, documentcontent);
740         attribute = getAttribute(attributeName);
741         values = attribute.getSearchStorageValues(context);
742         assertEquals("Number of search attribute values is wrong",1,values.size());
743         for (Iterator iter = values.iterator(); iter.hasNext();) {
744             SearchableAttributeValue searchAttValue = (SearchableAttributeValue) iter.next();
745             assertEquals("Key of attribute is wrong",keyName,searchAttValue.getSearchableAttributeKey());
746             assertEquals("Value of attribute is wrong",returnValue,searchAttValue.getSearchableAttributeDisplayValue());
747         }
748     }
749 
750     */
751 
752     private String insertCommasIfNeeded(String value, int interval) {
753         int indexOfDecimal = value.indexOf(".");
754         String decimalPointOn = value.substring(indexOfDecimal);
755         String temp = value.substring(0, indexOfDecimal);
756         StringBuffer builtValue = new StringBuffer();
757         if (temp.length() <= interval) {
758             builtValue.append(temp);
759         } else {
760             int counter = 0;
761             for (int i = temp.length() - 1; (i >= 0); i--) {
762                 if (counter == interval) {
763                     builtValue.insert(0, ",");
764                     counter = 0;
765                 }
766                 counter++;
767                 builtValue.insert(0, temp.substring(i, i+1));
768             }
769         }
770         return (builtValue.append(decimalPointOn)).toString();
771     }
772 
773     /*
774      * Test method for 'org.kuali.rice.kew.docsearch.xml.StandardGenericXMLSearchableAttribute.getSearchingRows()'
775      */
776     /*
777 
778     TODO - Rice 2.0 - need to resurrect and rewrite this test
779 
780     @Test public void testGetSearchingRows() {
781         StandardGenericXMLSearchableAttribute searchAttribute = getAttribute(null);
782         //Filling in a random document type name... Revisit
783         String documentTypeName = "SearchDocType";
784         DocumentSearchContext context = DocSearchUtils.getDocumentSearchContext("", documentTypeName, "");
785         assertTrue("Invalid number of search rows", searchAttribute.getSearchingRows(context).size() == 1);
786 
787         //we really just want this to load without exploding
788         List searchRows = getAttribute("BlankDropDownSearchAttribute").getSearchingRows(context);
789         assertEquals("Invalid number of search rows", 1, searchRows.size());
790         Row row = (Row) searchRows.get(0);
791         Field field = row.getField(0);
792         assertEquals("Should be 5 valid values", 5, field.getFieldValidValues().size());
793 
794         assertEquals("Default value is not correct", "AMST", field.getPropertyValue());
795     }
796     */
797 
798     /*
799      * Test method for 'org.kuali.rice.kew.docsearch.xml.StandardGenericXMLSearchableAttribute.validateUserSearchInputs(Map)'
800      */
801     /*
802 
803     TODO - Rice 2.0 - need to resurrect and rewrite this test
804 
805     @Test  public void testValidateUserSearchInputs() {
806         StandardGenericXMLSearchableAttribute searchAttribute = getAttribute("XMLSearchableAttribute");
807         Map paramMap = new HashMap();
808         paramMap.put(TestXMLSearchableAttributeString.SEARCH_STORAGE_KEY, "jack");
809         String documentTypeName = "SearchDocType";
810         //TODO: put document content here?
811         DocumentSearchContext context = DocSearchUtils.getDocumentSearchContext("", documentTypeName, "");
812         List validationErrors = searchAttribute.validateUserSearchInputs(paramMap, context);
813         assertEquals("Validation should not have returned an error.", 0, validationErrors.size());
814         paramMap.clear();
815         paramMap.put(TestXMLSearchableAttributeString.SEARCH_STORAGE_KEY, "jack.jack");
816         validationErrors = searchAttribute.validateUserSearchInputs(paramMap, context);
817         assertEquals("Validation should return a single error message.", 1, validationErrors.size());
818         WorkflowAttributeValidationError error = (WorkflowAttributeValidationError) validationErrors.get(0);
819         assertEquals("Validation error should match xml attribute message", "Invalid first name", error.getMessage());
820         paramMap.clear();
821         paramMap.put(TestXMLSearchableAttributeString.SEARCH_STORAGE_KEY, "jack*jack");
822         validationErrors = searchAttribute.validateUserSearchInputs(paramMap, context);
823         assertEquals("Validation should return a single error message.", 0, validationErrors.size());
824 
825         searchAttribute = getAttribute("XMLSearchableAttributeStdLong");
826         paramMap = new HashMap();
827         paramMap.put(TestXMLSearchableAttributeLong.SEARCH_STORAGE_KEY, TestXMLSearchableAttributeLong.SEARCH_STORAGE_VALUE.toString());
828         validationErrors = searchAttribute.validateUserSearchInputs(paramMap, context);
829         assertEquals("Validation should not have returned an error.", 0, validationErrors.size());
830         paramMap.clear();
831         paramMap.put(TestXMLSearchableAttributeLong.SEARCH_STORAGE_KEY, TestXMLSearchableAttributeLong.SEARCH_STORAGE_VALUE.toString() + ".33");
832         validationErrors = searchAttribute.validateUserSearchInputs(paramMap, context);
833         assertEquals("Validation should return a single error message.", 1, validationErrors.size());
834         error = (WorkflowAttributeValidationError) validationErrors.get(0);
835         assertTrue("Validation error is incorrect", error.getMessage().endsWith("does not conform to standard validation for field type."));
836         paramMap.clear();
837         paramMap.put(TestXMLSearchableAttributeLong.SEARCH_STORAGE_KEY, "jack*jack");
838         validationErrors = searchAttribute.validateUserSearchInputs(paramMap, context);
839         assertEquals("Validation should return a single error message.", 1, validationErrors.size());
840         error = (WorkflowAttributeValidationError) validationErrors.get(0);
841         assertTrue("Validation error is incorrect", error.getMessage().endsWith("does not conform to standard validation for field type."));
842 
843         searchAttribute = getAttribute("XMLSearchableAttributeStdFloat");
844         paramMap = new HashMap();
845         paramMap.put(TestXMLSearchableAttributeFloat.SEARCH_STORAGE_KEY, TestXMLSearchableAttributeFloat.SEARCH_STORAGE_VALUE.toString());
846         validationErrors = searchAttribute.validateUserSearchInputs(paramMap, context);
847         assertEquals("Validation should not have returned an error.", 0, validationErrors.size());
848         paramMap.clear();
849         paramMap.put(TestXMLSearchableAttributeFloat.SEARCH_STORAGE_KEY, TestXMLSearchableAttributeFloat.SEARCH_STORAGE_VALUE.toString() + "a");
850         validationErrors = searchAttribute.validateUserSearchInputs(paramMap, context);
851         assertEquals("Validation should return a single error message.", 1, validationErrors.size());
852         error = (WorkflowAttributeValidationError) validationErrors.get(0);
853         assertTrue("Validation error is incorrect", error.getMessage().endsWith("does not conform to standard validation for field type."));
854         paramMap.clear();
855         paramMap.put(TestXMLSearchableAttributeFloat.SEARCH_STORAGE_KEY, TestXMLSearchableAttributeFloat.SEARCH_STORAGE_VALUE.toString() + "*");
856         validationErrors = searchAttribute.validateUserSearchInputs(paramMap, context);
857         assertEquals("Validation should return a single error message.", 1, validationErrors.size());
858         error = (WorkflowAttributeValidationError) validationErrors.get(0);
859         assertTrue("Validation error is incorrect", error.getMessage().endsWith("does not conform to standard validation for field type."));
860 
861         searchAttribute = getAttribute("XMLSearchableAttributeStdCurrency");
862         String key = "testCurrencyKey";
863         Float value = Float.valueOf("5486.25");
864         paramMap = new HashMap();
865         paramMap.put(key, value.toString());
866         validationErrors = searchAttribute.validateUserSearchInputs(paramMap, context);
867         assertEquals("Validation should not have returned an error.", 0, validationErrors.size());
868         paramMap.clear();
869         paramMap.put(key, value.toString() + "a");
870         validationErrors = searchAttribute.validateUserSearchInputs(paramMap, context);
871         assertEquals("Validation should return a single error message.", 1, validationErrors.size());
872         error = (WorkflowAttributeValidationError) validationErrors.get(0);
873         assertTrue("Validation error is incorrect", error.getMessage().endsWith("does not conform to standard validation for field type."));
874         paramMap.clear();
875         paramMap.put(key, value.toString() + "*");
876         validationErrors = searchAttribute.validateUserSearchInputs(paramMap, context);
877         assertEquals("Validation should return a single error message.", 1, validationErrors.size());
878         error = (WorkflowAttributeValidationError) validationErrors.get(0);
879         assertTrue("Validation error is incorrect", error.getMessage().endsWith("does not conform to standard validation for field type."));
880 
881         searchAttribute = getAttribute("XMLSearchableAttributeStdDateTime");
882         paramMap = new HashMap();
883         paramMap.put(TestXMLSearchableAttributeDateTime.SEARCH_STORAGE_KEY, DocSearchUtils.getDisplayValueWithDateOnly(TestXMLSearchableAttributeDateTime.SEARCH_STORAGE_VALUE));
884         validationErrors = searchAttribute.validateUserSearchInputs(paramMap, context);
885         assertEquals("Validation should not have returned an error.", 0, validationErrors.size());
886         paramMap.clear();
887         paramMap.put(TestXMLSearchableAttributeDateTime.SEARCH_STORAGE_KEY, "001/5/08");
888         validationErrors = searchAttribute.validateUserSearchInputs(paramMap, context);
889         assertEquals("Validation should not have returned an error.", 0, validationErrors.size());
890         paramMap.clear();
891         paramMap.put(TestXMLSearchableAttributeDateTime.SEARCH_STORAGE_KEY, "41/5/08");
892         validationErrors = searchAttribute.validateUserSearchInputs(paramMap, context);
893         assertEquals("Validation should return a single error message.", 1, validationErrors.size());
894         error = (WorkflowAttributeValidationError) validationErrors.get(0);
895         assertTrue("Validation error is incorrect", error.getMessage().endsWith("does not conform to standard validation for field type."));
896         paramMap.clear();
897         paramMap.put(TestXMLSearchableAttributeDateTime.SEARCH_STORAGE_KEY, "01/02/20*");
898         validationErrors = searchAttribute.validateUserSearchInputs(paramMap, context);
899         assertEquals("Validation should return a single error message.", 1, validationErrors.size());
900         error = (WorkflowAttributeValidationError) validationErrors.get(0);
901         assertTrue("Validation error is incorrect", error.getMessage().endsWith("does not conform to standard validation for field type."));
902     }
903 
904     */
905 
906     /**
907      * Tests the XStreamSafeEvaluator against searchable attributes to resolve EN-63 and KULWF-723.
908      *
909      * This test is pretty much just a copy of testRouteDocumentWithSearchableAttribute using a
910      * different document type which defines the same xpath expression, only with embedded
911      * XStream "reference" attributes in the XML.
912      */
913     @Test public void testRouteDocumentWithXStreamSearchableAttribute() throws Exception {
914     	String documentTypeName = "SearchDocType";
915     	String key = "givenname";
916     	DocumentType docType = ((DocumentTypeService)KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_TYPE_SERVICE)).findByName(documentTypeName);
917 
918         WorkflowDocument workflowDocument = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("rkirkend"), "SearchDocTypeXStream");
919         WorkflowAttributeDefinition.Builder givennameXMLDef = WorkflowAttributeDefinition.Builder.create("XMLXStreamSearchableAttribute");
920 
921         workflowDocument.setApplicationContent("<test></test>");
922 
923         givennameXMLDef.addPropertyDefinition("givenname", "jack");
924         workflowDocument.addSearchableDefinition(givennameXMLDef.build());
925 
926         workflowDocument.setTitle("Routing style");
927         workflowDocument.route("routing this document.");
928 
929         DocumentSearchService docSearchService = (DocumentSearchService) KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_SEARCH_SERVICE);
930 
931         Person user = KimApiServiceLocator.getPersonService().getPersonByPrincipalName("rkirkend");
932         DocumentLookupCriteria.Builder criteria = DocumentLookupCriteria.Builder.create();
933         criteria.setDocumentTypeName(documentTypeName);
934         addSearchableAttribute(criteria, key, "jack");
935         DocumentLookupResults results =  docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
936 
937         assertEquals("Search results should be empty.", 0, results.getLookupResults().size());
938 
939         criteria = DocumentLookupCriteria.Builder.create();
940         criteria.setDocumentTypeName(documentTypeName);
941         addSearchableAttribute(criteria, key, "fred");
942         results =  docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
943 
944         assertEquals("Search results should be empty.", 0, results.getLookupResults().size());
945 
946         criteria = DocumentLookupCriteria.Builder.create();
947         criteria.setDocumentTypeName(documentTypeName);
948         addSearchableAttribute(criteria, "fakeproperty", "doesntexist");
949         try {
950             results =  docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
951             fail("Search results should be throwing a validation exception for use of non-existant searchable attribute");
952         } catch (WorkflowServiceErrorException wsee) {}
953     }
954 
955 
956     /**
957      * Tests the resolution to issues EN-95, KULWF-757, KULOWF-52 whereby the use of a quickfinder is causing
958      * NullPointers when searching for documents.
959      */
960     @Test public void testSearchableAttributeWithQuickfinder() throws Exception {
961     	String documentTypeName = "AttributeWithQuickfinderDocType";
962     	String key = "chart";
963     	DocumentType docType = ((DocumentTypeService)KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_TYPE_SERVICE)).findByName(documentTypeName);
964     	 WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("rkirkend"), documentTypeName);
965 
966     	 // define the chart for the searchable attribute
967     	 WorkflowAttributeDefinition.Builder chartDef = WorkflowAttributeDefinition.Builder.create("SearchableAttributeWithQuickfinder");
968          chartDef.addPropertyDefinition(key, "BL");
969          document.addSearchableDefinition(chartDef.build());
970 
971          // save the document
972          document.setTitle("Routin' with style");
973          document.saveDocument("Savin' this document.");
974 
975          // prepare to search
976          DocumentSearchService docSearchService = (DocumentSearchService) KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_SEARCH_SERVICE);
977          Person user = KimApiServiceLocator.getPersonService().getPersonByPrincipalName("rkirkend");
978 
979          // execute the search by our chart, we should see one result
980          DocumentLookupCriteria.Builder criteria = DocumentLookupCriteria.Builder.create();
981          criteria.setDocumentTypeName(documentTypeName);
982          addSearchableAttribute(criteria, key, "BL");
983          DocumentLookupResults results = docSearchService.lookupDocuments(user.getPrincipalId(),
984                  criteria.build());
985          assertEquals("Search results should have one document.", 1, results.getLookupResults().size());
986          DocumentLookupResult result = results.getLookupResults().get(0);
987          String documentId = result.getDocument().getDocumentId();
988          assertEquals("Wrong document in search results.", document.getDocumentId(), documentId);
989 
990          // search with no searchable attribute criteria, should return our document as well
991          criteria = DocumentLookupCriteria.Builder.create();
992          criteria.setDocumentTypeName(documentTypeName);
993          results = docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
994          assertEquals("Search results should have one document.", 1, results.getLookupResults().size());
995          result = results.getLookupResults().get(0);
996          assertEquals("Wrong document in search results.", document.getDocumentId(), result.getDocument().getDocumentId());
997 
998     }
999 
1000     /**
1001      * Tests that the hidding of fields and columns works properly to resolve EN-53.
1002      *
1003      * TODO this is currently commented out because we can't test this properly through the unit
1004      * test since the filtering of the column actually happens in the web-tier.  Shoudl this be
1005      * the case?  Maybe we need to re-examine when we refactor document search.
1006      */
1007     @Test public void testSearchableAttributeWithHiddens() throws Exception {
1008     	// for the following document, the chart field should not show up in the result set and the org field
1009     	// should not show up in the criteriaw
1010     	String docType = "AttributeWithHiddensDocType";
1011     	DocumentType documentType = ((DocumentTypeService)KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_TYPE_SERVICE)).findByName(docType);
1012 
1013     	String attributeName = "SearchableAttributeWithHiddens";
1014     	WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("rkirkend"), docType);
1015 
1016    	 	// define the chart for the searchable attribute
1017    	 	WorkflowAttributeDefinition.Builder chartDef = WorkflowAttributeDefinition.Builder.create(attributeName);
1018         chartDef.addPropertyDefinition("chart", "BL");
1019         chartDef.addPropertyDefinition("org", "ARSC");
1020         chartDef.addPropertyDefinition("dollar", "24");
1021         document.addSearchableDefinition(chartDef.build());
1022 
1023         // save the document
1024         document.setTitle("Routin' with style");
1025         document.saveDocument("Savin' this document.");
1026 
1027         // prepare to search
1028         DocumentSearchService docSearchService = (DocumentSearchService) KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_SEARCH_SERVICE);
1029         Person user = KimApiServiceLocator.getPersonService().getPersonByPrincipalName("rkirkend");
1030 
1031         // execute the search by our chart, we should see one result
1032         DocumentLookupCriteria.Builder criteria = DocumentLookupCriteria.Builder.create();
1033         criteria.setDocumentTypeName(docType);
1034         addSearchableAttribute(criteria, "chart", "BL");
1035         DocumentLookupResults results = docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
1036         assertEquals("Search results should have one document.", 1, results.getLookupResults().size());
1037         DocumentLookupResult result = results.getLookupResults().get(0);
1038         assertEquals("Wrong document in search results.", document.getDocumentId(), result.getDocument().getDocumentId());
1039         // also check that the chart field is not in the result set and the org field is
1040         DocumentAttribute documentAttribute = result.getSingleDocumentAttributeByName("chart");
1041         assertNull("The chart column should not be in the result set!", documentAttribute);
1042         documentAttribute = result.getSingleDocumentAttributeByName("org");
1043         assertNotNull("The org column should be in the result set", documentAttribute);
1044         assertEquals("Wrong org code.", "ARSC", documentAttribute.getValue());
1045         documentAttribute = result.getSingleDocumentAttributeByName("dollar");
1046         assertNotNull("The dollar column should be in the result set", documentAttribute);
1047         assertEquals("Wrong dollar code.", "24", documentAttribute.getValue().toString());
1048     }
1049 
1050     @Test public void testSetApplicationContentXMLRoutedDocument() throws Exception {
1051         String documentTypeName = "SearchDocType";
1052         String key = "givenname";
1053         DocumentType docType = ((DocumentTypeService)KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_TYPE_SERVICE)).findByName(documentTypeName);
1054         WorkflowDocument workflowDocument = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("rkirkend"), documentTypeName);
1055         workflowDocument.setApplicationContent("<documentContent><searchableContent><putWhateverWordsIwantInsideThisTag>" +
1056                                                "<givenname><value>jack</value></givenname>" +
1057                                                "</putWhateverWordsIwantInsideThisTag></searchableContent></documentContent>");
1058 
1059         workflowDocument.setTitle("Routing style");
1060         workflowDocument.route("routing this document.");
1061 
1062         DocumentSearchService docSearchService = (DocumentSearchService) KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_SEARCH_SERVICE);
1063 
1064         Person user = KimApiServiceLocator.getPersonService().getPersonByPrincipalName("rkirkend");
1065         DocumentLookupCriteria.Builder criteria = DocumentLookupCriteria.Builder.create();
1066         criteria.setDocumentTypeName(documentTypeName);
1067         addSearchableAttribute(criteria, key, "jack");
1068         DocumentLookupResults results =  docSearchService.lookupDocuments(user.getPrincipalId(),
1069                 criteria.build());
1070 
1071         assertEquals("Search results should be empty.", 1, results.getLookupResults().size());
1072 
1073         criteria = DocumentLookupCriteria.Builder.create();
1074         criteria.setDocumentTypeName(documentTypeName);
1075         addSearchableAttribute(criteria, key, "fred");
1076         results =  docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
1077 
1078         assertEquals("Search results should be empty.", 0, results.getLookupResults().size());
1079 
1080         criteria = DocumentLookupCriteria.Builder.create();
1081         criteria.setDocumentTypeName(documentTypeName);
1082         addSearchableAttribute(criteria, "fakeproperty", "doesntexist");
1083         try {
1084             results =  docSearchService.lookupDocuments(user.getPrincipalId(), criteria.build());
1085             fail("Search results should be throwing a validation exception for use of non-existant searchable attribute");
1086         } catch (WorkflowServiceErrorException wsee) {}
1087     }
1088 
1089     /**
1090      * Tests that Field objects use correct KeyValue instances when checks for blank valid values are performed
1091      * (such as when JSP renders drop-downs), to verify that KULRICE-3587 has been fixed.
1092      * 
1093      * @throws Exception
1094      */
1095     /*
1096 
1097     TODO - Rice 2.0 - need to resurrect and rewrite this test
1098 
1099     @Test public void testBlankValidValuesOnKeyValues() throws Exception {
1100     	boolean[] shouldHaveBlank = {true, false};
1101     	String[] attributesToTest = {"XMLSearchableAttributeWithBlank", "XMLSearchableAttributeWithoutBlank"};
1102         DocumentSearchContext docSearchContext = DocSearchUtils.getDocumentSearchContext("", "BlankValidValuesDocType", "");
1103         // Verify that the getHasBlankValidValue() method on each field returns the correct result and does not cause unexpected exceptions.
1104         for (int i = 0; i < shouldHaveBlank.length; i++) {
1105         	List<Row> rowList = getAttribute(attributesToTest[i]).getSearchingRows(docSearchContext);
1106             assertEquals("The searching rows list for " + attributesToTest[i] + " should have exactly one element", 1, rowList.size());
1107         	assertEquals("Searching row for " + attributesToTest[i] + " should have exactly one field", 1, rowList.get(0).getFields().size());
1108         	Field testField = rowList.get(0).getFields().get(0);
1109         	try {
1110         		assertEquals("The field for " + attributesToTest[i] + " does not have the expected getHasBlankValidValue() result",
1111         				shouldHaveBlank[i], testField.getHasBlankValidValue());
1112         	} catch (Exception ex) {
1113         		fail("An exception occurred while running getHasBlankValidValue() on " + attributesToTest[i] + ": " + ex.getMessage());
1114         	}
1115         }
1116     }
1117     */
1118     
1119 }