View Javadoc
1   /*
2    * Copyright (C) 2012 eXo Platform SAS.
3    *
4    * This is free software; you can redistribute it and/or modify it
5    * under the terms of the GNU Lesser General Public License as
6    * published by the Free Software Foundation; either version 2.1 of
7    * the License, or (at your option) any later version.
8    *
9    * This software is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12   * Lesser General Public License for more details.
13   *
14   * You should have received a copy of the GNU Lesser General Public
15   * License along with this software; if not, write to the Free
16   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
17   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
18   */
19  package org.exoplatform.calendar.service.test;
20  
21  import javax.jcr.query.Query;
22  
23  import java.io.IOException;
24  import java.io.InputStream;
25  import java.text.SimpleDateFormat;
26  import java.util.*;
27  import java.util.concurrent.CountDownLatch;
28  import java.util.concurrent.atomic.AtomicBoolean;
29  
30  import org.exoplatform.calendar.service.*;
31  import org.exoplatform.calendar.service.Calendar;
32  import org.exoplatform.calendar.service.impl.CalendarSearchResult;
33  import org.exoplatform.calendar.service.impl.CalendarSearchServiceConnector;
34  import org.exoplatform.calendar.service.impl.EventSearchConnector;
35  import org.exoplatform.calendar.service.impl.UnifiedQuery;
36  import org.exoplatform.commons.api.search.data.SearchContext;
37  import org.exoplatform.commons.api.search.data.SearchResult;
38  import org.exoplatform.commons.utils.DateUtils;
39  import org.exoplatform.container.ExoContainerContext;
40  import org.exoplatform.container.PortalContainer;
41  import org.exoplatform.web.controller.metadata.ControllerDescriptor;
42  import org.exoplatform.web.controller.metadata.DescriptorBuilder;
43  import org.exoplatform.web.controller.router.Router;
44  import org.exoplatform.web.controller.router.RouterConfigException;
45  
46  public class UnifiedSearchTestCase extends BaseCalendarServiceTestCase {
47  
48    private CalendarSearchServiceConnector unifiedSearchService_;
49  
50    private CalendarSearchServiceConnector eventSearchConnector_;
51  
52    @Override
53    public void setUp() throws Exception {
54      super.setUp();
55      unifiedSearchService_ = getService(CalendarSearchServiceConnector.class);
56      eventSearchConnector_ = getService(EventSearchConnector.class);
57    }
58  
59    public void testParseKeyword() {
60      String keyword = "hello \" i am  a \" new guy";
61      List<String> formated = UnifiedQuery.parse(keyword);
62      assertEquals(4, formated.size());
63      keyword = keyword + " \" why don't \"we talk \" ";
64      formated = UnifiedQuery.parse(keyword);
65      assertEquals(8, formated.size());
66    }
67  
68    public void testUnifiedSeach() throws Exception {
69      // Simple case
70      login(username);
71      String keyword = "hello \"how are\" you ";
72      EventQuery query = new UnifiedQuery();
73      query.setQueryType(Query.SQL);
74      query.setText(keyword);
75      query.setOrderType(Utils.ORDER_TYPE_ASCENDING);
76      query.setOrderBy(new String[] { Utils.ORDERBY_TITLE });
77      Collection<String> params = new ArrayList<String>();
78      Collection<SearchResult> result = unifiedSearchService_.search(null,
79                                                                     query.getText(),
80                                                                     params,
81                                                                     0,
82                                                                     10,
83                                                                     query.getOrderBy()[0],
84                                                                     query.getOrderType());
85      assertNotNull(result);
86      assertEquals(0, result.size());
87  
88      // create/get calendar in private folder
89      Calendar cal = createPrivateCalendar(username, "myCalendar", "Description");
90  
91      // =Test search generic type=//
92      // Search summary
93      CalendarEvent calEvent = createUserEvent(username,
94                                               cal.getId(),
95                                               "do you getting Have some busy day?",
96                                               "", true);
97      List<String> ids = new ArrayList<String>();
98      ids.add(cal.getId());
99      List<CalendarEvent> data = calendarService_.getUserEventByCalendar(username, ids);
100     // Success to add event
101     assertEquals(1, data.size());
102 
103     // =Keyword to search=//
104     keyword = "Have \"you getting\" busy";
105     query.setText(keyword);
106     result = unifiedSearchService_.search(null,
107                                           query.getText(),
108                                           params,
109                                           0,
110                                           10,
111                                           query.getOrderBy()[0],
112                                           query.getOrderType());
113     // Success to search
114     assertEquals(1, result.size());
115     for (SearchResult item : result) {
116       checkFieldsValueWithType(cal.getName(), calEvent, item);
117     }
118 
119     // Search summary and description
120     calEvent.setDescription("we have meeting with CEO");
121     calendarService_.saveUserEvent(username, cal.getId(), calEvent, false);
122     keyword = "do \"you getting\" CEO";
123     query.setText(keyword);
124     result = unifiedSearchService_.search(null,
125                                           query.getText(),
126                                           params,
127                                           0,
128                                           10,
129                                           query.getOrderBy()[0],
130                                           query.getOrderType());
131     // Success to search
132     assertEquals(1, result.size());
133     for (SearchResult item : result) {
134       checkFieldsValueWithType(cal.getName(), calEvent, item);
135     }
136 
137     // Search summary , description and location
138     calEvent.setLocation("in Hanoi");
139     calendarService_.saveUserEvent(username, cal.getId(), calEvent, false);
140     keyword = "hanoi CEO";
141     query.setText(keyword);
142     query.setOrderBy(new String[] { Utils.ORDERBY_DATE });
143     result = unifiedSearchService_.search(null,
144                                           query.getText(),
145                                           params,
146                                           0,
147                                           10,
148                                           query.getOrderBy()[0],
149                                           query.getOrderType());
150     // Success to search
151     assertEquals(1, result.size());
152     for (SearchResult item : result) {
153       checkFieldsValueWithType(cal.getName(), calEvent, item);
154     }
155 
156     // == test event search ==//
157     calEvent.setEventType(CalendarEvent.TYPE_EVENT);
158     calendarService_.saveUserEvent(username, cal.getId(), calEvent, false);
159     query.setOrderBy(new String[] { Utils.ORDERBY_RELEVANCY });
160     result = eventSearchConnector_.search(null,
161                                           query.getText(),
162                                           params,
163                                           0,
164                                           10,
165                                           query.getOrderBy()[0],
166                                           query.getOrderType());
167     assertEquals(1, result.size());
168     for (SearchResult item : result) {
169       checkFieldsValueWithType(cal.getName(), calEvent, item);
170     }
171   }
172 
173   public void testSearchResultURL() throws Exception {
174     Calendar cal = createPrivateCalendar(username, "myCalendar", "Description");
175     createUserEvent(username, cal.getId(), "do you getting", "", true);
176 
177     String siteName = "classic";
178     // test search context to build url
179     SearchContext sc = new SearchContext(loadConfiguration("conf/portal/controller.xml"), siteName);
180     assertNotNull(sc);
181     sc.lang("en");
182     Router rt = sc.getRouter();
183     assertNotNull(rt);
184     ExoContainerContext context = (ExoContainerContext) ExoContainerContext.getCurrentContainer()
185                                                                            .getComponentInstanceOfType(ExoContainerContext.class);
186     String portalName = context.getPortalContainerName();
187 
188     // router page expected return /portal/intranet/calendar
189     String spaceGroupId = null;
190     String url = unifiedSearchService_.getUrl(rt,
191                                               portalName,
192                                               siteName,
193                                               spaceGroupId,
194                                               Utils.PAGE_NAGVIGATION);
195     assertEquals("/" + portalName + "/" + siteName + "/" + Utils.PAGE_NAGVIGATION, url);
196     spaceGroupId = "/spaces/space1";
197     // router space expected return /portal/g/:spaces:space1/space1/calendar
198     url = unifiedSearchService_.getUrl(rt,
199                                        portalName,
200                                        siteName,
201                                        spaceGroupId,
202                                        Utils.PAGE_NAGVIGATION);
203     assertEquals("/" + portalName + "/g/" + spaceGroupId.replaceAll(Utils.SLASH, ":") + "/space1/"
204         + Utils.PAGE_NAGVIGATION, url);
205 
206     EventQuery query = new UnifiedQuery();
207     query.setQueryType(Query.SQL);
208     query.setText("do you getting");
209     query.setOrderType(Utils.ORDER_TYPE_ASCENDING);
210     query.setOrderBy(new String[] { Utils.ORDERBY_TITLE });
211     Collection<String> params = new ArrayList<String>();
212     Collection<SearchResult> result = eventSearchConnector_.search(sc,
213                                                                    query.getText(),
214                                                                    params,
215                                                                    0,
216                                                                    10,
217                                                                    query.getOrderBy()[0],
218                                                                    query.getOrderType());
219     assertEquals(1, result.size());
220 
221     url = unifiedSearchService_.getUrl(rt, portalName, siteName, null, Utils.PAGE_NAGVIGATION);
222     for (SearchResult sr : result) {
223       checkFields(sr);
224       assertEquals(url + Utils.SLASH + Utils.DETAIL_PATH + Utils.SLASH
225                        + sr.getUrl().split(Utils.SLASH)[sr.getUrl().split(Utils.SLASH).length - 1],
226                    sr.getUrl());
227     }
228 
229     // site name null
230     sc = new SearchContext(loadConfiguration("conf/portal/controller.xml"), null);
231     sc.lang("en");
232     siteName = Utils.DEFAULT_SITENAME;
233     spaceGroupId = null;
234     url = unifiedSearchService_.getUrl(rt,
235                                        portalName,
236                                        siteName,
237                                        spaceGroupId,
238                                        Utils.PAGE_NAGVIGATION);
239     assertEquals("/" + portalName + "/" + siteName + "/" + Utils.PAGE_NAGVIGATION, url);
240     spaceGroupId = "/spaces/space1";
241     // router space expected return /portal/g/:spaces:space1/space1/calendar
242     url = unifiedSearchService_.getUrl(rt,
243                                        portalName,
244                                        siteName,
245                                        spaceGroupId,
246                                        Utils.PAGE_NAGVIGATION);
247     assertEquals("/" + portalName + "/g/" + spaceGroupId.replaceAll(Utils.SLASH, ":") + "/space1/"
248         + Utils.PAGE_NAGVIGATION, url);
249     result = eventSearchConnector_.search(sc,
250                                           query.getText(),
251                                           params,
252                                           0,
253                                           10,
254                                           query.getOrderBy()[0],
255                                           query.getOrderType());
256     assertEquals(1, result.size());
257     url = unifiedSearchService_.getUrl(rt, portalName, siteName, null, "");
258     for (SearchResult sr : result) {
259       checkFields(sr);
260       assertEquals(url + Utils.SLASH + Utils.DETAIL_PATH + Utils.SLASH
261                        + sr.getUrl().split(Utils.SLASH)[sr.getUrl().split(Utils.SLASH).length - 1],
262                    sr.getUrl());
263     }
264   }
265 
266   public void testSearchWithDate() throws Exception {
267     Calendar cal = createPrivateCalendar(username, "root calendar", "");
268     CalendarEvent inPassEvent = createUserEvent(username, cal.getId(), "Summary CEO", "Hanoi", true);
269     java.util.Calendar current = java.util.Calendar.getInstance();
270     current.add(java.util.Calendar.HOUR_OF_DAY, -1);
271     inPassEvent.setFromDateTime(current.getTime());
272     current.add(java.util.Calendar.MINUTE, 30);
273     inPassEvent.setToDateTime(current.getTime());
274     calendarService_.saveUserEvent(username, cal.getId(), inPassEvent, false);
275 
276     List<CalendarEvent> events = calendarService_.getUserEventByCalendar(username,
277                                                                          Arrays.asList(new String[] { cal.getId() }));
278     assertEquals(1, events.size());
279 
280     // Test case search only up coming events only
281     EventQuery query = new UnifiedQuery();
282     query.setQueryType(Query.SQL);
283     query.setText("Hanoi CEO");
284     query.setOrderType(Utils.ORDER_TYPE_ASCENDING);
285     query.setOrderBy(new String[] { Utils.ORDERBY_TITLE });
286     Collection<String> params = new ArrayList<String>();
287     Collection<SearchResult> result = eventSearchConnector_.search(null,
288                                                                    query.getText(),
289                                                                    params,
290                                                                    0,
291                                                                    10,
292                                                                    query.getOrderBy()[0],
293                                                                    query.getOrderType());
294     assertEquals(0, result.size());
295 
296     current = java.util.Calendar.getInstance();
297     current.add(java.util.Calendar.MINUTE, 1);
298     inPassEvent.setFromDateTime(current.getTime());
299     current.add(java.util.Calendar.MINUTE, 30);
300     inPassEvent.setToDateTime(current.getTime());
301     calendarService_.saveUserEvent(username, cal.getId(), inPassEvent, false);
302     result = eventSearchConnector_.search(null,
303                                           query.getText(),
304                                           params,
305                                           0,
306                                           10,
307                                           query.getOrderBy()[0],
308                                           query.getOrderType());
309     assertEquals(1, result.size());
310   }
311 
312   public void testSearchPermission() throws Exception {
313     String john = "john";
314     // Test query filter by permission
315     Calendar johnCalendar = createPrivateCalendar(john, "johnCalendar", "");
316     createUserEvent(john,
317                     johnCalendar.getId(),
318                     "Summary CEO come we will have some dayoff",
319                     "Hanoi",
320                     true);
321 
322     EventQuery query = new UnifiedQuery();
323     query.setQueryType(Query.SQL);
324     query.setText("Hanoi CEO");
325     query.setOrderType(Utils.ORDER_TYPE_ASCENDING);
326     query.setOrderBy(new String[] { Utils.ORDERBY_TITLE });
327 
328     login(john);
329     Collection<String> params = new ArrayList<String>();
330     Collection<SearchResult> result = eventSearchConnector_.search(null,
331                                                                    query.getText(),
332                                                                    params,
333                                                                    0,
334                                                                    10,
335                                                                    query.getOrderBy()[0],
336                                                                    query.getOrderType());
337     assertEquals(1, result.size());
338 
339     login(username);
340     result = eventSearchConnector_.search(null,
341                                           query.getText(),
342                                           params,
343                                           0,
344                                           10,
345                                           query.getOrderBy()[0],
346                                           query.getOrderType());
347     assertEquals(0, result.size());
348   }
349 
350   public void testSearchOrder() throws Exception {
351     Calendar cal = createPrivateCalendar(username, "myCalendar", "Description");
352     CalendarEvent calEvent = createUserEvent(username,
353                                              cal.getId(),
354                                              "today is friday, we will have a weekend",
355                                              "",
356                                              true);
357     CalendarEvent calEvent2 = createUserEvent(username,
358                                               cal.getId(),
359                                               "Summary CEO come we will have some dayoff",
360                                               "friday", true);
361 
362     String keyword = "\"we will have\" friday";
363     EventQuery query = new UnifiedQuery();
364     query.setText(keyword);
365     query.setOrderType(Utils.ORDER_TYPE_DESCENDING);
366     query.setOrderBy(new String[] { Utils.ORDERBY_RELEVANCY });
367     Collection<String> params = new ArrayList<String>();
368     Collection<SearchResult> result = eventSearchConnector_.search(null,
369                                                                    query.getText(),
370                                                                    params,
371                                                                    0,
372                                                                    10,
373                                                                    query.getOrderBy()[0],
374                                                                    query.getOrderType());
375     assertEquals(2, result.size());
376     SearchResult item = (SearchResult) result.toArray()[0];
377     checkFields(item);
378     SearchResult item2 = (SearchResult) result.toArray()[1];
379     checkFields(item2);
380     assertEquals(false, item2.getRelevancy() > item.getRelevancy());
381 
382     query.setOrderBy(new String[] { Utils.ORDERBY_DATE });
383     query.setOrderType(Utils.ORDER_TYPE_ASCENDING);
384     result = eventSearchConnector_.search(null,
385                                           query.getText(),
386                                           params,
387                                           0,
388                                           10,
389                                           query.getOrderBy()[0],
390                                           query.getOrderType());
391     assertEquals(2, result.size());
392     CalendarSearchResult calSerResult = (CalendarSearchResult) result.toArray()[0];
393     checkFields(calSerResult);
394     checkFieldsValueWithType(cal.getName(), calEvent, calSerResult);
395     CalendarSearchResult calSerResult2 = (CalendarSearchResult) result.toArray()[1];
396     checkFields(calSerResult2);
397     checkFieldsValueWithType(cal.getName(), calEvent2, calSerResult2);
398     assertEquals(true, item.getDate() < item2.getDate());
399   }
400 
401   public void testUnifiedSeachEx() throws Exception {
402     login(username);
403     String calId = createPrivateCalendar(username, "root calendar", "").getId();
404     createUserEvent(username, calId, "how do you do root", "you are a search able event", false);
405     createUserEvent(username, calId, "are you here?", "I am not search able event with john", false);
406 
407     String john = "john";
408     calendarService_.shareCalendar(username, calId, Arrays.asList(new String[] { john }));
409 
410     // Simple case
411     String keyword = "you are search able";
412     EventQuery query = new UnifiedQuery();
413     query.setText(keyword);
414     query.setOrderType(Utils.ORDER_TYPE_ASCENDING);
415     query.setOrderBy(new String[] { Utils.ORDERBY_TITLE });
416     Collection<String> params = new ArrayList<String>();
417 
418     Collection<SearchResult> result = unifiedSearchService_.search(null,
419                                                                    query.getText(),
420                                                                    params,
421                                                                    0,
422                                                                    10,
423                                                                    query.getOrderBy()[0],
424                                                                    query.getOrderType());
425     assertNotNull(result);
426     assertEquals(2, result.size());
427 
428     login(john);
429     result = unifiedSearchService_.search(null,
430                                           query.getText(),
431                                           params,
432                                           0,
433                                           10,
434                                           query.getOrderBy()[0],
435                                           query.getOrderType());
436     assertEquals(2, result.size());
437   }
438 
439   public void testUnifiedSeachAllWord() throws Exception {
440     String keyword = "abcde fghik";
441     Calendar cal = createPrivateCalendar(username, "root calendar", "");
442 
443     createUserEvent(cal.getId(), null, keyword);
444     createUserEvent(cal.getId(), null, "abcde");
445     createUserEvent(cal.getId(), null, "fghik");
446 
447     // Simple case
448     EventQuery query = new UnifiedQuery();
449     query.setText(keyword);
450     Collection<String> params = new ArrayList<String>();
451     query.setOrderType(Utils.ORDER_TYPE_ASCENDING);
452     query.setOrderBy(new String[] { Utils.ORDERBY_TITLE });
453     Collection<SearchResult> result = unifiedSearchService_.search(null,
454                                                                    query.getText(),
455                                                                    params,
456                                                                    0,
457                                                                    10,
458                                                                    query.getOrderBy()[0],
459                                                                    query.getOrderType());
460     assertNotNull(result);
461     assertEquals(result.size(), 1);
462     assertEquals(keyword, result.iterator().next().getTitle());
463   }
464 
465   public void testSearchSpecialCharacter() throws Exception {
466     String keyword = "Have a%'\\_-\". meeting";
467     createUserEvent(keyword);
468 
469     EventQuery query = new EventQuery();
470     query.setText(keyword);
471 
472     query.setQueryType(Query.XPATH);
473     assertEquals(1, calendarService_.searchEvent(username, query, new String[] {}).getAll().size());
474     assertEquals(1, calendarService_.getEvents(username, query, new String[] {}).size());
475 
476     query.setQueryType(Query.SQL);
477     assertEquals(1, calendarService_.searchEvent(username, query, new String[] {}).getAll().size());
478     assertEquals(1, calendarService_.getEvents(username, query, new String[] {}).size());
479 
480     EventQuery uQuery = new UnifiedQuery();
481     uQuery.setText(keyword);
482     Collection<String> params = new ArrayList<String>();
483     uQuery.setOrderType(Utils.ORDER_TYPE_ASCENDING);
484     uQuery.setOrderBy(new String[] { Utils.ORDERBY_TITLE });
485     Collection<SearchResult> result = unifiedSearchService_.search(null,
486                                                                    uQuery.getText(),
487                                                                    params,
488                                                                    0,
489                                                                    10,
490                                                                    uQuery.getOrderBy()[0],
491                                                                    uQuery.getOrderType());
492     assertNotNull(result);
493     assertEquals(1, result.size());
494   }
495 
496   public void testMultiThreadSearch() throws Exception {
497     String keyword = "Have a meeting";
498 
499     List<Calendar> calendars = new LinkedList<Calendar>();
500     for (int i = 0; i < 100; i++) {
501       Calendar cal = new Calendar();
502       cal.setName("CalendarName" + i);
503       calendarService_.saveUserCalendar(username, cal, true);
504       calendars.add(cal);
505 
506       CalendarEvent calEvent = createCalendarEventInstance(keyword);
507       calendarService_.saveUserEvent(username, cal.getId(), calEvent, true);
508     }
509 
510     final EventQuery uQuery = new UnifiedQuery();
511     uQuery.setText(keyword);
512     final Collection<String> params = new ArrayList<String>();
513     uQuery.setOrderType(Utils.ORDER_TYPE_ASCENDING);
514     uQuery.setOrderBy(new String[] { Utils.ORDERBY_TITLE });
515 
516     final AtomicBoolean fail = new AtomicBoolean(false);
517     final CountDownLatch wait = new CountDownLatch(1);
518     final PortalContainer container = getContainer();
519     Runnable runner = new Runnable() {
520       @Override
521       public void run() {
522         ExoContainerContext.setCurrentContainer(container);
523         try {
524           wait.await();
525         } catch (InterruptedException e) {
526         }
527         begin();
528         login(username);
529         Collection<SearchResult> result = unifiedSearchService_.search(null,
530                                                                        uQuery.getText(),
531                                                                        params,
532                                                                        0,
533                                                                        -1,
534                                                                        uQuery.getOrderBy()[0],
535                                                                        uQuery.getOrderType());
536         if (result == null || result.size() < 100) {
537           fail.set(true);
538         }
539         end();
540         ExoContainerContext.setCurrentContainer(null);
541       }
542     };
543 
544     List<Thread> threads = new LinkedList<Thread>();
545     for (int i = 0; i < 20; i++) {
546       Thread t = new Thread(runner);
547       t.start();
548       threads.add(t);
549     }
550     wait.countDown();
551 
552     // wait for all threads complete
553     for (Thread t : threads) {
554       t.join();
555     }
556 
557     assertFalse(fail.get());
558   }
559   
560   public void testUnifiedSeachDetail() throws Exception {
561     login(username);
562     Calendar cal = new Calendar();
563     cal.setName("root calendar");
564     cal.setTimeZone(TimeZone.getAvailableIDs(0)[0]); //GMT+0
565     calendarService_.saveUserCalendar(username, cal, true);
566     CalendarSetting calSetting = calendarService_.getCalendarSetting(username);
567 
568     String keyword = "test";
569     CalendarEvent calEvent = createUserEvent(username, cal.getId(), keyword, "", true);
570     java.util.Calendar fromCal = java.util.Calendar.getInstance();
571     fromCal.setTime(calEvent.getFromDateTime());
572 
573     //Simple case
574     EventQuery query = new UnifiedQuery();
575     query.setText(keyword);
576     Collection<String> params = new ArrayList<String>();
577     query.setOrderType(Utils.ORDER_TYPE_ASCENDING);
578     query.setOrderBy(new String[]{Utils.ORDERBY_TITLE});
579     Collection<SearchResult> result = unifiedSearchService_.search(null, query.getText(), params, 0, 10, query.getOrderBy()[0] , query.getOrderType());
580     assertNotNull(result);
581     assertEquals(result.size(), 1);
582     SearchResult r = result.iterator().next();
583     assertEquals(keyword, r.getTitle());
584     
585     SimpleDateFormat df = new SimpleDateFormat(Utils.DATE_TIME_FORMAT);
586     df.setTimeZone(DateUtils.getTimeZone(calSetting.getTimeZone()));
587     String detail = "root calendar - " + df.format(fromCal.getTime());
588     assertEquals(detail, r.getDetail());
589   }
590 
591   public void testUnifiedSearchInReadOnlySharedCalendar() throws Exception {
592     java.util.Calendar fromCal = java.util.Calendar.getInstance();
593     fromCal.add(java.util.Calendar.MINUTE, 5);
594     java.util.Calendar toCal = java.util.Calendar.getInstance();
595     toCal.add(java.util.Calendar.MINUTE, 65);
596 
597     String keyword = "search this event" ;
598     String publicEventTitle = "UnifiedSearchWithPublicEventInReadonlySharedCalendar";
599     String privateEventTitle = "UnifiedSearchWithPrivateEventInReadonlySharedCalendar";
600 
601     //. Create shared calendar
602     login(username);
603 
604     // Create calendar and share with John
605     Calendar cal = new Calendar() ;
606     cal.setName("root shared calendar as readonly");
607     calendarService_.saveUserCalendar(username, cal, true);
608     calendarService_.shareCalendar(username, cal.getId(), Arrays.asList("john"));
609 
610     //. Create public event
611     CalendarEvent pubEvent = new CalendarEvent();
612     pubEvent.setFromDateTime(fromCal.getTime());
613     pubEvent.setToDateTime(toCal.getTime());
614     pubEvent.setSummary(publicEventTitle);
615     pubEvent.setDescription("you can search this event");
616     pubEvent.setCalendarId(cal.getId());
617     pubEvent.setPrivate(false);
618     calendarService_.saveUserEvent(username, cal.getId(),pubEvent, true);
619 
620     // Create private event
621     CalendarEvent priEvent = new CalendarEvent();
622     priEvent.setFromDateTime(fromCal.getTime());
623     priEvent.setToDateTime(toCal.getTime());
624     priEvent.setSummary(privateEventTitle);
625     priEvent.setDescription("you can not search this event");
626     priEvent.setCalendarId(cal.getId());
627     priEvent.setPrivate(true);
628     calendarService_.saveUserEvent(username, cal.getId(), priEvent, true);
629 
630     login("john");
631     Collection<SearchResult> result = unifiedSearchService_.search(null, keyword, Arrays.<String>asList(), 0, 10, Utils.ORDERBY_TITLE , Utils.ORDER_TYPE_ASCENDING);
632     assertNotFoundInSearchResults(privateEventTitle, result);
633     assertFoundInSearchResults(publicEventTitle, result);
634   }
635 
636   public void testUnifiedSearchInEditableSharedCalendar() throws Exception {
637     java.util.Calendar fromCal = java.util.Calendar.getInstance();
638     fromCal.add(java.util.Calendar.MINUTE, 5);
639     java.util.Calendar toCal = java.util.Calendar.getInstance();
640     toCal.add(java.util.Calendar.MINUTE, 65);
641 
642     String keyword = "search this event";
643     String publicEventTitle = "UnifiedSearchWithPublicEventInEditableSharedCalendar";
644     String privateEventTitle = "UnifiedSearchWithPrivateEventInEditableSharedCalendar";
645 
646     //. Create shared calendar
647     login(username);
648 
649     // Create calendar and share with John
650     Calendar cal = new Calendar() ;
651     cal.setName("root shared calendar as editable");
652     calendarService_.saveUserCalendar(username, cal, true);
653     calendarService_.shareCalendar(username, cal.getId(), Arrays.asList("john"));
654     // User John have permission on this calendar
655     cal.setEditPermission(new String[]{"john"});
656     calendarService_.saveUserCalendar(username, cal, false);
657 
658 
659     //. Create public event
660     CalendarEvent pubEvent = new CalendarEvent();
661     pubEvent.setFromDateTime(fromCal.getTime());
662     pubEvent.setToDateTime(toCal.getTime());
663     pubEvent.setSummary(publicEventTitle);
664     pubEvent.setDescription("you can search this event");
665     pubEvent.setCalendarId(cal.getId());
666     pubEvent.setPrivate(false);
667     calendarService_.saveUserEvent(username, cal.getId(),pubEvent, true);
668 
669     // Create private event
670     CalendarEvent priEvent = new CalendarEvent();
671     priEvent.setFromDateTime(fromCal.getTime());
672     priEvent.setToDateTime(toCal.getTime());
673     priEvent.setSummary(privateEventTitle);
674     priEvent.setDescription("you can still search this event");
675     priEvent.setCalendarId(cal.getId());
676     priEvent.setPrivate(true);
677     calendarService_.saveUserEvent(username, cal.getId(), priEvent, true);
678 
679     login("john");
680     Collection<SearchResult> results = unifiedSearchService_.search(null, keyword, Arrays.<String>asList(), 0, 10, Utils.ORDERBY_TITLE , Utils.ORDER_TYPE_ASCENDING);
681     assertFoundInSearchResults(privateEventTitle, results);
682     assertFoundInSearchResults(publicEventTitle, results);
683   }
684 
685   public void testUnifiedSearchInReadOnlyGroupCalendar() throws Exception {
686     java.util.Calendar fromCal = java.util.Calendar.getInstance();
687     fromCal.add(java.util.Calendar.MINUTE, 5);
688     java.util.Calendar toCal = java.util.Calendar.getInstance();
689     toCal.add(java.util.Calendar.MINUTE, 65);
690 
691     String keyword = "search this event";
692     String publicEventTitle = "UnifiedSearchWithPublicEventInReadonlyGroupCalendar";
693     String privateEventTitle = "UnifiedSearchWithPrivateEventInReadonlyGroupCalendar";
694 
695     //. Create shared calendar
696     login(username);
697 
698     // Create group calendar
699     Calendar cal = new Calendar();
700     cal.setName("Group calendar");
701     cal.setDescription("user group calendar");
702     cal.setPublic(true);
703     cal.setGroups(new String[]{"/platform/users"});
704     calendarService_.savePublicCalendar(cal, true);
705 
706 
707     //. Create public event
708     CalendarEvent pubEvent = new CalendarEvent();
709     pubEvent.setFromDateTime(fromCal.getTime());
710     pubEvent.setToDateTime(toCal.getTime());
711     pubEvent.setSummary(publicEventTitle);
712     pubEvent.setDescription("you can search this event");
713     pubEvent.setCalendarId(cal.getId());
714     pubEvent.setPrivate(false);
715     calendarService_.savePublicEvent(cal.getId(), pubEvent, true);
716 
717     // Create private event
718     CalendarEvent priEvent = new CalendarEvent();
719     priEvent.setFromDateTime(fromCal.getTime());
720     priEvent.setToDateTime(toCal.getTime());
721     priEvent.setSummary(privateEventTitle);
722     priEvent.setDescription("you can not search this event");
723     priEvent.setCalendarId(cal.getId());
724     priEvent.setPrivate(true);
725     calendarService_.savePublicEvent(cal.getId(), priEvent, true);
726 
727     login("john");
728     Collection<SearchResult> result = unifiedSearchService_.search(null, keyword, Arrays.<String>asList(), 0, 10, Utils.ORDERBY_TITLE , Utils.ORDER_TYPE_ASCENDING);
729     assertNotFoundInSearchResults(privateEventTitle, result);
730     assertFoundInSearchResults(publicEventTitle, result);
731   }
732 
733   public void testUnifiedSearchInEditableGroupCalendar() throws Exception {
734     java.util.Calendar fromCal = java.util.Calendar.getInstance();
735     fromCal.add(java.util.Calendar.MINUTE, 5);
736     java.util.Calendar toCal = java.util.Calendar.getInstance();
737     toCal.add(java.util.Calendar.MINUTE, 65);
738 
739     String keyword = "search this event";
740     String publicEventTitle = "UnifiedSearchWithPublicEventInEditableGroupCalendar";
741     String privateEventTitle = "UnifiedSearchWithPrivateEventInEditableGroupCalendar";
742 
743     //. Create shared calendar
744     login(username);
745 
746     // Create group calendar
747     Calendar cal = new Calendar();
748     cal.setName("Group calendar");
749     cal.setDescription("user group calendar");
750     cal.setPublic(true);
751     cal.setGroups(new String[]{"/platform/users"});
752     calendarService_.savePublicCalendar(cal, true);
753     cal.setEditPermission(new String[]{"john"});
754     calendarService_.savePublicCalendar(cal, false);
755 
756 
757     //. Create public event
758     CalendarEvent pubEvent = new CalendarEvent();
759     pubEvent.setFromDateTime(fromCal.getTime());
760     pubEvent.setToDateTime(toCal.getTime());
761     pubEvent.setSummary(publicEventTitle);
762     pubEvent.setDescription("you can search this event");
763     pubEvent.setCalendarId(cal.getId());
764     pubEvent.setPrivate(false);
765     calendarService_.savePublicEvent(cal.getId(), pubEvent, true);
766 
767     // Create private event
768     CalendarEvent priEvent = new CalendarEvent();
769     priEvent.setFromDateTime(fromCal.getTime());
770     priEvent.setToDateTime(toCal.getTime());
771     priEvent.setSummary(privateEventTitle);
772     priEvent.setDescription("you can still search this event");
773     priEvent.setCalendarId(cal.getId());
774     priEvent.setPrivate(true);
775     calendarService_.savePublicEvent(cal.getId(), priEvent, true);
776 
777     login("john");
778     Collection<SearchResult> result = unifiedSearchService_.search(null, keyword, Arrays.<String>asList(), 0, 10, Utils.ORDERBY_TITLE , Utils.ORDER_TYPE_ASCENDING);
779     assertFoundInSearchResults(privateEventTitle, result);
780     assertFoundInSearchResults(publicEventTitle, result);
781   }
782 
783   public void assertNotFoundInSearchResults(String eventTitle, Collection<SearchResult> results) {
784     for(SearchResult result : results) {
785       if(result.getTitle().equals(eventTitle)) {
786         fail("The event with title " + eventTitle + " should not found in search");
787       }
788     }
789   }
790   public void assertFoundInSearchResults(String eventTitle, Collection<SearchResult> results) {
791     for (SearchResult result : results) {
792       if (result.getTitle().equals(eventTitle)) {
793         return;
794       }
795     }
796     fail("The event with title " + eventTitle + " should be returned in search");
797   }
798 
799   //mvn test -Dtest=TestCalendarService#testUnifiedSearchWithSpecialCharacter
800   public void testUnifiedSearchWithSpecialCharacter() throws Exception {
801     final String specialCharacter = "!.,:;\"'()\"-@#$%^~*<>?/}{[]-=|\\";
802 
803     login(username);
804 
805     // Create calendar
806     Calendar calendar = new Calendar();
807     calendar.setName("testUnifiedSeachWitchSpecialCharacter");
808     calendar.setDescription("testUnifiedSeachWitchSpecialCharacter");
809     calendar.setPublic(false);
810     calendarService_.saveUserCalendar(username, calendar, true);
811 
812     // Create category
813     EventCategory category = new EventCategory();
814     category.setName("testUnifiedSeachWitchSpecialCharacter");
815     calendarService_.saveEventCategory(username, category, true);
816 
817     // Create event with special character
818     CalendarEvent event = this.createUserEvent(username, calendar.getId(), "" + specialCharacter, "Event with " + specialCharacter, false);
819     //calendarService_.saveUserEvent(username, calendar.getId(), event, true);
820 
821     EventQuery query = new UnifiedQuery();
822     query.setOrderType(Utils.ORDER_TYPE_ASCENDING);
823     query.setOrderBy(new String[]{Utils.ORDERBY_TITLE});
824     Collection<String> params = new ArrayList<String>();
825 
826     // Search with with all special key
827     String keyword = specialCharacter + "~0.5" ;
828     query.setText(keyword);
829     Collection<SearchResult> results = unifiedSearchService_.search(null, query.getText(), params, 0, 10, query.getOrderBy()[0] , query.getOrderType());
830     assertEquals(0, results.size());
831 
832     // Search with 1 special character
833     for(int i = 0; i < specialCharacter.length(); i++) {
834       keyword = specialCharacter.charAt(i) + "~0.5";
835       query.setText(keyword) ;
836       results = unifiedSearchService_.search(null, query.getText(), params, 0, 10, query.getOrderBy()[0] , query.getOrderType());
837       // I can not assert here because some special character like * is accepted and it will return all existing event
838       //assertEquals(0, results.size());
839     }
840 
841     //
842     for(int i = 0; i < specialCharacter.length(); i++) {
843       keyword = "gatein" + specialCharacter.charAt(i) + "~0.5";
844       query.setText(keyword) ;
845       results = unifiedSearchService_.search(null, query.getText(), params, 0, 10, query.getOrderBy()[0] , query.getOrderType());
846       assertEquals(0, results.size());
847     }
848 
849     //
850     for(int i = 0; i < specialCharacter.length(); i++) {
851       keyword = "gatein3" + specialCharacter.charAt(i) + "5~0.5";
852       query.setText(keyword) ;
853       results = unifiedSearchService_.search(null, query.getText(), params, 0, 10, query.getOrderBy()[0] , query.getOrderType());
854       assertEquals(0, results.size());
855     }
856 
857     //
858     for(int i = 0; i < specialCharacter.length(); i++) {
859       keyword = "3" + specialCharacter.charAt(i) + "5~0.5";
860       query.setText(keyword) ;
861       results = unifiedSearchService_.search(null, query.getText(), params, 0, 10, query.getOrderBy()[0] , query.getOrderType());
862       assertEquals(0, results.size());
863     }
864   }
865 
866   //mvn test -Dtest=TestCalendarService#testUnifiedSearchWithEmptyKeyword
867   public void testUnifiedSearchWithEmptyKeyword() throws Exception {
868     //. Create calendar and event
869     Calendar calendar = createPrivateCalendar(username, "testUnifiedSeachWithEmptyKeyword", "testUnifiedSeachWithEmptyKeyword");
870     createUserEvent(username, calendar.getId(), "testUnifiedSeachWithEmptyKeyword", "testUnifiedSeachWithEmptyKeyword", false);
871 
872     EventQuery query = new UnifiedQuery();
873     query.setOrderType(Utils.ORDER_TYPE_ASCENDING);
874     query.setOrderBy(new String[]{Utils.ORDERBY_TITLE});
875     Collection<String> params = new ArrayList<String>();
876 
877     // keyword is empty string
878     String keyword = "";
879     query.setText(keyword);
880     Collection<SearchResult> results = unifiedSearchService_.search(null, query.getText(), params, 0, 10, query.getOrderBy()[0] , query.getOrderType());
881     assertEquals(0, results.size());
882 
883     // keyword contains only space character
884     keyword = "  ";
885     query.setText(keyword);
886     results = unifiedSearchService_.search(null, query.getText(), params, 0, 10, query.getOrderBy()[0] , query.getOrderType());
887     assertEquals(0, results.size());
888   }
889 
890   public void testSearchEventEndInFuture() throws Exception {
891     Calendar calendar = createPrivateCalendar(username, "testSearchEventEndInFuture", "");
892     //. Create event start from past and end in future
893     java.util.Calendar fromCal = java.util.Calendar.getInstance();
894     fromCal.add(java.util.Calendar.HOUR_OF_DAY, -1);
895     java.util.Calendar toCal = java.util.Calendar.getInstance();
896     toCal.add(java.util.Calendar.HOUR_OF_DAY, 2);
897 
898     CalendarEvent event = createUserEvent(calendar.getId(), null, "testSearchEventEndInFuture", true, fromCal, toCal);
899 
900     EventQuery query = new UnifiedQuery();
901     query.setText("testSearchEventEndInFuture~0.5");
902     query.setOrderType(Utils.ORDER_TYPE_ASCENDING);
903     query.setOrderBy(new String[]{Utils.ORDERBY_TITLE});
904     Collection<String> params = new ArrayList<String>();
905 
906     Collection<SearchResult> results = eventSearchConnector_.search(null, query.getText(), params, 0, 10, query.getOrderBy()[0] , query.getOrderType());
907     assertFoundInSearchResults(event.getSummary(), results);
908   }
909 
910   private CalendarEvent createUserEvent(String username, String calId, String summary, String desc, boolean isPrivate) throws Exception {
911     CalendarEvent calEvent = createCalendarEventInstance(summary);
912     calEvent.setDescription(desc);
913     calEvent.setPrivate(isPrivate);
914     calendarService_.saveUserEvent(username, calId, calEvent, true);
915     return calEvent;
916   }
917 
918   // TODO: @nttuyen consider move it to common
919   private Router loadConfiguration(String path) throws IOException {
920     InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(path);
921     try {
922       ControllerDescriptor routerDesc = new DescriptorBuilder().build(in);
923       return new Router(routerDesc);
924     } catch (RouterConfigException e) {
925       log.info(e.getMessage());
926     } finally {
927       in.close();
928     }
929     return null;
930   }
931 
932   private void checkFieldsValueWithType(String calName,
933                                         CalendarEvent calEvent,
934                                         CalendarSearchResult item) {
935     checkFieldsValueWithType(calName, calEvent, (SearchResult) item);
936     if (CalendarEvent.TYPE_EVENT.equals(calEvent.getEventType())) {
937       assertEquals(item.getFromDateTime(), calEvent.getFromDateTime().getTime());
938       assertNull(item.getImageUrl());
939       assertEquals(Utils.EVENT_ICON_URL, item.getImageUrl());
940     }
941     assertNotNull(item.getTimeZoneName());
942   }
943 
944   private void checkFieldsValueWithType(String calName, CalendarEvent calEvent, SearchResult item) {
945     assertEquals(calEvent.getSummary(), item.getTitle());
946     if (CalendarEvent.TYPE_EVENT.equals(calEvent.getEventType())) {
947       if (calEvent.getLocation() != null)
948         assertEquals(calName + Utils.SPACE + Utils.MINUS + Utils.SPACE
949                          + df.format(calEvent.getFromDateTime()) + Utils.SPACE + Utils.MINUS
950                          + Utils.SPACE + calEvent.getLocation(),
951                      item.getDetail());
952     } else {
953       assertEquals(calName + Utils.SPACE + Utils.MINUS + Utils.SPACE + Utils.DUE_FOR
954                        + df.format(calEvent.getToDateTime()),
955                    item.getDetail());
956     }
957     SimpleDateFormat tempFm = new SimpleDateFormat("MM/dd/yyyy hh");
958     assertEquals(tempFm.format(new Date()), tempFm.format(new Date(item.getDate())));
959     assertEquals(true, item.getRelevancy() > 0);
960     // case could not init url
961     assertEquals(Utils.NONE_NAGVIGATION, item.getUrl());
962     StringBuffer sb = new StringBuffer(Utils.EMPTY_STR);
963     if (calEvent.getDescription() != null)
964       sb.append(calEvent.getDescription());
965     assertEquals(sb.toString(), item.getExcerpt());
966   }
967 
968   private void checkFields(SearchResult item) {
969     assertNotNull(item.getTitle());
970     assertNotNull(item.getExcerpt());
971     assertNotNull(item.getDetail());
972     assertNull(item.getImageUrl());
973     assertNotNull(item.getUrl());
974     assertEquals(true, item.getDate() > 0);
975   }
976 
977   private void checkFields(CalendarSearchResult item) {
978     checkFields((SearchResult) (item));
979     assertEquals(item.getDataType(), CalendarEvent.TYPE_EVENT);
980     if (CalendarEvent.TYPE_EVENT.equals(item.getDataType())) {
981       assertNull(item.getImageUrl());
982       assertNull(item.getTaskStatus());
983     }
984   }
985 }