001    /*
002     * Copyright 2006-2011 The Kuali Foundation
003     *
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.opensource.org/licenses/ecl2.php
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.kuali.rice.kew.docsearch;
017    
018    import org.junit.Test;
019    import org.kuali.rice.core.api.parameter.Parameter;
020    import org.kuali.rice.core.framework.services.CoreFrameworkServiceLocator;
021    import org.kuali.rice.core.util.ClassLoaderUtils;
022    import org.kuali.rice.kew.docsearch.service.DocumentSearchService;
023    import org.kuali.rice.kew.doctype.bo.DocumentType;
024    import org.kuali.rice.kew.doctype.service.DocumentTypeService;
025    
026    import org.kuali.rice.kew.dto.WorkflowAttributeDefinitionDTO;
027    import org.kuali.rice.kew.service.KEWServiceLocator;
028    import org.kuali.rice.kew.service.WorkflowDocument;
029    import org.kuali.rice.kew.util.KEWConstants;
030    import org.kuali.rice.kim.api.services.KimApiServiceLocator;
031    import org.kuali.rice.kim.bo.Person;
032    import org.kuali.rice.kns.util.KNSConstants;
033    
034    import static org.junit.Assert.assertEquals;
035    
036    /**
037     *
038     * @author Kuali Rice Team (rice.collab@kuali.org)
039     */
040    public class CustomDocumentSearchGeneratorTest extends DocumentSearchTestBase {
041    //      private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(CustomSearchAttributesTest.class);
042    
043        protected void loadTestData() throws Exception {
044            loadXmlFile("SearchAttributeConfig.xml");
045        }
046    
047        @Test public void testCustomDocumentSearchGeneratorUse() throws Exception {
048            DocumentType docType = ((DocumentTypeService)KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_TYPE_SERVICE)).findByName("SearchDocType");
049            assertEquals("The document search Generator class is incorrect.",StandardDocumentSearchGenerator.class,(ClassLoaderUtils.unwrapFromProxy(docType.getDocumentSearchGenerator())).getClass());
050            docType = ((DocumentTypeService)KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_TYPE_SERVICE)).findByName("SearchDocType_DefaultCustomProcessor");
051            assertEquals("The document search Generator class is incorrect.",CustomDocumentSearchGenerator.class,(ClassLoaderUtils.unwrapFromProxy(docType.getDocumentSearchGenerator())).getClass());
052        }
053    
054            private DocumentType getValidDocumentType(String documentTypeFullName) {
055                    if (org.apache.commons.lang.StringUtils.isEmpty(documentTypeFullName)) {
056                            return null;
057                    }
058                    DocumentType docType = KEWServiceLocator.getDocumentTypeService().findByName(documentTypeFullName);
059                    if (docType == null) {
060                            throw new RuntimeException("No Valid Document Type Found for document type name '" + documentTypeFullName + "'");
061                    } else {
062                            return docType;
063                    }
064            }
065    
066        @Test public void testCustomDocSearchGeneratorResultSetLimit() throws Exception {
067            String documentTypeName = "SearchDocType_DefaultCustomProcessor";
068            String userNetworkId = "rkirkend";
069            Person user = KimApiServiceLocator.getPersonService().getPersonByPrincipalName(userNetworkId);
070    
071    
072            DocSearchCriteriaDTO criteria = new DocSearchCriteriaDTO();
073            criteria.setDocTypeFullName(documentTypeName);
074            criteria.addSearchableAttribute(createSearchAttributeCriteriaComponent(TestXMLSearchableAttributeString.SEARCH_STORAGE_KEY, TestXMLSearchableAttributeString.SEARCH_STORAGE_VALUE, KEWServiceLocator.getDocumentTypeService().findByName(documentTypeName)));
075    
076            Parameter orig = CoreFrameworkServiceLocator.getParameterService().getParameter(KEWConstants.KEW_NAMESPACE, KNSConstants.DetailTypes.DOCUMENT_SEARCH_DETAIL_TYPE, KEWConstants.DOC_SEARCH_RESULT_CAP);
077    
078            String origValue = orig.getValue();
079            // adjust the app constant to be greater than custom generator value
080            adjustResultSetCapApplicationConstantValue(orig, CustomDocumentSearchGenerator.RESULT_SET_LIMIT + 1);
081            KEWServiceLocator.getDocumentSearchService().getList(user.getPrincipalId(), criteria);
082            assertEquals("Criteria threshold should equal custom generator class threshold", CustomDocumentSearchGenerator.RESULT_SET_LIMIT, criteria.getThreshold().intValue());
083    
084            orig = CoreFrameworkServiceLocator.getParameterService().getParameter(KEWConstants.KEW_NAMESPACE, KNSConstants.DetailTypes.DOCUMENT_SEARCH_DETAIL_TYPE, KEWConstants.DOC_SEARCH_RESULT_CAP);
085            // adjust the app constant to be less than custom generator value
086            int newLimit = CustomDocumentSearchGenerator.RESULT_SET_LIMIT - 1;
087            adjustResultSetCapApplicationConstantValue(orig, newLimit);
088            KEWServiceLocator.getDocumentSearchService().getList(user.getPrincipalId(), criteria);
089            assertEquals("Criteria threshold should equal system result set threshold", newLimit, criteria.getThreshold().intValue());
090    
091            orig = CoreFrameworkServiceLocator.getParameterService().getParameter(KEWConstants.KEW_NAMESPACE, KNSConstants.DetailTypes.DOCUMENT_SEARCH_DETAIL_TYPE, KEWConstants.DOC_SEARCH_RESULT_CAP);
092            // reset the parameter
093            Parameter.Builder pb = Parameter.Builder.create(orig);
094            pb.setValue(origValue);
095            CoreFrameworkServiceLocator.getParameterService().updateParameter(pb.build());
096    
097            // old parameter value will still be cached, let's flush the cache
098            //KNSServiceLocator.getParameterService().clearCache();
099            
100            KEWServiceLocator.getDocumentSearchService().getList(user.getPrincipalId(), criteria);
101            assertEquals("Criteria threshold should equal custom generator class threshold", CustomDocumentSearchGenerator.RESULT_SET_LIMIT, criteria.getThreshold().intValue());
102        }
103    
104        private void adjustResultSetCapApplicationConstantValue(Parameter p, Integer newValue) {
105            Parameter.Builder ps = Parameter.Builder.create(p);
106    
107            //ps.setNamespaceCode(KEWConstants.KEW_NAMESPACE);
108            //ps.setName(KEWConstants.DOC_SEARCH_RESULT_CAP);
109            ps.setValue(newValue.toString());
110            //ps.setParameterType(ParameterType.Builder.create("CONFG"));
111            //ps.setVersionNumber(p.getVersionNumber());
112            //ps.setComponentCode(KNSConstants.DetailTypes.DOCUMENT_SEARCH_DETAIL_TYPE);
113            //ps.setEvaluationOperator(EvaluationOperator.ALLOW);
114            CoreFrameworkServiceLocator.getParameterService().updateParameter(ps.build());
115        }
116    
117        /**
118         * Tests function of adding extra document type names to search including using searchable attributes
119         * that may or may not exist on all the document type names being searched on.
120         *
121         * @throws Exception
122         */
123        @Test public void testSearchOnExtraDocType() throws Exception {
124            String userNetworkId = "rkirkend";
125            DocumentSearchService docSearchService = (DocumentSearchService) KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_SEARCH_SERVICE);
126            Person user = KimApiServiceLocator.getPersonService().getPersonByPrincipalName(userNetworkId);
127    
128            String documentTypeName1 = "SearchDocType_DefaultCustomProcessor";
129            WorkflowDocument workDoc_Matching1 = WorkflowDocument.createDocument(getPrincipalIdForName(userNetworkId), documentTypeName1);
130            DocumentType docType1 = ((DocumentTypeService)KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_TYPE_SERVICE)).findByName(documentTypeName1);
131            WorkflowAttributeDefinitionDTO stringXMLDef1 = new WorkflowAttributeDefinitionDTO("SearchableAttributeVisible");
132            stringXMLDef1.addProperty(TestXMLSearchableAttributeString.SEARCH_STORAGE_KEY, TestXMLSearchableAttributeString.SEARCH_STORAGE_VALUE);
133            workDoc_Matching1.addSearchableDefinition(stringXMLDef1);
134            workDoc_Matching1.routeDocument("");
135    
136            String documentTypeName2 = "SearchDocType_DefaultCustomProcessor_2";
137            WorkflowDocument workDoc_Matching2 = WorkflowDocument.createDocument(getPrincipalIdForName(userNetworkId), documentTypeName2);
138            DocumentType docType2 = ((DocumentTypeService)KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_TYPE_SERVICE)).findByName(documentTypeName2);
139            WorkflowAttributeDefinitionDTO stringXMLDef2 = new WorkflowAttributeDefinitionDTO("SearchableAttributeVisible");
140            stringXMLDef2.addProperty(TestXMLSearchableAttributeString.SEARCH_STORAGE_KEY, TestXMLSearchableAttributeString.SEARCH_STORAGE_VALUE);
141            workDoc_Matching2.addSearchableDefinition(stringXMLDef2);
142            workDoc_Matching2.routeDocument("");
143    
144            // do search with attribute using doc type 1... make sure both docs are returned
145            DocSearchCriteriaDTO criteria = new DocSearchCriteriaDTO();
146            criteria.setDocTypeFullName(documentTypeName1);
147            criteria.addSearchableAttribute(createSearchAttributeCriteriaComponent(TestXMLSearchableAttributeString.SEARCH_STORAGE_KEY, TestXMLSearchableAttributeString.SEARCH_STORAGE_VALUE, docType1));
148            DocumentSearchResultComponents result = docSearchService.getList(user.getPrincipalId(), criteria);
149            assertEquals("Search results should have one document.", 2, result.getSearchResults().size());
150    
151            // do search with attribute using doc type 2... make sure both docs are returned
152            criteria = new DocSearchCriteriaDTO();
153            criteria.setDocTypeFullName(documentTypeName2);
154            criteria.addSearchableAttribute(createSearchAttributeCriteriaComponent(TestXMLSearchableAttributeString.SEARCH_STORAGE_KEY, TestXMLSearchableAttributeString.SEARCH_STORAGE_VALUE, docType2));
155            result = docSearchService.getList(user.getPrincipalId(), criteria);
156            assertEquals("Search results should have one document.", 2, result.getSearchResults().size());
157    
158            // do search without attribute using doc type 1... make sure both docs are returned
159            criteria = new DocSearchCriteriaDTO();
160            criteria.setDocTypeFullName(documentTypeName1);
161            result = docSearchService.getList(user.getPrincipalId(), criteria);
162            assertEquals("Search results should have one document.", 2, result.getSearchResults().size());
163    
164            // do search without attribute using doc type 2... make sure both docs are returned
165            criteria = new DocSearchCriteriaDTO();
166            criteria.setDocTypeFullName(documentTypeName2);
167            result = docSearchService.getList(user.getPrincipalId(), criteria);
168            assertEquals("Search results should have one document.", 2, result.getSearchResults().size());
169    
170            String documentTypeName3 = "SearchDocType_DefaultCustomProcessor_3";
171            WorkflowDocument workDoc_Matching3 = WorkflowDocument.createDocument(getPrincipalIdForName(userNetworkId), documentTypeName3);
172            DocumentType docType3 = ((DocumentTypeService)KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_TYPE_SERVICE)).findByName(documentTypeName3);
173            WorkflowAttributeDefinitionDTO stringXMLDef3 = new WorkflowAttributeDefinitionDTO("SearchableAttributeVisible");
174            stringXMLDef3.addProperty(TestXMLSearchableAttributeString.SEARCH_STORAGE_KEY, TestXMLSearchableAttributeString.SEARCH_STORAGE_VALUE);
175            workDoc_Matching3.addSearchableDefinition(stringXMLDef3);
176            workDoc_Matching3.routeDocument("");
177    
178            // do search with attribute using doc type 3... make sure 1 doc is returned
179            criteria = new DocSearchCriteriaDTO();
180            criteria.setDocTypeFullName(documentTypeName3);
181            criteria.addSearchableAttribute(createSearchAttributeCriteriaComponent(TestXMLSearchableAttributeString.SEARCH_STORAGE_KEY, TestXMLSearchableAttributeString.SEARCH_STORAGE_VALUE, docType3));
182            result = docSearchService.getList(user.getPrincipalId(), criteria);
183            assertEquals("Search results should have one document.", 1, result.getSearchResults().size());
184    
185            // do search without attribute using doc type 3... make sure 1 doc is returned
186            criteria = new DocSearchCriteriaDTO();
187            criteria.setDocTypeFullName(documentTypeName3);
188            result = docSearchService.getList(user.getPrincipalId(), criteria);
189            assertEquals("Search results should have one document.", 1, result.getSearchResults().size());
190    
191            WorkflowDocument workDoc_NonMatching2 = WorkflowDocument.createDocument(getPrincipalIdForName(userNetworkId), documentTypeName2);
192            WorkflowAttributeDefinitionDTO stringXMLDef1a = new WorkflowAttributeDefinitionDTO("SearchableAttributeVisible");
193            // TODO delyea - adding underscore below invalidates via REGEX but doesn't blow up on route or addSearchable?
194            String searchAttributeValue = TestXMLSearchableAttributeString.SEARCH_STORAGE_VALUE + "nonMatching";
195            stringXMLDef1a.addProperty(TestXMLSearchableAttributeString.SEARCH_STORAGE_KEY, searchAttributeValue);
196            workDoc_NonMatching2.addSearchableDefinition(stringXMLDef1a);
197            workDoc_NonMatching2.routeDocument("");
198    
199            // do search with attribute using doc type 1... make sure 1 doc is returned
200            criteria = new DocSearchCriteriaDTO();
201            criteria.setDocTypeFullName(documentTypeName1);
202            criteria.addSearchableAttribute(createSearchAttributeCriteriaComponent(TestXMLSearchableAttributeString.SEARCH_STORAGE_KEY, searchAttributeValue, docType1));
203            result = docSearchService.getList(user.getPrincipalId(), criteria);
204            assertEquals("Search results should have one document.", 1, result.getSearchResults().size());
205    
206            // do search without attribute using doc type 1... make sure all 3 docs are returned
207            criteria = new DocSearchCriteriaDTO();
208            criteria.setDocTypeFullName(documentTypeName1);
209            result = docSearchService.getList(user.getPrincipalId(), criteria);
210            assertEquals("Search results should have one document.", 3, result.getSearchResults().size());
211        }
212    }