1   /*******************************************************************************
2    *   Gisgraphy Project 
3    * 
4    *   This library is free software; you can redistribute it and/or
5    *   modify it under the terms of the GNU Lesser General Public
6    *   License as published by the Free Software Foundation; either
7    *   version 2.1 of the License, or (at your option) any later version.
8    * 
9    *   This library is distributed in the hope that it will be useful,
10   *   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12   *   Lesser General Public License for more details.
13   * 
14   *   You should have received a copy of the GNU Lesser General Public
15   *   License along with this library; if not, write to the Free Software
16   *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
17   * 
18   *  Copyright 2008  Gisgraphy project 
19   *  David Masclet <davidmasclet@gisgraphy.com>
20   *  
21   *  
22   *******************************************************************************/
23  package com.gisgraphy.domain.repository;
24  
25  import java.util.ArrayList;
26  import java.util.List;
27  
28  import javax.annotation.Resource;
29  
30  import org.junit.Test;
31  import org.springframework.beans.factory.annotation.Required;
32  
33  import com.gisgraphy.domain.geoloc.entity.City;
34  import com.gisgraphy.domain.geoloc.entity.GisFeature;
35  import com.gisgraphy.domain.geoloc.entity.ZipCode;
36  import com.gisgraphy.domain.geoloc.service.fulltextsearch.AbstractIntegrationHttpSolrTestCase;
37  import com.gisgraphy.domain.valueobject.GisFeatureDistance;
38  import com.gisgraphy.helper.URLUtils;
39  import com.gisgraphy.test.GeolocTestHelper;
40  
41  /**
42   * test cityDao and GenericDao
43   */
44  public class CityDaoTest extends AbstractIntegrationHttpSolrTestCase {
45  
46      private ICityDao cityDao;
47  
48      private IGisFeatureDao gisFeatureDao;
49  
50      @Resource
51      private GeolocTestHelper geolocTestHelper;
52  
53      
54      // it is the genericDaotest apply to a city
55  
56     @Test
57      public void testGetAllShouldRetrieveAllTheCityInTheDataStore() {
58  	int nbToInsert = 2;
59  	for (int i = 0; i < nbToInsert; i++) {
60  	    City paris = GeolocTestHelper.createCityWithAlternateNames("paris"
61  		    + i, 3);
62  	    City savedParis = this.cityDao.save(paris);
63  	    City retrievedParis = this.cityDao.get(savedParis.getId());
64  	    assertNotNull(retrievedParis);
65  	    assertEquals(paris.getId(), retrievedParis.getId());
66  	}
67  	List<City> cities = this.cityDao.getAll();
68  	assertNotNull(cities);
69  	assertEquals(nbToInsert, cities.size());
70      }
71  
72      @Test
73      public void testCitiesShouldbeSavedInABatch() {
74  	int nbToInsert = 10;
75  	for (int i = 0; i < nbToInsert; i++) {
76  	    City paris = GeolocTestHelper.createCityWithAlternateNames("paris"
77  		    + i, 0);
78  	    City savedParis = this.cityDao.save(paris);
79  	    City retrievedParis = this.cityDao.get(savedParis.getId());
80  	    assertNotNull(retrievedParis);
81  	    assertEquals(paris.getId(), retrievedParis.getId());
82  	}
83  	List<City> cities = this.cityDao.getAll();
84  	assertNotNull(cities);
85  	assertEquals(nbToInsert, cities.size());
86      }
87  
88      @Test
89      public void testGetAllpaginateShouldPaginate() {
90  	int nbToInsert = 10;
91  	int from = 3;
92  	int max = 5;
93  	// save 0,1,2,3,4,5,6,7,8,9
94  	for (int i = 0; i < nbToInsert; i++) {
95  	    City paris = GeolocTestHelper.createCityWithAlternateNames("paris"
96  		    + i, 0);
97  	    City savedParis = this.cityDao.save(paris);
98  	    City retrievedParis = this.cityDao.get(savedParis.getId());
99  	    assertNotNull(retrievedParis);
100 	    assertEquals(paris.getId(), retrievedParis.getId());
101 	}
102 	List<City> cities = this.cityDao.getAllPaginate(from, max);
103 	// should be 2,3,4,5,6
104 	assertNotNull(cities);
105 	assertEquals(max, cities.size());
106 	// check values
107 	for (int i = 0; i < cities.size(); i++) {
108 	    assertEquals("paris" + (i + from - 1), cities.get(i).getName());
109 	}
110     }
111 
112     @Test
113     public void testGetAllpaginateShouldNotConsiderFromIfItIsLessThan1() {
114 	int nbToInsert = 10;
115 	int from = 0;
116 	int max = 5;
117 	// save 0,1,2,3,4,5,6,7,8,9
118 	for (int i = 0; i < nbToInsert; i++) {
119 	    City paris = GeolocTestHelper.createCityWithAlternateNames("paris"
120 		    + i, 0);
121 	    City savedParis = this.cityDao.save(paris);
122 	    City retrievedParis = this.cityDao.get(savedParis.getId());
123 	    assertNotNull(retrievedParis);
124 	    assertEquals(paris.getId(), retrievedParis.getId());
125 	}
126 	List<City> cities = this.cityDao.getAllPaginate(from, max);
127 	// should be 0,1,2,3,4
128 	assertNotNull(cities);
129 	assertEquals(max, cities.size());
130 	// check values
131 	for (int i = 0; i < cities.size(); i++) {
132 	    assertEquals("paris" + (i), cities.get(i).getName());
133 	}
134     }
135 
136     @Test
137     public void testGetAllpaginateShouldNotConsiderMaxIfItIsLessOrEqualsTo0() {
138 	int nbToInsert = 10;
139 	int from = 3;
140 	int max = 0;
141 	// save 0,1,2,3,4,5,6,7,8,9
142 	for (int i = 0; i < nbToInsert; i++) {
143 	    City paris = GeolocTestHelper.createCityWithAlternateNames("paris"
144 		    + i, 0);
145 	    City savedParis = this.cityDao.save(paris);
146 	    City retrievedParis = this.cityDao.get(savedParis.getId());
147 	    assertNotNull(retrievedParis);
148 	    assertEquals(paris.getId(), retrievedParis.getId());
149 	}
150 	List<City> cities = this.cityDao.getAllPaginate(from, max);
151 	// should be 2,3,4,5,6,7,8,9
152 	assertNotNull(cities);
153 	assertEquals(8, cities.size());
154 	// check values
155 	for (int i = 0; i < cities.size(); i++) {
156 	    assertEquals("paris" + (i + from - 1), cities.get(i).getName());
157 	}
158     }
159 
160     @Test
161     public void testSaveShouldSaveTheInheritedGisFeature() {
162 	City paris = GeolocTestHelper.createCityWithAlternateNames("paris", 0);
163 	City savedParis = this.cityDao.save(paris);
164 	City retrievedParis = this.cityDao.get(savedParis.getId());
165 	assertNotNull(retrievedParis);
166 	assertEquals(paris.getId(), retrievedParis.getId());
167 	GisFeature retrievedgisFeature = this.gisFeatureDao.get(retrievedParis
168 		.getId());
169 	assertNotNull(retrievedgisFeature);
170     }
171 
172     @Test
173     public void testsaveCityInABatchShouldCascadeAlternateNames() {
174 	int nbToInsert = 20;
175 	for (int i = 0; i < nbToInsert; i++) {
176 	    City paris = GeolocTestHelper.createCityWithAlternateNames("paris"
177 		    + i, 3);
178 	    City savedParis = this.cityDao.save(paris);
179 	    City retrievedParis = this.cityDao.get(savedParis.getId());
180 	    assertNotNull(retrievedParis);
181 	    assertEquals(paris.getId(), retrievedParis.getId());
182 	}
183 	List<City> cities = this.cityDao.getAll();
184 	assertNotNull(cities);
185 	assertEquals(nbToInsert, cities.size());
186     }
187 
188     @Test
189     public void testSaveCityShouldCascadeAlternateNames() {
190 	City paris = GeolocTestHelper.createCityWithAlternateNames("paris", 3);
191 	assertNotNull(paris.getAlternateNames());
192 	assertEquals(3, paris.getAlternateNames().size());
193 	City savedParis = this.cityDao.save(paris);
194 	City retrievedParis = this.cityDao.get(savedParis.getId());
195 	assertNotNull(retrievedParis);
196 	assertEquals(paris.getId(), retrievedParis.getId());
197 	assertNotNull(retrievedParis.getAlternateNames());
198 	assertEquals(3, retrievedParis.getAlternateNames().size());
199     }
200 
201     @Test
202     public void testGetShouldRetrieveNullIfTheSpecifiedIdDoesntExists() {
203 	City city = this.cityDao.get(100000L);
204 	assertEquals(null, city);
205     }
206 
207     @Test
208     public void testGetShouldRetrieveCorrectData() {
209 	City paris = GeolocTestHelper.createCityWithAlternateNames("paris", 0);
210 	City savedParis = this.cityDao.save(paris);
211 	City retrievedParis = this.cityDao.get(savedParis.getId());
212 	assertNotNull(retrievedParis);
213 	assertEquals(paris.getId(), retrievedParis.getId());
214 	GisFeature retrievedgisFeature = this.gisFeatureDao.get(retrievedParis
215 		.getId());
216 	assertNotNull(retrievedgisFeature);
217     }
218 
219     @Test
220     public void testGetAllShouldRetrieveanEmptyListIfNoCitiesInTheDatastore() {
221 	List<City> cities = this.cityDao.getAll();
222 	assertEquals(0, cities.size());
223     }
224 
225     @Test
226     public void testExistsShouldReturnFalseWhenNoCityWithTheSpecifiedIdExists() {
227 	assertFalse(this.cityDao.exists(-1L));
228     }
229 
230     @Test
231     public void testListByNameShouldRetrieveTheCorrectCity() {
232 	City paris = GeolocTestHelper.createCityWithAlternateNames("paris", 3);
233 	City savedParis = this.cityDao.save(paris);
234 	List<City> results = this.cityDao.listByName("paris");
235 	assertNotNull(results);
236 	assertEquals(1, results.size());
237 	assertEquals(savedParis, results.get(0));
238     }
239 
240     @Test
241     public void testListByNameShouldNotRetrieveNullIfNoCityExistsWithTheSpecifiedName() {
242 	List<City> results = this.cityDao.listByName("paris");
243 	assertNotNull(results);
244     }
245 
246     @Test
247     public void testRemoveShouldRemoveTheCity() {
248 	// create and save city
249 	City paris = GeolocTestHelper.createCityWithAlternateNames("paris", 3);
250 	City savedParis = this.cityDao.save(paris);
251 
252 	// check it is saved
253 	Long id = savedParis.getId();
254 	City retrievedParis = this.cityDao.get(savedParis.getId());
255 	assertNotNull(retrievedParis);
256 	assertEquals(paris.getId(), retrievedParis.getId());
257 	// remove city
258 	this.cityDao.remove(savedParis);
259 	// check city is removed
260 	City retrievedParisafterRemove = this.cityDao.get(id);
261 	assertNull(retrievedParisafterRemove);
262     }
263 
264     @Test
265     public void testRemoveCityShouldRemoveTheCityAndTheInheritedGisFeatureInCascade() {
266 	City paris = GeolocTestHelper.createCityWithAlternateNames("paris", 3);
267 	// save city
268 	City savedParis = this.cityDao.save(paris);
269 	// chek city is well saved
270 	Long id = savedParis.getId();
271 	City retrievedParis = this.cityDao.get(savedParis.getId());
272 	assertNotNull(retrievedParis);
273 	assertEquals(paris.getId(), retrievedParis.getId());
274 	// check gisFeature is well saved
275 	Long savedGisFeatureId = retrievedParis.getId();
276 	GisFeature savedGisFeature = this.gisFeatureDao.get(savedGisFeatureId);
277 	assertNotNull(savedGisFeature);
278 
279 	// remove city
280 	this.cityDao.remove(savedParis);
281 
282 	// check city is removed
283 	City retrievedParisafterRemove = this.cityDao.get(id);
284 	assertEquals(null, retrievedParisafterRemove);
285 
286 	// check gisFeature is remove
287 	GisFeature savedGisFeatureafterRemove = this.gisFeatureDao
288 		.get(savedGisFeatureId);
289 	assertNull(savedGisFeatureafterRemove);
290     }
291 
292     // distance
293 
294     @Test
295     public void testgetNearestAndDistanceFromShouldReturnCorrectDistance() {
296 	City p1 = GeolocTestHelper.createCity("paris", 48.86667F, 2.3333F, 1L);
297 	City p2 = GeolocTestHelper.createCity("bordeaux", 44.83333F, -0.56667F,
298 		3L);
299 	City p3 = GeolocTestHelper.createCity("goussainville", 49.01667F,
300 		2.46667F, 2L);
301 
302 	this.cityDao.save(p1);
303 	this.cityDao.save(p2);
304 	this.cityDao.save(p3);
305 	List<GisFeatureDistance> results = this.cityDao
306 		.getNearestAndDistanceFrom(p1.getLocation(), 1000000);
307 	assertEquals(3, results.size());
308 	checkDistancePercentError(p1, results);
309 
310     }
311 
312     @Test
313     public void testGetNearestAndDistanceFromShouldReturnAfullFilledDTO() {
314 	City p1 = geolocTestHelper
315 		.createAndSaveCityWithFullAdmTreeAndCountry(1L);
316 	p1.setAdm4Code("D4");
317 	p1.setAdm4Name("adm");
318 
319 
320 	this.cityDao.save(p1);
321 	List<GisFeatureDistance> results = this.cityDao
322 		.getNearestAndDistanceFrom(p1.getLocation(), 1000000);
323 	assertEquals(1, results.size());
324 	GisFeatureDistance gisFeatureDistance = results.get(0);
325 	assertEquals(p1.getFeatureId(), gisFeatureDistance.getFeatureId());
326 	assertEquals(p1.getName(), gisFeatureDistance.getName());
327 	assertEquals(p1.getAsciiName(), gisFeatureDistance.getAsciiName());
328 	assertEquals(p1.getLocation().toText(), gisFeatureDistance
329 		.getLocation().toText());
330 	assertEquals(p1.getLatitude(), gisFeatureDistance.getLat());
331 	assertEquals(p1.getLongitude(), gisFeatureDistance.getLng());
332 	assertEquals(p1.getAdm1Code(), gisFeatureDistance.getAdm1Code());
333 	assertEquals(p1.getAdm2Code(), gisFeatureDistance.getAdm2Code());
334 	assertEquals(p1.getAdm3Code(), gisFeatureDistance.getAdm3Code());
335 	assertEquals(p1.getAdm4Code(), gisFeatureDistance.getAdm4Code());
336 	assertEquals(p1.getAdm1Name(), gisFeatureDistance.getAdm1Name());
337 	assertEquals(p1.getAdm2Name(), gisFeatureDistance.getAdm2Name());
338 	assertEquals(p1.getAdm3Name(), gisFeatureDistance.getAdm3Name());
339 	assertEquals(p1.getAdm4Name(), gisFeatureDistance.getAdm4Name());
340 	assertEquals(p1.getFeatureClass(), gisFeatureDistance.getFeatureClass());
341 	assertEquals(p1.getFeatureCode(), gisFeatureDistance.getFeatureCode());
342 	assertEquals(p1.getCountryCode(), gisFeatureDistance.getCountryCode());
343 	assertEquals(p1.getPopulation(), gisFeatureDistance.getPopulation());
344 	assertEquals(p1.getElevation(), gisFeatureDistance.getElevation());
345 	assertEquals(p1.getGtopo30(), gisFeatureDistance.getGtopo30());
346 	assertEquals(p1.getTimezone(), gisFeatureDistance.getTimezone());
347 	assertEquals("gisfeatureDistance should have the same number of zipCodes as the original features",p1.getZipCodes().size(),
348 			gisFeatureDistance.getZipCodes().size());
349 	assertTrue(gisFeatureDistance.getZipCodes().contains(p1.getZipCodes().get(0).getCode()));
350 	assertTrue(gisFeatureDistance.getZipCodes().contains(p1.getZipCodes().get(1).getCode()));
351 	assertEquals("City", gisFeatureDistance.getPlaceType());
352 	// check transcient field
353 	assertEquals(URLUtils.createCountryFlagUrl(p1.getCountryCode()),
354 		gisFeatureDistance.getCountry_flag_url());
355 	assertEquals(URLUtils
356 		.createGoogleMapUrl(p1.getLocation(), p1.getName()),
357 		gisFeatureDistance.getGoogle_map_url());
358 	assertEquals(URLUtils.createYahooMapUrl(p1.getLocation()),
359 		gisFeatureDistance.getYahoo_map_url());
360 	assertNotNull(gisFeatureDistance.getDistance());
361 
362 	checkDistancePercentError(p1, results);
363 
364     }
365     
366     @Test
367     public void testGetNearestAndDistanceFromShouldPaginateWhenThereIsMoreThanOneZipCodes() {
368 	City p1 = GeolocTestHelper.createCity("paris", 48.86667F, 2.3333F, 1L);
369 	City p2 = GeolocTestHelper.createCity("vanves", 48.82F, 2.289F, 2L);
370 	City p3 = GeolocTestHelper.createCity("goussainville", 49.01667F,
371 		2.46667F, 3L);
372 	p2.addZipCode(new ZipCode("75000"));
373 	p2.addZipCode(new ZipCode("75001"));
374 	p2.addZipCode(new ZipCode("75002"));
375 	this.cityDao.save(p1);
376 	this.cityDao.save(p2);
377 	this.cityDao.save(p3);
378 	List<GisFeatureDistance> results = this.cityDao
379 		.getNearestAndDistanceFrom(p1.getLocation(), 1000000, 1, 2);
380 	assertEquals(2, results.size());
381 	// check values and sorted
382 	assertEquals(p1.getName(), results.get(0).getName());
383 	assertEquals(p2.getName(), results.get(1).getName());
384     }
385 
386     @Test
387     public void testgetNearestAndDistanceFromShouldPaginate() {
388 	City p1 = GeolocTestHelper.createCity("paris", 48.86667F, 2.3333F, 1L);
389 	City p2 = GeolocTestHelper.createCity("bordeaux", 44.83333F, -0.56667F,
390 		3L);
391 	City p3 = GeolocTestHelper.createCity("goussainville", 49.01667F,
392 		2.46667F, 2L);
393 
394 	this.cityDao.save(p1);
395 	this.cityDao.save(p2);
396 	this.cityDao.save(p3);
397 	List<GisFeatureDistance> results = this.cityDao
398 		.getNearestAndDistanceFrom(p1.getLocation(), 1000000, 2, 5);
399 	assertEquals(2, results.size());
400 	// check values and sorted
401 	assertEquals(p3.getName(), results.get(0).getName());
402 	assertEquals(p2.getName(), results.get(1).getName());
403 
404     }
405 
406     @Test
407     public void testGetNearestAndDistanceFromGisFeatureShouldReturnCorrectDistance() {
408 	City p1 = GeolocTestHelper.createCity("paris", 48.86667F, 2.3333F, 1L);
409 	City p2 = GeolocTestHelper.createCity("bordeaux", 44.83333F, -0.56667F,
410 		3L);
411 	City p3 = GeolocTestHelper.createCity("goussainville", 49.01667F,
412 		2.46667F, 2L);
413 
414 	this.cityDao.save(p1);
415 	this.cityDao.save(p2);
416 	this.cityDao.save(p3);
417 	// for city dao
418 	List<GisFeatureDistance> results = this.cityDao
419 		.getNearestAndDistanceFromGisFeature(p1, 1000000, -1, -1);
420 	assertEquals(2, results.size());
421 	checkDistancePercentError(p1, results);
422 
423 	results = this.cityDao.getNearestAndDistanceFromGisFeature(p1, 100);
424 	assertNotNull("getNearestAndDistanceFrom should never return null",
425 		results);
426 	assertTrue(results.isEmpty());
427 
428 	results = this.cityDao.getNearestAndDistanceFromGisFeature(p1, 22000);
429 	assertTrue(results.isEmpty());
430 
431 	results = this.cityDao.getNearestAndDistanceFromGisFeature(p1, 23000);
432 	assertEquals(1, results.size());
433 	checkDistancePercentError(p1, results);
434 	// will try with the gisFeature implementation
435 	this.cityDao.remove(p1);
436 	this.cityDao.remove(p2);
437 	this.cityDao.remove(p3);
438 	assertEquals(0, this.cityDao.getAll().size());
439 
440 	GisFeature p4 = GeolocTestHelper.createGisFeature("_paris", 48.86667F,
441 		2.3333F, 1L);
442 	GisFeature p5 = GeolocTestHelper.createGisFeature("_bordeaux",
443 		44.83333F, -0.56667F, 3L);
444 	GisFeature p6 = GeolocTestHelper.createGisFeature("_goussainville",
445 		49.01667F, 2.46667F, 2L);
446 
447 	this.gisFeatureDao.save(p4);
448 	this.gisFeatureDao.save(p5);
449 	this.gisFeatureDao.save(p6);
450 	assertEquals(3, this.gisFeatureDao.getAll().size());
451 
452 	// for gisfeatureDao because there is two implementation
453 
454 	results = this.gisFeatureDao.getNearestAndDistanceFromGisFeature(p4,
455 		1000000);
456 	assertEquals(2, results.size());
457 	checkDistancePercentError(p4, results);
458 
459 	results = this.gisFeatureDao.getNearestAndDistanceFromGisFeature(p4,
460 		100);
461 	assertNotNull("getNearestAndDistanceFrom should never return null",
462 		results);
463 	assertTrue(results.isEmpty());
464 
465 	results = this.gisFeatureDao.getNearestAndDistanceFromGisFeature(p4,
466 		22000);
467 	assertTrue(results.isEmpty());
468 
469 	results = this.gisFeatureDao.getNearestAndDistanceFromGisFeature(p4,
470 		23000);
471 	assertEquals(1, results.size());
472 	checkDistancePercentError(p4, results);
473 
474     }
475 
476     @Test
477     public void testgetNearestAndDistanceFromGisFeatureShouldPaginate() {
478 	City p1 = GeolocTestHelper.createCity("paris", 48.86667F, 2.3333F, 1L);// N
479 	// 48°
480 	// 52'
481 	// 0''
482 	// 2°
483 	// 20'
484 	// 0''
485 	// E
486 	City p2 = GeolocTestHelper.createCity("bordeaux", 44.83333F, -0.56667F,
487 		3L);// 44
488 	// 50 0
489 	// N; 0
490 	// 34 0
491 	// W
492 	City p3 = GeolocTestHelper.createCity("goussainville", 49.01667F,
493 		2.46667F, 2L);// N
494 	// 49°
495 	// 1'
496 	// 0''
497 	// E 2°
498 	// 28'
499 	// 0''
500 
501 	this.gisFeatureDao.save(p1);
502 	this.gisFeatureDao.save(p2);
503 	this.gisFeatureDao.save(p3);
504 	// for city dao
505 	List<GisFeatureDistance> results = this.cityDao
506 		.getNearestAndDistanceFromGisFeature(p1, 1000000, 1, 5);
507 	assertEquals(2, results.size());
508 	assertEquals(p3.getName(), results.get(0).getName());
509 	assertEquals(p2.getName(), results.get(1).getName());
510 
511 	results = this.cityDao.getNearestAndDistanceFromGisFeature(p1, 1000000,
512 		2, 5);
513 	assertEquals(1, results.size());
514 	assertEquals(p2.getName(), results.get(0).getName());
515 
516 	results = this.cityDao.getNearestAndDistanceFromGisFeature(p1, 1000000,
517 		1, 1);
518 	assertEquals(1, results.size());
519 	assertEquals(p3.getName(), results.get(0).getName());
520 
521 	results = this.cityDao.getNearestAndDistanceFromGisFeature(p1, 1000000,
522 		0, 1);
523 	assertEquals(1, results.size());
524 	assertEquals(p3.getName(), results.get(0).getName());
525 
526 	results = this.cityDao.getNearestAndDistanceFromGisFeature(p1, 1000000,
527 		1, 0);
528 	assertEquals(2, results.size());
529 	assertEquals(p3.getName(), results.get(0).getName());
530 	assertEquals(p2.getName(), results.get(1).getName());
531 	// remove city and replace with gisFeature
532 	this.cityDao.remove(p1);
533 	this.cityDao.remove(p2);
534 	this.cityDao.remove(p3);
535 	assertEquals(0, this.cityDao.getAll().size());
536 
537 	GisFeature p4 = GeolocTestHelper.createCity("paris", 48.86667F,
538 		2.3333F, 1L);// N
539 	// 48°
540 	// 52'
541 	// 0''
542 	// 2°
543 	// 20'
544 	// 0''
545 	// E
546 	GisFeature p5 = GeolocTestHelper.createCity("bordeaux", 44.83333F,
547 		-0.56667F, 3L);// N 44
548 	// 50 0
549 	// ; 0
550 	// 34 0
551 	// W
552 	GisFeature p6 = GeolocTestHelper.createCity("goussainville", 49.01667F,
553 		2.46667F, 2L);// N
554 	// 49°
555 	// 1'
556 	// 0''
557 	// E 2°
558 	// 28'
559 	// 0''
560 
561 	this.gisFeatureDao.save(p4);
562 	this.gisFeatureDao.save(p5);
563 	this.gisFeatureDao.save(p6);
564 	assertEquals(3, this.gisFeatureDao.getAll().size());
565 
566 	results = this.gisFeatureDao.getNearestAndDistanceFromGisFeature(p4,
567 		1000000, 2, 5);
568 	assertEquals(1, results.size());
569 	assertEquals(p5.getName(), results.get(0).getName());
570 
571 	results = this.gisFeatureDao.getNearestAndDistanceFromGisFeature(p4,
572 		1000000, 1, 1);
573 	assertEquals(1, results.size());
574 	assertEquals(p6.getName(), results.get(0).getName());
575 
576 	results = this.gisFeatureDao.getNearestAndDistanceFromGisFeature(p4,
577 		1000000, 0, 1);
578 	assertEquals(1, results.size());
579 	assertEquals(p6.getName(), results.get(0).getName());
580 
581 	results = this.gisFeatureDao.getNearestAndDistanceFromGisFeature(p4,
582 		1000000, 1, 0);
583 	assertEquals(2, results.size());
584 	assertEquals(p6.getName(), results.get(0).getName());
585 	assertEquals(p5.getName(), results.get(1).getName());
586 
587     }
588 
589     private void checkDistancePercentError(GisFeature p1,
590 	    List<GisFeatureDistance> results) {
591 	Double lastOne = null;
592 	for (GisFeatureDistance gisFeatureDistance : results) {
593 	    double calculatedDist = p1.distanceTo(gisFeatureDistance
594 		    .getLocation());
595 	    double retrieveDistance = gisFeatureDistance.getDistance();
596 	    if (lastOne != null) {
597 		assertNotNull(retrieveDistance);
598 		assertNotNull(lastOne);
599 		if (!(lastOne.doubleValue() <= retrieveDistance)) {
600 		    fail("The results are not sorted");
601 		}
602 	    }
603 	    double percent = (Math.abs(calculatedDist - retrieveDistance) * 100)
604 		    / Math.min(retrieveDistance, calculatedDist);
605 	    log.info("Distance difference beetween " + p1.getName() + " and "
606 		    + gisFeatureDistance.getName() + " is " + percent + "%");
607 	    if (calculatedDist > 0.001) {
608 		assertTrue(
609 			"The results are not at the expected distance : should be "
610 				+ calculatedDist + " but was "
611 				+ retrieveDistance + " (purcent error="
612 				+ percent + ")",
613 			(percent < GeolocTestHelper.DISTANCE_PURCENT_ERROR_ACCEPTED)
614 				|| (calculatedDist == retrieveDistance));// tolerence
615 	    }
616 	    lastOne = retrieveDistance;
617 	}
618 
619     }
620 
621     @Test
622     public void testIsCityShouldReturnTrueIfItIsACity() {
623 	City city = GeolocTestHelper.createCityWithAlternateNames("paris", 0);
624 	assertTrue(city.isCity());
625     }
626 
627     @Test
628     public void testIsCityShouldReturnFalseIfItIsNotACity() {
629 	GisFeature gisFeature = GeolocTestHelper.createGisFeatureForAdm("",
630 		20F, 30F, null, 2);
631 	assertFalse(gisFeature.isCity());
632     }
633 
634     public void testGetByFeatureIdsShouldOnlyReturnCities() {
635 	City city1 = GeolocTestHelper.createCity("cityGisFeature", null, null,
636 		100L);
637 	City city2 = GeolocTestHelper.createCity("cityGisFeature", null, null,
638 		200L);
639 	GisFeature gisFeature = GeolocTestHelper
640 		.createGisFeatureWithAlternateNames("gisfeature", 0);
641 	gisFeature.setFeatureId(300L);
642 	GisFeature gisFeature2 = GeolocTestHelper
643 		.createGisFeatureWithAlternateNames("gisfeature", 0);
644 	gisFeature2.setFeatureId(400L);
645 
646 	this.gisFeatureDao.save(city1);
647 	this.gisFeatureDao.save(city2);
648 	this.gisFeatureDao.save(gisFeature);
649 	this.gisFeatureDao.save(gisFeature2);
650 
651 	// check it is well saved
652 	List<GisFeature> gisFeatures = this.gisFeatureDao.getAll();
653 	assertNotNull(gisFeatures);
654 	assertEquals(4, gisFeatures.size());
655 
656 	List<Long> ids = new ArrayList<Long>();
657 	ids.add(100L);
658 	ids.add(200L);
659 	ids.add(300L);
660 	List<City> gisByIds = this.cityDao.listByFeatureIds(ids);
661 	assertNotNull(gisByIds);
662 	assertEquals(2, gisByIds.size());
663 
664     }
665 
666     @Test
667     public void testListByZipCodeShouldReturnCorrectValues() {
668 	City city1 = GeolocTestHelper.createCity("paris", 48.86667F, 2.3333F,
669 		1L);
670 	city1.addZipCode(new ZipCode("75003"));
671 	city1.setCountryCode("FR");
672 	City city2 = GeolocTestHelper.createCity("paris2", 48.86667F, 2.3333F,
673 		2L);
674 	city2.addZipCode(new ZipCode("75003"));
675 	city2.setCountryCode("EN");
676 	this.cityDao.save(city1);
677 	this.cityDao.save(city2);
678 	List<City> results = this.cityDao.listByZipCode("75003", null);
679 	assertEquals(2, results.size());
680 	results = this.cityDao.listByZipCode("75004", null);
681 	assertNotNull(results);
682 	assertEquals(0, results.size());
683 	results = this.cityDao.listByZipCode("75003", "fr");
684 	assertEquals(
685 		"ListByZipCode should be case insensitive for countrycode", 1,
686 		results.size());
687 
688     }
689     @Test
690     public void testCreateGISTIndexForLocationColumnShouldNotThrow(){
691 	cityDao.createGISTIndexForLocationColumn();
692     }
693 
694     @Required
695     public void setCityDao(ICityDao cityDao) {
696 	this.cityDao = cityDao;
697     }
698 
699     @Required
700     public void setGisFeatureDao(IGisFeatureDao gisFeatureDao) {
701 	this.gisFeatureDao = gisFeatureDao;
702     }
703 
704 }