001    /**
002     * Copyright 2005-2013 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.kns.workflow;
017    
018    import org.junit.Test;
019    import org.kuali.rice.core.api.CoreApiServiceLocator;
020    import org.kuali.rice.kew.api.document.search.DocumentSearchCriteria;
021    import org.kuali.rice.kew.api.document.search.DocumentSearchResults;
022    import org.kuali.rice.kew.docsearch.service.DocumentSearchService;
023    import org.kuali.rice.kew.doctype.bo.DocumentType;
024    import org.kuali.rice.kew.engine.RouteContext;
025    import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
026    import org.kuali.rice.kew.service.KEWServiceLocator;
027    import org.kuali.rice.kim.api.services.KimApiServiceLocator;
028    import org.kuali.rice.krad.UserSession;
029    import org.kuali.rice.krad.service.DocumentService;
030    import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
031    import org.kuali.rice.krad.test.document.SearchAttributeIndexTestDocument;
032    import org.kuali.rice.krad.util.GlobalVariables;
033    import org.kuali.rice.krad.test.KRADTestCase;
034    
035    import static org.junit.Assert.assertEquals;
036    import static org.junit.Assert.fail;
037    import org.junit.Assert;
038    
039    /**
040     * tests that a document, which goes through a regular or blanket approval process, is indexed correctly
041     * 
042     * @author Kuali Rice Team (rice.collab@kuali.org)
043     */
044    public class SearchAttributeIndexRequestTest extends KRADTestCase {
045            static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(SearchAttributeIndexRequestTest.class);
046            final static String SEARCH_ATTRIBUTE_INDEX_DOCUMENT_TEST_DOC_TYPE = "SearchAttributeIndexTestDocument";
047            
048            enum DOCUMENT_FIXTURE {
049                    NORMAL_DOCUMENT("hippo","routing");
050                    
051                    private String constantString;
052                    private String routingString;
053                    private DOCUMENT_FIXTURE(String constantString, String routingString) {
054                            this.constantString = constantString;
055                            this.routingString = routingString;
056                    }
057                    
058                    public SearchAttributeIndexTestDocument getDocument(DocumentService documentService) throws Exception {
059                            SearchAttributeIndexTestDocument doc = (SearchAttributeIndexTestDocument)documentService.getNewDocument(SearchAttributeIndexRequestTest.SEARCH_ATTRIBUTE_INDEX_DOCUMENT_TEST_DOC_TYPE);
060                            doc.initialize(constantString, routingString);
061                            return doc;
062                    }
063            }
064            
065            /**
066             * Tests that a document, which goes through a regular approval process, is indexed correctly
067             */
068            @Test
069            public void regularApproveTest() throws Exception {
070                    LOG.warn("message.delivery state: "+ CoreApiServiceLocator.getKualiConfigurationService().getPropertyValueAsString(
071                    "message.delivery"));
072                    
073                    final DocumentService documentService = KRADServiceLocatorWeb.getDocumentService();
074                    final String principalName = "quickstart";
075            final String principalId = KimApiServiceLocator.getPersonService().getPersonByPrincipalName(principalName).getPrincipalId();
076            GlobalVariables.setUserSession(new UserSession(principalName));
077            RouteContext.clearCurrentRouteContext();
078    
079                    SearchAttributeIndexTestDocument document = DOCUMENT_FIXTURE.NORMAL_DOCUMENT.getDocument(documentService);
080                    document.getDocumentHeader().setDocumentDescription("Routed SAIndexTestDoc");
081                    final String documentNumber = document.getDocumentNumber();
082                    final DocumentType docType = KEWServiceLocator.getDocumentTypeService().findByName(SearchAttributeIndexRequestTest.SEARCH_ATTRIBUTE_INDEX_DOCUMENT_TEST_DOC_TYPE);
083                    
084                    documentService.routeDocument(document, "Routed SearchAttributeIndexTestDocument", null);
085                    
086                    document = (SearchAttributeIndexTestDocument)documentService.getByDocumentHeaderId(documentNumber);
087                    DocumentRouteHeaderValue routeHeader = KEWServiceLocator.getRouteHeaderService().getRouteHeader(documentNumber);
088                                                    
089                    assertDDSearchableAttributesWork(docType,principalId,"routeLevelCount",
090                                    new String[] {"1","0","2","7"},
091                                    new int[] {1, 0, 0, 0}
092                    );
093                    
094                    assertDDSearchableAttributesWork(docType,principalId,"constantString",
095                                    new String[] {"hippo","monkey"},
096                                    new int[] {1, 0}
097                    );
098                    
099                    assertDDSearchableAttributesWork(docType,principalId,"routedString",
100                                    new String[] {"routing","hippo"},
101                                    new int[] {1, 0}
102                    );
103                    
104                    GlobalVariables.setUserSession(new UserSession("user1"));
105                    document = (SearchAttributeIndexTestDocument)documentService.getByDocumentHeaderId(documentNumber);
106                    documentService.approveDocument(document, "User1 approved document", null);
107                    
108                    routeHeader = KEWServiceLocator.getRouteHeaderService().getRouteHeader(documentNumber);
109                                                    
110                    assertDDSearchableAttributesWork(docType,principalId,"routeLevelCount",
111                                    new String[] {"1","0","2","7"},
112                                    new int[] {0, 0, 1, 0}
113                    );
114                    
115                    assertDDSearchableAttributesWork(docType,principalId,"constantString",
116                                    new String[] {"hippo","monkey"},
117                                    new int[] {1, 0}
118                    );
119                    
120                    assertDDSearchableAttributesWork(docType,principalId,"routedString",
121                                    new String[] {"routing","hippo"},
122                                    new int[] {1, 0}
123                    );
124                    
125                    LOG.info("Read Access Count not at expected value: "+document.getReadAccessCount());
126                    
127                    GlobalVariables.setUserSession(new UserSession("user2"));
128                    document = (SearchAttributeIndexTestDocument)documentService.getByDocumentHeaderId(documentNumber);
129                    documentService.approveDocument(document, "User1 approved document", null);
130                    
131                    routeHeader = KEWServiceLocator.getRouteHeaderService().getRouteHeader(documentNumber);
132                                    
133                    assertDDSearchableAttributesWork(docType,principalId,"routeLevelCount",
134                                    new String[] {"1","0","2","3","4","7"},
135                                    new int[] {0, 0, 0, 1, 0, 0}
136                    );
137                    
138                    assertDDSearchableAttributesWork(docType,principalId,"constantString",
139                                    new String[] {"hippo","monkey"},
140                                    new int[] {1, 0}
141                    );
142                    
143                    assertDDSearchableAttributesWork(docType,principalId,"routedString",
144                                    new String[] {"routing","hippo"},
145                                    new int[] {1, 0}
146                    );
147                    
148                    LOG.info("Read Access Count not at expected value: "+document.getReadAccessCount());
149                    
150                    GlobalVariables.setUserSession(new UserSession("user3"));
151                    document = (SearchAttributeIndexTestDocument)documentService.getByDocumentHeaderId(documentNumber);
152                    documentService.approveDocument(document, "User3 approved document", null);
153                    
154                    routeHeader = KEWServiceLocator.getRouteHeaderService().getRouteHeader(documentNumber);
155                                                    
156                    assertDDSearchableAttributesWork(docType,principalId,"routeLevelCount",
157                                    new String[] {"1","0","2","3","4","7"},
158                                    new int[] {0, 0, 0, 1, 0, 0}
159                    );
160                    
161                    assertDDSearchableAttributesWork(docType,principalId,"constantString",
162                                    new String[] {"hippo","monkey"},
163                                    new int[] {1, 0}
164                    );
165                    
166                    assertDDSearchableAttributesWork(docType,principalId,"routedString",
167                                    new String[] {"routing","hippo"},
168                                    new int[] {1, 0}
169                    );
170                    
171                    LOG.info("Read Access Count not at expected value: "+document.getReadAccessCount());
172                    
173                    GlobalVariables.setUserSession(null);
174            }
175            
176            /**
177             * Tests that a blanket approved document is indexed correctly
178             */
179            @Test
180            public void blanketApproveTest() throws Exception {
181                    LOG.warn("message.delivery state: "+ CoreApiServiceLocator.getKualiConfigurationService().getPropertyValueAsString(
182                    "message.delivery"));
183                    
184                    final DocumentService documentService = KRADServiceLocatorWeb.getDocumentService();
185                    final String principalName = "admin";
186            final String principalId = KimApiServiceLocator.getPersonService().getPersonByPrincipalName(principalName).getPrincipalId();
187            GlobalVariables.setUserSession(new UserSession(principalName));
188    
189                    SearchAttributeIndexTestDocument document = DOCUMENT_FIXTURE.NORMAL_DOCUMENT.getDocument(documentService);
190                    document.getDocumentHeader().setDocumentDescription("Blanket Approved SAIndexTestDoc");
191                    final String documentNumber = document.getDocumentNumber();
192                    final DocumentType docType = KEWServiceLocator.getDocumentTypeService().findByName(SearchAttributeIndexRequestTest.SEARCH_ATTRIBUTE_INDEX_DOCUMENT_TEST_DOC_TYPE);
193                                    
194                    documentService.blanketApproveDocument(document, "Blanket Approved SearchAttributeIndexTestDocument", null);
195                    
196                    document = (SearchAttributeIndexTestDocument)documentService.getByDocumentHeaderId(documentNumber);
197                    DocumentRouteHeaderValue routeHeader = KEWServiceLocator.getRouteHeaderService().getRouteHeader(documentNumber);
198                                                    
199                    assertDDSearchableAttributesWork(docType,principalId,"routeLevelCount",
200                                    new String[] {"1","0","2","3","7"},
201                                    new int[] {0, 0, 0, 1, 0}
202                    );
203                    
204                    assertDDSearchableAttributesWork(docType,principalId,"constantString",
205                                    new String[] {"hippo","monkey"},
206                                    new int[] {1, 0}
207                    );
208                    
209                    assertDDSearchableAttributesWork(docType,principalId,"routedString",
210                                    new String[] {"routing","hippo"},
211                                    new int[] {1, 0}
212                    );
213                    
214                    LOG.info("Read Access Count not at expected value: "+document.getReadAccessCount());
215                    
216                    GlobalVariables.setUserSession(null);
217            }
218            
219            /**
220         * A convenience method for testing wildcards on data dictionary searchable attributes.
221         *
222         * @param docType The document type containing the attributes.
223         * @param principalId The ID of the user performing the search.
224         * @param fieldName The name of the field on the test document.
225         * @param searchValues The search expressions to test. Has to be a String array (for regular fields) or a String[] array (for multi-select fields).
226         * @param resultSizes The number of expected documents to be returned by the search; use -1 to indicate that an error should have occurred.
227         * @throws Exception
228         */
229        private void assertDDSearchableAttributesWork(DocumentType docType, String principalId, String fieldName, Object[] searchValues,
230                    int[] resultSizes) throws Exception {
231            if (!(searchValues instanceof String[]) && !(searchValues instanceof String[][])) {
232                    throw new IllegalArgumentException("'searchValues' parameter has to be either a String[] or a String[][]");
233            }
234            DocumentSearchCriteria.Builder criteria = null;
235            DocumentSearchResults results = null;
236            DocumentSearchService docSearchService = KEWServiceLocator.getDocumentSearchService();
237            for (int i = 0; i < resultSizes.length; i++) {
238                    criteria = DocumentSearchCriteria.Builder.create();
239                    criteria.setDocumentTypeName(docType.getName());
240                    criteria.addDocumentAttributeValue(fieldName, searchValues[i].toString());
241                    try {
242                            results = docSearchService.lookupDocuments(principalId, criteria.build());
243                            if (resultSizes[i] < 0) {
244                                    Assert.fail(fieldName + "'s search at loop index " + i + " should have thrown an exception");
245                            }
246                            if(resultSizes[i] != results.getSearchResults().size()){
247                                    assertEquals(fieldName + "'s search results at loop index " + i + " returned the wrong number of documents.", resultSizes[i], results.getSearchResults().size());
248                            }
249                    } catch (Exception ex) {
250                            if (resultSizes[i] >= 0) {
251                                    Assert.fail(fieldName + "'s search at loop index " + i + " should not have thrown an exception");
252                            }
253                    }
254                    GlobalVariables.clear();
255            }
256        }
257    }