package com.plugtree.solradvert;
/**
* Copyright 2011 Plugtree LLC
*
* Licensed 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.File;
import java.io.IOException;
import java.util.Date;
import org.apache.commons.io.FileUtils;
import org.apache.solr.common.SolrException;
import org.junit.Test;
import com.plugtree.solradvert.util.AbstractAdvertTestCase;
import com.plugtree.solradvert.util.SolrTest;
/**
* Using the request hanlders:
*
* <requestHandler name="requestHandlerWithAdvert" class="solr.StandardRequestHandler">
* <lst name="defaults">
* <str name="defType">dismax</str>
* <str name="qf">id product brand description</str>
* </lst>
* <arr name="first-components">
* <str>adverts</str>
* </arr>
* </requestHandler>
*
* <requestHandler name="requestHandlerWithoutAdvert" class="solr.StandardRequestHandler">
* <lst name="defaults">
* <str name="defType">dismax</str>
* <str name="qf">id product brand description</str>
* </lst>
* </requestHandler>
*
* @author salaboy
*/
public class AdvertComponentTest extends AbstractAdvertTestCase {
@Test
@SolrTest
public void testBoosting() throws Exception {
assertAddDoc("1", "shoes", "nike", "running shoes", new Date(), 0.0);
assertAddDoc("2", "shoes", "adidas", "football shoes", new Date(), 0.0);
assertCommit();
// we are using the requestHandlerWithAdvert, but the request parameter
// "advert" isn't "true", so the documents should be returned in their
// index order
assertQuery(
newRequest(
"q","shoes",
"qt", "requestHandlerWithAdvert"),
"//*[@numFound='2']",
"//result/doc[1]/int[@name='id'][.='1']",
"//result/doc[2]/int[@name='id'][.='2']"
);
// now we add "&advert=true" to the request, so the Adidas shoes should
// be boosted (see rules/advert1.drl)
assertQuery(
newRequest(
"q","shoes",
"qt", "requestHandlerWithAdvert",
AdvertParams.ADVERT_COMPONENT_NAME, "true"),
"//*[@numFound='2']",
"//result/doc[1]/int[@name='id'][.='2']",
"//result/doc[2]/int[@name='id'][.='1']"
);
}
@Test
@SolrTest
public void testBoostingDsl() throws Exception {
assertAddDoc("1", "shoes", "nike", "running shoes", new Date(), 0.0);
assertAddDoc("2", "shoes", "adidas", "football shoes", new Date(), 0.0);
assertCommit();
// we are using the requestHandlerWithAdvert, but the request parameter
// "advert" isn't "true", so the documents should be returned in their
// index order
assertQuery(
newRequest(
"q","shoes",
"qt", "requestHandlerWithAdvert"),
"//*[@numFound='2']",
"//result/doc[1]/int[@name='id'][.='1']",
"//result/doc[2]/int[@name='id'][.='2']"
);
// now we add "&advert=true" to the request, so the Adidas shoes should
// be boosted
assertQuery(
newRequest(
"q","shoes",
"qt", "requestHandlerWithAdvert",
AdvertParams.ADVERT_COMPONENT_NAME, "true",
AdvertParams.ADVERT_RULES, "kbase4"),
"//*[@numFound='2']",
"//result/doc[1]/int[@name='id'][.='2']",
"//result/doc[2]/int[@name='id'][.='1']"
);
}
@Test
@SolrTest
public void testSorting() throws Exception {
assertAddDoc("1", "tennis racquet", "babolat", "", new Date(), 150.0);
assertAddDoc("2", "tennis racquet", "prince", "", new Date(), 100.0);
assertAddDoc("3", "tennis racquet", "head", "", new Date(), 300.0);
assertCommit();
// we are using the requestHandlerWithAdvert, but the request parameter
// "advert" isn't "true", so the documents should be returned in their
// index order
assertQuery(
newRequest(
"q","\"tennis racquet\"",
"qt", "requestHandlerWithAdvert"),
"//*[@numFound='3']",
"//result/doc[1]/int[@name='id'][.='1']",
"//result/doc[2]/int[@name='id'][.='2']",
"//result/doc[3]/int[@name='id'][.='3']"
);
// now we add "&advert=true" to the request, so the documents should be
// returned sorted by price
assertQuery(
newRequest(
"q","\"tennis racquet\"",
"qt", "requestHandlerWithAdvert",
AdvertParams.ADVERT_COMPONENT_NAME, "true"),
"//*[@numFound='3']",
"//result/doc[1]/int[@name='id'][.='2']",
"//result/doc[2]/int[@name='id'][.='1']",
"//result/doc[3]/int[@name='id'][.='3']"
);
}
@Test
@SolrTest
/**
* Test if the kbase parameter is taken into account
* @throws Exception
*/
public void testTwoDifferentSessions() throws Exception {
assertAddDoc("1", "tennis racquet", "babolat", "", new Date(), 150.0);
assertAddDoc("2", "tennis racquet", "prince", "", new Date(), 100.0);
assertAddDoc("3", "tennis racquet", "head", "", new Date(), 300.0);
assertCommit();
// No rules applied
assertQuery(
newRequest(
"q","\"tennis racquet\"",
"qt", "requestHandlerWithAdvert"),
"//*[@numFound='3']",
"//result/doc[1]/int[@name='id'][.='1']",
"//result/doc[2]/int[@name='id'][.='2']",
"//result/doc[3]/int[@name='id'][.='3']"
);
// ksession1 will sort results by price in ascending order
assertQuery(
newRequest(
"q","\"tennis racquet\"",
"qt", "requestHandlerWithAdvert",
AdvertParams.ADVERT_COMPONENT_NAME, "true",
AdvertParams.ADVERT_RULES, "kbase1"),
"//*[@numFound='3']",
"//result/doc[1]/int[@name='id'][.='2']",
"//result/doc[2]/int[@name='id'][.='1']",
"//result/doc[3]/int[@name='id'][.='3']"
);
// ksession3 will sort results by price in descending order
assertQuery(
newRequest(
"q","\"tennis racquet\"",
"qt", "requestHandlerWithAdvert",
AdvertParams.ADVERT_COMPONENT_NAME, "true",
AdvertParams.ADVERT_RULES, "kbase3"),
"//*[@numFound='3']",
"//result/doc[1]/int[@name='id'][.='3']",
"//result/doc[2]/int[@name='id'][.='1']",
"//result/doc[3]/int[@name='id'][.='2']"
);
}
@Test(expected=SolrException.class)
@SolrTest
public void testUndefinedSession() throws Exception {
assertQuery(
newRequest(
"q","foo",
"qt", "requestHandlerWithAdvert",
AdvertParams.ADVERT_COMPONENT_NAME, "true",
AdvertParams.ADVERT_RULES, "bar123"),
"//*[@numFound='0']"
);
}
@Test
@SolrTest(solrConfig="solrconfig-context3.xml")
public void testRulesChangeBetweenRequests() throws Exception {
assertAddDoc("1", "", "", "", new Date(), 150.0);
assertAddDoc("2", "", "", "", new Date(), 100.0);
assertAddDoc("3", "", "", "", new Date(), 300.0);
assertCommit();
File advert3File = new File(getClass().getResource("/rules/testSortByPriceDesc.drl").toURI());
File advert5File = new File(getClass().getResource("/rules/testSortByPriceAsc.drl").toURI());
File tempFile = tmpFolder.newFile("temp.drl");
// advert3.drl will sort results by price in descending order
assertQuery(
newRequest(
"q", "*:*",
AdvertParams.ADVERT_COMPONENT_NAME, "true"),
"//*[@numFound='3']",
"//result/doc[1]/int[@name='id'][.='3']",
"//result/doc[2]/int[@name='id'][.='1']",
"//result/doc[3]/int[@name='id'][.='2']"
);
FileUtils.copyFile(advert3File, tempFile);
try {
FileUtils.copyFile(advert5File, advert3File);
// advert5.drl will sort results by price in ascending order
assertQuery(
newRequest(
"q", "*:*",
AdvertParams.ADVERT_COMPONENT_NAME, "true",
AdvertParams.ADVERT_RELOAD_RULES, "true"),
"//*[@numFound='3']",
"//result/doc[1]/int[@name='id'][.='2']",
"//result/doc[2]/int[@name='id'][.='1']",
"//result/doc[3]/int[@name='id'][.='3']"
);
} finally {
FileUtils.copyFile(tempFile, advert3File);
}
}
@Test
@SolrTest
public void testMatchAllDocs() throws Exception {
assertQuery(
newRequest(
"q", "{!lucene}*:*",
"qt", "requestHandlerWithAdvert",
AdvertParams.ADVERT_COMPONENT_NAME, "true"));
}
@Test
@SolrTest
public void testPhraseQuery() throws Exception {
assertQuery(
newRequest(
"q", "{!lucene}description:i-pod",
"qt", "requestHandlerWithAdvert",
AdvertParams.ADVERT_COMPONENT_NAME, "true"));
}
@Test
@SolrTest(solrConfig="solr/conf/solrconfig2.xml")
public void testAnotherKnowledgeContext() throws IOException, Exception {
assertAddDoc("1", "tennis racquet", "babolat", "", new Date(), 150.0);
assertAddDoc("2", "tennis racquet", "prince", "", new Date(), 100.0);
assertAddDoc("3", "tennis racquet", "head", "", new Date(), 300.0);
assertCommit();
// now we add "&advert=true" to the request, so the documents should be
// returned sorted by price
assertQuery(
newRequest(
"q", "\"tennis racquet\"",
"qt", "requestHandlerWithAdvert",
AdvertParams.ADVERT_COMPONENT_NAME, "true",
AdvertParams.ADVERT_RULES, "kbase1"
),
"//*[@numFound='3']",
"//result/doc[1]/int[@name='id'][.='3']",
"//result/doc[2]/int[@name='id'][.='1']",
"//result/doc[3]/int[@name='id'][.='2']"
);
}
@Test
@SolrTest
public void testQueryGeneralQuery() throws Exception {
assertQuery(
newRequest("q", "some content"));
}
@Test
@SolrTest
public void testMoveTermToFilter() throws Exception {
assertAddDoc("1", "shoes", "adidas", "", new Date(), 150.0);
assertAddDoc("2", "shoes", "nike", "", new Date(), 100.0);
assertAddDoc("3", "socks", "adidas", "", new Date(), 300.0);
assertCommit();
// assert that nothing happens when the rule is disabled
assertQuery(
newRequest(
"q", "adidas shoes",
"qt", "requestHandlerWithAdvert",
"mm", "1",
AdvertParams.ADVERT_COMPONENT_NAME, "false",
AdvertParams.ADVERT_BATCH, "batchTestMoveTermToFilter"
),
"//*[@numFound='3']"
);
// assert that the rule is not applied when the term appears in a filter query
assertQuery(
newRequest(
"q", "shoes",
"qt", "requestHandlerWithAdvert",
"fq", "brand:adidas OR brand:nike",
"mm", "1",
AdvertParams.ADVERT_COMPONENT_NAME, "true",
AdvertParams.ADVERT_BATCH, "batchTestMoveTermToFilter",
AdvertParams.ADVERT_RULES, "kbaseTestMoveTermToFilter"
),
"//*[@numFound='2']"
);
// assert that the rule is applied when the term appears in the main query
assertQuery(
newRequest(
"q", "adidas shoes",
"qt", "requestHandlerWithAdvert",
"mm", "1",
AdvertParams.ADVERT_COMPONENT_NAME, "true",
AdvertParams.ADVERT_BATCH, "batchTestMoveTermToFilter",
AdvertParams.ADVERT_RULES, "kbaseTestMoveTermToFilter"
),
"//*[@numFound='1']"
);
}
}