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\GeoIP2\Tests; |
14
|
|
|
|
15
|
|
|
use Geocoder\Collection; |
16
|
|
|
use Geocoder\IntegrationTest\BaseTestCase; |
17
|
|
|
use Geocoder\Location; |
18
|
|
|
use Geocoder\Query\GeocodeQuery; |
19
|
|
|
use Geocoder\Query\ReverseQuery; |
20
|
|
|
use Geocoder\Provider\GeoIP2\GeoIP2; |
21
|
|
|
use Geocoder\Provider\GeoIP2\GeoIP2Adapter; |
22
|
|
|
use GeoIp2\Database\Reader; |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* @author Jens Wiese <[email protected]> |
26
|
|
|
*/ |
27
|
|
|
class GeoIP2Test extends BaseTestCase |
28
|
|
|
{ |
29
|
|
|
/** |
30
|
|
|
* @var GeoIP2 |
31
|
|
|
*/ |
32
|
|
|
protected $provider; |
33
|
|
|
|
34
|
|
|
public function setUp() |
35
|
|
|
{ |
36
|
|
|
$this->provider = new GeoIP2($this->getGeoIP2AdapterMock()); |
37
|
|
|
} |
38
|
|
|
|
39
|
|
|
protected function getCacheDir() |
40
|
|
|
{ |
41
|
|
|
return __DIR__.'/.cached_responses'; |
42
|
|
|
} |
43
|
|
|
|
44
|
|
|
public function testGetName() |
45
|
|
|
{ |
46
|
|
|
$this->assertEquals('geoip2', $this->provider->getName()); |
47
|
|
|
} |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* @expectedException \Geocoder\Exception\UnsupportedOperation |
51
|
|
|
* @expectedExceptionMessage The GeoIP2 provider is not able to do reverse geocoding. |
52
|
|
|
*/ |
53
|
|
|
public function testQueryingReverseLeadsToException() |
54
|
|
|
{ |
55
|
|
|
$this->provider->reverseQuery(ReverseQuery::fromCoordinates(50, 9)); |
56
|
|
|
} |
57
|
|
|
|
58
|
|
|
public function testGeocodeWithLocalhostIPv4() |
59
|
|
|
{ |
60
|
|
|
$results = $this->provider->geocodeQuery(GeocodeQuery::create('127.0.0.1')); |
61
|
|
|
|
62
|
|
|
$this->assertInstanceOf('Geocoder\Model\AddressCollection', $results); |
63
|
|
|
$this->assertCount(1, $results); |
64
|
|
|
|
65
|
|
|
/** @var Location $result */ |
66
|
|
|
$result = $results->first(); |
67
|
|
|
$this->assertInstanceOf('\Geocoder\Model\Address', $result); |
68
|
|
|
$this->assertEquals('localhost', $result->getLocality()); |
69
|
|
|
$this->assertEquals('localhost', $result->getCountry()->getName()); |
70
|
|
|
} |
71
|
|
|
|
72
|
|
|
/** |
73
|
|
|
* @expectedException \Geocoder\Exception\UnsupportedOperation |
74
|
|
|
* @expectedExceptionMessage The GeoIP2 provider does not support street addresses, only IP addresses. |
75
|
|
|
*/ |
76
|
|
|
public function testOnlyIpAddressesCouldBeResolved() |
77
|
|
|
{ |
78
|
|
|
$this->provider->geocodeQuery(GeocodeQuery::create('Street 123, Somewhere')); |
79
|
|
|
} |
80
|
|
|
|
81
|
|
|
/** |
82
|
|
|
* Provides data for geocode test. |
83
|
|
|
* |
84
|
|
|
* @return array |
85
|
|
|
*/ |
86
|
|
|
public static function provideDataForRetrievingGeodata() |
87
|
|
|
{ |
88
|
|
|
$testdata = [ |
89
|
|
|
'Response with data' => [ |
90
|
|
|
'74.200.247.59', |
91
|
|
|
'{"city":{"geoname_id":2911298,"names":{"de":"Hamburg","en":"Hamburg","es":"Hamburgo","fr":"Hambourg","ja":"\u30cf\u30f3\u30d6\u30eb\u30af","pt-BR":"Hamburgo","ru":"\u0413\u0430\u043c\u0431\u0443\u0440\u0433","zh-CN":"\u6c49\u5821\u5e02"}},"continent":{"code":"EU","geoname_id":6255148,"names":{"de":"Europa","en":"Europe","es":"Europa","fr":"Europe","ja":"\u30e8\u30fc\u30ed\u30c3\u30d1","pt-BR":"Europa","ru":"\u0415\u0432\u0440\u043e\u043f\u0430","zh-CN":"\u6b27\u6d32"}},"country":{"geoname_id":2921044,"iso_code":"DE","names":{"de":"Deutschland","en":"Germany","es":"Alemania","fr":"Allemagne","ja":"\u30c9\u30a4\u30c4\u9023\u90a6\u5171\u548c\u56fd","pt-BR":"Alemanha","ru":"\u0413\u0435\u0440\u043c\u0430\u043d\u0438\u044f","zh-CN":"\u5fb7\u56fd"}},"location":{"latitude":53.55,"longitude":10,"time_zone":"Europe\/Berlin"},"registered_country":{"geoname_id":2921044,"iso_code":"DE","names":{"de":"Deutschland","en":"Germany","es":"Alemania","fr":"Allemagne","ja":"\u30c9\u30a4\u30c4\u9023\u90a6\u5171\u548c\u56fd","pt-BR":"Alemanha","ru":"\u0413\u0435\u0440\u043c\u0430\u043d\u0438\u044f","zh-CN":"\u5fb7\u56fd"}},"subdivisions":[{"geoname_id":2911297,"iso_code":"HH","names":{"de":"Hamburg","en":"Hamburg","es":"Hamburgo","fr":"Hambourg"}}],"traits":{"ip_address":"74.200.247.59"},"postal":{"code":"EC4N"}}', |
92
|
|
|
[ |
93
|
|
|
'latitude' => 53.55, |
94
|
|
|
'longitude' => 10, |
95
|
|
|
'boundsDefined' => null, |
96
|
|
|
'streetNumber' => null, |
97
|
|
|
'streetName' => null, |
98
|
|
|
'locality' => 'Hamburg', |
99
|
|
|
'subLocality' => null, |
100
|
|
|
'postalCode' => 'EC4N', |
101
|
|
|
'adminLevels' => [1 => [ |
102
|
|
|
'name' => 'Hamburg', |
103
|
|
|
'code' => 'HH', |
104
|
|
|
]], |
105
|
|
|
'country' => 'Germany', |
106
|
|
|
'countryCode' => 'DE', |
107
|
|
|
'timezone' => 'Europe/Berlin', |
108
|
|
|
], |
109
|
|
|
], |
110
|
|
|
'Response with all possible data' => [ |
111
|
|
|
'93.36.20.217', |
112
|
|
|
'{"country": {"iso_code": "IT","names": {"pt-BR": "Itália","es": "Italia","ru": "Италия","en": "Italy","zh-CN": "意大利","fr": "Italie","de": "Italien","ja": "イタリア共和国"},"geoname_id": 3175395},"location": {"longitude": 9.2667,"latitude": 45.5833,"time_zone": "Europe/Rome"},"subdivisions": [{"iso_code": "25","names": {"en": "Lombardy","fr": "Lombardie","de": "Lombardei","es": "Lombardía"},"geoname_id": 3174618},{"iso_code": "MB","names": {"en": "Monza Brianza"},"geoname_id": 6955700}],"postal": {"code": "20900"},"city": {"names": {"pt-BR": "Monza","es": "Monza","ru": "Монца","en": "Monza","zh-CN": "蒙扎","fr": "Monza","de": "Monza","ja": "モンツァ"},"geoname_id": 3172629},"continent": {"names": {"pt-BR": "Europa","es": "Europa","ru": "Европа","en": "Europe","zh-CN": "欧洲","fr": "Europe","de": "Europa","ja": "ヨーロッパ"},"geoname_id": 6255148,"code": "EU"},"registered_country": {"iso_code": "IT","names": {"pt-BR": "Itália","es": "Italia","ru": "Италия","en": "Italy","zh-CN": "意大利","fr": "Italie","de": "Italien","ja": "イタリア共和国"},"geoname_id": 3175395},"traits": {"domain": "fastwebnet.it","autonomous_system_number": 12874,"ip_address": "93.36.20.217","organization": "Fastweb","isp": "Fastweb","autonomous_system_organization": "Fastweb SpA"},"represented_country": {"names": {}}}', |
113
|
|
|
[ |
114
|
|
|
'latitude' => 45.5833, |
115
|
|
|
'longitude' => 9.2667, |
116
|
|
|
'boundsDefined' => null, |
117
|
|
|
'streetNumber' => null, |
118
|
|
|
'streetName' => null, |
119
|
|
|
'locality' => 'Monza', |
120
|
|
|
'subLocality' => null, |
121
|
|
|
'postalCode' => '20900', |
122
|
|
|
'adminLevels' => [ |
123
|
|
|
1 => [ |
124
|
|
|
'name' => 'Lombardy', |
125
|
|
|
'code' => '25', |
126
|
|
|
], |
127
|
|
|
2 => [ |
128
|
|
|
'name' => 'Monza Brianza', |
129
|
|
|
'code' => 'MB', |
130
|
|
|
], |
131
|
|
|
], |
132
|
|
|
'country' => 'Italy', |
133
|
|
|
'countryCode' => 'IT', |
134
|
|
|
'timezone' => 'Europe/Rome', |
135
|
|
|
], |
136
|
|
|
], |
137
|
|
|
'Response with all data null' => [ |
138
|
|
|
'74.200.247.59', |
139
|
|
|
'{}', |
140
|
|
|
[ |
141
|
|
|
'latitude' => null, |
142
|
|
|
'longitude' => null, |
143
|
|
|
'boundsDefined' => null, |
144
|
|
|
'streetNumber' => null, |
145
|
|
|
'streetName' => null, |
146
|
|
|
'locality' => null, |
147
|
|
|
'subLocality' => null, |
148
|
|
|
'postalCode' => null, |
149
|
|
|
'adminLevels' => [], |
150
|
|
|
'country' => null, |
151
|
|
|
'countryCode' => null, |
152
|
|
|
'timezone' => null, |
153
|
|
|
], |
154
|
|
|
], |
155
|
|
|
]; |
156
|
|
|
|
157
|
|
|
return $testdata; |
158
|
|
|
} |
159
|
|
|
|
160
|
|
|
/** |
161
|
|
|
* @dataProvider provideDataForRetrievingGeodata |
162
|
|
|
* |
163
|
|
|
* @param string $address |
164
|
|
|
* @param mixed $adapterResponse |
165
|
|
|
* @param mixed $expectedGeodata |
166
|
|
|
*/ |
167
|
|
|
public function testRetrievingGeodata($address, $adapterResponse, $expectedGeodata) |
168
|
|
|
{ |
169
|
|
|
$adapter = $this->getGeoIP2AdapterMock($adapterResponse); |
170
|
|
|
$provider = new GeoIP2($adapter); |
171
|
|
|
|
172
|
|
|
$results = $provider->geocodeQuery(GeocodeQuery::create($address)); |
173
|
|
|
|
174
|
|
|
$this->assertInstanceOf('Geocoder\Model\AddressCollection', $results); |
175
|
|
|
$this->assertCount(1, $results); |
176
|
|
|
|
177
|
|
|
/** @var Location $result */ |
178
|
|
|
$result = $results->first(); |
179
|
|
|
$this->assertInstanceOf('\Geocoder\Model\Address', $result); |
180
|
|
|
if (isset($expectedGeodata['latitude'])) { |
181
|
|
|
$this->assertEquals($expectedGeodata['latitude'], $result->getCoordinates()->getLatitude()); |
182
|
|
|
$this->assertEquals($expectedGeodata['longitude'], $result->getCoordinates()->getLongitude()); |
183
|
|
|
} else { |
184
|
|
|
$this->assertNull($result->getCoordinates()); |
185
|
|
|
} |
186
|
|
|
|
187
|
|
|
if ($expectedGeodata['boundsDefined']) { |
188
|
|
|
$this->assertNotNull($result->getBounds()); |
189
|
|
|
} else { |
190
|
|
|
$this->assertNull($result->getBounds()); |
191
|
|
|
} |
192
|
|
|
|
193
|
|
|
$this->assertEquals($expectedGeodata['streetNumber'], $result->getStreetNumber()); |
194
|
|
|
$this->assertEquals($expectedGeodata['streetName'], $result->getStreetName()); |
195
|
|
|
$this->assertEquals($expectedGeodata['locality'], $result->getLocality()); |
196
|
|
|
$this->assertEquals($expectedGeodata['subLocality'], $result->getSubLocality()); |
197
|
|
|
$this->assertEquals($expectedGeodata['postalCode'], $result->getPostalCode()); |
198
|
|
|
$this->assertEquals($expectedGeodata['country'], $result->getCountry()->getName()); |
199
|
|
|
$this->assertEquals($expectedGeodata['countryCode'], $result->getCountry()->getCode()); |
200
|
|
|
$this->assertEquals($expectedGeodata['timezone'], $result->getTimezone()); |
201
|
|
|
foreach ($expectedGeodata['adminLevels'] as $level => $data) { |
202
|
|
|
$this->assertEquals($data['name'], $result->getAdminLevels()->get($level)->getName()); |
203
|
|
|
$this->assertEquals($data['code'], $result->getAdminLevels()->get($level)->getCode()); |
204
|
|
|
} |
205
|
|
|
} |
206
|
|
|
|
207
|
|
|
public function testRetrievingGeodataNotExistingLocation() |
208
|
|
|
{ |
209
|
|
|
$adapter = $this->getGeoIP2AdapterMock(''); |
210
|
|
|
$provider = new GeoIP2($adapter); |
211
|
|
|
|
212
|
|
|
$result = $provider->geocodeQuery(GeocodeQuery::create('74.200.247.59')); |
213
|
|
|
$this->assertInstanceOf(Collection::class, $result); |
214
|
|
|
$this->assertEquals(0, $result->count()); |
215
|
|
|
} |
216
|
|
|
|
217
|
|
|
public function testGeoIp2Encoding() |
218
|
|
|
{ |
219
|
|
|
$reader = new Reader(__DIR__.'/fixtures/GeoLite2-City.mmdb'); |
220
|
|
|
$adapter = new GeoIP2Adapter($reader); |
221
|
|
|
$provider = new GeoIP2($adapter); |
222
|
|
|
$locality = $provider->geocodeQuery(GeocodeQuery::create('79.114.34.148'))->first()->getLocality(); |
223
|
|
|
$this->assertEquals('Timișoara', $locality); |
224
|
|
|
} |
225
|
|
|
|
226
|
|
|
/** |
227
|
|
|
* @param mixed $returnValue |
228
|
|
|
* |
229
|
|
|
* @return \PHPUnit_Framework_MockObject_MockObject|GeoIP2Adapter |
230
|
|
|
*/ |
231
|
|
|
private function getGeoIP2AdapterMock($returnValue = '') |
232
|
|
|
{ |
233
|
|
|
$mock = $this->getMockBuilder(GeoIP2Adapter::class) |
234
|
|
|
->disableOriginalConstructor() |
235
|
|
|
->setMethods(['getContent']) |
236
|
|
|
->getMock(); |
237
|
|
|
|
238
|
|
|
if ($returnValue instanceof \Exception) { |
239
|
|
|
$returnValue = $this->throwException($returnValue); |
240
|
|
|
} else { |
241
|
|
|
$returnValue = $this->returnValue($returnValue); |
242
|
|
|
} |
243
|
|
|
|
244
|
|
|
$mock->expects($this->any())->method('getContent')->will($returnValue); |
245
|
|
|
|
246
|
|
|
return $mock; |
247
|
|
|
} |
248
|
|
|
} |
249
|
|
|
|