1   package com.atlassian.bonnie.search;
2   
3   import com.atlassian.bonnie.LuceneUtils;
4   import com.atlassian.bonnie.Searchable;
5   
6   import java.util.*;
7   
8   public class TestLuceneSearcher extends BaseLuceneTest
9   {
10      protected void setUp() throws Exception
11      {
12          super.setUp();
13  
14          List<Searchable> searchables = new LinkedList<Searchable>();
15          searchables.add(createSearchableObject(111, "apple", "apple desc"));
16          searchables.add(createSearchableObject(112, "orange", "orange desc"));
17          searchables.add(createSearchableObject(113, "appletwo", "appletwo desc"));
18          searchables.add(createSearchableObject(114, "Pear", "More dull content desc"));
19          index(searchables);
20      }
21  
22      public void testSimpleSearch() throws Exception
23      {
24          List searchHits = luceneSearcher.search(luceneSearcher.buildStandardQuery("description", "\"apple\""));
25  
26          assertNotNull(searchHits);
27          assertEquals(1, searchHits.size());
28          assertEquals(MockSearchableObject.class.getName()+"-111", searchHits.get(0));
29      }
30  
31      public void testLongerSearch() throws Exception
32      {
33          List searchHits = luceneSearcher.search(luceneSearcher.buildStandardQuery("description", "appl*"));
34  
35          assertNotNull(searchHits);
36          assertEquals(2, searchHits.size());
37          assertEquals(MockSearchableObject.class.getName()+"-111", searchHits.get(0));
38          assertEquals(MockSearchableObject.class.getName()+"-113", searchHits.get(1));
39      }
40  
41      public void testMultiFieldSearch() throws Exception
42      {
43          List searchHits = luceneSearcher.search(luceneSearcher.buildStandardQuery(new String[]{"description", "title"}, "apple OR pear"));
44  
45          assertNotNull(searchHits);
46          assertEquals(2, searchHits.size());
47          assertEquals(MockSearchableObject.class.getName()+"-111", searchHits.get(0));
48          assertEquals(MockSearchableObject.class.getName()+"-114", searchHits.get(1));
49      }
50  
51      public void testSearchByClass() throws Exception
52      {
53          MockSearchableObject uniqueClassedObject = createSearchableObjectDifferentClass(115, "fish", "More fish");
54          index(uniqueClassedObject);
55          List searchHits = luceneSearcher.search(LuceneUtils.buildSingleFieldSingleValueTermQuery(BaseDocumentBuilder.FieldName.CLASS_NAME, uniqueClassedObject.getClass().getName()));
56  
57          assertNotNull(searchHits);
58          assertEquals(1, searchHits.size());
59          assertEquals(uniqueClassedObject.getClass().getName() + "-115", searchHits.get(0));
60      }
61  
62      public void testSimpleSearchForFields() throws Exception
63      {
64          List searchHits = luceneSearcher.searchForFields(luceneSearcher.buildStandardQuery("description", "\"apple\""), makeFieldSet("description"), 0, 500);
65  
66          assertNotNull(searchHits);
67          assertEquals(1, searchHits.size());
68          Map result = (Map) searchHits.get(0);
69          assertEquals("apple desc", result.get("description"));
70      }
71  
72      public void testSearchForFieldsNoFieldsSpecified() throws Exception
73      {
74          List searchHits = luceneSearcher.searchForFields(luceneSearcher.buildStandardQuery("description", "\"apple\""), Collections.EMPTY_SET, 0, 500);
75  
76          assertNotNull(searchHits);
77          assertEquals(1, searchHits.size());
78          Map result = (Map) searchHits.get(0);
79          assertNull(result.get("description"));
80          assertEquals(MockSearchableObject.class.getName()+"-111", result.get(BaseDocumentBuilder.FieldName.HANDLE));
81      }
82  
83      public void testSearchForFieldsNullFieldsSpecified() throws Exception
84      {
85          List searchHits = luceneSearcher.searchForFields(luceneSearcher.buildStandardQuery("description", "\"apple\""), Collections.EMPTY_SET, 0, 500);
86  
87          assertNotNull(searchHits);
88          assertEquals(1, searchHits.size());
89          Map result = (Map) searchHits.get(0);
90          assertNull(result.get("description"));
91          assertEquals(MockSearchableObject.class.getName()+"-111", result.get(BaseDocumentBuilder.FieldName.HANDLE));
92      }
93  
94      public void testPagingInSearchForFields() throws Exception
95      {
96          index(createSearchableObject(115, "another apple", "apples again"));
97          index(createSearchableObject(116, "more apples", "more apples desc"));
98  
99          // we should get 4 results back for appl*, but 1 and 4 should be null, we want results 2 and 3 to have values for both fields
100         List searchHits = luceneSearcher.searchForFields(luceneSearcher.buildStandardQuery("description", "appl*"), makeFieldSet("title", "description", BaseDocumentBuilder.FieldName.HANDLE), 1, 2);
101 
102         assertNotNull(searchHits);
103         assertEquals(4, searchHits.size());
104         assertNull(searchHits.get(0));
105         assertNull(searchHits.get(3));
106         Map result = (Map) searchHits.get(1);
107         assertEquals(MockSearchableObject.class.getName()+"-113", result.get(BaseDocumentBuilder.FieldName.HANDLE));
108         assertEquals("appletwo desc", result.get("description"));
109         assertEquals("appletwo", result.get("title"));
110 
111         result = (Map) searchHits.get(2);
112         assertEquals(MockSearchableObject.class.getName()+"-115", result.get(BaseDocumentBuilder.FieldName.HANDLE));
113         assertEquals("apples again", result.get("description"));
114         assertEquals("another apple", result.get("title"));
115     }
116 
117     public void testGetAllFieldValues() throws Exception
118     {
119         index(makeSearchableObjectWithKeyword(200, "title 1", "keyword 1", "1 keyword"));
120         index(makeSearchableObjectWithKeyword(300, "title 2", "keyword 2", "2 keyword"));
121         index(makeSearchableObjectWithKeyword(400, "title 3", "keyword 2", "2 keyword"));
122         index(makeSearchableObjectWithKeyword(500, "title 4", "keyword 3", "1 keyword"));
123 
124         List valuesForKeyword1 = luceneSearcher.getAllFieldValues("keyword1");
125         String valuesForKeywordString1 = valuesForKeyword1.toString();
126 
127         assertEquals("Wanted four results, got: " + valuesForKeywordString1, 4, valuesForKeyword1.size());
128         assertTrue("Wanted empty value, got: " + valuesForKeywordString1, valuesForKeyword1.contains(""));
129         assertTrue("Wanted keyword 1, got: " + valuesForKeywordString1, valuesForKeyword1.contains("keyword 1"));
130         assertTrue("Wanted keyword 2, got: " + valuesForKeywordString1, valuesForKeyword1.contains("keyword 2"));
131         assertTrue("Wanted keyword 3, got: " + valuesForKeywordString1, valuesForKeyword1.contains("keyword 3"));
132 
133         List valuesForKeyword2 = luceneSearcher.getAllFieldValues("keyword2");
134         String valuesForKeywordString2 = valuesForKeyword2.toString();
135 
136         assertEquals("Wanted four results, got: " + valuesForKeywordString2, 3, valuesForKeyword2.size());
137         assertTrue("Wanted empty value, got: " + valuesForKeywordString2, valuesForKeyword2.contains(""));
138         assertTrue("Wanted keyword 1, got: " + valuesForKeywordString2, valuesForKeyword2.contains("1 keyword"));
139         assertTrue("Wanted keyword 2, got: " + valuesForKeywordString2, valuesForKeyword2.contains("2 keyword"));
140     }
141 
142     private Set makeFieldSet(String f1, String f2, String f3)
143     {
144         Set set = new HashSet();
145         set.add(f1);
146         set.add(f2);
147         set.add(f3);
148         return set;
149     }
150 
151     private Set makeFieldSet(String fieldname)
152     {
153         Set set = new HashSet();
154         set.add(fieldname);
155         return set;
156     }
157 
158     private MockSearchableObject makeSearchableObjectWithKeyword(int id, String title, String keyword1, String keyword2)
159     {
160         MockSearchableObject obj = createSearchableObject(id, title, "I like cheese");
161         obj.setKeyword1(keyword1);
162         obj.setKeyword2(keyword2);
163         return obj;
164     }
165 
166 }