/*******************************************************************************
* Gisgraphy Project
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
*
* Copyright 2008 Gisgraphy project
* David Masclet <davidmasclet@gisgraphy.com>
*
*
*******************************************************************************/
package com.gisgraphy.geoloc;
import static com.gisgraphy.domain.valueobject.Pagination.paginate;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import static org.junit.Assert.*;
import javax.annotation.Resource;
import org.junit.Assert;
import org.junit.Test;
import com.gisgraphy.domain.geoloc.entity.Adm;
import com.gisgraphy.domain.geoloc.entity.City;
import com.gisgraphy.domain.geoloc.entity.GisFeature;
import com.gisgraphy.domain.geoloc.entity.Street;
import com.gisgraphy.domain.repository.IAdmDao;
import com.gisgraphy.domain.repository.ICityDao;
import com.gisgraphy.domain.valueobject.GisFeatureDistance;
import com.gisgraphy.domain.valueobject.Output;
import com.gisgraphy.domain.valueobject.Pagination;
import com.gisgraphy.fulltext.AbstractIntegrationHttpSolrTestCase;
import com.gisgraphy.geocoloc.IGeolocSearchEngine;
import com.gisgraphy.helper.FileHelper;
import com.gisgraphy.helper.GeolocHelper;
import com.gisgraphy.serializer.common.OutputFormat;
import com.gisgraphy.service.IStatsUsageService;
import com.gisgraphy.stats.StatsUsageType;
import com.gisgraphy.test.FeedChecker;
import com.gisgraphy.test.GisgraphyTestHelper;
public class GeolocSearchEngineTest extends AbstractIntegrationHttpSolrTestCase {
@Resource
IGeolocSearchEngine geolocSearchEngine;
@Resource
private GisgraphyTestHelper geolocTestHelper;
@Resource
ICityDao cityDao;
@Resource
IAdmDao admDao;
@Resource
IStatsUsageService statsUsageService;
@Test
public void testExecuteAndSerializeShouldSerialize() {
City p1 = GisgraphyTestHelper.createCity("paris", 48.86667F, 2.3333F, 1L);
// N 48° 52' 0'' 2° 20' 0'' E
City p2 = GisgraphyTestHelper.createCity("bordeaux", 44.83333F, -0.56667F,
3L);
// N 44 50 0 ; 0 34 0 W
City p3 = GisgraphyTestHelper.createCity("goussainville", 49.01667F,
2.46667F, 2L);
// N49° 1' 0'' E 2° 28' 0''
this.cityDao.save(p1);
this.cityDao.save(p2);
this.cityDao.save(p3);
File tempDir = FileHelper.createTempDir(this.getClass()
.getSimpleName());
File file = new File(tempDir.getAbsolutePath()
+ System.getProperty("file.separator") + "serializegeoloc.txt");
Pagination pagination = paginate().from(1).to(15);
Output output = Output.withFormat(OutputFormat.XML).withIndentation();
GeolocQuery query = new GeolocQuery(p1.getLocation(), 1000000,
pagination, output, GisFeature.class);
FileOutputStream outputStream = null;
try {
outputStream = new FileOutputStream(file);
} catch (FileNotFoundException e) {
fail("Error when instanciate OutputStream");
}
geolocSearchEngine.executeAndSerialize(query, outputStream);
String content = "";
try {
content = GisgraphyTestHelper.readFileAsString(file.getAbsolutePath());
} catch (IOException e) {
fail("can not get content of file " + file.getAbsolutePath());
}
FeedChecker.assertQ("The query returns incorrect values", content, "/"
+ GeolocResultsDto.GEOLOCRESULTSDTO_JAXB_NAME + "/"
+ GisFeatureDistance.GISFEATUREDISTANCE_JAXB_NAME + "[1]/name[.='"
+ p1.getName() + "']", "/"
+ GeolocResultsDto.GEOLOCRESULTSDTO_JAXB_NAME + "/"
+ GisFeatureDistance.GISFEATUREDISTANCE_JAXB_NAME + "[2]/name[.='"
+ p3.getName() + "']", "/"
+ GeolocResultsDto.GEOLOCRESULTSDTO_JAXB_NAME + "/"
+ GisFeatureDistance.GISFEATUREDISTANCE_JAXB_NAME + "[3]/name[.='"
+ p2.getName() + "']");
// delete temp dir
assertTrue("the tempDir has not been deleted", GisgraphyTestHelper
.DeleteNonEmptyDirectory(tempDir));
}
@Test
public void testExecuteQueryToStringShouldReturnsAValidStringWithResults() {
City p1 = GisgraphyTestHelper.createCity("paris", 48.86667F, 2.3333F, 1L);
// N 48° 52' 0'' 2° 20' 0'' E
City p2 = GisgraphyTestHelper.createCity("bordeaux", 44.83333F, -0.56667F,
3L);
// N 44 50 0 ; 0 34 0 W
City p3 = GisgraphyTestHelper.createCity("goussainville", 49.01667F,
2.46667F, 2L);
// N49° 1' 0'' E 2° 28' 0''
this.cityDao.save(p1);
this.cityDao.save(p2);
this.cityDao.save(p3);
Pagination pagination = paginate().from(1).to(15);
Output output = Output.withFormat(OutputFormat.XML).withIndentation();
GeolocQuery query = new GeolocQuery(p1.getLocation(), 1000001,
pagination, output, City.class);
String results = geolocSearchEngine.executeQueryToString(query);
FeedChecker.assertQ("The query returns incorrect values", results, "/"
+ GeolocResultsDto.GEOLOCRESULTSDTO_JAXB_NAME + "/"
+ GisFeatureDistance.GISFEATUREDISTANCE_JAXB_NAME + "[1]/name[.='"
+ p1.getName() + "']", "/"
+ GeolocResultsDto.GEOLOCRESULTSDTO_JAXB_NAME + "/"
+ GisFeatureDistance.GISFEATUREDISTANCE_JAXB_NAME + "[2]/name[.='"
+ p3.getName() + "']", "/"
+ GeolocResultsDto.GEOLOCRESULTSDTO_JAXB_NAME + "/"
+ GisFeatureDistance.GISFEATUREDISTANCE_JAXB_NAME + "[3]/name[.='"
+ p2.getName() + "']");
}
@Test
public void testExecuteQueryShouldReturnsAValidDTOOrderedByDistance() {
City p1 = GisgraphyTestHelper.createCity("paris", 48.86667F, 2.3333F, 1L);
// N 48° 52' 0'' 2° 20' 0'' E
City p2 = GisgraphyTestHelper.createCity("bordeaux", 44.83333F, -0.56667F,
3L);
// N 44 50 0 ; 0 34 0 W
City p3 = GisgraphyTestHelper.createCity("goussainville", 49.01667F,
2.46667F, 2L);
// N49° 1' 0'' E 2° 28' 0''
this.cityDao.save(p1);
this.cityDao.save(p2);
this.cityDao.save(p3);
Pagination pagination = paginate().from(1).to(15);
Output output = Output.withFormat(OutputFormat.XML).withIndentation();
GeolocQuery query = new GeolocQuery(p1.getLocation(), 1000001,
pagination, output, City.class);
GeolocResultsDto results = geolocSearchEngine.executeQuery(query);
assertEquals(3, results.getResult().size());
assertEquals(p1.getName(), results.getResult().get(0).getName());
assertEquals(p3.getName(), results.getResult().get(1).getName());
assertEquals(p2.getName(), results.getResult().get(2).getName());
}
@Test
public void testExecuteQueryShouldNotReturnTheDistanceFieldIfDistanceFieldIsFalse() {
City p1 = GisgraphyTestHelper.createCity("paris", 48.86667F, 2.3333F, 1L);
// N 48° 52' 0'' 2° 20' 0'' E
City p2 = GisgraphyTestHelper.createCity("bordeaux", 44.83333F, -0.56667F,
3L);
// N 44 50 0 ; 0 34 0 W
City p3 = GisgraphyTestHelper.createCity("goussainville", 49.01667F,
2.46667F, 2L);
// N49° 1' 0'' E 2° 28' 0''
this.cityDao.save(p1);
this.cityDao.save(p2);
this.cityDao.save(p3);
Pagination pagination = paginate().from(1).to(15);
Output output = Output.withFormat(OutputFormat.XML).withIndentation();
GeolocQuery query = new GeolocQuery(p1.getLocation(), 1000001,
pagination, output, City.class);
query.withDistanceField(false);
GeolocResultsDto results = geolocSearchEngine.executeQuery(query);
assertEquals(3, results.getResult().size());
assertNull("Distance should not be null if withDistance is false", results.getResult().get(0).getDistance());
assertNull("Distance should not be null if withDistance is false", results.getResult().get(1).getDistance());
assertNull("Distance should not be null if withDistance is false", results.getResult().get(2).getDistance());
}
@Test
public void testExecuteQueryShouldfilterMunicipalityIfMunicipalityFilterIsTrue() {
City p1 = GisgraphyTestHelper.createCity("paris", 48.86667F, 2.3333F, 1L);
// N 48° 52' 0'' 2° 20' 0'' E
City p2 = GisgraphyTestHelper.createCity("bordeaux", 44.83333F, -0.56667F,
3L);
p2.setMunicipality(true);
// N 44 50 0 ; 0 34 0 W
City p3 = GisgraphyTestHelper.createCity("goussainville", 49.01667F,
2.46667F, 2L);
// N49° 1' 0'' E 2° 28' 0''
this.cityDao.save(p1);
this.cityDao.save(p2);
this.cityDao.save(p3);
Adm adm1 = GisgraphyTestHelper.createAdm("name", "FR", "A1", "B2", "C3", "D4", "E5",p2, 4);
this.admDao.save(adm1);
//true
Pagination pagination = paginate().from(1).to(15);
Output output = Output.withFormat(OutputFormat.XML).withIndentation();
GeolocQuery query = new GeolocQuery(p1.getLocation(), 1000001,
pagination, output, City.class);
query.withMunicipalityFilter(true);
GeolocResultsDto results = geolocSearchEngine.executeQuery(query);
assertEquals(1, results.getResult().size());
assertEquals("bordeaux",results.getResult().get(0).getName());
//false
query = new GeolocQuery(p1.getLocation(), 1000001, pagination, output, City.class);
query.withMunicipalityFilter(false);
results = geolocSearchEngine.executeQuery(query);
assertEquals(3, results.getResult().size());
// with gisfeature placetype
query = new GeolocQuery(p1.getLocation(), 1000001, pagination, output, GisFeature.class);
query.withMunicipalityFilter(true);
results = geolocSearchEngine.executeQuery(query);
assertEquals(1, results.getResult().size());
assertEquals("bordeaux", results.getResult().get(0).getName());
}
@Test
public void testExecuteQueryShouldReturnsAnEmptyListIfThereIsNoResults() {
City p1 = GisgraphyTestHelper.createCity("paris", 48.86667F, 2.3333F, 1L);
Pagination pagination = paginate().from(1).to(15);
Output output = Output.withFormat(OutputFormat.XML).withIndentation();
GeolocQuery query = new GeolocQuery(p1.getLocation(), 1000001,
pagination, output, City.class);
GeolocResultsDto results = geolocSearchEngine.executeQuery(query);
assertNotNull(
"Geoloc search engine should never return null but an empty list",
results);
assertEquals(0, results.getResult().size());
}
@Test
public void testExecuteQueryInJSONShouldReturnValidJson() {
City p1 = geolocTestHelper
.createAndSaveCityWithFullAdmTreeAndCountry(10000000L);
p1.setAdm4Code("D4");
p1.setAdm4Name("adm");
p1.setAdm5Code("D5");
p1.setAdm5Name("adm5");
this.cityDao.save(p1);
Pagination pagination = paginate().from(1).to(15);
Output output = Output.withFormat(OutputFormat.JSON).withIndentation();
GeolocQuery query = new GeolocQuery(p1.getLocation(), 40000,
pagination, output, City.class);
String results = geolocSearchEngine.executeQueryToString(query);
GeolocResultsDto geolocResultsDto = geolocSearchEngine.executeQuery(query);
/// new GisFeatureDistance(((GisFeature)p1),0D);
FeedChecker.checkGeolocResultsDtoJSON(geolocResultsDto, results);
}
@Test
public void testExecuteQueryInGEORSShouldReturnValidFeed() {
GisFeature city = geolocTestHelper
.createAndSaveCityWithFullAdmTreeAndCountry(1L);
city.setAdm4Code("D4");
city.setAdm4Name("adm");
this.cityDao.save((City)city);
Pagination pagination = Pagination.DEFAULT_PAGINATION;
Output output = Output.withFormat(OutputFormat.GEORSS).withIndentation();
GeolocQuery query = new GeolocQuery(city.getLocation(), 40000,
pagination, output, City.class);
GeolocResultsDto geolocResultsDto = geolocSearchEngine.executeQuery(query);
String results = geolocSearchEngine.executeQueryToString(query);
FeedChecker.checkGeolocResultsDtoGEORSS(geolocResultsDto, results);
}
@Test
public void testExecuteQueryWithStreetPlaceTypeShouldIgnoreAllTrantientField() {
//is_in field are only for sync openstreetmap entity to gisfeature
//so the is_in fields are transcient and the property should be mark with introspectionignore field
GisFeature city = geolocTestHelper
.createAndSaveCityWithFullAdmTreeAndCountry(1L);
city.setAdm4Code("D4");
city.setAdm4Name("adm");
this.cityDao.save((City)city);
Pagination pagination = Pagination.DEFAULT_PAGINATION;
Output output = Output.withFormat(OutputFormat.GEORSS).withIndentation();
GeolocQuery query = new GeolocQuery(city.getLocation(), 40000,
pagination, output, Street.class);
geolocSearchEngine.executeQuery(query);
//should not fails
}
@Test
public void testExecuteQueryInATOMShouldReturnValidFeed() {
City p1 = geolocTestHelper
.createAndSaveCityWithFullAdmTreeAndCountry(1L);
p1.setAdm4Code("D4");
p1.setAdm4Name("adm");
this.cityDao.save(p1);
Pagination pagination = Pagination.DEFAULT_PAGINATION;
Output output = Output.withFormat(OutputFormat.ATOM).withIndentation();
GeolocQuery query = new GeolocQuery(p1.getLocation(), 40000,
pagination, output, City.class);
GeolocResultsDto geolocResultsDto = geolocSearchEngine.executeQuery(query);
String results = geolocSearchEngine.executeQueryToString(query);
FeedChecker.checkGeolocResultsDtoATOM(geolocResultsDto, results);
}
public void testStatsShouldBeIncreaseForAllCall() {
statsUsageService.resetUsage(StatsUsageType.GEOLOC);
Pagination pagination = paginate().from(1).to(15);
Output output = Output.withFormat(OutputFormat.JSON).withIndentation();
GeolocQuery query = new GeolocQuery(GeolocHelper.createPoint(2F, 3F),
40000, pagination, output, City.class);
geolocSearchEngine.executeQueryToString(query);
assertEquals(new Long(1), statsUsageService
.getUsage(StatsUsageType.GEOLOC));
geolocSearchEngine.executeQuery(query);
assertEquals(new Long(2), statsUsageService
.getUsage(StatsUsageType.GEOLOC));
geolocSearchEngine.executeAndSerialize(query,
new ByteArrayOutputStream());
assertEquals(new Long(3), statsUsageService
.getUsage(StatsUsageType.GEOLOC));
}
public void testExecuteQueryWithNullQueryShouldThrows() {
try {
geolocSearchEngine.executeQuery(null);
fail("executeQuery does not accept null query");
} catch (IllegalArgumentException e) {
} catch (GeolocSearchException e) {
fail("executequery does not accept null query and must throws an IllegalArgumentException, not GeolocServiceException");
}
}
public void testExecuteQueryToStringWithNullQueryShouldThrows() {
try {
geolocSearchEngine.executeQueryToString(null);
fail("executeQueryToString does not accept null query");
} catch (IllegalArgumentException e) {
} catch (GeolocSearchException e) {
fail("executequeryToString does not accept null query and must throws an IllegalArgumentException, not GeolocServiceException");
}
}
public void testExecuteAndSerializeWithNullQueryShouldThrows() {
try {
geolocSearchEngine.executeAndSerialize(null,
new ByteArrayOutputStream());
fail("executeAndSerialize does not accept null query");
} catch (IllegalArgumentException e) {
} catch (GeolocSearchException e) {
fail("executeAndSerialize does not accept null query and must throws an IllegalArgumentException, not GeolocServiceException");
}
}
public void testExecuteAndSerializeWithNullOutputStreamShouldThrows() {
try {
geolocSearchEngine.executeAndSerialize(new GeolocQuery(GeolocHelper
.createPoint(1F, 1F)), null);
fail("executeAndSerialize does not accept null query");
} catch (IllegalArgumentException e) {
} catch (GeolocSearchException e) {
fail("executeAndSerialize does not accept null outputStream and must throws an IllegalArgumentException, not GeolocServiceException");
}
}
@Test
public void testExecuteQueryShouldTakeCallbackParameterIntoAccountForScriptLanguage() {
City p1 = GisgraphyTestHelper.createCity("paris", 48.86667F, 2.3333F, 1L);
// N 48° 52' 0'' 2° 20' 0'' E
City p2 = GisgraphyTestHelper.createCity("bordeaux", 44.83333F, -0.56667F,
3L);
// N 44 50 0 ; 0 34 0 W
City p3 = GisgraphyTestHelper.createCity("goussainville", 49.01667F,
2.46667F, 2L);
// N49° 1' 0'' E 2° 28' 0''
this.cityDao.save(p1);
this.cityDao.save(p2);
this.cityDao.save(p3);
Pagination pagination = paginate().from(1).to(15);
Output output = Output.withFormat(OutputFormat.JSON).withIndentation();
GeolocQuery query = new GeolocQuery(p1.getLocation(), 1000001,
pagination, output, City.class);
query.withCallback("doit");
String content = geolocSearchEngine.executeQueryToString(query);
Assert.assertTrue(content.startsWith("doit("));
Assert.assertTrue(content.endsWith(");"));
}
@Test
public void testExecuteQueryShouldTakeCallbackParameterIntoAccountForScriptLanguageWhenNoResult() {
City p1 = GisgraphyTestHelper.createCity("paris", 48.86667F, 2.3333F, 1L);
// N 48° 52' 0'' 2° 20' 0'' E
City p2 = GisgraphyTestHelper.createCity("bordeaux", 44.83333F, -0.56667F,
3L);
// N 44 50 0 ; 0 34 0 W
City p3 = GisgraphyTestHelper.createCity("goussainville", 49.01667F,
2.46667F, 2L);
// N49° 1' 0'' E 2° 28' 0''
this.cityDao.save(p1);
this.cityDao.save(p2);
this.cityDao.save(p3);
Pagination pagination = paginate().from(15).to(20);
Output output = Output.withFormat(OutputFormat.JSON).withIndentation();
GeolocQuery query = new GeolocQuery(p1.getLocation(), 1000001,
pagination, output, City.class);
query.withCallback("doit");
String content = geolocSearchEngine.executeQueryToString(query);
Assert.assertTrue(content.startsWith("doit("));
Assert.assertTrue(content.endsWith(");"));
}
@Test
public void testExecuteQueryShouldNotTakeCallbackParameterIntoAccountForXML() {
City p1 = GisgraphyTestHelper.createCity("paris", 48.86667F, 2.3333F, 1L);
// N 48° 52' 0'' 2° 20' 0'' E
City p2 = GisgraphyTestHelper.createCity("bordeaux", 44.83333F, -0.56667F,
3L);
// N 44 50 0 ; 0 34 0 W
City p3 = GisgraphyTestHelper.createCity("goussainville", 49.01667F,
2.46667F, 2L);
// N49° 1' 0'' E 2° 28' 0''
this.cityDao.save(p1);
this.cityDao.save(p2);
this.cityDao.save(p3);
Pagination pagination = paginate().from(1).to(15);
Output output = Output.withFormat(OutputFormat.XML).withIndentation();
GeolocQuery query = new GeolocQuery(p1.getLocation(), 1000001,
pagination, output, City.class);
query.withCallback("doit");
String content = geolocSearchEngine.executeQueryToString(query);
Assert.assertFalse(content.startsWith("doit("));
Assert.assertFalse(content.endsWith(");"));
}
}