PageRenderTime 66ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/tests/GeocodableBehaviorTest.php

https://github.com/jpetitcolas/GeocodableBehavior
PHP | 426 lines | 347 code | 65 blank | 14 comment | 1 complexity | 01a209d73e31db1fea7c4a4b7b6b1468 MD5 | raw file
  1. <?php
  2. /*
  3. * This file is part of the Propel package.
  4. * For the full copyright and license information, please view the LICENSE
  5. * file that was distributed with this source code.
  6. *
  7. * @license MIT License
  8. */
  9. /**
  10. * Tests for GeocodableBehavior class
  11. *
  12. * @author William Durand <william.durand1@gmail.com>
  13. */
  14. class GeocodableBehaviorTest extends \PHPUnit_Framework_TestCase
  15. {
  16. public function setUp()
  17. {
  18. if (!class_exists('GeocodedObject')) {
  19. $schema = <<<EOF
  20. <database name="bookstore" defaultIdMethod="native">
  21. <table name="simple_geocoded_object">
  22. <column name="id" required="true" primaryKey="true" autoIncrement="true" type="INTEGER" />
  23. <behavior name="geocodable" />
  24. </table>
  25. <table name="geocoded_object">
  26. <column name="id" required="true" primaryKey="true" autoIncrement="true" type="INTEGER" />
  27. <column name="name" type="VARCHAR" size="100" primaryString="true" />
  28. <column name="street" type="VARCHAR" size="100" primaryString="true" />
  29. <column name="city" type="VARCHAR" size="100" primaryString="true" />
  30. <column name="country" type="VARCHAR" size="100" primaryString="true" />
  31. <behavior name="geocodable">
  32. <!-- IP -->
  33. <parameter name="geocode_ip" value="true" />
  34. <!-- Address -->
  35. <parameter name="geocode_address" value="true" />
  36. <parameter name="address_columns" value="street, city, country" />
  37. <!-- Geocoder -->
  38. <parameter name="geocoder_api_key" value="YOUR_API_KEY" />
  39. </behavior>
  40. </table>
  41. <table name="geocoded_object_no_autoupdate">
  42. <column name="id" required="true" primaryKey="true" autoIncrement="true" type="INTEGER" />
  43. <column name="name" type="VARCHAR" size="100" primaryString="true" />
  44. <column name="street" type="VARCHAR" size="100" primaryString="true" />
  45. <column name="city" type="VARCHAR" size="100" primaryString="true" />
  46. <column name="country" type="VARCHAR" size="100" primaryString="true" />
  47. <behavior name="geocodable">
  48. <parameter name="auto_update" value="false" />
  49. <!-- IP -->
  50. <parameter name="geocode_ip" value="true" />
  51. <!-- Address -->
  52. <parameter name="geocode_address" value="true" />
  53. <parameter name="address_columns" value="street, city, country" />
  54. <!-- Geocoder -->
  55. <parameter name="geocoder_api_key" value="YOUR_API_KEY" />
  56. </behavior>
  57. </table>
  58. <table name="geocoded_object_key_provider">
  59. <column name="id" required="true" primaryKey="true" autoIncrement="true" type="INTEGER" />
  60. <column name="name" type="VARCHAR" size="100" primaryString="true" />
  61. <column name="street" type="VARCHAR" size="100" primaryString="true" />
  62. <column name="city" type="VARCHAR" size="100" primaryString="true" />
  63. <column name="country" type="VARCHAR" size="100" primaryString="true" />
  64. <behavior name="geocodable">
  65. <!-- IP -->
  66. <parameter name="geocode_ip" value="true" />
  67. <!-- Address -->
  68. <parameter name="geocode_address" value="true" />
  69. <parameter name="address_columns" value="street, city, country" />
  70. <!-- Geocoder -->
  71. <parameter name="geocoder_api_key_provider" value="GeoApikeyProvider" />
  72. </behavior>
  73. </table>
  74. <table name="geocoded_object_key_provider_static">
  75. <column name="id" required="true" primaryKey="true" autoIncrement="true" type="INTEGER" />
  76. <column name="name" type="VARCHAR" size="100" primaryString="true" />
  77. <column name="street" type="VARCHAR" size="100" primaryString="true" />
  78. <column name="city" type="VARCHAR" size="100" primaryString="true" />
  79. <column name="country" type="VARCHAR" size="100" primaryString="true" />
  80. <behavior name="geocodable">
  81. <!-- IP -->
  82. <parameter name="geocode_ip" value="true" />
  83. <!-- Address -->
  84. <parameter name="geocode_address" value="true" />
  85. <parameter name="address_columns" value="street, city, country" />
  86. <!-- Geocoder -->
  87. <parameter name="geocoder_api_key_provider" value="GeoApikeyProvider::getKey()" />
  88. </behavior>
  89. </table>
  90. <table name="geocoded_object_key_provider_method">
  91. <column name="id" required="true" primaryKey="true" autoIncrement="true" type="INTEGER" />
  92. <column name="name" type="VARCHAR" size="100" primaryString="true" />
  93. <column name="street" type="VARCHAR" size="100" primaryString="true" />
  94. <column name="city" type="VARCHAR" size="100" primaryString="true" />
  95. <column name="country" type="VARCHAR" size="100" primaryString="true" />
  96. <behavior name="geocodable">
  97. <!-- IP -->
  98. <parameter name="geocode_ip" value="true" />
  99. <!-- Address -->
  100. <parameter name="geocode_address" value="true" />
  101. <parameter name="address_columns" value="street, city, country" />
  102. <!-- Geocoder -->
  103. <parameter name="geocoder_api_key_provider" value="GeoApikeyProvider->getApiKeyMethod()" />
  104. </behavior>
  105. </table>
  106. </database>
  107. EOF;
  108. $builder = new PropelQuickBuilder();
  109. $config = $builder->getConfig();
  110. $config->setBuildProperty('behavior.geocodable.class', '../src/GeocodableBehavior');
  111. $builder->setConfig($config);
  112. $builder->setSchema($schema);
  113. $con = $builder->build();
  114. $con->sqliteCreateFunction('ACOS', 'acos', 1);
  115. $con->sqliteCreateFunction('COS', 'cos', 1);
  116. $con->sqliteCreateFunction('RADIANS', 'deg2rad', 1);
  117. $con->sqliteCreateFunction('SIN', 'sin', 1);
  118. }
  119. }
  120. public function testObjectMethods()
  121. {
  122. $this->assertTrue(method_exists('GeocodedObject', 'getLatitude'));
  123. $this->assertTrue(method_exists('GeocodedObject', 'getLongitude'));
  124. $this->assertTrue(method_exists('GeocodedObject', 'geocode'));
  125. $this->assertTrue(method_exists('GeocodedObject', 'isGeocoded'));
  126. $this->assertTrue(method_exists('GeocodedObject', 'isGeocodingNecessary'));
  127. $this->assertTrue(method_exists('GeocodedObject', 'getDistanceTo'));
  128. $this->assertTrue(method_exists('GeocodedObject', 'getCoordinates'));
  129. $this->assertTrue(method_exists('GeocodedObject', 'setCoordinates'));
  130. }
  131. public function testQueryMethods()
  132. {
  133. $this->assertTrue(method_exists('GeocodedObjectQuery', 'filterByDistanceFrom'));
  134. $this->assertTrue(method_exists('GeocodedObjectQuery', 'filterNear'));
  135. }
  136. public function testPeerConstants()
  137. {
  138. $this->assertTrue(defined('GeocodedObjectPeer::KILOMETERS_UNIT'));
  139. $this->assertTrue(defined('GeocodedObjectPeer::MILES_UNIT'));
  140. $this->assertTrue(defined('GeocodedObjectPeer::NAUTICAL_MILES_UNIT'));
  141. }
  142. public function testGetDistanceToInKilometers()
  143. {
  144. $geo1 = new GeocodedObject();
  145. $geo1->setLatitude(45.795463);
  146. $geo1->setLongitude(3.163237);
  147. $geo2 = new GeocodedObject();
  148. $geo2->setLatitude(45.77722154971201);
  149. $geo2->setLongitude(3.086986541748047);
  150. $dist = round($geo1->getDistanceTo($geo2), 2);
  151. $this->assertEquals(6.25, $dist);
  152. }
  153. public function testGetDistanceToInMiles()
  154. {
  155. $geo1 = new GeocodedObject();
  156. $geo1->setLatitude(45.795463);
  157. $geo1->setLongitude(3.163237);
  158. $geo2 = new GeocodedObject();
  159. $geo2->setLatitude(45.77722154971201);
  160. $geo2->setLongitude(3.086986541748047);
  161. $dist = round($geo1->getDistanceTo($geo2, GeocodedObjectPeer::MILES_UNIT), 2);
  162. $this->assertEquals(3.88, $dist);
  163. }
  164. public function testGetDistanceToInNauticalMiles()
  165. {
  166. $geo1 = new GeocodedObject();
  167. $geo1->setLatitude(45.795463);
  168. $geo1->setLongitude(3.163237);
  169. $geo2 = new GeocodedObject();
  170. $geo2->setLatitude(45.77722154971201);
  171. $geo2->setLongitude(3.086986541748047);
  172. $dist = round($geo1->getDistanceTo($geo2, GeocodedObjectPeer::NAUTICAL_MILES_UNIT), 2);
  173. $this->assertEquals(3.37, $dist);
  174. }
  175. public function testSetCoordinates()
  176. {
  177. $geo = new GeocodedObject();
  178. $geo->setCoordinates(1, 2);
  179. $this->assertEquals(1, $geo->getLatitude());
  180. $this->assertEquals(2, $geo->getLongitude());
  181. }
  182. public function testGetCoordinates()
  183. {
  184. $obj = new GeocodedObject();
  185. $obj->setCoordinates(1, 2);
  186. $this->assertEquals(array('latitude' => 1, 'longitude' => 2), $obj->getCoordinates());
  187. }
  188. public function testIsGeocoded()
  189. {
  190. $obj = new GeocodedObject();
  191. $this->assertFalse($obj->isGeocoded());
  192. $obj->setCoordinates(1, 2);
  193. $this->assertTrue($obj->isGeocoded());
  194. }
  195. public function testFilterByDistanceFromReturnsNoObjects()
  196. {
  197. GeocodedObjectPeer::doDeleteAll();
  198. $geo1 = new GeocodedObject();
  199. $geo1->setName('Aulnat Area');
  200. $geo1->setCity('Aulnat');
  201. $geo1->setCountry('France');
  202. $geo1->save();
  203. $geo2 = new GeocodedObject();
  204. $geo2->setName('Lyon Area');
  205. $geo2->setCity('Lyon');
  206. $geo2->setCountry('France');
  207. $geo2->save();
  208. $objects = GeocodedObjectQuery::create()
  209. ->filterByDistanceFrom($geo1->getLatitude(), $geo1->getLongitude(), 5)
  210. ->find()
  211. ;
  212. $this->assertEquals(1, count($objects));
  213. }
  214. public function testFilterByDistanceFromReturnsObjects()
  215. {
  216. GeocodedObjectPeer::doDeleteAll();
  217. $geo1 = new GeocodedObject();
  218. $geo1->setName('Aulnat Area');
  219. $geo1->setCity('Aulnat');
  220. $geo1->setCountry('France');
  221. $geo1->save();
  222. $geo2 = new GeocodedObject();
  223. $geo2->setName('Lyon Area');
  224. $geo2->setCity('Lyon');
  225. $geo2->setCountry('France');
  226. $geo2->save();
  227. $geo3 = new GeocodedObject();
  228. $geo3->setName('Lempdes Area');
  229. $geo3->setCity('Lempdes');
  230. $geo3->setCountry('France');
  231. $geo3->save();
  232. $objects = GeocodedObjectQuery::create()
  233. ->filterByDistanceFrom($geo1->getLatitude(), $geo1->getLongitude(), 20)
  234. ->find()
  235. ;
  236. $this->assertEquals(2, count($objects));
  237. }
  238. public function testGeocodeIp()
  239. {
  240. $geo = new GeocodedObject();
  241. $geo->setIpAddress('74.200.247.59');
  242. $geo->save();
  243. $this->assertEquals(33.036711, $geo->getLatitude());
  244. $this->assertEquals(-96.813541, $geo->getLongitude());
  245. }
  246. public function testGeocodeAddress()
  247. {
  248. $geo = new GeocodedObject();
  249. $geo->setStreet('10 avenue Gambetta');
  250. $geo->setCity('Paris');
  251. $geo->setCountry('France');
  252. $geo->save();
  253. $this->assertEquals(48.863217, $geo->getLatitude());
  254. $this->assertEquals(2.388821, $geo->getLongitude());
  255. }
  256. public function testGeocodeAddressWithUpdate()
  257. {
  258. $geo = new GeocodedObject();
  259. $geo->setStreet('10 avenue Gambetta');
  260. $geo->setCity('Paris');
  261. $geo->setCountry('France');
  262. $geo->save();
  263. $this->assertEquals(48.863217, $geo->getLatitude());
  264. $this->assertEquals(2.388821, $geo->getLongitude());
  265. $geo->setStreet('1 avenue LĂŠon Maniez');
  266. $geo->save();
  267. $this->assertEquals(48.85693, $geo->getLatitude());
  268. $this->assertEquals(2.3412, $geo->getLongitude());
  269. }
  270. public function testGeocodeAddressForceCoordinates()
  271. {
  272. $geo = new GeocodedObject();
  273. $geo->setStreet('10 avenue Gambetta');
  274. $geo->setCity('Paris');
  275. $geo->setCountry('France');
  276. $geo->save();
  277. $this->assertEquals(48.863217, $geo->getLatitude());
  278. $this->assertEquals(2.388821, $geo->getLongitude());
  279. // If we force the values, we should bypass the geocoding process
  280. $geo->setLatitude(48.85693);
  281. $geo->setLongitude(2.3412);
  282. $geo->save();
  283. $this->assertEquals(48.85693, $geo->getLatitude());
  284. $this->assertEquals(2.3412, $geo->getLongitude());
  285. }
  286. public function testNoFieldUpdate()
  287. {
  288. $geo = new GeocodedObject();
  289. $geo->setStreet('10 avenue Gambetta');
  290. $geo->setCity('Paris');
  291. $geo->setCountry('France');
  292. $geo->setLatitude(48.123456);
  293. $geo->setLongitude(2.3412);
  294. $geo->save();
  295. $this->assertEquals(48.123456, $geo->getLatitude());
  296. $this->assertEquals(2.3412, $geo->getLongitude());
  297. // If fields are unchanged, we should bypass the geocoding process
  298. $geo->setLongitude(2.123456);
  299. $geo->save();
  300. $this->assertEquals(48.123456, $geo->getLatitude());
  301. $this->assertEquals(2.123456, $geo->getLongitude());
  302. }
  303. public function testNoAutoUpdate()
  304. {
  305. $geo = new GeocodedObjectNoAutoUpdate();
  306. $geo->setStreet('10 avenue Gambetta');
  307. $geo->setCity('Paris');
  308. $geo->setCountry('France');
  309. $geo->save();
  310. $this->assertEquals(null, $geo->getLatitude());
  311. $this->assertEquals(null, $geo->getLongitude());
  312. }
  313. public function testKeyProvider()
  314. {
  315. $geo = new GeocodedObjectKeyProvider();
  316. $geo->setStreet('10 avenue Gambetta');
  317. $geo->setCity('Paris');
  318. $geo->setCountry('France');
  319. $geo->save();
  320. $this->assertEquals(48.863217, $geo->getLatitude());
  321. $this->assertEquals(2.388821, $geo->getLongitude());
  322. }
  323. public function testKeyProviderStatic()
  324. {
  325. $geo = new GeocodedObjectKeyProviderStatic();
  326. $geo->setStreet('10 avenue Gambetta');
  327. $geo->setCity('Paris');
  328. $geo->setCountry('France');
  329. $geo->save();
  330. $this->assertEquals(48.863217, $geo->getLatitude());
  331. $this->assertEquals(2.388821, $geo->getLongitude());
  332. }
  333. public function testKeyProviderMethod()
  334. {
  335. $geo = new GeocodedObjectKeyProviderMethod();
  336. $geo->setStreet('10 avenue Gambetta');
  337. $geo->setCity('Paris');
  338. $geo->setCountry('France');
  339. $geo->save();
  340. $this->assertEquals(48.863217, $geo->getLatitude());
  341. $this->assertEquals(2.388821, $geo->getLongitude());
  342. }
  343. public function testGeocode()
  344. {
  345. $geo = new GeocodedObject();
  346. $this->assertNull($geo->geocode(), 'The method returns null as there is nothing to geocode');
  347. $this->assertFalse($geo->isModified());
  348. $geo->setCity('Paris');
  349. $result = $geo->geocode();
  350. $this->assertTrue($geo->isModified());
  351. $this->assertInstanceOf('Geocoder\Result\ResultInterface', $result);
  352. $this->assertEquals('Paris', $result->getCity());
  353. $this->assertEquals('France', $result->getCountry());
  354. }
  355. public function testGeocodeIsEffectLessIfGeocodingDisabled()
  356. {
  357. $geo = new SimpleGeocodedObject();
  358. $geo->geocode();
  359. $this->assertFalse($geo->isModified());
  360. }
  361. }