1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kew.docsearch.service.impl;
17
18 import org.apache.commons.lang.RandomStringUtils;
19 import org.apache.commons.lang.StringUtils;
20 import org.joda.time.DateTime;
21 import org.junit.Before;
22 import org.junit.Test;
23 import org.kuali.rice.kew.api.document.DocumentStatus;
24 import org.kuali.rice.kew.api.document.DocumentStatusCategory;
25 import org.kuali.rice.kew.api.document.search.DocumentSearchCriteria;
26 import org.kuali.rice.kew.api.document.search.RouteNodeLookupLogic;
27 import org.kuali.rice.kew.docsearch.DocumentSearchInternalUtils;
28 import org.kuali.rice.kew.useroptions.UserOptions;
29 import org.kuali.rice.kew.useroptions.UserOptionsService;
30
31 import java.util.ArrayList;
32 import java.util.Arrays;
33 import java.util.Collection;
34 import java.util.HashMap;
35 import java.util.List;
36 import java.util.Map;
37
38 import static org.junit.Assert.assertEquals;
39
40
41
42
43 public class DocSearchSavingTest {
44
45 private class MockUserOptionsService implements UserOptionsService {
46
47 private HashMap<String, String> options = new HashMap<String, String>();
48
49 public Collection<UserOptions> findByWorkflowUser(String principalId) {
50 List<UserOptions> userOpts = new ArrayList<UserOptions>();
51 for (Map.Entry<String, String> entry : options.entrySet()) {
52 UserOptions opt = new UserOptions();
53 opt.setOptionId(entry.getKey());
54 opt.setOptionVal(entry.getValue());
55 userOpts.add(opt);
56 }
57
58 return userOpts;
59 }
60
61 public List<UserOptions> findByUserQualified(String principalId, String likeString) {
62 String prefix = likeString.replaceAll("%", "");
63 List<UserOptions> userOpts = new ArrayList<UserOptions>();
64 for(Map.Entry<String, String> entry : options.entrySet()) {
65 if (entry.getKey().startsWith(prefix)) {
66 UserOptions opt = new UserOptions();
67 opt.setOptionId(entry.getKey());
68 opt.setOptionVal(entry.getValue());
69 userOpts.add(opt);
70 }
71 }
72
73 return userOpts;
74 }
75
76 public void save(UserOptions userOptions) {
77 options.put(userOptions.getOptionId(), userOptions.getOptionVal());
78 }
79
80 public void save(String principalId, Map<String, String> optionsMap) {
81 options.putAll(optionsMap);
82 }
83
84 public void save(String principalId, String optionId, String optionValue) {
85 options.put(optionId, optionValue);
86 }
87
88 public void deleteUserOptions(UserOptions userOptions) {
89 options.remove(userOptions.getOptionId());
90 }
91
92 public UserOptions findByOptionId(String optionId, String principalId) {
93 if (options.containsKey(optionId)) {
94 UserOptions opt = new UserOptions();
95 opt.setOptionId(optionId);
96 opt.setOptionVal(options.get(optionId));
97 return opt;
98 } else {
99 return null;
100 }
101 }
102
103 public List<UserOptions> retrieveEmailPreferenceUserOptions(String emailSetting) {
104 return null;
105 }
106 }
107
108 private class MockDocumentSearchService extends DocumentSearchServiceImpl {
109 private static final int MAX_SEARCH_ITEMS = 5;
110 private static final String LAST_SEARCH_ORDER_OPTION = "DocSearch.LastSearch.Order";
111 private static final String NAMED_SEARCH_ORDER_BASE = "DocSearch.NamedSearch.";
112 private static final String LAST_SEARCH_BASE_NAME = "DocSearch.LastSearch.Holding";
113
114 public void saveSearch(String principalId, DocumentSearchCriteria criteria) {
115 if (StringUtils.isBlank(principalId)) {
116 return;
117 }
118
119 try {
120 String savedSearchString = DocumentSearchInternalUtils.marshalDocumentSearchCriteria(criteria);
121
122 if (StringUtils.isNotBlank(criteria.getSaveName())) {
123 userOptionsService.save(principalId, NAMED_SEARCH_ORDER_BASE + criteria.getSaveName(), savedSearchString);
124 } else {
125
126 UserOptions searchOrder = userOptionsService.findByOptionId(LAST_SEARCH_ORDER_OPTION, principalId);
127
128 if (searchOrder == null) {
129 userOptionsService.save(principalId, LAST_SEARCH_BASE_NAME + "0", savedSearchString);
130 userOptionsService.save(principalId, LAST_SEARCH_ORDER_OPTION, LAST_SEARCH_BASE_NAME + "0");
131 } else {
132 String[] currentOrder = searchOrder.getOptionVal().split(",");
133
134 if (currentOrder.length == MAX_SEARCH_ITEMS) {
135
136
137
138 String searchName = currentOrder[currentOrder.length - 1];
139 String[] newOrder = new String[MAX_SEARCH_ITEMS];
140 newOrder[0] = searchName;
141 for (int i = 0; i < currentOrder.length - 1; i++) {
142 newOrder[i + 1] = currentOrder[i];
143 }
144
145 String newSearchOrder = rejoinWithCommas(newOrder);
146
147 userOptionsService.save(principalId, searchName, savedSearchString);
148 userOptionsService.save(principalId, LAST_SEARCH_ORDER_OPTION, newSearchOrder);
149 } else {
150
151
152
153
154 int absMax = 0;
155 for (String aCurrentOrder : currentOrder) {
156 int current = new Integer(aCurrentOrder.substring(LAST_SEARCH_BASE_NAME.length(),
157 aCurrentOrder.length()));
158 if (current > absMax) {
159 absMax = current;
160 }
161 }
162 String searchName = LAST_SEARCH_BASE_NAME + ++absMax;
163 String[] newOrder = new String[currentOrder.length + 1];
164 newOrder[0] = searchName;
165 for (int i = 0; i < currentOrder.length; i++) {
166 newOrder[i + 1] = currentOrder[i];
167 }
168
169 String newSearchOrder = rejoinWithCommas(newOrder);
170
171 userOptionsService.save(principalId, searchName, savedSearchString);
172 userOptionsService.save(principalId, LAST_SEARCH_ORDER_OPTION, newSearchOrder);
173 }
174 }
175 }
176 } catch (Exception e) {
177
178 }
179
180 }
181
182
183
184
185
186
187 private String rejoinWithCommas(String[] newOrder) {
188 StringBuilder newSearchOrder = new StringBuilder("");
189 for (String aNewOrder : newOrder) {
190 if (newSearchOrder.length() != 0) {
191 newSearchOrder.append(",");
192 }
193 newSearchOrder.append(aNewOrder);
194 }
195 return newSearchOrder.toString();
196 }
197 }
198
199 private MockDocumentSearchService docSearchService;
200 private MockUserOptionsService userOptionsService;
201
202 @Before
203 public void init() {
204 userOptionsService = new MockUserOptionsService();
205 docSearchService = new MockDocumentSearchService();
206 docSearchService.setUserOptionsService(userOptionsService);
207 }
208
209 @Test
210 public void testConsumesExceptions() {
211
212 docSearchService.saveSearch("princ", null);
213 }
214
215 @Test
216 public void testUnnamedDocSearch() throws Exception {
217
218 String princ = "not blank";
219
220 Collection<UserOptions> allUserOptions_before = userOptionsService.findByWorkflowUser(princ);
221
222 assertEquals(0, allUserOptions_before.size());
223 DocumentSearchCriteria c1 = saveSearch(princ, null);
224
225 Collection<UserOptions> allUserOptions_after = userOptionsService.findByWorkflowUser(princ);
226
227
228
229 assertEquals(allUserOptions_before.size() + 2, allUserOptions_after.size());
230
231 assertEquals("DocSearch.LastSearch.Holding0", userOptionsService.findByOptionId("DocSearch.LastSearch.Order",
232 princ).getOptionVal());
233 assertEquals(DocumentSearchInternalUtils.marshalDocumentSearchCriteria(c1), userOptionsService.findByOptionId(
234 "DocSearch.LastSearch.Holding0", princ).getOptionVal());
235
236
237
238 DocumentSearchCriteria c2 = saveSearch(princ, null);
239
240 allUserOptions_after = userOptionsService.findByWorkflowUser(princ);
241
242
243 assertEquals(allUserOptions_before.size() + 3, allUserOptions_after.size());
244 assertEquals("DocSearch.LastSearch.Holding1,DocSearch.LastSearch.Holding0", userOptionsService.findByOptionId(
245 "DocSearch.LastSearch.Order", princ).getOptionVal());
246 assertEquals(DocumentSearchInternalUtils.marshalDocumentSearchCriteria(c1), userOptionsService.findByOptionId(
247 "DocSearch.LastSearch.Holding0", princ).getOptionVal());
248 assertEquals(DocumentSearchInternalUtils.marshalDocumentSearchCriteria(c2), userOptionsService.findByOptionId(
249 "DocSearch.LastSearch.Holding1", princ).getOptionVal());
250
251 docSearchService.clearNamedSearches(princ);
252 assertEquals(0, userOptionsService.findByWorkflowUser(princ).size());
253 }
254
255 @Test
256 public void testNamedDocSearch() throws Exception {
257
258 String princ = "not blank";
259 Collection<UserOptions> allUserOptions_before = userOptionsService.findByWorkflowUser(princ);
260
261 assertEquals(0, allUserOptions_before.size());
262
263 DocumentSearchCriteria c1 = saveSearch(princ, "save1");
264
265 Collection<UserOptions> allUserOptions_after = userOptionsService.findByWorkflowUser(princ);
266 assertEquals(allUserOptions_before.size() + 1, allUserOptions_after.size());
267 assertEquals(DocumentSearchInternalUtils.marshalDocumentSearchCriteria(c1), userOptionsService.findByOptionId(
268 "DocSearch.NamedSearch." + c1.getSaveName(), princ).getOptionVal());
269
270
271 DocumentSearchCriteria c2 = saveSearch(princ, "save2");
272
273 allUserOptions_after = userOptionsService.findByWorkflowUser(princ);
274
275 assertEquals(allUserOptions_before.size() + 2, allUserOptions_after.size());
276 assertEquals(DocumentSearchInternalUtils.marshalDocumentSearchCriteria(c2), userOptionsService.findByOptionId(
277 "DocSearch.NamedSearch." + c2.getSaveName(), princ).getOptionVal());
278
279 docSearchService.clearNamedSearches(princ);
280 assertEquals(0, userOptionsService.findByWorkflowUser(princ).size());
281 }
282
283 @Test
284 public void testSavedSearchOrdering() throws Exception {
285
286 Integer MAX_SEARCH_ITEMS = 5;
287 String princ = "not blank";
288
289 Collection<UserOptions> allUserOptions_before = userOptionsService.findByWorkflowUser(princ);
290
291 DocumentSearchCriteria c1 = saveSearch(princ, null);
292 DocumentSearchCriteria c2 = saveSearch(princ, null);
293 DocumentSearchCriteria c3 = saveSearch(princ, null);
294 DocumentSearchCriteria c4 = saveSearch(princ, null);
295 DocumentSearchCriteria c5 = saveSearch(princ, null);
296
297 Collection<UserOptions> allUserOptions_after = userOptionsService.findByWorkflowUser(princ);
298 assertEquals(allUserOptions_before.size() + 5 + 1, allUserOptions_after.size());
299 assertEquals("DocSearch.LastSearch.Holding4,DocSearch.LastSearch.Holding3,DocSearch.LastSearch.Holding2,"
300 + "DocSearch.LastSearch.Holding1,DocSearch.LastSearch.Holding0", userOptionsService.findByOptionId(
301 "DocSearch.LastSearch.Order", princ).getOptionVal());
302 assertEquals(DocumentSearchInternalUtils.marshalDocumentSearchCriteria(c5), userOptionsService.findByOptionId(
303 "DocSearch.LastSearch.Holding4", princ).getOptionVal());
304 assertEquals(DocumentSearchInternalUtils.marshalDocumentSearchCriteria(c4), userOptionsService.findByOptionId(
305 "DocSearch.LastSearch.Holding3", princ).getOptionVal());
306 assertEquals(DocumentSearchInternalUtils.marshalDocumentSearchCriteria(c3), userOptionsService.findByOptionId(
307 "DocSearch.LastSearch.Holding2", princ).getOptionVal());
308 assertEquals(DocumentSearchInternalUtils.marshalDocumentSearchCriteria(c2), userOptionsService.findByOptionId(
309 "DocSearch.LastSearch.Holding1", princ).getOptionVal());
310 assertEquals(DocumentSearchInternalUtils.marshalDocumentSearchCriteria(c1), userOptionsService.findByOptionId(
311 "DocSearch.LastSearch.Holding0", princ).getOptionVal());
312
313
314
315 DocumentSearchCriteria c6 = saveSearch(princ, null);
316
317
318 allUserOptions_after = userOptionsService.findByWorkflowUser(princ);
319
320
321
322 assertEquals(allUserOptions_before.size() + 5 + 1, allUserOptions_after.size());
323 assertEquals("DocSearch.LastSearch.Holding0,DocSearch.LastSearch.Holding4,DocSearch.LastSearch.Holding3,"
324 + "DocSearch.LastSearch.Holding2,DocSearch.LastSearch.Holding1", userOptionsService.findByOptionId(
325 "DocSearch.LastSearch.Order", princ).getOptionVal());
326 assertEquals(DocumentSearchInternalUtils.marshalDocumentSearchCriteria(c6), userOptionsService.findByOptionId(
327 "DocSearch.LastSearch.Holding0", princ).getOptionVal());
328 assertEquals(DocumentSearchInternalUtils.marshalDocumentSearchCriteria(c5), userOptionsService.findByOptionId(
329 "DocSearch.LastSearch.Holding4", princ).getOptionVal());
330 assertEquals(DocumentSearchInternalUtils.marshalDocumentSearchCriteria(c4), userOptionsService.findByOptionId(
331 "DocSearch.LastSearch.Holding3", princ).getOptionVal());
332 assertEquals(DocumentSearchInternalUtils.marshalDocumentSearchCriteria(c3), userOptionsService.findByOptionId(
333 "DocSearch.LastSearch.Holding2", princ).getOptionVal());
334 assertEquals(DocumentSearchInternalUtils.marshalDocumentSearchCriteria(c2), userOptionsService.findByOptionId(
335 "DocSearch.LastSearch.Holding1", princ).getOptionVal());
336
337 docSearchService.clearNamedSearches(princ);
338 assertEquals(0, userOptionsService.findByWorkflowUser(princ).size());
339 }
340
341 private DocumentSearchCriteria saveSearch(String princ, String name) {
342 DocumentSearchCriteria dsc = createDocSearchCriteria(name);
343 docSearchService.saveSearch(princ, dsc);
344 return dsc;
345 }
346
347 private DocumentSearchCriteria createDocSearchCriteria(String saveName) {
348 DocumentSearchCriteria.Builder builder = DocumentSearchCriteria.Builder.create();
349 builder.setApplicationDocumentId(RandomStringUtils.randomAlphanumeric(5));
350 builder.setApplicationDocumentStatus(RandomStringUtils.randomAlphanumeric(5));
351 builder.setApproverPrincipalName(RandomStringUtils.randomAlphanumeric(5));
352 builder.setApproverPrincipalId(RandomStringUtils.randomAlphanumeric(5));
353 builder.setDocumentId( RandomStringUtils.randomAlphanumeric(5));
354 builder.setDocumentTypeName(RandomStringUtils.randomAlphanumeric(5));
355 builder.setDocumentStatusCategories(Arrays.asList(DocumentStatusCategory.PENDING, DocumentStatusCategory.SUCCESSFUL));
356 builder.setDocumentStatuses(Arrays.asList(DocumentStatus.ENROUTE, DocumentStatus.INITIATED, DocumentStatus.SAVED));
357 builder.setInitiatorPrincipalName(RandomStringUtils.randomAlphanumeric(10));
358 builder.setInitiatorPrincipalId(RandomStringUtils.randomAlphanumeric(10));
359 builder.setMaxResults(500);
360 builder.setRouteNodeName(RandomStringUtils.randomAlphanumeric(5));
361 builder.setSaveName(saveName);
362 builder.setStartAtIndex(1);
363 builder.setTitle(RandomStringUtils.randomAlphanumeric(10));
364 builder.setGroupViewerId(RandomStringUtils.randomAlphanumeric(5));
365 builder.setViewerPrincipalName(RandomStringUtils.randomAlphanumeric(10));
366 builder.setViewerPrincipalId(RandomStringUtils.randomAlphanumeric(10));
367 builder.setRouteNodeLookupLogic(RouteNodeLookupLogic.EXACTLY);
368
369 builder.setDateApplicationDocumentStatusChangedFrom(new DateTime());
370 builder.setDateApplicationDocumentStatusChangedTo(new DateTime());
371 builder.setDateApprovedFrom(new DateTime());
372 builder.setDateApprovedTo(new DateTime());
373 builder.setDateCreatedFrom(new DateTime());
374 builder.setDateCreatedTo(new DateTime());
375 builder.setDateFinalizedFrom(new DateTime());
376 builder.setDateFinalizedTo(new DateTime());
377 builder.setDateLastModifiedFrom(new DateTime());
378 builder.setDateLastModifiedTo(new DateTime());
379
380 Map<String, List<String>> attrs = new HashMap<String, List<String>>();
381 for (int i = 1;i<6;i++) {
382 ArrayList<String> list = new ArrayList<String>();
383 for (int j = 1;j<6;j++) {
384 list.add(RandomStringUtils.randomAlphanumeric(5));
385 }
386 attrs.put(RandomStringUtils.randomAlphanumeric(5), list);
387 }
388 builder.setDocumentAttributeValues(attrs);
389
390 return builder.build();
391 }
392 }