1 package org.marketchangers.prayer.lucene;
2
3 import java.io.IOException;
4 import java.text.SimpleDateFormat;
5 import java.util.Collection;
6 import java.util.Date;
7 import java.util.HashMap;
8 import java.util.Iterator;
9 import java.util.LinkedHashSet;
10 import java.util.Map;
11 import java.util.Set;
12
13 import junit.framework.TestCase;
14
15 import org.apache.lucene.analysis.Analyzer;
16 import org.apache.lucene.analysis.standard.StandardAnalyzer;
17 import org.apache.lucene.document.DateField;
18 import org.apache.lucene.document.Document;
19 import org.apache.lucene.index.IndexWriter;
20 import org.apache.lucene.index.Term;
21 import org.apache.lucene.queryParser.MultiFieldQueryParser;
22 import org.apache.lucene.search.BooleanClause;
23 import org.apache.lucene.search.BooleanQuery;
24 import org.apache.lucene.search.Query;
25 import org.apache.lucene.search.RangeQuery;
26 import org.apache.lucene.search.Searcher;
27 import org.apache.lucene.search.TermQuery;
28 import org.apache.lucene.store.Directory;
29 import org.apache.lucene.store.RAMDirectory;
30 import org.marketchangers.prayer.PrayerCategory;
31 import org.marketchangers.prayer.PrayerRequest;
32 import org.marketchangers.prayer.PrayerRequestQuery;
33
34 /***
35 * @author <a href="mailto:mtodd@wc-group.com">Matthew Todd</a>
36 */
37 public class DefaultIndexProviderTest extends TestCase {
38 private IndexProvider provider;
39
40
41 public void setUp() throws IOException {
42 Directory directory = new RAMDirectory();
43 Analyzer analyzer = new StandardAnalyzer();
44
45 provider = new DefaultIndexProvider(directory, analyzer);
46 }
47
48
49 public void testCanGetAWriter() throws IOException {
50 assertNotNull(provider.getWriter());
51 }
52
53 public void testBreaksWhenYouTryToGetASecondWriter() throws IOException {
54 provider.getWriter();
55 try {
56 provider.getWriter();
57 } catch (IOException ioe) {
58
59 }
60 }
61
62 public void testWorksIfCloseOneBeforeOpeningASecond() throws IOException {
63 provider.getWriter().close();
64 provider.getWriter();
65 }
66
67 public void testCannotGetAReaderWithoutFirstGettingAWriter() {
68 try {
69 provider.getReader();
70 fail("Should have to getWriter() before getReader().");
71 } catch (Exception e) {
72
73 }
74 }
75
76 public void testCanGetAReaderAfterGettingAWriter() throws IOException {
77 provider.getWriter();
78 assertNotNull(provider.getReader());
79 }
80
81 public void testBreaksWhenYouTryToGetASecondReader() throws IOException {
82 provider.getWriter();
83 provider.getReader();
84 try {
85 provider.getReader();
86 } catch (IOException ioe) {
87
88 }
89 }
90 public void testWorksIfCloseOneReaderBeforeOpeningASecond()
91 throws IOException {
92 provider.getWriter();
93 provider.getReader().close();
94 provider.getReader();
95 }
96
97 public void testReusesTheSameDirectory() throws IOException {
98 IndexWriter writer;
99
100 writer = provider.getWriter();
101 writer.addDocument(new Document());
102 writer.optimize();
103 writer.close();
104
105 assertEquals(1, writer.docCount());
106
107 writer = provider.getWriter();
108 writer.addDocument(new Document());
109 writer.optimize();
110 writer.close();
111
112 assertEquals(2, writer.docCount());
113 }
114
115 public void testTranslatesRequestsIntoDocumentsAppropriately() {
116 PrayerRequest request = buildDummyPrayerRequest(false);
117 Document document = provider.translateToDocument(request);
118
119 assertEquals(request.getBackground(), document.get("background"));
120 assertEquals(request.getCategory().getName(), document.get("category"));
121 assertEquals(request.getContent(), document.get("content"));
122 assertEquals(request.getId().toString(), document.get("id"));
123 assertEquals(request.getStatus(), document.get("status"));
124 assertEquals(request.getSubject(), document.get("subject"));
125
126 assertEquals(
127 request.getEndDate(),
128 DateField.stringToDate(document.get("endDate")));
129 assertEquals(
130 request.getRequestorUserId(),
131 document.get("requestorUserId"));
132 assertEquals(
133 request.getStartDate(),
134 DateField.stringToDate(document.get("startDate")));
135 }
136
137 public void testTranslatesRequestsIntoDocumentsAppropriatelyWithNullCategory() {
138 PrayerRequest request = buildDummyPrayerRequest(true);
139 Document document = provider.translateToDocument(request);
140
141 assertEquals(request.getBackground(), document.get("background"));
142 assertEquals("", document.get("category"));
143 assertEquals(request.getContent(), document.get("content"));
144 assertEquals(request.getId().toString(), document.get("id"));
145 assertEquals(request.getStatus(), document.get("status"));
146 assertEquals(request.getSubject(), document.get("subject"));
147
148 assertEquals(
149 request.getEndDate(),
150 DateField.stringToDate(document.get("endDate")));
151 assertEquals(
152 request.getRequestorUserId(),
153 document.get("requestorUserId"));
154 assertEquals(
155 request.getStartDate(),
156 DateField.stringToDate(document.get("startDate")));
157 }
158
159 public void testTranslateKeepsTheAppropriateFieldsUntokenized() {
160 Document document =
161 provider.translateToDocument(buildDummyPrayerRequest(false));
162
163 assertFalse(document.getField("category").isTokenized());
164 assertFalse(document.getField("endDate").isTokenized());
165 assertFalse(document.getField("id").isTokenized());
166 assertFalse(document.getField("requestorUserId").isTokenized());
167 assertFalse(document.getField("startDate").isTokenized());
168 assertFalse(document.getField("status").isTokenized());
169 }
170
171 public void testTranslateToDocumentDoesNotFailForDefaultValues() {
172 provider.translateToDocument(new PrayerRequest());
173 }
174
175 public void testCanGetASearcherAfterGettingAWriter() throws IOException {
176 provider.getWriter();
177 assertNotNull(provider.getSearcher());
178 assertTrue(provider.getSearcher() instanceof Searcher);
179 }
180
181 public void testCannotGetASearcherBeforeYouveGottenAWriter() {
182 try {
183 provider.getSearcher();
184 fail("Should have to getWriter() before getSearcher().");
185 } catch (Exception e) {
186
187 }
188 }
189
190 public void testTranslateToQueryEmptyScenarios() {
191 Query query =
192 provider.translateToQuery(buildDummyEmptyPrayerRequestQuery());
193 assertEquals(new BooleanQuery(), query);
194 }
195
196 public void testTranslateToQueryDefault() throws java.text.ParseException {
197 Date startDateVar = date("08-01-2004");
198 Date endDateVar = date("08-08-2004");
199
200 BooleanClause categoryClause =
201 new BooleanClause(categoryName("test category"), true, false);
202
203 BooleanClause endDateClause =
204 new BooleanClause(endDate(endDateVar), true, false);
205
206 Set dummyHashSet = new LinkedHashSet();
207 dummyHashSet.add("userid");
208 BooleanClause requestorUserIdsClause =
209 new BooleanClause(requestorUserIds(dummyHashSet), true, false);
210
211 BooleanClause searchTermsClause =
212 new BooleanClause(searchTerms("random"), true, false);
213
214 BooleanClause startDateClause =
215 new BooleanClause(startDate(startDateVar), true, false);
216
217 BooleanClause statusClause =
218 new BooleanClause(status(PrayerRequest.OPEN), true, false);
219
220 PrayerRequestQuery requestQuery = buildDummyPrayerRequestQuery();
221
222 BooleanQuery query =
223 (BooleanQuery) provider.translateToQuery(requestQuery);
224 BooleanClause[] booleanClauses = query.getClauses();
225 assertEquals(
226 booleanClauseToString(categoryClause),
227 booleanClauseToString(booleanClauses[0]));
228 assertEquals(
229 booleanClauseToString(endDateClause),
230 booleanClauseToString(booleanClauses[1]));
231 assertEquals(
232 booleanClauseToString(requestorUserIdsClause),
233 booleanClauseToString(booleanClauses[2]));
234 assertEquals(
235 booleanClauseToString(searchTermsClause),
236 booleanClauseToString(booleanClauses[3]));
237 assertEquals(
238 booleanClauseToString(startDateClause),
239 booleanClauseToString(booleanClauses[4]));
240 assertEquals(
241 booleanClauseToString(statusClause),
242 booleanClauseToString(booleanClauses[5]));
243 }
244
245 public void testTranslatePrayerRequestToQuery() {
246 PrayerRequest request = new PrayerRequest();
247 Date startDate = new Date();
248 Date endDate = new Date();
249 PrayerCategory category = new PrayerCategory();
250 category.setId(new Integer(11));
251 category.setName("test");
252 BooleanQuery bq = new BooleanQuery();
253 bq.add(new TermQuery(new Term("category", "test")), true, false);
254 bq.add(
255 new RangeQuery(
256 null,
257 new Term("endDate", DateField.dateToString(endDate)),
258 true),
259 true,
260 false);
261 bq.add(new TermQuery(new Term("requestorUserId", "jniu")), true, false);
262 bq.add(searchTerms("this is a test"), true, false);
263 bq.add(
264 new RangeQuery(
265 new Term("startDate", DateField.dateToString(startDate)),
266 null,
267 true),
268 true,
269 false);
270
271 request.setCategory(category);
272 request.setContent("this is a test");
273 request.setStartDate(startDate);
274 request.setEndDate(endDate);
275 request.setRequestorUserId("jniu");
276 Query query = provider.translateToQuery(request);
277
278 assertEquals(bq.toString(), query.toString());
279 }
280
281 public void testTranslatePrayerRequestToQueryCanHandleNullCategory() {
282 PrayerRequest request = new PrayerRequest();
283 Date startDate = new Date();
284 Date endDate = new Date();
285 PrayerCategory category = null;
286 BooleanQuery bq = new BooleanQuery();
287 bq.add(
288 new RangeQuery(
289 null,
290 new Term("endDate", DateField.dateToString(endDate)),
291 true),
292 true,
293 false);
294 bq.add(new TermQuery(new Term("requestorUserId", "jniu")), true, false);
295 bq.add(searchTerms("this is a test"), true, false);
296 bq.add(
297 new RangeQuery(
298 new Term("startDate", DateField.dateToString(startDate)),
299 null,
300 true),
301 true,
302 false);
303
304 request.setContent("this is a test");
305 request.setStartDate(startDate);
306 request.setEndDate(endDate);
307 request.setRequestorUserId("jniu");
308 Query query = provider.translateToQuery(request);
309
310 assertEquals(bq.toString(), query.toString());
311 }
312
313
314 private Query all() {
315 return new TermQuery(new Term("catchAll", "catchAll"));
316 }
317
318 private String[] array(String value) {
319 return new String[] { value };
320 }
321
322 private String booleanClauseToString(BooleanClause clause) {
323 return clause.query.toString();
324 }
325
326 private PrayerRequestQuery buildDummyEmptyPrayerRequestQuery() {
327 Map map = new HashMap();
328 return new PrayerRequestQuery(map);
329 }
330
331 private PrayerRequest buildDummyPrayerRequest(boolean nullCategory) {
332 PrayerCategory category;
333 if (nullCategory) {
334 category = null;
335 } else {
336 category = new PrayerCategory();
337 category.setName("foo");
338 }
339
340 PrayerRequest request = new PrayerRequest();
341 request.setBackground("foo");
342 request.setCategory(category);
343 request.setContent("foo");
344 request.setEndDate(new Date());
345 request.setId(new Integer(42));
346 request.setRequestorUserId("foo");
347 request.setStartDate(new Date());
348 request.setStatus("foo");
349 request.setSubject("foo");
350
351 return request;
352 }
353
354 private PrayerRequestQuery buildDummyPrayerRequestQuery() {
355 Map map = new HashMap();
356 map.put("categoryName", array("test category"));
357 map.put("endDate", array("08-08-2004"));
358 map.put("organizationName", array("new org"));
359 map.put("requestorUserId", array("userid"));
360 map.put("searchTerms", array("random"));
361 map.put("startDate", array("08-01-2004"));
362 map.put("status", array(PrayerRequest.OPEN));
363 return new PrayerRequestQuery(map);
364 }
365
366 private Query categoryName(String categoryName) {
367 return new TermQuery(new Term("category", categoryName));
368 }
369
370 private Date date(String value) throws java.text.ParseException {
371 return new SimpleDateFormat("MM-dd-yyyy").parse(value);
372 }
373
374 private Query endDate(Date date) {
375 Term upperTerm = new Term("endDate", DateField.dateToString(date));
376 return new RangeQuery(null, upperTerm, true);
377 }
378
379 private Query requestorUserId(String requestorUserId) {
380 return new TermQuery(new Term("requestorUserId", requestorUserId));
381 }
382
383 private Query requestorUserIds(Collection requestors) {
384 BooleanQuery query = new BooleanQuery();
385
386 Iterator requestorUserIds = requestors.iterator();
387 while (requestorUserIds.hasNext()) {
388 String requestorUserId = (String) requestorUserIds.next();
389 query.add(requestorUserId(requestorUserId), false, false);
390 }
391 return query;
392 }
393
394 private Query searchTerms(String searchTerms) {
395 String[] fields = { "background", "content", "subject" };
396
397 try {
398 return MultiFieldQueryParser.parse(
399 searchTerms,
400 fields,
401 new StandardAnalyzer());
402 } catch (Exception pe) {
403 return all();
404 }
405 }
406
407 private Query startDate(Date date) {
408 Term lowerTerm = new Term("startDate", DateField.dateToString(date));
409 return new RangeQuery(lowerTerm, null, true);
410 }
411
412 private Query status(String status) {
413 return new TermQuery(new Term("status", status));
414 }
415
416 }