org.opentestsystem.shared.search.SearchTest.java Source code

Java tutorial

Introduction

Here is the source code for org.opentestsystem.shared.search.SearchTest.java

Source

/*******************************************************************************
 * Educational Online Test Delivery System
 * Copyright (c) 2013 American Institutes for Research
 *
 * Distributed under the AIR Open Source License, Version 1.0
 * See accompanying file AIR-License-1_0.txt or at
 * http://www.smarterapp.org/documents/American_Institutes_for_Research_Open_Source_Software_License.pdf
 ******************************************************************************/
package org.opentestsystem.shared.search;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.ArrayUtils;
import org.joda.time.DateTime;
import org.junit.Test;
import org.opentestsystem.shared.AbstractPersistenceEmbeddedTest;

public class SearchTest extends AbstractPersistenceEmbeddedTest {
    private static final String ONE_HUNDRED = "100";
    private static final String PAGE_SIZE = "pageSize";
    private static final String CURRENT_PAGE = "currentPage";
    private static final String SORT_DIR = "sortDir";
    private static final String ASC = "asc";
    private static final String DESC = "desc";
    private static final String SORT_KEY = "sortKey";
    private static final String WRONG_NUM_RETURNED = "wrong number returned";
    private static final String ONE_DOT_TWO = "1.2";
    private static final String WRONG_NUM_RESULTS = "wrong number of results";
    private static final String WRONG_VALUE_RESULT = "wrong value from search result";
    private static final String DOUBLE_VAL_GT = "doubleValueGreaterThan";
    private static final String DOUBLE_VAL_LT = "doubleValueLessThan";
    private static final String RESULT_MUST_BE_GREATER = "result must be greater";
    private static final String RESULT_MUST_BE_LESS = "result must be less";
    private static final String INT_VAL_GT = "intValueGreaterThan";
    private static final String RESULT_MUST_BE_GTE = "result must be greater than or equal";
    private static final String RESULT_MUST_BE_LTE = "result must be less than or equal";
    private static final String TWO_THIRTEEN = "2013-02-13T15:40:38.213-06:00";
    private static final String DATETIME_GT = "dateTimeValueGreaterThan";
    private static final String DATETIMEMILLIS_GT = "dateTimeValueMillisGreaterThan";
    private static final String ONE_THIRTEEN = "2036-01-13T15:40:38.213-06:00";

    private List<TestDomain> preformSearch(final String param, final String... value) {
        Map<String, String[]> requestMap = new HashMap<String, String[]>();
        requestMap.put(PAGE_SIZE, new String[] { ONE_HUNDRED });
        requestMap.put(CURRENT_PAGE, new String[] { "0" });
        requestMap.put(SORT_DIR, new String[] { ASC });
        requestMap.put(SORT_KEY, new String[] { "id" });
        requestMap.put(param, value);

        TestDomainSearchRequest searchRequest = new TestDomainSearchRequest(requestMap);
        return mongoTemplate.find(searchRequest.buildQuery(), TestDomain.class);
    }

    @Test
    public void testDoubleFilter() {
        TestDomain testDomain = FACTORY.manufacturePojo(TestDomain.class);
        for (int integer = 0; integer < 10; integer++) {
            testDomain.setId(null);
            testDomain.setDoubleValue(new Double("1." + integer));
            // System.out.println("here is the dub " + td.getDoubleValue());
            mongoTemplate.save(testDomain);
        }

        List<TestDomain> allValues = mongoTemplate.findAll(TestDomain.class);
        assertEquals(WRONG_NUM_RETURNED, 10, allValues.size());

        List<TestDomain> results = preformSearch("doubleValue", ONE_DOT_TWO);
        assertEquals(WRONG_NUM_RESULTS, 1, results.size());
        assertEquals(WRONG_VALUE_RESULT, new Double(ONE_DOT_TWO), results.get(0).getDoubleValue());

        results = preformSearch("doubleValue", "3.2");
        assertEquals(WRONG_NUM_RESULTS, 0, results.size());

        results = preformSearch(DOUBLE_VAL_GT, "3.2");
        assertEquals(WRONG_NUM_RESULTS, 0, results.size());

        results = preformSearch(DOUBLE_VAL_GT, "1.5");
        assertEquals(WRONG_NUM_RESULTS, 4, results.size());
        for (TestDomain result : results) {
            assertTrue(RESULT_MUST_BE_GREATER, result.getDoubleValue() > 1.5d);
        }

        results = preformSearch("doubleValueGreaterThanOrEqual", "1.5");
        assertEquals(WRONG_NUM_RESULTS, 5, results.size());
        for (TestDomain result : results) {
            assertTrue(RESULT_MUST_BE_GREATER, result.getDoubleValue() >= 1.5d);
        }

        results = preformSearch(DOUBLE_VAL_GT, "1.599");
        assertEquals(WRONG_NUM_RESULTS, 4, results.size());
        for (TestDomain result : results) {
            assertTrue(RESULT_MUST_BE_GREATER, result.getDoubleValue() > 1.599d);
        }

        results = preformSearch(DOUBLE_VAL_GT, "2.0");
        assertEquals(WRONG_NUM_RESULTS, 0, results.size());

        results = preformSearch(DOUBLE_VAL_LT, "1.1");
        assertEquals(WRONG_NUM_RESULTS, 1, results.size());

        results = preformSearch(DOUBLE_VAL_LT, ONE_DOT_TWO);
        assertEquals(WRONG_NUM_RESULTS, 2, results.size());
        for (TestDomain result : results) {
            assertTrue(RESULT_MUST_BE_LESS, result.getDoubleValue() < 1.2d);
        }
        results = preformSearch(DOUBLE_VAL_LT, "1.201");
        assertEquals(WRONG_NUM_RESULTS, 3, results.size());
        for (TestDomain result : results) {
            assertTrue(RESULT_MUST_BE_LESS, result.getDoubleValue() < 1.201d);
        }

        results = preformSearch(DOUBLE_VAL_LT, "0.99");
        assertEquals(WRONG_NUM_RESULTS, 0, results.size());

        results = preformSearch("doubleValueLessThanOrEqual", ONE_DOT_TWO);
        assertEquals(WRONG_NUM_RESULTS, 3, results.size());
        for (TestDomain result : results) {
            assertTrue("result should be less than or equal", result.getDoubleValue() <= 1.2d);
        }
    }

    @Test
    public void testIntegerFilter() {
        TestDomain testDomain = FACTORY.manufacturePojo(TestDomain.class);
        for (int integer = 1; integer <= 10; integer++) {
            testDomain.setId(null);
            testDomain.setIntValue(integer);
            // System.out.println("here is the int " + td.getIntValue());
            mongoTemplate.save(testDomain);
        }

        List<TestDomain> allValues = mongoTemplate.findAll(TestDomain.class);
        assertEquals(WRONG_NUM_RETURNED, 10, allValues.size());

        List<TestDomain> results = preformSearch("intValue", "1");
        assertEquals(WRONG_NUM_RESULTS, 1, results.size());
        assertEquals(WRONG_VALUE_RESULT, Integer.valueOf(1), results.get(0).getIntValue());

        results = preformSearch("intValue", "0");
        assertEquals(WRONG_NUM_RESULTS, 0, results.size());

        results = preformSearch(INT_VAL_GT, "6");
        assertEquals(WRONG_NUM_RESULTS, 4, results.size());
        for (TestDomain result : results) {
            assertTrue(RESULT_MUST_BE_GREATER, result.getIntValue() > 6);
        }

        results = preformSearch("intValueGreaterThanOrEqual", "6");
        assertEquals(WRONG_NUM_RESULTS, 5, results.size());
        for (TestDomain result : results) {
            assertTrue(RESULT_MUST_BE_GTE, result.getIntValue() >= 6);
        }

        results = preformSearch(INT_VAL_GT, "10");
        assertEquals(WRONG_NUM_RESULTS, 0, results.size());

        results = preformSearch(INT_VAL_GT, "-10");
        assertEquals(WRONG_NUM_RESULTS, 10, results.size());

        results = preformSearch(INT_VAL_GT, "5.5");
        assertEquals(WRONG_NUM_RESULTS, 5, results.size());
        for (TestDomain result : results) {
            assertTrue(RESULT_MUST_BE_GTE, result.getIntValue().doubleValue() >= 5.5d);
        }

        results = preformSearch("intValueLessThanOrEqual", "6");
        assertEquals(WRONG_NUM_RESULTS, 6, results.size());
        for (TestDomain result : results) {
            assertTrue(RESULT_MUST_BE_LTE, result.getIntValue() <= 6);
        }

        results = preformSearch("intValueLessThan", "6");
        assertEquals(WRONG_NUM_RESULTS, 5, results.size());
        for (TestDomain result : results) {
            assertTrue(RESULT_MUST_BE_LESS, result.getIntValue() < 6);
        }

        results = preformSearch("intValueLessThan", "-100");
        assertEquals(WRONG_NUM_RESULTS, 0, results.size());

    }

    @Test
    public void testDateInbetweenFilter() {
        TestDomain testDomain = FACTORY.manufacturePojo(TestDomain.class);
        DateTime feb1303 = new DateTime(TWO_THIRTEEN);

        for (int integer = 1; integer <= 30; integer++) {
            testDomain.setId(null);
            DateTime newDate = feb1303.withYear(2013 + integer);
            testDomain.setDateTimeValue(newDate);
            // System.out.println("here is the date " + td.getDateTimeValue());
            mongoTemplate.save(testDomain);
        }

        Map<String, String[]> requestMap = new HashMap<String, String[]>();
        requestMap.put(PAGE_SIZE, new String[] { ONE_HUNDRED });
        requestMap.put(CURRENT_PAGE, new String[] { "0" });
        requestMap.put(SORT_DIR, new String[] { ASC });
        requestMap.put(SORT_KEY, new String[] { "id" });

        requestMap.put(DATETIME_GT, new String[] { "2028-02-13T15:40:38.213-06:00" });
        requestMap.put("dateTimeValueLessThan", new String[] { "2033-02-13T15:40:38.213-06:00" });

        TestDomainSearchRequest searchRequest = new TestDomainSearchRequest(requestMap);
        List<TestDomain> results = mongoTemplate.find(searchRequest.buildQuery(), TestDomain.class);
        assertEquals("Wrong number of results.", 4, results.size());
        for (TestDomain result : results) {
            assertTrue(RESULT_MUST_BE_GREATER,
                    result.getDateTimeValue().compareTo(new DateTime("2028-02-13T15:40:38.213-06:00")) > 0);
            assertTrue(RESULT_MUST_BE_LESS,
                    result.getDateTimeValue().compareTo(new DateTime("2033-02-13T15:40:38.213-06:00")) < 0);
        }

    }

    @Test
    public void testDateInbetweenMillisFilter() {
        TestDomain testDomain = FACTORY.manufacturePojo(TestDomain.class);
        DateTime feb1303 = new DateTime(TWO_THIRTEEN);

        for (int integer = 1; integer <= 30; integer++) {
            testDomain.setId(null);
            DateTime newDate = feb1303.withYear(2013 + integer);
            testDomain.setDateTimeValue(newDate);
            // System.out.println("here is the date " + td.getDateTimeValue());
            mongoTemplate.save(testDomain);
        }

        String feb2028 = "2028-02-13T15:40:38.213-06:00";
        String feb2033 = "2033-02-13T15:40:38.213-06:00";

        long feb2028Millis = new DateTime(feb2028).getMillis();
        long feb2033Millis = new DateTime(feb2033).getMillis();
        Map<String, String[]> requestMap = new HashMap<String, String[]>();
        requestMap.put(PAGE_SIZE, new String[] { ONE_HUNDRED });
        requestMap.put(CURRENT_PAGE, new String[] { "0" });
        requestMap.put(SORT_DIR, new String[] { ASC });
        requestMap.put(SORT_KEY, new String[] { "id" });
        requestMap.put(DATETIMEMILLIS_GT, new String[] { Long.toString(feb2028Millis) });
        requestMap.put("dateTimeValueMillisLessThan", new String[] { Long.toString(feb2033Millis) });

        TestDomainSearchRequest searchRequest = new TestDomainSearchRequest(requestMap);

        List<TestDomain> results = mongoTemplate.find(searchRequest.buildQuery(), TestDomain.class);
        assertEquals("Wrong number of results.", 4, results.size());
        for (TestDomain result : results) {
            assertTrue(RESULT_MUST_BE_GREATER, result.getDateTimeValue().compareTo(new DateTime(feb2028)) > 0);
            assertTrue(RESULT_MUST_BE_LESS, result.getDateTimeValue().compareTo(new DateTime(feb2033)) < 0);
        }
    }

    @Test
    public void testIntInbetweenFilter() {

        TestDomain testDomain = FACTORY.manufacturePojo(TestDomain.class);
        for (int integer = 1; integer <= 10; integer++) {
            testDomain.setId(null);
            testDomain.setIntValue(integer);
            // System.out.println("here is the int " + td.getIntValue());
            mongoTemplate.save(testDomain);
        }

        Map<String, String[]> requestMap = new HashMap<String, String[]>();
        requestMap.put(PAGE_SIZE, new String[] { ONE_HUNDRED });
        requestMap.put(CURRENT_PAGE, new String[] { "0" });
        requestMap.put(SORT_DIR, new String[] { ASC });
        requestMap.put(SORT_KEY, new String[] { "id" });
        requestMap.put(INT_VAL_GT, new String[] { "3" });
        requestMap.put("intValueLessThan", new String[] { "5" });

        TestDomainSearchRequest searchRequest = new TestDomainSearchRequest(requestMap);
        List<TestDomain> results = mongoTemplate.find(searchRequest.buildQuery(), TestDomain.class);

        assertEquals("One Result expected", 1, results.size());
        assertEquals("wrong object found", Integer.valueOf(4), results.get(0).getIntValue());
    }

    @Test
    public void testDateFilter() {
        TestDomain testDomain = FACTORY.manufacturePojo(TestDomain.class);
        DateTime feb1303 = new DateTime(TWO_THIRTEEN);

        for (int integer = 1; integer <= 30; integer++) {
            testDomain.setId(null);
            DateTime newDate = feb1303.withYear(2013 + integer);
            testDomain.setDateTimeValue(newDate);
            // System.out.println("here is the date " + td.getDateTimeValue());
            mongoTemplate.save(testDomain);
        }

        String feb2040 = "2040-02-13T15:40:38.213-06:00";
        String feb2050 = "2050-02-13T15:40:38.213-06:00";
        String feb1960 = "1960-02-13T15:40:38.213-06:00";
        List<TestDomain> allValues = mongoTemplate.findAll(TestDomain.class);
        assertEquals(WRONG_NUM_RETURNED, 30, allValues.size());

        List<TestDomain> results = preformSearch("dateTimeValue", "2014-02-13T15:40:38.213-06:00");
        assertEquals(WRONG_NUM_RESULTS, 1, results.size());
        assertEquals(WRONG_VALUE_RESULT, feb1303.withYear(2014), results.get(0).getDateTimeValue());

        results = preformSearch("dateTimeValue", "2014-02-16T15:40:38.213-06:00");
        assertEquals(WRONG_NUM_RESULTS, 0, results.size());

        results = preformSearch(DATETIME_GT, feb2040);
        assertEquals(WRONG_NUM_RESULTS, 3, results.size());
        for (TestDomain result : results) {
            assertTrue(RESULT_MUST_BE_GREATER, result.getDateTimeValue().compareTo(new DateTime(feb2040)) > 0);
        }

        // one milli off from previous search
        results = preformSearch(DATETIME_GT, "2040-02-13T15:40:38.212-06:00");
        assertEquals(WRONG_NUM_RESULTS, 4, results.size());
        for (TestDomain result : results) {
            assertTrue(RESULT_MUST_BE_GREATER,
                    result.getDateTimeValue().compareTo(new DateTime("2040-02-13T15:40:38.212-06:00")) > 0);
        }

        results = preformSearch("dateTimeValueGreaterThanOrEqual", feb2040);
        assertEquals(WRONG_NUM_RESULTS, 4, results.size());
        for (TestDomain result : results) {
            assertTrue(RESULT_MUST_BE_GTE, result.getDateTimeValue().compareTo(new DateTime(feb2040)) >= 0);
        }

        results = preformSearch(DATETIME_GT, feb2050);
        assertEquals(WRONG_NUM_RESULTS, 0, results.size());

        results = preformSearch(DATETIME_GT, feb1960);
        assertEquals(WRONG_NUM_RESULTS, 30, results.size());

        results = preformSearch(DATETIME_GT, ONE_THIRTEEN);
        assertEquals(WRONG_NUM_RESULTS, 8, results.size());
        for (TestDomain result : results) {
            assertTrue(RESULT_MUST_BE_GREATER, result.getDateTimeValue().compareTo(new DateTime(ONE_THIRTEEN)) > 0);
        }

        results = preformSearch("dateTimeValueLessThanOrEqual", feb2040);
        assertEquals(WRONG_NUM_RESULTS, 27, results.size());
        for (TestDomain result : results) {
            assertTrue(RESULT_MUST_BE_LTE, result.getDateTimeValue().compareTo(new DateTime(feb2040)) <= 0);
        }

        results = preformSearch("dateTimeValueLessThan", feb2040);
        assertEquals(WRONG_NUM_RESULTS, 26, results.size());
        for (TestDomain result : results) {
            assertTrue(RESULT_MUST_BE_LESS, result.getDateTimeValue().compareTo(new DateTime(feb2040)) < 0);
        }

        results = preformSearch("dateTimeValueLessThan", feb2050);
        assertEquals(WRONG_NUM_RESULTS, 30, results.size());

    }

    @Test
    public void testDateFilterMillis() {
        TestDomain testDomain = FACTORY.manufacturePojo(TestDomain.class);
        DateTime feb1303 = new DateTime(TWO_THIRTEEN);

        for (int integer = 1; integer <= 30; integer++) {
            testDomain.setId(null);
            DateTime newDate = feb1303.withYear(2013 + integer);
            testDomain.setDateTimeValue(newDate);
            // System.out.println("here is the date " + td.getDateTimeValue());
            mongoTemplate.save(testDomain);
        }

        String feb2040 = "2040-02-13T15:40:38.213-06:00";

        String feb2040millis = Long.toString(new DateTime("2040-02-13T15:40:38.213-06:00").getMillis());
        String feb2050millis = Long.toString(new DateTime("2050-02-13T15:40:38.213-06:00").getMillis());
        String feb1960millis = Long.toString(new DateTime("1960-02-13T15:40:38.213-06:00").getMillis());
        List<TestDomain> allValues = mongoTemplate.findAll(TestDomain.class);
        assertEquals(WRONG_NUM_RETURNED, 30, allValues.size());

        long millis = new DateTime("2014-02-13T15:40:38.213-06:00").getMillis();
        List<TestDomain> results = preformSearch("dateTimeValueMillis", Long.toString(millis));
        assertEquals(WRONG_NUM_RESULTS, 1, results.size());
        assertEquals(WRONG_VALUE_RESULT, feb1303.withYear(2014), results.get(0).getDateTimeValue());

        millis = new DateTime("2014-02-16T15:40:38.213-06:00").getMillis();
        results = preformSearch("dateTimeValueMillis", Long.toString(millis));
        assertEquals(WRONG_NUM_RESULTS, 0, results.size());

        results = preformSearch(DATETIMEMILLIS_GT, feb2040millis);
        assertEquals(WRONG_NUM_RESULTS, 3, results.size());
        for (TestDomain result : results) {
            assertTrue(RESULT_MUST_BE_GREATER, result.getDateTimeValue().compareTo(new DateTime(feb2040)) > 0);
        }

        // one milli off from previous search
        millis = Long.parseLong(feb2040millis) - 1;
        results = preformSearch(DATETIMEMILLIS_GT, Long.toString(millis));
        assertEquals(WRONG_NUM_RESULTS, 4, results.size());
        for (TestDomain result : results) {
            assertTrue(RESULT_MUST_BE_GREATER,
                    result.getDateTimeValue().compareTo(new DateTime("2040-02-13T15:40:38.212-06:00")) > 0);
        }

        results = preformSearch("dateTimeValueMillisGreaterThanOrEqual", feb2040millis);
        assertEquals(WRONG_NUM_RESULTS, 4, results.size());
        for (TestDomain result : results) {
            assertTrue(RESULT_MUST_BE_GTE, result.getDateTimeValue().compareTo(new DateTime(feb2040)) >= 0);
        }

        results = preformSearch(DATETIMEMILLIS_GT, feb2050millis);
        assertEquals(WRONG_NUM_RESULTS, 0, results.size());

        results = preformSearch(DATETIMEMILLIS_GT, feb1960millis);
        assertEquals(WRONG_NUM_RESULTS, 30, results.size());

        millis = new DateTime(ONE_THIRTEEN).getMillis();
        results = preformSearch(DATETIMEMILLIS_GT, Long.toString(millis));
        assertEquals(WRONG_NUM_RESULTS, 8, results.size());
        for (TestDomain result : results) {
            assertTrue(RESULT_MUST_BE_GREATER, result.getDateTimeValue().compareTo(new DateTime(ONE_THIRTEEN)) > 0);
        }

        results = preformSearch("dateTimeValueMillisLessThanOrEqual", feb2040millis);
        assertEquals(WRONG_NUM_RESULTS, 27, results.size());
        for (TestDomain result : results) {
            assertTrue(RESULT_MUST_BE_LTE, result.getDateTimeValue().compareTo(new DateTime(feb2040)) <= 0);
        }

        results = preformSearch("dateTimeValueMillisLessThan", feb2040millis);
        assertEquals(WRONG_NUM_RESULTS, 26, results.size());
        for (TestDomain result : results) {
            assertTrue(RESULT_MUST_BE_LESS, result.getDateTimeValue().compareTo(new DateTime(feb2040)) < 0);
        }

        results = preformSearch("dateTimeValueMillisLessThan", feb2050millis);
        assertEquals(WRONG_NUM_RESULTS, 30, results.size());

    }

    @Test
    public void testStringFilter() {
        TestDomain testDomain = FACTORY.manufacturePojo(TestDomain.class);
        for (int integer = 1; integer <= 10; integer++) {
            testDomain.setId(null);
            testDomain.setStringValue("This is a great blah " + integer + " message to find.");
            mongoTemplate.save(testDomain);
        }

        List<TestDomain> allValues = mongoTemplate.findAll(TestDomain.class);
        assertEquals(WRONG_NUM_RETURNED, 10, allValues.size());

        List<TestDomain> results = preformSearch("stringValueWildcardedRegex", "9");
        assertEquals("wrong number of results finding '9'", 1, results.size());

        results = preformSearch("stringValueWildcardedRegex", "blah");
        assertEquals("wrong number of results finding 'blah'", 10, results.size());

        results = preformSearch("stringValueWildcardedRegex", "blah 7");
        assertEquals("wrong number of results finding 'blah 7'", 1, results.size());

    }

    @Test
    public void testStringCaseInsensitiveFilter() {
        TestDomain testDomain = FACTORY.manufacturePojo(TestDomain.class);
        String[] stringvals = new String[10];
        String[] upperStringvals = new String[10];
        for (int i = 0; i < stringvals.length; i++) {
            testDomain.setId(null);
            String stringVal = "This is a great blah " + i + " message to find.";
            stringvals[i] = stringVal;
            upperStringvals[i] = stringVal.toUpperCase();
            testDomain.setStringValue(stringVal);
            mongoTemplate.save(testDomain);
        }

        //there are 10 inserted
        List<TestDomain> allValues = mongoTemplate.findAll(TestDomain.class);
        assertEquals(WRONG_NUM_RETURNED, 10, allValues.size());

        //I can find one using exact string
        List<TestDomain> results = preformSearch("stringValueCaseInsensitive", stringvals[9]);
        assertEquals("wrong number of results finding '9'", 1, results.size());

        //I can find all 10 using exact string
        results = preformSearch("stringValueCaseInsensitive", stringvals);
        assertEquals("wrong number of results finding 'all'", 10, results.size());

        //like search doesn't work
        results = preformSearch("stringValueCaseInsensitive", "blah");
        assertEquals("wrong number of results finding 'blah'", 0, results.size());

        //i can find one using all caps
        results = preformSearch("stringValueCaseInsensitive", upperStringvals[9]);
        assertEquals("wrong number of results finding '9'", 1, results.size());

        //i can find all ten using all caps
        results = preformSearch("stringValueCaseInsensitive", upperStringvals);
        assertEquals("wrong number of results finding 'all'", 10, results.size());

    }

    @Test
    public void testArrayFilter() {
        TestDomain testDomain = FACTORY.manufacturePojo(TestDomain.class);
        List<String> colors = Arrays.asList(new String[] { "red", "blue", "black" });
        testDomain.setColors(colors);
        mongoTemplate.save(testDomain);

        testDomain = FACTORY.manufacturePojo(TestDomain.class);
        colors = Arrays.asList(new String[] { "orange", "red", "yello" });
        testDomain.setColors(colors);
        mongoTemplate.save(testDomain);

        testDomain = FACTORY.manufacturePojo(TestDomain.class);
        colors = Arrays.asList(new String[] { "orange", "purple", "darklacknight" });
        testDomain.setColors(colors);
        mongoTemplate.save(testDomain);

        testDomain = FACTORY.manufacturePojo(TestDomain.class);
        colors = Arrays.asList(new String[0]);
        testDomain.setColors(colors);
        mongoTemplate.save(testDomain);

        List<TestDomain> allValues = mongoTemplate.findAll(TestDomain.class);
        assertEquals(WRONG_NUM_RETURNED, 4, allValues.size());

        List<TestDomain> results = preformSearch("colors", "red");
        assertEquals("wrong number of results finding true", 2, results.size());

        results = preformSearch("colors", "black");
        assertEquals("wrong number of results finding true", 1, results.size());

        results = preformSearch("colorsLike", "lack");
        assertEquals("wrong number of results finding true", 2, results.size());
    }

    @Test
    public void testSorting() {
        String[] stringvals = new String[] { "Alpha", "Beta", "Delta", "Elephant" };
        Integer[] intValues = new Integer[] { 3, 11, 12, 14 };
        initializeSortObjects(stringvals, intValues);

        List<TestDomain> allValues = mongoTemplate.findAll(TestDomain.class);
        for (int i = 0; i < stringvals.length; i++) {
            assertFalse("id order, for: " + i, stringvals[i].equals(allValues.get(i).getStringValue()));
        }

        Map<String, String[]> requestMap = new HashMap<String, String[]>();
        requestMap.put(PAGE_SIZE, new String[] { ONE_HUNDRED });
        requestMap.put(CURRENT_PAGE, new String[] { "0" });
        requestMap.put(SORT_DIR, new String[] { ASC });
        requestMap.put(SORT_KEY, new String[] { "stringValue" });

        TestDomainSearchRequest searchRequest = new TestDomainSearchRequest(requestMap);
        List<TestDomain> results = mongoTemplate.find(searchRequest.buildQuery(), TestDomain.class);
        assertEquals("wrong number of results finding true", 4, results.size());

        checkStringOrder(stringvals, results);

        requestMap.put(SORT_DIR, new String[] { DESC });
        searchRequest = new TestDomainSearchRequest(requestMap);
        results = mongoTemplate.find(searchRequest.buildQuery(), TestDomain.class);
        ArrayUtils.reverse(stringvals);
        checkStringOrder(stringvals, results);
    }

    @Test
    public void testNumericSorting() {
        String[] stringvals = new String[] { "Foo", "Bar", "Alpha", "Beta" };
        Integer[] intValues = new Integer[] { 3, 11, 12, 14 };

        initializeSortObjects(stringvals, intValues);

        List<TestDomain> allValues = mongoTemplate.findAll(TestDomain.class);
        for (int i = 0; i < intValues.length; i++) {
            assertFalse("id order, for: " + i, intValues[i].equals(allValues.get(i).getIntValue()));
        }

        Map<String, String[]> requestMap = new HashMap<String, String[]>();
        requestMap.put(PAGE_SIZE, new String[] { ONE_HUNDRED });
        requestMap.put(CURRENT_PAGE, new String[] { "0" });
        requestMap.put(SORT_DIR, new String[] { ASC });
        requestMap.put(SORT_KEY, new String[] { "intValue" });

        TestDomainSearchRequest searchRequest = new TestDomainSearchRequest(requestMap);
        List<TestDomain> results = mongoTemplate.find(searchRequest.buildQuery(), TestDomain.class);
        assertEquals("wrong number of results finding true", 4, results.size());

        checkIntOrder(intValues, results);

        requestMap.put(SORT_DIR, new String[] { DESC });
        searchRequest = new TestDomainSearchRequest(requestMap);
        results = mongoTemplate.find(searchRequest.buildQuery(), TestDomain.class);
        ArrayUtils.reverse(intValues);
        checkIntOrder(intValues, results);
    }

    @Test
    public void testMultiSorting() {
        String[] stringvals = new String[] { "Alpha", "Alpha", "Alpha", "Beta" };
        Integer[] intValues = new Integer[] { 3, 11, 12, 14 };

        initializeSortObjects(stringvals, intValues);

        List<TestDomain> allValues = mongoTemplate.findAll(TestDomain.class);
        for (int i = 0; i < intValues.length; i++) {
            assertFalse("id order, for: " + i, intValues[i].equals(allValues.get(i).getIntValue()));
        }

        Map<String, String[]> requestMap = new HashMap<String, String[]>();
        requestMap.put(PAGE_SIZE, new String[] { ONE_HUNDRED });
        requestMap.put(CURRENT_PAGE, new String[] { "0" });
        requestMap.put(SORT_DIR, new String[] { ASC });
        requestMap.put(SORT_KEY, new String[] { "stringValue", "intValue" });

        TestDomainSearchRequest searchRequest = new TestDomainSearchRequest(requestMap);
        List<TestDomain> results = mongoTemplate.find(searchRequest.buildQuery(), TestDomain.class);
        assertEquals("wrong number of results finding true", 4, results.size());
        checkIntOrder(intValues, results);

        requestMap.put(SORT_DIR, new String[] { DESC, DESC });
        searchRequest = new TestDomainSearchRequest(requestMap);
        results = mongoTemplate.find(searchRequest.buildQuery(), TestDomain.class);
        ArrayUtils.reverse(intValues);
        checkIntOrder(intValues, results);

        requestMap.put(SORT_DIR, new String[] { ASC });
        searchRequest = new TestDomainSearchRequest(requestMap);
        results = mongoTemplate.find(searchRequest.buildQuery(), TestDomain.class);
        ArrayUtils.reverse(intValues);
        checkIntOrder(intValues, results);

        requestMap.put(SORT_DIR, new String[] { DESC, DESC });
        searchRequest = new TestDomainSearchRequest(requestMap);
        results = mongoTemplate.find(searchRequest.buildQuery(), TestDomain.class);
        Integer[] newVals = new Integer[] { 14, 12, 11, 3 };
        checkIntOrder(newVals, results);

        requestMap.put(SORT_DIR, new String[] { ASC, DESC });
        searchRequest = new TestDomainSearchRequest(requestMap);
        results = mongoTemplate.find(searchRequest.buildQuery(), TestDomain.class);
        newVals = new Integer[] { 12, 11, 3, 14 };
        checkIntOrder(newVals, results);

        requestMap.put(SORT_DIR, new String[] { ASC, ASC });
        searchRequest = new TestDomainSearchRequest(requestMap);
        results = mongoTemplate.find(searchRequest.buildQuery(), TestDomain.class);
        newVals = new Integer[] { 3, 11, 12, 14 };
        checkIntOrder(newVals, results);

        requestMap.put(SORT_DIR, new String[] { ASC });
        searchRequest = new TestDomainSearchRequest(requestMap);
        results = mongoTemplate.find(searchRequest.buildQuery(), TestDomain.class);
        newVals = new Integer[] { 3, 11, 12, 14 };
        checkIntOrder(newVals, results);

        requestMap.put(SORT_DIR, new String[] { DESC, ASC });
        searchRequest = new TestDomainSearchRequest(requestMap);
        results = mongoTemplate.find(searchRequest.buildQuery(), TestDomain.class);
        newVals = new Integer[] { 14, 3, 11, 12 };
        checkIntOrder(newVals, results);

        requestMap.put(SORT_DIR, new String[] { DESC });
        searchRequest = new TestDomainSearchRequest(requestMap);
        results = mongoTemplate.find(searchRequest.buildQuery(), TestDomain.class);
        newVals = new Integer[] { 14, 3, 11, 12 };
        checkIntOrder(newVals, results);

    }

    private void checkStringOrder(final String[] stringvals, final List<TestDomain> results) {
        for (int i = 0; i < stringvals.length; i++) {
            assertEquals("wrong order, for: " + i, stringvals[i], results.get(i).getStringValue());
        }
    }

    private void checkIntOrder(final Integer[] intValues, final List<TestDomain> results) {
        for (int i = 0; i < intValues.length; i++) {
            assertEquals("wrong order, for: " + i, intValues[i], results.get(i).getIntValue());
        }
    }

    private void initializeSortObjects(final String[] stringvals, final Integer[] intValues) {
        TestDomain testDomain = FACTORY.manufacturePojo(TestDomain.class);
        testDomain.setIntValue(intValues[2]);
        testDomain.setStringValue(stringvals[2]);
        mongoTemplate.save(testDomain);

        testDomain = FACTORY.manufacturePojo(TestDomain.class);
        testDomain.setIntValue(intValues[3]);
        testDomain.setStringValue(stringvals[3]);
        mongoTemplate.save(testDomain);

        testDomain = FACTORY.manufacturePojo(TestDomain.class);
        testDomain.setIntValue(intValues[0]);
        testDomain.setStringValue(stringvals[0]);
        mongoTemplate.save(testDomain);

        testDomain = FACTORY.manufacturePojo(TestDomain.class);
        testDomain.setIntValue(intValues[1]);
        testDomain.setStringValue(stringvals[1]);
        mongoTemplate.save(testDomain);
    }

    @Test
    public void testBooleanFilter() {
        TestDomain testDomain = FACTORY.manufacturePojo(TestDomain.class);
        boolean isInactiveVal = false;
        for (int integer = 1; integer <= 10; integer++) {
            testDomain.setId(null);
            testDomain.setInactive(isInactiveVal);
            mongoTemplate.save(testDomain);
            //toggle value back & forth
            isInactiveVal = !isInactiveVal;
        }

        List<TestDomain> allValues = mongoTemplate.findAll(TestDomain.class);
        assertEquals(WRONG_NUM_RETURNED, 10, allValues.size());

        List<TestDomain> results = preformSearch("booleanValue", "true");
        assertEquals("wrong number of results finding true", 5, results.size());

        for (TestDomain testDomain2 : results) {
            assertEquals(true, testDomain2.isInactive());
        }

        results = preformSearch("booleanValue", "false");
        assertEquals("wrong number of results finding 'false'", 5, results.size());
        for (TestDomain testDomain2 : results) {
            assertEquals(false, testDomain2.isInactive());
        }

        //when parsing a boolean, if returns false for anyting but ignorecase(true)
        results = preformSearch("booleanValue", "blah");
        assertEquals("wrong number of results finding 'blah 7'", 5, results.size());

    }

    @Test
    public void testObjectIdFilter() {
        TestDomain testDomain = FACTORY.manufacturePojo(TestDomain.class);
        for (int integer = 1; integer <= 10; integer++) {
            testDomain.setId(null);
            testDomain.setStringValue("This is a great blah " + integer + " message to find.");
            mongoTemplate.save(testDomain);
        }

        List<TestDomain> allValues = mongoTemplate.findAll(TestDomain.class);
        assertEquals(WRONG_NUM_RETURNED, 10, allValues.size());

        for (TestDomain testDomain2 : allValues) {
            List<TestDomain> results = preformSearch("objectIdEquals", testDomain2.getId());
            assertEquals("wrong number of results finding 'id' of: " + testDomain2.getId(), 1, results.size());
        }
    }

    @Test
    public void testDynamicElement() {
        TestDomain testDomain = FACTORY.manufacturePojo(TestDomain.class);
        for (int integer = 1; integer <= 10; integer++) {
            testDomain.setId(null);
            //introduce variability into the dynamic element's values
            testDomain.getDynamicObject().setDynamicElement1(Math.random() + "");
            testDomain.getDynamicObject().setDynamicElement2(Math.random() + "");
            mongoTemplate.save(testDomain);
        }
        //create one without the dynamic object
        testDomain.setId(null);
        testDomain.setDynamicObject(null);
        mongoTemplate.save(testDomain);

        //find all: should be 11
        List<TestDomain> allValues = mongoTemplate.findAll(TestDomain.class);
        assertEquals(WRONG_NUM_RETURNED, 11, allValues.size());

        //find all with the dynamicElement1 present
        List<TestDomain> allDomainsWithDynamicElement1 = preformSearch("dynamicElement", "dynamicElement1");
        assertEquals(WRONG_NUM_RETURNED, 10, allDomainsWithDynamicElement1.size());

        //find all with the dynamicElement2 present
        List<TestDomain> allDomainsWithDynamicElement2 = preformSearch("dynamicElement", "dynamicElement2");
        assertEquals(WRONG_NUM_RETURNED, 10, allDomainsWithDynamicElement2.size());

        //search for each dynamicElement (1 & 2)'s values
        for (TestDomain testDomain2 : allDomainsWithDynamicElement1) {
            List<TestDomain> results = preformSearch("dynamicElement", "dynamicElement1",
                    testDomain2.getDynamicObject().getDynamicElement1());
            assertEquals("wrong number of results finding 'id' of: " + testDomain2.getId(), 1, results.size());

            List<TestDomain> results2 = preformSearch("dynamicElement", "dynamicElement2",
                    testDomain2.getDynamicObject().getDynamicElement2());
            assertEquals("wrong number of results finding 'id' of: " + testDomain2.getId(), 1, results2.size());
        }

        //search (an in equality) for the first two object's element1 value.
        String firstDynamicElement1 = allDomainsWithDynamicElement1.get(0).getDynamicObject().getDynamicElement1();
        String secondDynamicElement1 = allDomainsWithDynamicElement1.get(1).getDynamicObject().getDynamicElement1();
        List<TestDomain> allDomainsWithSpecificElement1Value = preformSearch("dynamicElement", "dynamicElement1",
                firstDynamicElement1, secondDynamicElement1);
        assertEquals(WRONG_NUM_RETURNED, 2, allDomainsWithSpecificElement1Value.size());

        //Should not be able to find any that equal made up value
        List<TestDomain> shouldBeNone = preformSearch("dynamicElement", "dynamicElement1", "foo");
        assertEquals(WRONG_NUM_RETURNED, 0, shouldBeNone.size());

        //Should not be able to find any in a list of made up values
        List<TestDomain> shouldAlsoBeNone = preformSearch("dynamicElement", "dynamicElement1", "foo", "bar");
        assertEquals(WRONG_NUM_RETURNED, 0, shouldAlsoBeNone.size());
    }
}