Java tutorial
package org.opencommercesearch; /* * Licensed to OpenCommerceSearch under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. OpenCommerceSearch licenses this * file to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.io.IOException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; import atg.multisite.Site; import atg.repository.Repository; import atg.repository.RepositoryException; import atg.repository.RepositoryItem; import org.apache.commons.lang.StringUtils; import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.response.Group; import org.apache.solr.client.solrj.response.GroupCommand; import org.apache.solr.client.solrj.response.GroupResponse; import org.apache.solr.client.solrj.response.QueryResponse; import org.junit.Before; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.mockito.Mock; import org.opencommercesearch.client.impl.Facet; import org.opencommercesearch.junit.SearchTest; import org.opencommercesearch.junit.runners.SearchJUnit4ClassRunner; import org.opencommercesearch.repository.FacetProperty; import org.opencommercesearch.repository.FacetRuleProperty; import org.opencommercesearch.repository.FieldFacetProperty; import org.opencommercesearch.repository.QueryFacetProperty; import org.opencommercesearch.repository.RedirectRuleProperty; import org.opencommercesearch.repository.RuleProperty; import org.opencommercesearch.repository.SearchRepositoryItemDescriptor; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import static org.junit.Assert.*; import static org.mockito.Mockito.*; import static org.mockito.MockitoAnnotations.initMocks; /** * @author rmerizalde */ @Category(IntegrationSearchTest.class) @RunWith(SearchJUnit4ClassRunner.class) public class AbstractSearchServerIntegrationTest { private static final String FIELD_FACET = "fieldFacet"; private static final String QUERY_FACET = "queryFacet"; public static final int ROWS = 20; public static final SimpleDateFormat isoDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); @Mock private Site site; @Mock private RepositoryItem catalog; @Mock private RepositoryItem redirectRule; @Mock private RepositoryItem expiredRule; @Mock private RepositoryItem futureRule; @Mock private RepositoryItem expiredRedirectRule; @Mock private Repository searchRepository; @Mock private RulesBuilder rulesBuilder; @Before public void setUp() throws RepositoryException { initMocks(this); when(site.getRepositoryId()).thenReturn("outdoorSite"); when(site.getPropertyValue("defaultCatalog")).thenReturn(catalog); when(catalog.getRepositoryId()).thenReturn("mycatalog"); when(searchRepository.getItem("redirectRuleId", SearchRepositoryItemDescriptor.RULE)) .thenReturn(redirectRule); when(redirectRule.getPropertyValue(RedirectRuleProperty.URL)).thenReturn("/redirect"); when(redirectRule.getPropertyValue(RedirectRuleProperty.RULE_TYPE)).thenReturn("redirectRule"); when(searchRepository.getItem("oldRule", SearchRepositoryItemDescriptor.RULE)) .thenReturn(expiredRedirectRule); when(expiredRule.getPropertyValue(RedirectRuleProperty.URL)).thenReturn("/redirect"); when(expiredRule.getPropertyValue(RedirectRuleProperty.RULE_TYPE)).thenReturn("redirectRule"); when(searchRepository.getItem("futureRule", SearchRepositoryItemDescriptor.RULE)).thenReturn(futureRule); when(futureRule.getPropertyValue(RedirectRuleProperty.URL)).thenReturn("/redirect"); when(futureRule.getPropertyValue(RedirectRuleProperty.RULE_TYPE)).thenReturn("redirectRule"); } @SearchTest(newInstance = true, productData = "/product_catalog/sandal.xml") public void testSearchCategoryName(SearchServer server) throws SearchServerException { testSearchCategoryAux(server, "shoe", "TNF3137"); } @SearchTest(newInstance = true, productData = "/product_catalog/sandal.xml") public void testSearchCategoryNameSynonyms(SearchServer server) throws SearchServerException { testSearchCategoryAux(server, "sneakers", "TNF3137"); } @SearchTest(newInstance = true, rulesData = "/rules/redirect.xml") public void testSearchSedirect(SearchServer server) throws SearchServerException { AbstractSearchServer baseServer = (AbstractSearchServer) server; baseServer.setSearchRepository(searchRepository); SolrQuery query = new SolrQuery("redirect"); query.setRows(ROWS); SearchResponse res = server.search(query, site); assertEquals("/redirect", res.getRedirectResponse()); } @SearchTest(newInstance = true) public void testRulesLifetime(SearchServer server) throws SearchServerException, SolrServerException, IOException { EmbeddedSearchServer baseServer = (EmbeddedSearchServer) server; baseServer.updateCollection(baseServer.getRulesCollection(), generateDatedRulesXml(), new Locale("en")); baseServer.setSearchRepository(searchRepository); SolrQuery query = new SolrQuery("redirect"); query.setRows(ROWS); SearchResponse res = server.search(query, site); verify(redirectRule, times(1)).getPropertyValue(RedirectRuleProperty.URL); assertEquals("/redirect", res.getRedirectResponse()); } @SearchTest(newInstance = true, productData = "/product_catalog/sandal.xml") public void testBrowseCategory(SearchServer server) throws SearchServerException { //scenario where we want to display only the top level categories. no results BrowseOptions options = new BrowseOptions(true, false, false, false, 100, null, "cat3000003", "mycatalog.cat3000003", "mycatalog", -1, null); SolrQuery query = new SolrQuery(); SearchResponse response = server.browse(options, query, site, Locale.US, null); assertNull(response.getQueryResponse().getGroupResponse()); validateFilterByCat3000003(response); validateCategoryPathNotInFacets(response); //scenario where we want to show results. not only display the top level categories options = new BrowseOptions(false, false, false, false, 100, null, "cat3000003", "mycatalog.cat3000003", "mycatalog", -1, null); query = new SolrQuery(); response = server.browse(options, query, site, Locale.US, null); validateCategoryPathNotInFacets(response); assertNull(response.getQueryResponse().getGroupResponse()); assertNull(response.getCategoryGraph()); } @SearchTest(newInstance = true, productData = "/product_catalog/sandal.xml") public void testBrowseCategoryDepthLimit(SearchServer server) throws SearchServerException { //scenario where we want to display only the top level categories. no results BrowseOptions options = new BrowseOptions(true, false, false, false, 100, null, "cat3000003", "mycatalog.cat3000003", "mycatalog", 2, "."); SolrQuery query = new SolrQuery(); SearchResponse response = server.browse(options, query, site, Locale.US, null); int maxDepth = 0; for (CategoryGraph currentLevel : response.getCategoryGraph()) { //we are checking 3 as max depth cause the base depth is level 1 plus 2 extra level we added in the call validateCategoryGraphDepth(currentLevel, 0, 3); } } private void validateCategoryGraphDepth(CategoryGraph graph, int currentDepth, int maxDepth) { if (currentDepth > maxDepth) { fail("category graph generated was too deep"); } else { for (CategoryGraph child : graph.getCategoryGraphNodes()) { validateCategoryGraphDepth(child, currentDepth + 1, maxDepth); } } } @SearchTest(newInstance = true, productData = "/product_catalog/sandal.xml") public void testBrowseBrand(SearchServer server) throws SearchServerException { //scenario where we want to display only the top level categories for products that have a specific brand BrowseOptions options = new BrowseOptions(true, false, false, false, 100, "88", null, null, "mycatalog", -1, null); SolrQuery query = new SolrQuery(); SearchResponse response = server.browse(options, query, site, Locale.US, null); assertNull(response.getQueryResponse().getGroupResponse()); validateFilterByTopLevelCat(response, options.isFetchProducts()); validateCategoryPathNotInFacets(response); //scenario where we want to show results for products from a given brand. Not only display the top level categories options = new BrowseOptions(false, true, false, false, 100, "88", null, null, "mycatalog", -1, null); query = new SolrQuery(); query.setRows(ROWS); response = server.browse(options, query, site, Locale.US, null); assertEquals(1, response.getQueryResponse().getGroupResponse().getValues().size()); assertEquals("The North Face", getFirstResponseProperty(response, "brand")); validateFilterByTopLevelCat(response, options.isFetchProducts()); validateCategoryPathNotInFacets(response); //scenario where we want to show results for products from a given brand and category. Not only display the top level categories options = new BrowseOptions(false, true, false, false, 100, "88", "cat3000003", "mycatalog.cat3000003", "mycatalog", -1, null); query = new SolrQuery(); query.setRows(ROWS); response = server.browse(options, query, site, Locale.US, null); assertEquals(1, response.getQueryResponse().getGroupResponse().getValues().size()); assertEquals("The North Face", getFirstResponseProperty(response, "brand")); //for brand categories we shouldn't generate the category graph. Use the regular category facet assertNull(response.getCategoryGraph()); Facet categoryFacet = response.getFacets().get(0); assertNotNull(categoryFacet); assertEquals("Kids' Clothing", categoryFacet.getFilters().get(0).getName()); assertEquals("Shoes & Footwear", categoryFacet.getFilters().get(1).getName()); validateCategoryPathNotInFacets(response); } @SearchTest(newInstance = true, productData = "/product_catalog/sandal.xml") public void testMinimumTerms(SearchServer server) throws SearchServerException { AbstractSearchServer abstractServer = (AbstractSearchServer) server; abstractServer.setMinimumMatch("2<-1 3<-2 5<80%"); SolrQuery query = new SolrQuery("Camp Sandal"); query.setRows(ROWS); SearchResponse res = abstractServer.search(query, site); QueryResponse queryResponse = res.getQueryResponse(); assertTrue(new Integer(1) <= queryResponse.getGroupResponse().getValues().get(0).getMatches()); //for 2 terms both should match query = new SolrQuery("Camp asdhja"); query.setRows(ROWS); res = abstractServer.search(query, site); queryResponse = res.getQueryResponse(); assertTrue(new Integer(0) == queryResponse.getGroupResponse().getValues().get(0).getMatches()); //for 3 terms, atleast 2 should match query = new SolrQuery("Camp Sandal asdhja"); query.setRows(ROWS); res = abstractServer.search(query, site); queryResponse = res.getQueryResponse(); assertTrue(new Integer(1) <= queryResponse.getGroupResponse().getValues().get(0).getMatches()); query = new SolrQuery("Camp asdhja sdjfhksd"); query.setRows(ROWS); res = abstractServer.search(query, site); queryResponse = res.getQueryResponse(); assertTrue(new Integer(0) == queryResponse.getGroupResponse().getValues().get(0).getMatches()); } @SearchTest(newInstance = true, productData = "/product_catalog/sandal.xml") public void testOnSale(SearchServer server) throws SearchServerException { //scenario where we want to display only the top level categories for products that are on sale. BrowseOptions options = new BrowseOptions(true, false, true, false, 100, null, null, null, "mycatalog", -1, null); SolrQuery query = new SolrQuery(); SearchResponse response = server.browse(options, query, site, Locale.US, null); assertNull(response.getQueryResponse().getGroupResponse()); validateFilterByTopLevelCat(response, options.isFetchProducts()); validateCategoryPathNotInFacets(response); //scenario where we want to show results for products that are on sale. not only display the top level categories options = new BrowseOptions(false, true, true, false, 100, null, null, null, "mycatalog", -1, null); query = new SolrQuery(); query.setFields("id"); query.setRows(ROWS); response = server.browse(options, query, site, Locale.US, null); validateCategoryPathNotInFacets(response); assertEquals(1, response.getQueryResponse().getGroupResponse().getValues().size()); assertEquals("TNF3137-FUPINYL-S1", getFirstResponseProperty(response, "id")); assertNull(response.getCategoryGraph()); } @SearchTest(newInstance = true, productData = "/product_catalog/sandal.xml") public void testRuleBasedCategory(SearchServer server) throws SearchServerException { AbstractSearchServer abstractServer = (AbstractSearchServer) server; abstractServer.setRulesBuilder(rulesBuilder); //scenario where we want to display a rule based category that shows product with a discount > 15% BrowseOptions options = new BrowseOptions(false, false, false, true, 100, null, "cat3000003", null, "mycatalog", -1, null); when(rulesBuilder.buildRulesFilter(options.getCategoryId(), Locale.US)) .thenReturn("(categoryId:ruleCategory) OR (discountPercentUS:[15 TO 100])"); SolrQuery query = new SolrQuery(); query.setRows(ROWS); query.setFields("id"); SearchResponse response = server.browse(options, query, site, Locale.US, null); assertEquals(1, response.getQueryResponse().getGroupResponse().getValues().size()); assertEquals("TNF3137-FUPINYL-S1", response.getQueryResponse().getGroupResponse().getValues().get(0) .getValues().get(0).getResult().get(0).getFieldValue("id")); } @SearchTest(newInstance = true, productData = "/product_catalog/sandal.xml") public void testCorrectedTermsAllMatches(SearchServer server) throws SearchServerException { //validate term correction from the title validateCorrectedTerms(server, "basa", "base", true); //validate terms correction from the category validateCorrectedTerms(server, "fotwear", "footwear", true); //validate terms correction from the brand validateCorrectedTerms(server, "nort face", "north face", true); //validate terms correction from the features validateCorrectedTerms(server, "ruber", "rubber", true); //validate terms correction from phrases with multiple entries validateCorrectedTerms(server, "sandl footwear", "sandal footwear", true); } @SearchTest(newInstance = true, productData = "/product_catalog/sandal.xml") public void testCorrectedTermsAnyMatches(SearchServer server) throws SearchServerException { //scenario where it needs to do a search by any terms because we don't have jacket in the index validateCorrectedTerms(server, "jckt footwear", "jckt footwear", false); } @SearchTest(newInstance = true, productData = "/product_catalog/sandal.xml") public void testSortbySortField(SearchServer server) throws SearchServerException { AbstractSearchServer baseServer = (AbstractSearchServer) server; baseServer.setGroupSortingEnabled(true); SolrQuery query = new SolrQuery("Camp Sandal"); query.setRows(ROWS); SearchResponse res = baseServer.search(query, site); QueryResponse queryResponse = res.getQueryResponse(); assertEquals("TNF3137-FUPINYL-S3", (String) queryResponse.getGroupResponse().getValues().get(0).getValues() .get(0).getResult().get(0).getFirstValue("id")); } @SearchTest(newInstance = true) public void testDeleteByQuery(SearchServer server) throws SearchServerException { SolrQuery query = new SolrQuery("jacket"); query.setRows(ROWS); SearchResponse res = server.search(query, site); QueryResponse queryResponse = res.getQueryResponse(); GroupResponse groupResponse = queryResponse.getGroupResponse(); assertNotEquals(new Integer(1), groupResponse.getValues().get(0).getNGroups()); server.deleteByQuery("*:*"); server.commit(); res = server.search(query, site); queryResponse = res.getQueryResponse(); groupResponse = queryResponse.getGroupResponse(); assertEquals(new Integer(0), groupResponse.getValues().get(0).getNGroups()); } @SearchTest(newInstance = true, productData = "/product_catalog/sandal.xml", rulesData = "/rules/facetBlacklist.xml") public void testFacetBlacklist(SearchServer server) throws SearchServerException, RepositoryException { // Scenario to validate that the facet blacklist removes facet filter items. // The test creates a global facet rule, in the rules collection, with the scale and brand facets. // The test data has two values for scale: "US Kids Footwear" and "UK Kids Footwear". For this facet, we are // adding a blacklist that should remove the "UK Kids Footwear". // For the brand facet, the test data only has one entry: "The North Face" and we defined a // blacklist with "Fake Brand". Because the terms don't match, then we shouldn't filter any entry. List<RepositoryItem> facetList = new ArrayList<RepositoryItem>(); facetList.add(mockFacet("scale", "scale", FIELD_FACET, "UK Kids Footwear", null, false)); facetList.add(mockFacet("brand", "brand", FIELD_FACET, "Fake Brand", null, false)); mockFacetRuleResponse("facetRuleId", server, facetList); SolrQuery query = new SolrQuery("shoe"); query.setRows(ROWS); SearchResponse response = server.search(query, site); for (Facet facet : response.getFacets()) { if (facet.getName().equals("scale")) { assertEquals(facet.getFilters().size(), 1); assertEquals(facet.getFilters().get(0).getName(), "US Kids Footwear"); } if (facet.getName().equals("brand")) { assertEquals(facet.getFilters().size(), 1); assertEquals(facet.getFilters().get(0).getName(), "The North Face"); } } } @SearchTest(newInstance = true, productData = "/product_catalog/sandal.xml", rulesData = "/rules/facetBlacklist.xml") public void testMultiSelectFacet(SearchServer server) throws SearchServerException, RepositoryException { // Scenario to validate multi-select facets filter results correctly // The test creates a global facet rule, in the rules collection, with the price and brand facets. // The brand facet will return one filter : the north face. // The price facet will return two filters: $10-$20 and $20 And Up // We are going to apply first the brand filter 'the-north-face' // Then we apply the '$10-$20' and the '$20 And Up' filters. For each of them we verify they are selected // Finally we proceed to un-select them. First we remove the '$20 And Up', then the brand 'the-north-face' // and lastly we remove '$10-$20' and check no facet filters are selected. List<RepositoryItem> facetList = new ArrayList<RepositoryItem>(); facetList.add(mockFacet("price", "salePriceUS", QUERY_FACET, null, Lists.newArrayList("[* TO 10]", "[10 TO 20]", "[20 TO *]"), true)); facetList.add(mockFacet("brand", "brand", FIELD_FACET, null, null, true)); mockFacetRuleResponse("facetRuleId", server, facetList); SolrQuery query = new SolrQuery("shoe"); query.setRows(ROWS); SearchResponse response = server.search(query, site); Map<String, Facet> facetMap = Maps.newHashMap(); validateRegularFacets(response, facetMap, null, null); //apply brand filter FilterQuery[] filterQueries = FilterQuery .parseFilterQueries(facetMap.get("brand").getFilters().get(0).getFilterQueries()); response = server.search(query, site, filterQueries); validateRegularFacets(response, facetMap, Sets.newHashSet(0), null); //add filter by $10-$20 filterQueries = FilterQuery .parseFilterQueries(facetMap.get("price").getFilters().get(0).getFilterQueries()); response = server.search(query, site, filterQueries); validateRegularFacets(response, facetMap, Sets.newHashSet(0), Sets.newHashSet(0)); //add filter by $20 and up filterQueries = FilterQuery .parseFilterQueries(facetMap.get("price").getFilters().get(1).getFilterQueries()); response = server.search(query, site, filterQueries); validateRegularFacets(response, facetMap, Sets.newHashSet(0), Sets.newHashSet(0, 1)); //remove filter by $20 and up filterQueries = FilterQuery .parseFilterQueries(facetMap.get("price").getFilters().get(1).getFilterQueries()); response = server.search(query, site, filterQueries); validateRegularFacets(response, facetMap, Sets.newHashSet(0), Sets.newHashSet(0)); //remove brand filter filterQueries = FilterQuery .parseFilterQueries(facetMap.get("brand").getFilters().get(0).getFilterQueries()); response = server.search(query, site, filterQueries); validateRegularFacets(response, facetMap, null, Sets.newHashSet(0)); //remove filter by $10-$20 filterQueries = FilterQuery .parseFilterQueries(facetMap.get("price").getFilters().get(0).getFilterQueries()); response = server.search(query, site, filterQueries); validateRegularFacets(response, facetMap, null, null); } @SearchTest(newInstance = true, productData = "/product_catalog/sandal.xml", rulesData = "/rules/facetBlacklist.xml") public void testMultiSelectFacetRepeatedValues(SearchServer server) throws SearchServerException, RepositoryException { // Scenario to validate that multi select facets that have the same values but different fieldNames work ok // We are creating two facets: waterproof: yes,no and sunblock: yes,no // The test first selects waterproof=no and validates it's selected // Then we select sunblock=yes, do the corresponding validations and then proceed to deselect // first waterproof and finally sunblock List<RepositoryItem> facetList = new ArrayList<RepositoryItem>(); facetList.add(mockFacet("waterproof", "attr_waterproof", FIELD_FACET, null, null, true)); facetList.add(mockFacet("sunblock", "attr_sunblock", FIELD_FACET, null, null, true)); mockFacetRuleResponse("facetRuleId", server, facetList); SolrQuery query = new SolrQuery("shoe"); query.setRows(ROWS); SearchResponse response = server.search(query, site); Map<String, Facet> facetMap = Maps.newHashMap(); validateLocalFacets(response, facetMap, null, null); //add filter by waterproof = no FilterQuery[] filterQueries = FilterQuery .parseFilterQueries(facetMap.get("waterproof").getFilters().get(0).getFilterQueries()); response = server.search(query, site, filterQueries); validateLocalFacets(response, facetMap, Sets.newHashSet(0), null); //add filter by sunblock = yes filterQueries = FilterQuery .parseFilterQueries(facetMap.get("sunblock").getFilters().get(1).getFilterQueries()); response = server.search(query, site, filterQueries); validateLocalFacets(response, facetMap, Sets.newHashSet(0), Sets.newHashSet(1)); //remove filter by waterproof = no filterQueries = FilterQuery .parseFilterQueries(facetMap.get("waterproof").getFilters().get(0).getFilterQueries()); response = server.search(query, site, filterQueries); validateLocalFacets(response, facetMap, null, Sets.newHashSet(1)); //remove filter by sunblock = yes filterQueries = FilterQuery .parseFilterQueries(facetMap.get("sunblock").getFilters().get(1).getFilterQueries()); response = server.search(query, site, filterQueries); validateLocalFacets(response, facetMap, null, null); } @SearchTest(newInstance = true, productData = "/product_catalog/sandal.xml") public void testGetFacet(SearchServer server) throws SearchServerException { Facet facet = server.getFacet(site, Locale.US, "brandId", 100, -1, null); assertNotNull(facet); assertEquals(1, facet.getFilters().size()); assertEquals("88", facet.getFilters().get(0).getName()); RepositoryItem catalogZ = mock(RepositoryItem.class); Site siteZ = mock(Site.class); when(siteZ.getPropertyValue("defaultCatalog")).thenReturn(catalogZ); when(catalogZ.getRepositoryId()).thenReturn("Zcatalog"); facet = server.getFacet(siteZ, Locale.US, "brandId", 100, -1, null); assertNull(facet); } @SearchTest(newInstance = true, productData = "/product_catalog/sandal.xml") public void testGetFacetDepthLimit(SearchServer server) throws SearchServerException { Facet facet = server.getFacet(site, Locale.US, "categoryPath", 100, 2, "."); assertNotNull(facet); for (Facet.Filter filter : facet.getFilters()) { assertTrue(StringUtils.countMatches(filter.getName(), ".") <= 2); } facet = server.getFacet(site, Locale.US, "categoryPath", 100, -1, "."); assertNotNull(facet); boolean fullFacetDepth = false; for (Facet.Filter filter : facet.getFilters()) { if (StringUtils.countMatches(filter.getName(), ".") > 2) { fullFacetDepth = true; break; } } assertEquals( "the depth of the generated categoryPath facet should be greater than 2. checkout possible incorrect prune logic", true, fullFacetDepth); } protected void validateFilterByTopLevelCat(SearchResponse response, boolean hasProducts) { if (hasProducts) { assertEquals(1, response.getQueryResponse().getGroupResponse().getValues().size()); } else { assertNull(response.getQueryResponse().getGroupResponse()); } assertEquals("cat3000003", response.getCategoryGraph().get(0).getId()); assertEquals("cat3100004", response.getCategoryGraph().get(0).getCategoryGraphNodes().get(0).getId()); assertEquals("cat31000077", response.getCategoryGraph().get(0).getCategoryGraphNodes().get(1).getId()); assertEquals("cat4000003", response.getCategoryGraph().get(1).getId()); assertEquals("cat410000178", response.getCategoryGraph().get(1).getCategoryGraphNodes().get(0).getId()); } protected void validateFilterByCat3000003(SearchResponse response) { assertEquals("cat3100004", response.getCategoryGraph().get(0).getId()); assertEquals("cat411000179", response.getCategoryGraph().get(0).getCategoryGraphNodes().get(0).getId()); assertEquals("categoryPath:mycatalog.cat3000003.cat3100004.cat411000179", response.getCategoryGraph().get(0).getCategoryGraphNodes().get(0).getPath()); assertEquals("cat31000077", response.getCategoryGraph().get(1).getId()); assertEquals("cat411000196", response.getCategoryGraph().get(1).getCategoryGraphNodes().get(0).getId()); assertEquals("categoryPath:mycatalog.cat3000003.cat31000077.cat411000196", response.getCategoryGraph().get(1).getCategoryGraphNodes().get(0).getPath()); } protected void validateCategoryPathNotInFacets(SearchResponse response) { for (Facet facet : response.getFacets()) { if (facet.getName().equals("categoryPath")) { fail("facet's shouldn't contain category path"); } } } private void testSearchCategoryAux(SearchServer server, String term, String expectedProductId) throws SearchServerException { SolrQuery query = new SolrQuery(term); query.setRows(ROWS); SearchResponse res = server.search(query, site); assertEquals(null, res.getCorrectedTerm()); assertEquals(true, res.matchesAll()); QueryResponse queryResponse = res.getQueryResponse(); GroupResponse groupResponse = queryResponse.getGroupResponse(); for (GroupCommand command : groupResponse.getValues()) { for (Group group : command.getValues()) { String productId = group.getGroupValue(); if (expectedProductId.equals(productId)) { return; } } } fail("Product TNF3137 not found"); } private String getFirstResponseProperty(SearchResponse response, String property) { return response.getQueryResponse().getGroupResponse().getValues().get(0).getValues().get(0).getResult() .get(0).getFieldValue(property).toString(); } private void validateCorrectedTerms(SearchServer server, String incorrectTerm, String expectedCorrectedTerm, boolean matchesAll) throws SearchServerException { SolrQuery query = new SolrQuery(incorrectTerm); query.setRows(ROWS); SearchResponse res = server.search(query, site); //SimpleOrderedMap params = (SimpleOrderedMap) res.getQueryResponse().getHeader().get("params"); //assertEquals(expectedCorrectedTerm, params.get("q")); assertEquals(expectedCorrectedTerm, res.getCorrectedTerm()); assertEquals(matchesAll, res.matchesAll()); } private RepositoryItem mockFacet(String name, String field, String type, String blacklist, List<String> queries, Boolean isMultiselect) { RepositoryItem facet = mock(RepositoryItem.class); when(facet.getRepositoryId()).thenReturn(name); when(facet.getPropertyValue(FacetProperty.TYPE)).thenReturn(type); when(facet.getPropertyValue(FacetProperty.NAME)).thenReturn(name); when(facet.getPropertyValue(FacetProperty.IS_MULTI_SELECT)).thenReturn(isMultiselect); when(facet.getPropertyValue(FieldFacetProperty.FIELD)).thenReturn(field); if (QUERY_FACET.equals(type)) { when(facet.getPropertyValue(QueryFacetProperty.QUERIES)).thenReturn(queries); } if (StringUtils.isNotBlank(blacklist)) { Set<String> blackListSet = new HashSet<String>(); blackListSet.add(blacklist); when(facet.getPropertyValue(FieldFacetProperty.BLACKLIST)).thenReturn(blackListSet); } return facet; } private void mockFacetRuleResponse(String facetRuleId, SearchServer server, List<RepositoryItem> facetList) throws RepositoryException { AbstractSearchServer baseServer = (AbstractSearchServer) server; baseServer.setSearchRepository(searchRepository); RepositoryItem facetRepoItem = mock(RepositoryItem.class); when(searchRepository.getItem(facetRuleId, SearchRepositoryItemDescriptor.RULE)).thenReturn(facetRepoItem); when(facetRepoItem.getPropertyValue(RuleProperty.RULE_TYPE)).thenReturn("facetRule"); when(facetRepoItem.getRepositoryId()).thenReturn(facetRuleId); when(facetRepoItem.getPropertyValue(FacetRuleProperty.FACETS)).thenReturn(facetList); } public void validateRegularFacets(SearchResponse response, Map<String, Facet> facetMap, Set<Integer> brandSelectedIndex, Set<Integer> priceSelectedIndex) { facetMap.clear(); for (Facet facet : response.getFacets()) { if (facet.getName().equals("price")) { assertEquals(facet.getFilters().size(), 2); assertEquals("$10-$20", facet.getFilters().get(0).getName()); assertEquals("$20 And Up", facet.getFilters().get(1).getName()); validateFacetFilter(priceSelectedIndex, facet); } else if (facet.getName().equals("brand")) { assertEquals(facet.getFilters().size(), 1); assertEquals(facet.getFilters().get(0).getName(), "The North Face"); validateFacetFilter(brandSelectedIndex, facet); } facetMap.put(facet.getName(), facet); } } public void validateLocalFacets(SearchResponse response, Map<String, Facet> facetMap, Set<Integer> waterproofSelectedIndex, Set<Integer> sunblockSelectedIndex) { facetMap.clear(); int facetsProcees = 0; for (Facet facet : response.getFacets()) { if (facet.getName().equals("waterproof")) { assertEquals(facet.getFilters().size(), 2); assertEquals("no", facet.getFilters().get(0).getName()); assertEquals("yes", facet.getFilters().get(1).getName()); validateFacetFilter(waterproofSelectedIndex, facet); facetsProcees++; } else if (facet.getName().equals("sunblock")) { assertEquals(facet.getFilters().size(), 2); assertEquals("no", facet.getFilters().get(0).getName()); assertEquals("yes", facet.getFilters().get(1).getName()); validateFacetFilter(sunblockSelectedIndex, facet); facetsProcees++; } facetMap.put(facet.getName(), facet); } assertEquals(2, facetsProcees); } public void validateFacetFilter(Set<Integer> selectedIndex, Facet facet) { if (selectedIndex == null) { selectedIndex = Sets.newHashSet(); } Set<Integer> fullIndex = Sets.newHashSet(); for (int i = 0; i < facet.getFilters().size(); i++) { fullIndex.add(i); } for (int index : selectedIndex) { assertTrue(facet.getFilters().get(index).isSelected()); } Set<Integer> unselectedIndex = Sets.difference(fullIndex, selectedIndex); for (int index : unselectedIndex) { assertFalse(facet.getFilters().get(index).isSelected()); } } /** * Updates existing rules in the index with dates relative to the current time. * @return update XML message with the date updates. */ private String generateDatedRulesXml() { StringBuffer update = new StringBuffer(); Calendar cal = Calendar.getInstance(); //Create updated dates for documents in the index (Solr4 rocks!) update.append("<add>"); //Add an expired rule update.append("<doc>"); update.append("<field name=\"id\">oldRule</field>"); cal.setTime(new Date()); cal.add(Calendar.DAY_OF_WEEK, -5); update.append("<field name=\"startDate\">" + getISODate(cal.getTime()) + "</field>"); cal.setTime(new Date()); cal.add(Calendar.DAY_OF_WEEK, -3); update.append("<field name=\"endDate\">" + getISODate(cal.getTime()) + "</field>"); appendBoilerPlateFields(update); update.append("</doc>"); //Add a valid rule now update.append("<doc>"); update.append("<field name=\"id\">redirectRuleId</field>"); cal.setTime(new Date()); cal.add(Calendar.DAY_OF_WEEK, -2); update.append("<field name=\"startDate\">" + getISODate(cal.getTime()) + "</field>"); cal.setTime(new Date()); cal.add(Calendar.DAY_OF_WEEK, 2); update.append("<field name=\"endDate\">" + getISODate(cal.getTime()) + "</field>"); appendBoilerPlateFields(update); update.append("</doc>"); //One that hast't started yet update.append("<doc>"); update.append("<field name=\"id\">futureRule</field>"); cal.setTime(new Date()); cal.add(Calendar.DAY_OF_WEEK, 5); update.append("<field name=\"startDate\">" + getISODate(cal.getTime()) + "</field>"); cal.setTime(new Date()); cal.add(Calendar.DAY_OF_WEEK, 6); update.append("<field name=\"endDate\">" + getISODate(cal.getTime()) + "</field>"); appendBoilerPlateFields(update); update.append("</doc>"); update.append("</add>"); return update.toString(); } private void appendBoilerPlateFields(StringBuffer update) { update.append("<field name=\"siteId\">__all__</field>"); update.append("<field name=\"catalogId\">__all__</field>"); update.append("<field name=\"category\">__all__</field>"); update.append("<field name=\"target\">allpages</field>"); update.append("<field name=\"query\">redirect</field>"); update.append("<field name=\"brandId\">__all__</field>"); update.append("<field name=\"subTarget\">__all__</field>"); } /** * Just format a date to be ISO 8601 compliant so it can be indexed to Solr. */ private String getISODate(Date date) { return isoDateFormat.format(date); } }