Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
| 1 | <?php |
||
| 23 | class GoogleMapsTest extends BaseTestCase |
||
| 24 | { |
||
| 25 | /** |
||
| 26 | * @var string |
||
| 27 | */ |
||
| 28 | private $testAPIKey = 'fake_key'; |
||
| 29 | |||
| 30 | protected function getCacheDir() |
||
| 31 | { |
||
| 32 | if (isset($_SERVER['USE_CACHED_RESPONSES']) && true === $_SERVER['USE_CACHED_RESPONSES']) { |
||
| 33 | return __DIR__.'/.cached_responses'; |
||
| 34 | } |
||
| 35 | |||
| 36 | return null; |
||
| 37 | } |
||
| 38 | |||
| 39 | public function testGetName() |
||
| 40 | { |
||
| 41 | $provider = new GoogleMaps($this->getMockedHttpClient()); |
||
| 42 | $this->assertEquals('google_maps', $provider->getName()); |
||
| 43 | } |
||
| 44 | |||
| 45 | /** |
||
| 46 | * @expectedException \Geocoder\Exception\UnsupportedOperation |
||
| 47 | */ |
||
| 48 | public function testGeocodeWithLocalhostIPv4() |
||
| 49 | { |
||
| 50 | $provider = new GoogleMaps($this->getMockedHttpClient()); |
||
| 51 | $provider->geocodeQuery(GeocodeQuery::create('127.0.0.1')); |
||
| 52 | } |
||
| 53 | |||
| 54 | /** |
||
| 55 | * @expectedException \Geocoder\Exception\UnsupportedOperation |
||
| 56 | * @expectedExceptionMessage The GoogleMaps provider does not support IP addresses, only street addresses. |
||
| 57 | */ |
||
| 58 | public function testGeocodeWithLocalhostIPv6() |
||
| 59 | { |
||
| 60 | $provider = new GoogleMaps($this->getMockedHttpClient()); |
||
| 61 | $provider->geocodeQuery(GeocodeQuery::create('::1')); |
||
| 62 | } |
||
| 63 | |||
| 64 | /** |
||
| 65 | * @expectedException \Geocoder\Exception\UnsupportedOperation |
||
| 66 | * @expectedExceptionMessage The GoogleMaps provider does not support IP addresses, only street addresses. |
||
| 67 | */ |
||
| 68 | public function testGeocodeWithRealIp() |
||
| 69 | { |
||
| 70 | $provider = new GoogleMaps($this->getHttpClient()); |
||
| 71 | $provider->geocodeQuery(GeocodeQuery::create('74.200.247.59')); |
||
| 72 | } |
||
| 73 | |||
| 74 | /** |
||
| 75 | * @expectedException \Geocoder\Exception\QuotaExceeded |
||
| 76 | * @expectedExceptionMessage Daily quota exceeded https://maps.googleapis.com/maps/api/geocode/json?address=10%20avenue%20Gambetta%2C%20Paris%2C%20France |
||
| 77 | */ |
||
| 78 | public function testGeocodeWithQuotaExceeded() |
||
| 79 | { |
||
| 80 | $provider = new GoogleMaps($this->getMockedHttpClient('{"status":"OVER_QUERY_LIMIT"}')); |
||
| 81 | $provider->geocodeQuery(GeocodeQuery::create('10 avenue Gambetta, Paris, France')); |
||
| 82 | } |
||
| 83 | |||
| 84 | public function testGeocodeWithRealAddress() |
||
| 85 | { |
||
| 86 | $provider = new GoogleMaps($this->getHttpClient(), 'Île-de-France'); |
||
| 87 | $results = $provider->geocodeQuery(GeocodeQuery::create('10 avenue Gambetta, Paris, France')->withLocale('fr-FR')); |
||
| 88 | |||
| 89 | $this->assertInstanceOf('Geocoder\Model\AddressCollection', $results); |
||
| 90 | $this->assertCount(1, $results); |
||
| 91 | |||
| 92 | /** @var Location $result */ |
||
| 93 | $result = $results->first(); |
||
| 94 | $this->assertInstanceOf('\Geocoder\Model\Address', $result); |
||
| 95 | $this->assertEquals(48.8630462, $result->getCoordinates()->getLatitude(), '', 0.001); |
||
| 96 | $this->assertEquals(2.3882487, $result->getCoordinates()->getLongitude(), '', 0.001); |
||
| 97 | $this->assertNotNull($result->getBounds()); |
||
| 98 | $this->assertEquals(48.8617, $result->getBounds()->getSouth(), '', 0.001); |
||
| 99 | $this->assertEquals(2.3882487, $result->getBounds()->getWest(), '', 0.001); |
||
| 100 | $this->assertEquals(48.8644, $result->getBounds()->getNorth(), '', 0.001); |
||
| 101 | $this->assertEquals(2.3901, $result->getBounds()->getEast(), '', 0.001); |
||
| 102 | $this->assertEquals(10, $result->getStreetNumber()); |
||
| 103 | $this->assertEquals('Avenue Gambetta', $result->getStreetName()); |
||
| 104 | $this->assertEquals(75020, $result->getPostalCode()); |
||
| 105 | $this->assertEquals('Paris', $result->getLocality()); |
||
| 106 | $this->assertEquals('Paris', $result->getAdminLevels()->get(2)->getName()); |
||
| 107 | $this->assertEquals('Île-de-France', $result->getAdminLevels()->get(1)->getName()); |
||
| 108 | $this->assertEquals('France', $result->getCountry()->getName()); |
||
| 109 | $this->assertEquals('FR', $result->getCountry()->getCode()); |
||
| 110 | |||
| 111 | // not provided |
||
| 112 | $this->assertNull($result->getTimezone()); |
||
| 113 | } |
||
| 114 | |||
| 115 | public function testGeocodeBoundsWithRealAddressForNonRooftopLocation() |
||
| 116 | { |
||
| 117 | $provider = new GoogleMaps($this->getHttpClient()); |
||
| 118 | $results = $provider->geocodeQuery(GeocodeQuery::create('Paris, France')); |
||
| 119 | |||
| 120 | $this->assertInstanceOf('Geocoder\Model\AddressCollection', $results); |
||
| 121 | $this->assertCount(1, $results); |
||
| 122 | |||
| 123 | /** @var Location $result */ |
||
| 124 | $result = $results->first(); |
||
| 125 | $this->assertInstanceOf('\Geocoder\Model\Address', $result); |
||
| 126 | $this->assertNotNull($result->getBounds()); |
||
| 127 | $this->assertEquals(48.815573, $result->getBounds()->getSouth(), '', 0.0001); |
||
| 128 | $this->assertEquals(2.224199, $result->getBounds()->getWest(), '', 0.0001); |
||
| 129 | $this->assertEquals(48.902145, $result->getBounds()->getNorth(), '', 0.0001); |
||
| 130 | $this->assertEquals(2.4699209, $result->getBounds()->getEast(), '', 0.0001); |
||
| 131 | } |
||
| 132 | |||
| 133 | /** |
||
| 134 | * @expectedException \Geocoder\Exception\InvalidServerResponse |
||
| 135 | */ |
||
| 136 | public function testReverse() |
||
| 137 | { |
||
| 138 | $provider = new GoogleMaps($this->getMockedHttpClient()); |
||
| 139 | $provider->reverseQuery(ReverseQuery::fromCoordinates(1, 2)); |
||
| 140 | } |
||
| 141 | |||
| 142 | public function testReverseWithRealCoordinates() |
||
| 143 | { |
||
| 144 | $provider = new GoogleMaps($this->getHttpClient()); |
||
| 145 | $results = $provider->reverseQuery(ReverseQuery::fromCoordinates(48.8631507, 2.388911)); |
||
| 146 | |||
| 147 | $this->assertInstanceOf('Geocoder\Model\AddressCollection', $results); |
||
| 148 | $this->assertCount(5, $results); |
||
| 149 | |||
| 150 | /** @var Location $result */ |
||
| 151 | $result = $results->first(); |
||
| 152 | $this->assertInstanceOf('\Geocoder\Model\Address', $result); |
||
| 153 | $this->assertEquals(12, $result->getStreetNumber()); |
||
| 154 | $this->assertEquals('Avenue Gambetta', $result->getStreetName()); |
||
| 155 | $this->assertEquals(75020, $result->getPostalCode()); |
||
| 156 | $this->assertEquals('Paris', $result->getLocality()); |
||
| 157 | $this->assertCount(2, $result->getAdminLevels()); |
||
| 158 | $this->assertEquals('Paris', $result->getAdminLevels()->get(2)->getName()); |
||
| 159 | $this->assertEquals('Île-de-France', $result->getAdminLevels()->get(1)->getName()); |
||
| 160 | $this->assertEquals('France', $result->getCountry()->getName()); |
||
| 161 | $this->assertEquals('FR', $result->getCountry()->getCode()); |
||
| 162 | } |
||
| 163 | |||
| 164 | public function testGeocodeWithCityDistrict() |
||
| 165 | { |
||
| 166 | $provider = new GoogleMaps($this->getHttpClient()); |
||
| 167 | $results = $provider->geocodeQuery(GeocodeQuery::create('Kalbacher Hauptstraße 10, 60437 Frankfurt, Germany')); |
||
| 168 | |||
| 169 | $this->assertInstanceOf('Geocoder\Model\AddressCollection', $results); |
||
| 170 | $this->assertCount(1, $results); |
||
| 171 | |||
| 172 | /** @var Location $result */ |
||
| 173 | $result = $results->first(); |
||
| 174 | $this->assertInstanceOf('\Geocoder\Model\Address', $result); |
||
| 175 | $this->assertEquals('Kalbach-Riedberg', $result->getSubLocality()); |
||
| 176 | } |
||
| 177 | |||
| 178 | /** |
||
| 179 | * @expectedException \Geocoder\Exception\InvalidCredentials |
||
| 180 | * @expectedExceptionMessage API key is invalid https://maps.googleapis.com/maps/api/geocode/json?address=10%20avenue%20Gambetta%2C%20Paris%2C%20France |
||
| 181 | */ |
||
| 182 | public function testGeocodeWithInavlidApiKey() |
||
| 183 | { |
||
| 184 | $provider = new GoogleMaps($this->getMockedHttpClient('{"error_message":"The provided API key is invalid.", "status":"REQUEST_DENIED"}')); |
||
| 185 | $provider->geocodeQuery(GeocodeQuery::create('10 avenue Gambetta, Paris, France')); |
||
| 186 | } |
||
| 187 | |||
| 188 | public function testGeocodeWithRealValidApiKey() |
||
| 189 | { |
||
| 190 | if (!isset($_SERVER['GOOGLE_GEOCODING_KEY'])) { |
||
| 191 | $this->markTestSkipped('You need to configure the GOOGLE_GEOCODING_KEY value in phpunit.xml'); |
||
| 192 | } |
||
| 193 | |||
| 194 | $provider = new GoogleMaps($this->getHttpClient($_SERVER['GOOGLE_GEOCODING_KEY']), null, $_SERVER['GOOGLE_GEOCODING_KEY']); |
||
| 195 | |||
| 196 | $results = $provider->geocodeQuery(GeocodeQuery::create('Columbia University')); |
||
| 197 | |||
| 198 | $this->assertInstanceOf('Geocoder\Model\AddressCollection', $results); |
||
| 199 | $this->assertCount(1, $results); |
||
| 200 | |||
| 201 | /** @var Location $result */ |
||
| 202 | $result = $results->first(); |
||
| 203 | $this->assertInstanceOf('\Geocoder\Model\Address', $result); |
||
| 204 | $this->assertNotNull($result->getCoordinates()->getLatitude()); |
||
| 205 | $this->assertNotNull($result->getCoordinates()->getLongitude()); |
||
| 206 | $this->assertEquals('New York', $result->getLocality()); |
||
| 207 | $this->assertEquals('Manhattan', $result->getSubLocality()); |
||
| 208 | $this->assertCount(2, $result->getAdminLevels()); |
||
| 209 | $this->assertEquals('New York', $result->getAdminLevels()->get(1)->getName()); |
||
| 210 | } |
||
| 211 | |||
| 212 | /** |
||
| 213 | * @expectedException \Geocoder\Exception\InvalidCredentials |
||
| 214 | * @expectedExceptionMessage API key is invalid https://maps.googleapis.com/maps/api/geocode/json?address=Columbia%20University&key=fake_key |
||
| 215 | */ |
||
| 216 | public function testGeocodeWithRealInvalidApiKey() |
||
| 217 | { |
||
| 218 | $provider = new GoogleMaps($this->getHttpClient(), null, $this->testAPIKey); |
||
| 219 | |||
| 220 | $provider->geocodeQuery(GeocodeQuery::create('Columbia University')); |
||
| 221 | } |
||
| 222 | |||
| 223 | public function testGeocodePostalTown() |
||
| 224 | { |
||
| 225 | $provider = new GoogleMaps($this->getHttpClient()); |
||
| 226 | $results = $provider->geocodeQuery(GeocodeQuery::create('CF37, United Kingdom')); |
||
| 227 | |||
| 228 | $this->assertInstanceOf('Geocoder\Model\AddressCollection', $results); |
||
| 229 | $this->assertCount(1, $results); |
||
| 230 | |||
| 231 | /** @var Location $result */ |
||
| 232 | $result = $results->first(); |
||
| 233 | $this->assertInstanceOf('\Geocoder\Model\Address', $result); |
||
| 234 | $this->assertEquals('Pontypridd', $result->getLocality()); |
||
| 235 | } |
||
| 236 | |||
| 237 | public function testBusinessQueryWithoutPrivateKey() |
||
| 238 | { |
||
| 239 | $uri = ''; |
||
| 240 | |||
| 241 | $provider = GoogleMaps::business( |
||
| 242 | $this->getMockedHttpClientCallback( |
||
| 243 | function (RequestInterface $request) use (&$uri) { |
||
| 244 | $uri = $request->getUri(); |
||
| 245 | } |
||
| 246 | ), |
||
| 247 | 'foo' |
||
| 248 | ); |
||
| 249 | |||
| 250 | try { |
||
| 251 | $provider->geocodeQuery(GeocodeQuery::create('blah')); |
||
| 252 | } catch (InvalidServerResponse $e) { |
||
| 253 | } |
||
| 254 | $this->assertEquals('https://maps.googleapis.com/maps/api/geocode/json?address=blah&client=foo', $uri); |
||
| 255 | } |
||
| 256 | |||
| 257 | public function testBusinessQueryWithPrivateKey() |
||
| 258 | { |
||
| 259 | $uri = ''; |
||
| 260 | |||
| 261 | $provider = GoogleMaps::business( |
||
| 262 | $this->getMockedHttpClientCallback( |
||
| 263 | function (RequestInterface $request) use (&$uri) { |
||
| 264 | $uri = (string) $request->getUri(); |
||
| 265 | } |
||
| 266 | ), |
||
| 267 | 'foo', |
||
| 268 | 'bogus' |
||
| 269 | ); |
||
| 270 | |||
| 271 | try { |
||
| 272 | $provider->geocodeQuery(GeocodeQuery::create('blah')); |
||
| 273 | } catch (InvalidServerResponse $e) { |
||
| 274 | } |
||
| 275 | $this->assertEquals( |
||
| 276 | 'https://maps.googleapis.com/maps/api/geocode/json?address=blah&client=foo&signature=9G2weMhhd4E2ciR681gp9YabvUg=', |
||
| 277 | $uri |
||
| 278 | ); |
||
| 279 | } |
||
| 280 | |||
| 281 | /** |
||
| 282 | * @expectedException \Geocoder\Exception\InvalidCredentials |
||
| 283 | */ |
||
| 284 | public function testGeocodeWithInvalidClientIdAndKey() |
||
| 285 | { |
||
| 286 | $provider = GoogleMaps::business($this->getHttpClient(), 'foo', 'bogus'); |
||
| 287 | $provider->geocodeQuery(GeocodeQuery::create('Columbia University')); |
||
| 288 | } |
||
| 289 | |||
| 290 | /** |
||
| 291 | * @expectedException \Geocoder\Exception\InvalidCredentials |
||
| 292 | */ |
||
| 293 | public function testGeocodeWithInvalidClientIdAndKeyNoSsl() |
||
| 294 | { |
||
| 295 | $provider = GoogleMaps::business($this->getHttpClient(), 'foo', 'bogus'); |
||
| 296 | $provider->geocodeQuery(GeocodeQuery::create('Columbia University')); |
||
| 297 | } |
||
| 298 | |||
| 299 | public function testGeocodeWithSupremise() |
||
| 300 | { |
||
| 301 | $provider = new GoogleMaps($this->getHttpClient()); |
||
| 302 | $results = $provider->geocodeQuery(GeocodeQuery::create('2123 W Mineral Ave Apt 61,Littleton,CO8 0120')); |
||
| 303 | |||
| 304 | $this->assertInstanceOf('Geocoder\Model\AddressCollection', $results); |
||
| 305 | $this->assertCount(1, $results); |
||
| 306 | |||
| 307 | /** @var Location $result */ |
||
| 308 | $result = $results->first(); |
||
| 309 | $this->assertInstanceOf('\Geocoder\Model\Address', $result); |
||
| 310 | $this->assertEquals('61', $result->getSubpremise()); |
||
| 311 | } |
||
| 312 | |||
| 313 | public function testGeocodeBoundsWithRealAddressWithViewportOnly() |
||
| 314 | { |
||
| 315 | $provider = new GoogleMaps($this->getHttpClient()); |
||
| 316 | $results = $provider->geocodeQuery(GeocodeQuery::create('Sibbe, Netherlands')); |
||
| 317 | |||
| 318 | $this->assertInstanceOf('Geocoder\Model\AddressCollection', $results); |
||
| 319 | $this->assertCount(1, $results); |
||
| 320 | |||
| 321 | /** @var \Geocoder\Model\Address $result */ |
||
| 322 | $result = $results->first(); |
||
| 323 | $this->assertInstanceOf('\Geocoder\Model\Address', $result); |
||
| 324 | $this->assertNotNull($result->getBounds()); |
||
| 325 | $this->assertEquals(50.8433, $result->getBounds()->getSouth(), '', 0.001); |
||
| 326 | $this->assertEquals(5.8259, $result->getBounds()->getWest(), '', 0.001); |
||
| 327 | $this->assertEquals(50.8460, $result->getBounds()->getNorth(), '', 0.001); |
||
| 328 | $this->assertEquals(5.8286, $result->getBounds()->getEast(), '', 0.001); |
||
| 329 | } |
||
| 330 | } |
||
| 331 |