|
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
|
|
|
|