Completed
Push — master ( cf9367...8a253f )
by Tobias
01:27
created

testReverseGeocodePlaceNearbyDistance()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 21
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
eloc 12
c 1
b 1
f 0
dl 0
loc 21
rs 9.8666
cc 1
nc 1
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\GoogleMapsPlaces\Tests;
14
15
use Geocoder\Exception\InvalidArgument;
16
use Geocoder\Exception\QuotaExceeded;
17
use Geocoder\Exception\UnsupportedOperation;
18
use Geocoder\IntegrationTest\BaseTestCase;
19
use Geocoder\Provider\GoogleMapsPlaces\GoogleMapsPlaces;
20
use Geocoder\Provider\GoogleMapsPlaces\Model\GooglePlace;
21
use Geocoder\Provider\GoogleMapsPlaces\Model\OpeningHours;
22
use Geocoder\Provider\GoogleMapsPlaces\Model\Photo;
23
use Geocoder\Provider\GoogleMapsPlaces\Model\PlusCode;
24
use Geocoder\Query\GeocodeQuery;
25
use Geocoder\Query\ReverseQuery;
26
27
/**
28
 * @author atymic <[email protected]>
29
 */
30
class GoogleMapsPlacesTest extends BaseTestCase
31
{
32
    protected function getCacheDir()
33
    {
34
        if (isset($_SERVER['USE_CACHED_RESPONSES']) && true === $_SERVER['USE_CACHED_RESPONSES']) {
35
            return __DIR__.'/.cached_responses';
36
        }
37
38
        return null;
39
    }
40
41
    public function testGetName()
42
    {
43
        $provider = new GoogleMapsPlaces($this->getMockedHttpClient(), 'key');
44
        $this->assertEquals('google_maps_places', $provider->getName());
45
    }
46
47
    public function testGeocodeWithLocalhostIPv4()
48
    {
49
        $this->expectException(UnsupportedOperation::class);
50
        $this->expectExceptionMessage('The GoogleMapsPlaces provider does not support IP addresses');
51
52
        $provider = new GoogleMapsPlaces($this->getMockedHttpClient(), 'key');
53
        $provider->geocodeQuery(GeocodeQuery::create('127.0.0.1'));
54
    }
55
56
    public function testGeocodeWithLocalhostIPv6()
57
    {
58
        $this->expectException(UnsupportedOperation::class);
59
        $this->expectExceptionMessage('The GoogleMapsPlaces provider does not support IP addresses');
60
61
        $provider = new GoogleMapsPlaces($this->getMockedHttpClient(), 'key');
62
        $provider->geocodeQuery(GeocodeQuery::create('::1'));
63
    }
64
65
    public function testGeocodeWithRealIp()
66
    {
67
        $this->expectException(UnsupportedOperation::class);
68
        $this->expectExceptionMessage('The GoogleMapsPlaces provider does not support IP addresses');
69
70
        $provider = $this->getGoogleMapsProvider();
71
        $provider->geocodeQuery(GeocodeQuery::create('74.200.247.59'));
72
    }
73
74
    public function testGeocodeWithQuotaExceeded()
75
    {
76
        $this->expectException(QuotaExceeded::class);
77
        $this->expectExceptionMessage('Daily quota exceeded https://maps.googleapis.com/maps/api/place/findplacefromtext/json?input=10+avenue+Gambetta%2C+Paris%2C+France&inputtype=textquery&fields=formatted_address%2Cgeometry%2Cicon%2Cname%2Cpermanently_closed%2Cphotos%2Cplace_id%2Cplus_code%2Ctypes&key=key');
78
79
        $provider = new GoogleMapsPlaces($this->getMockedHttpClient('{"status":"OVER_QUERY_LIMIT"}'), 'key');
80
        $provider->geocodeQuery(GeocodeQuery::create('10 avenue Gambetta, Paris, France'));
81
    }
82
83
    public function testGeocodePlaceFindMode()
84
    {
85
        $provider = $this->getGoogleMapsProvider();
86
87
        $query = GeocodeQuery::create('Museum of Contemporary Art Australia');
88
89
        $results = $provider->geocodeQuery($query);
90
        $this->assertCount(1, $results);
91
92
        $result = $results->first();
93
        $this->assertInstanceOf(GooglePlace::class, $result);
94
95
        $this->assertSame('ChIJ68aBlEKuEmsRHUA9oME5Zh0', $result->getId());
96
        $this->assertSame('https://maps.gstatic.com/mapfiles/place_api/icons/museum-71.png', $result->getIcon());
97
        $this->assertInstanceOf(PlusCode::class, $result->getPlusCode());
98
        $this->assertContainsOnlyInstancesOf(Photo::class, $result->getPhotos());
99
100
        $this->assertSame([
101
            'art_gallery',
102
            'museum',
103
            'cafe',
104
            'food',
105
            'store',
106
            'point_of_interest',
107
            'establishment',
108
        ], $result->getType());
109
    }
110
111
    public function testGeocodePlaceSearchMode()
112
    {
113
        $provider = $this->getGoogleMapsProvider();
114
115
        $query = GeocodeQuery::create('bar in sydney')
116
            ->withData('mode', GoogleMapsPlaces::GEOCODE_MODE_SEARCH);
117
118
        $results = $provider->geocodeQuery($query);
119
        $this->assertCount(20, $results);
120
121
        /** @var GooglePlace $resultOne */
122
        $resultOne = $results->first();
123
124
        $this->assertInstanceOf(GooglePlace::class, $resultOne);
125
        $this->assertSame('ChIJ3SS9Lj-uEmsRrVS7u1OEV_0', $resultOne->getId());
126
        $this->assertSame('Papa Gede\'s Bar', $resultOne->getName());
127
        $this->assertSame('348 Kent St, Sydney NSW 2000, Australia', $resultOne->getFormattedAddress());
128
129
        $this->assertSame([
130
            'bar',
131
            'restaurant',
132
            'food',
133
            'point_of_interest',
134
            'establishment',
135
        ], $resultOne->getType());
136
137
        $this->assertSame('https://maps.gstatic.com/mapfiles/place_api/icons/bar-71.png', $resultOne->getIcon());
138
139
        $this->assertInstanceOf(PlusCode::class, $resultOne->getPlusCode());
140
        $this->assertSame('4RRH46J3+3X', $resultOne->getPlusCode()->getGlobalCode());
141
142
        $this->assertContainsOnlyInstancesOf(Photo::class, $resultOne->getPhotos());
143
144
        $this->assertSame(2, $resultOne->getPriceLevel());
145
        $this->assertSame(4.7, $resultOne->getRating());
146
147
        $this->assertNull($resultOne->getFormattedPhoneNumber());
148
        $this->assertNull($resultOne->getInternationalPhoneNumber());
149
        $this->assertNull($resultOne->getWebsite());
150
151
        $this->assertInstanceOf(OpeningHours::class, $resultOne->getOpeningHours());
152
153
        $this->assertFalse($resultOne->isPermanentlyClosed());
154
    }
155
156
    public function testGeocodePlaceSearchAroundLocation()
157
    {
158
        $provider = $this->getGoogleMapsProvider();
159
160
        $query = GeocodeQuery::create('bar')
161
            ->withData('mode', GoogleMapsPlaces::GEOCODE_MODE_SEARCH)
162
            ->withData('location', '-32.926642, 151.783026')// Newcastle, NSW
163
            ->withData('radius', 100);
164
165
        $results = $provider->geocodeQuery($query);
166
        $this->assertCount(20, $results);
167
168
        /** @var GooglePlace $resultOne */
169
        $resultOne = $results->first();
170
171
        $this->assertInstanceOf(GooglePlace::class, $resultOne);
172
        $this->assertSame('ChIJ5_ZqMHsUc2sRHgfnw5D1FlY', $resultOne->getId());
173
        $this->assertSame('Reserve', $resultOne->getName());
174
        $this->assertSame('102 Hunter St, Newcastle NSW 2300, Australia', $resultOne->getFormattedAddress());
175
    }
176
177
    public function testReverseGeocodePlaceSearchWithoutType()
178
    {
179
        $this->expectException(InvalidArgument::class);
180
        $this->expectExceptionMessage('`type` is required to be set in the Query data for Reverse Geocoding when using search mode');
181
182
        $provider = $this->getGoogleMapsProvider();
183
        $query = ReverseQuery::fromCoordinates(-33.8865019, 151.2080413)
184
            ->withData('rankby', 'distance')
185
            ;
186
187
        $provider->reverseQuery($query);
188
    }
189
190
    public function testReverseGeocodePlaceSearch()
191
    {
192
        $provider = $this->getGoogleMapsProvider();
193
194
        $query = ReverseQuery::fromCoordinates(-33.892674, 151.200727)
195
            // ->withData('mode', GoogleMapsPlaces::GEOCODE_MODE_SEARCH) // =default
196
            ->withData('type', 'bar')
197
            ;
198
199
        $results = $provider->reverseQuery($query);
200
201
        $this->assertCount(20, $results);
202
203
        /** @var GooglePlace $resultOne */
204
        $resultOne = $results->first();
205
206
        $this->assertInstanceOf(GooglePlace::class, $resultOne);
207
        $this->assertSame('ChIJ3Y3vQdqxEmsRTvCcbZnsYJ8', $resultOne->getId());
208
        $this->assertSame('Arcadia', $resultOne->getName());
209
        $this->assertSame('7 Cope St, Redfern NSW 2016', $resultOne->getFormattedAddress());
210
    }
211
212
    public function testReverseGeocodePlaceNearbyDistanceWithoutKeyword()
213
    {
214
        $this->expectException(InvalidArgument::class);
215
        $this->expectExceptionMessage('keyword');
216
217
        $provider = $this->getGoogleMapsProvider();
218
        $query = ReverseQuery::fromCoordinates(-33.892674, 151.200727)
219
            ->withData('mode', GoogleMapsPlaces::GEOCODE_MODE_NEARBY)
220
            ->withData('rankby', 'distance')
221
            // ->withData('keyword', 'bar')
222
            ;
223
224
        $provider->reverseQuery($query);
225
    }
226
227
    public function testReverseGeocodePlaceNearbyDistance()
228
    {
229
        $provider = $this->getGoogleMapsProvider();
230
231
        $query = ReverseQuery::fromCoordinates(-33.892674, 151.200727)
232
            ->withData('mode', GoogleMapsPlaces::GEOCODE_MODE_NEARBY)
233
            ->withData('rankby', 'distance')
234
            ->withData('keyword', 'bar')
235
            ;
236
237
        $results = $provider->reverseQuery($query);
238
239
        $this->assertCount(20, $results);
240
241
        /** @var GooglePlace $resultOne */
242
        $resultOne = $results->first();
243
244
        $this->assertInstanceOf(GooglePlace::class, $resultOne);
245
        $this->assertSame('ChIJ3Y3vQdqxEmsRTvCcbZnsYJ8', $resultOne->getId());
246
        $this->assertSame('Arcadia', $resultOne->getName());
247
        $this->assertSame('7 Cope St, Redfern', $resultOne->getVicinity());
248
        // $this->assertNull($resultOne->getFormattedAddress());
249
        // formatted address not available with NEARBY endpoint ()
250
    }
251
252
    public function testReverseGeocodePlaceNearbyProminenceWithoutRadius()
253
    {
254
        $this->expectException(InvalidArgument::class);
255
        $this->expectExceptionMessage('radius');
256
257
        $provider = $this->getGoogleMapsProvider();
258
        $query = ReverseQuery::fromCoordinates(-33.892674, 151.200727)
259
            ->withData('mode', GoogleMapsPlaces::GEOCODE_MODE_NEARBY)
260
            // ->withData('rankby', 'prominence')
261
            // ->withData('radius', 500)
262
            ;
263
264
        $provider->reverseQuery($query);
265
    }
266
267
    public function testReverseGeocodePlaceNearbyProminence()
268
    {
269
        $provider = $this->getGoogleMapsProvider();
270
271
        $query = ReverseQuery::fromCoordinates(-33.892674, 151.200727)
272
                ->withData('mode', GoogleMapsPlaces::GEOCODE_MODE_NEARBY)
273
                //->withData('rankby', 'prominence'); // =default
274
                ->withData('radius', 500)
275
                ;
276
277
        $results = $provider->reverseQuery($query);
278
        $this->assertCount(20, $results);
279
280
        /** @var GooglePlace $resultOne */
281
        $resultOne = $results->first();
282
283
        $this->assertInstanceOf(GooglePlace::class, $resultOne);
284
        $this->assertSame('ChIJP3Sa8ziYEmsRUKgyFmh9AQM', $resultOne->getId()); // Sydney
285
    }
286
287
    public function testReverseGeocodePlaceSearchWithEmptyOpeningHours()
288
    {
289
        $provider = $this->getGoogleMapsProvider();
290
291
        $query = ReverseQuery::fromCoordinates(51.0572773, 13.7763207)
292
            ->withData('type', 'transit_station')
293
            ;
294
295
        $results = $provider->reverseQuery($query);
296
        $this->assertCount(20, $results);
297
298
        $this->markTestIncomplete('Test is giving irregular results. Marking incomplete for now.');
299
300
        /** @var GooglePlace $resultOne */
301
        $resultOne = $results->get(13);
302
        $this->assertNull($resultOne->getOpeningHours()->isOpenNow());
303
        // sometimes giving: Error: Call to a member function isOpenNow() on null
304
305
        /** @var GooglePlace $resultTwo */
306
        $resultTwo = $results->first();
307
        $this->assertNull($resultTwo->getOpeningHours());
308
        // sometimes giving: Failed asserting that Object ['openNow' => null, 'periods' => [], 'weekdayText' => []] is null
309
    }
310
311
    private function getGoogleMapsProvider(): GoogleMapsPlaces
312
    {
313
        if (!isset($_SERVER['GOOGLE_GEOCODING_KEY'])) {
314
            $this->markTestSkipped('You need to configure the GOOGLE_GEOCODING_KEY value in phpunit.xml');
315
        }
316
317
        $provider = new GoogleMapsPlaces(
318
            $this->getHttpClient($_SERVER['GOOGLE_GEOCODING_KEY']),
319
            $_SERVER['GOOGLE_GEOCODING_KEY']
320
        );
321
322
        return $provider;
323
    }
324
}
325