IntegrationTest   A
last analyzed

Complexity

Total Complexity 35

Size/Duplication

Total Lines 248
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 121
c 2
b 0
f 0
dl 0
loc 248
rs 9.6
wmc 35

13 Methods

Rating   Name   Duplication   Size   Complexity  
A getCacheDir() 0 3 1
A testGeocodeQueryCIT() 0 22 4
B assertWellFormattedResult() 0 73 8
A getApiKey() 0 3 1
A testGeocodeQueryWithNoResults() 0 14 3
A testReverseQuery() 0 14 3
A getCachedHttpClient() 0 14 2
A getAppCode() 0 3 1
A createProvider() 0 3 1
A testReverseQueryCIT() 0 14 3
A testGeocodeQuery() 0 22 4
A getAppId() 0 3 1
A testReverseQueryWithNoResults() 0 14 3
1
<?php
2
3
/*
4
 * This file is part of the Geocoder package.
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 *
8
 * @license    MIT License
9
 */
10
11
namespace Geocoder\Provider\Here\Tests;
12
13
use Geocoder\IntegrationTest\ProviderIntegrationTest;
14
use Geocoder\IntegrationTest\CachedResponseClient;
15
use Geocoder\Provider\Here\Here;
16
use Geocoder\Collection;
17
use Geocoder\Location;
18
use Geocoder\Model\AdminLevelCollection;
19
use Geocoder\Model\Bounds;
20
use Geocoder\Model\Coordinates;
21
use Geocoder\Model\Country;
22
use Geocoder\Query\GeocodeQuery;
23
use Geocoder\Query\ReverseQuery;
24
use Http\Client\HttpClient;
25
use Http\Discovery\HttpClientDiscovery;
26
27
/**
28
 * @author Sébastien Barré <[email protected]>
29
 */
30
class IntegrationTest extends ProviderIntegrationTest
31
{
32
    protected $testIpv4 = false;
33
34
    protected $testIpv6 = false;
35
36
    protected function createProvider(HttpClient $httpClient, bool $useCIT = false)
37
    {
38
        return Here::createUsingApiKey($httpClient, $this->getApiKey(), $useCIT);
39
    }
40
41
    protected function getCacheDir()
42
    {
43
        return __DIR__.'/.cached_responses';
44
    }
45
46
    /**
47
     * This client will make real request if cache was not found.
48
     *
49
     * @return CachedResponseClient
50
     */
51
    private function getCachedHttpClient()
52
    {
53
        try {
54
            $client = HttpClientDiscovery::find();
55
        } catch (\Http\Discovery\NotFoundException $e) {
56
            $client = $this->getMockForAbstractClass(HttpClient::class);
57
58
            $client
59
                ->expects($this->any())
60
                ->method('sendRequest')
61
                ->willThrowException($e);
62
        }
63
64
        return new CachedResponseClient($client, $this->getCacheDir(), $this->getApiKey());
65
    }
66
67
    protected function getApiKey()
68
    {
69
        return $_SERVER['HERE_APP_ID'];
70
    }
71
72
    protected function getAppId()
73
    {
74
        return $_SERVER['HERE_APP_ID'];
75
    }
76
77
    /**
78
     * @return string the Here AppCode or substring to be removed from cache
79
     */
80
    protected function getAppCode()
81
    {
82
        return $_SERVER['HERE_APP_CODE'];
83
    }
84
85
    public function testGeocodeQuery()
86
    {
87
        if (isset($this->skippedTests[__FUNCTION__])) {
88
            $this->markTestSkipped($this->skippedTests[__FUNCTION__]);
89
        }
90
        if (!$this->testAddress) {
91
            $this->markTestSkipped('Geocoding address is not supported by this provider');
92
        }
93
94
        $provider = $this->createProvider($this->getCachedHttpClient());
95
        $query = GeocodeQuery::create('10 Downing St, London, UK')->withLocale('en');
96
        $result = $provider->geocodeQuery($query);
97
        $this->assertWellFormattedResult($result);
98
99
        // Check Downing Street
100
        $location = $result->first();
101
        $this->assertEqualsWithDelta(51.5033, $location->getCoordinates()->getLatitude(), 0.1, 'Latitude should be in London');
102
        $this->assertEqualsWithDelta(-0.1276, $location->getCoordinates()->getLongitude(), 0.1, 'Longitude should be in London');
103
        $this->assertStringContainsString('Downing', $location->getStreetName(), 'Street name should contain "Downing St"');
0 ignored issues
show
Bug introduced by
It seems like $location->getStreetName() can also be of type null; however, parameter $haystack of PHPUnit\Framework\Assert...tStringContainsString() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

103
        $this->assertStringContainsString('Downing', /** @scrutinizer ignore-type */ $location->getStreetName(), 'Street name should contain "Downing St"');
Loading history...
104
105
        if (null !== $streetNumber = $location->getStreetNumber()) {
106
            $this->assertStringContainsString('10', $streetNumber, 'Street number should contain "10"');
107
        }
108
    }
109
110
    public function testGeocodeQueryCIT()
111
    {
112
        if (isset($this->skippedTests[__FUNCTION__])) {
113
            $this->markTestSkipped($this->skippedTests[__FUNCTION__]);
114
        }
115
        if (!$this->testAddress) {
116
            $this->markTestSkipped('Geocoding address is not supported by this provider');
117
        }
118
119
        $provider = $this->createProvider($this->getCachedHttpClient(), true);
120
        $query = GeocodeQuery::create('10 Downing St, London, UK')->withLocale('en');
121
        $result = $provider->geocodeQuery($query);
122
        $this->assertWellFormattedResult($result);
123
124
        // Check Downing Street
125
        $location = $result->first();
126
        $this->assertEqualsWithDelta(51.5033, $location->getCoordinates()->getLatitude(), 0.1, 'Latitude should be in London');
127
        $this->assertEqualsWithDelta(-0.1276, $location->getCoordinates()->getLongitude(), 0.1, 'Longitude should be in London');
128
        $this->assertStringContainsString('Downing', $location->getStreetName(), 'Street name should contain "Downing St"');
0 ignored issues
show
Bug introduced by
It seems like $location->getStreetName() can also be of type null; however, parameter $haystack of PHPUnit\Framework\Assert...tStringContainsString() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

128
        $this->assertStringContainsString('Downing', /** @scrutinizer ignore-type */ $location->getStreetName(), 'Street name should contain "Downing St"');
Loading history...
129
130
        if (null !== $streetNumber = $location->getStreetNumber()) {
131
            $this->assertStringContainsString('10', $streetNumber, 'Street number should contain "10"');
132
        }
133
    }
134
135
    public function testGeocodeQueryWithNoResults()
136
    {
137
        if (isset($this->skippedTests[__FUNCTION__])) {
138
            $this->markTestSkipped($this->skippedTests[__FUNCTION__]);
139
        }
140
        if (!$this->testAddress) {
141
            $this->markTestSkipped('Geocoding address is not supported by this provider');
142
        }
143
144
        $provider = $this->createProvider($this->getCachedHttpClient());
145
        $query = GeocodeQuery::create('jsajhgsdkfjhsfkjhaldkadjaslgldasd')->withLocale('en');
146
        $result = $provider->geocodeQuery($query);
147
        $this->assertWellFormattedResult($result);
148
        $this->assertEquals(0, $result->count());
149
    }
150
151
    public function testReverseQuery()
152
    {
153
        if (isset($this->skippedTests[__FUNCTION__])) {
154
            $this->markTestSkipped($this->skippedTests[__FUNCTION__]);
155
        }
156
        if (!$this->testReverse) {
157
            $this->markTestSkipped('Reverse geocoding address is not supported by this provider');
158
        }
159
160
        $provider = $this->createProvider($this->getCachedHttpClient());
161
162
        // Close to the white house
163
        $result = $provider->reverseQuery(ReverseQuery::fromCoordinates(38.900206, -77.036991)->withLocale('en'));
164
        $this->assertWellFormattedResult($result);
165
    }
166
167
    public function testReverseQueryCIT()
168
    {
169
        if (isset($this->skippedTests[__FUNCTION__])) {
170
            $this->markTestSkipped($this->skippedTests[__FUNCTION__]);
171
        }
172
        if (!$this->testReverse) {
173
            $this->markTestSkipped('Reverse geocoding address is not supported by this provider');
174
        }
175
176
        $provider = $this->createProvider($this->getCachedHttpClient(), true);
177
178
        // Close to the white house
179
        $result = $provider->reverseQuery(ReverseQuery::fromCoordinates(38.900206, -77.036991)->withLocale('en'));
180
        $this->assertWellFormattedResult($result);
181
    }
182
183
    public function testReverseQueryWithNoResults()
184
    {
185
        if (isset($this->skippedTests[__FUNCTION__])) {
186
            $this->markTestSkipped($this->skippedTests[__FUNCTION__]);
187
        }
188
189
        if (!$this->testReverse) {
190
            $this->markTestSkipped('Reverse geocoding address is not supported by this provider');
191
        }
192
193
        $provider = $this->createProvider($this->getCachedHttpClient());
194
195
        $result = $provider->reverseQuery(ReverseQuery::fromCoordinates(0, 0));
196
        $this->assertEquals(0, $result->count());
197
    }
198
199
    /**
200
     * Make sure that a result for a Geocoder is well formatted. Be aware that even
201
     * a Location with no data may be well formatted.
202
     *
203
     * @param $result
204
     */
205
    private function assertWellFormattedResult(Collection $result)
206
    {
207
        $this->assertInstanceOf(
208
            Collection::class,
209
            $result,
210
            'The result must be an instance of a Geocoder\Collection'
211
        );
212
213
        /** @var Location $location */
214
        foreach ($result as $location) {
215
            $this->assertInstanceOf(
216
                Location::class,
217
                $location,
218
                'All items in Geocoder\Collection must implement Geocoder\Location'
219
            );
220
221
            $this->assertInstanceOf(
222
                AdminLevelCollection::class,
223
                $location->getAdminLevels(),
224
                'Location::getAdminLevels MUST always return a AdminLevelCollection'
225
            );
226
            $arrayData = $location->toArray();
227
            $this->assertTrue(is_array($arrayData), 'Location::toArray MUST return an array.');
228
            $this->assertNotEmpty($arrayData, 'Location::toArray cannot be empty.');
229
230
            // Verify coordinates
231
            if (null !== $coords = $location->getCoordinates()) {
232
                $this->assertInstanceOf(
233
                    Coordinates::class,
234
                    $coords,
235
                    'Location::getCoordinates MUST always return a Coordinates or null'
236
                );
237
238
                // Using "assertNotEmpty" means that we can not have test code where coordinates is on equator or long = 0
239
                $this->assertNotEmpty($coords->getLatitude(), 'If coordinate object exists it cannot have an empty latitude.');
240
                $this->assertNotEmpty($coords->getLongitude(), 'If coordinate object exists it cannot have an empty longitude.');
241
            }
242
243
            // Verify bounds
244
            if (null !== $bounds = $location->getBounds()) {
245
                $this->assertInstanceOf(
246
                    Bounds::class,
247
                    $bounds,
248
                    'Location::getBounds MUST always return a Bounds or null'
249
                );
250
251
                // Using "assertNotEmpty" means that we can not have test code where coordinates is on equator or long = 0
252
                $this->assertNotEmpty($bounds->getSouth(), 'If bounds object exists it cannot have an empty values.');
253
                $this->assertNotEmpty($bounds->getWest(), 'If bounds object exists it cannot have an empty values.');
254
                $this->assertNotEmpty($bounds->getNorth(), 'If bounds object exists it cannot have an empty values.');
255
                $this->assertNotEmpty($bounds->getEast(), 'If bounds object exists it cannot have an empty values.');
256
            }
257
258
            // Check country
259
            if (null !== $country = $location->getCountry()) {
260
                $this->assertInstanceOf(
261
                    Country::class,
262
                    $country,
263
                    'Location::getCountry MUST always return a Country or null'
264
                );
265
                $this->assertFalse(null === $country->getCode() && null === $country->getName(), 'Both code and name cannot be empty');
266
267
                if (null !== $country->getCode()) {
268
                    $this->assertNotEmpty(
269
                        $location->getCountry()->getCode(),
270
                        'The Country should not have an empty code.'
271
                    );
272
                }
273
274
                if (null !== $country->getName()) {
275
                    $this->assertNotEmpty(
276
                        $location->getCountry()->getName(),
277
                        'The Country should not have an empty name.'
278
                    );
279
                }
280
            }
281
        }
282
    }
283
}
284