Completed
Push — master ( 6bf6c4...1c6e25 )
by Tobias
02:19
created

GoogleMapsTest::testBusinessQueryWithPrivateKey()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 23
Code Lines 14

Duplication

Lines 23
Ratio 100 %

Importance

Changes 0
Metric Value
dl 23
loc 23
rs 9.0856
c 0
b 0
f 0
cc 2
eloc 14
nc 2
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Geocoder package.
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 *
10
 * @license    MIT License
11
 */
12
13
namespace Geocoder\Provider\GoogleMaps\Tests;
14
15
use Geocoder\Exception\InvalidServerResponse;
16
use Geocoder\IntegrationTest\BaseTestCase;
17
use Geocoder\Location;
18
use Geocoder\Query\GeocodeQuery;
19
use Geocoder\Query\ReverseQuery;
20
use Geocoder\Provider\GoogleMaps\GoogleMaps;
21
use Psr\Http\Message\RequestInterface;
22
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