diff --git a/composer.json b/composer.json index 6df5d55..1c8b246 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,6 @@ "require": { "php": "^7.4 || ^8.0", "geocoder-php/plugin": "^1.5", - "php-http/curl-client": "^2.3", "php-http/discovery": "^1.14", "symfony/console": "^5.4 || ^6.4 || ^7.0", "symfony/framework-bundle": "^5.4 || ^6.4 || ^7.0", @@ -62,13 +61,12 @@ "nyholm/nsa": "^1.3", "nyholm/psr7": "^1.5", "nyholm/symfony-bundle-test": "^2.0 || ^3.0", - "php-http/message": "^1.13", - "php-http/mock-client": "^1.6", "phpstan/phpstan": "^1.9.2", "psr/http-client": "^1.0", "psr/simple-cache": "^1.0 || ^2.0", "symfony/cache": "^5.4 || ^6.4 || ^7.0", "symfony/config": "^5.4 || ^6.4 || ^7.0", + "symfony/http-client": "^5.4 || ^6.4 || ^7.0", "symfony/phpunit-bridge": "^5.4 || ^6.4 || ^7.0", "symfony/validator": "^5.4 || ^6.4 || ^7.0", "symfony/var-exporter": "^5.4 || ^6.4 || ^7.0", diff --git a/tests/DependencyInjection/Compiler/AddProvidersPassTest.php b/tests/DependencyInjection/Compiler/AddProvidersPassTest.php index 7144744..97f9ed2 100644 --- a/tests/DependencyInjection/Compiler/AddProvidersPassTest.php +++ b/tests/DependencyInjection/Compiler/AddProvidersPassTest.php @@ -15,10 +15,11 @@ use Bazinga\GeocoderBundle\DependencyInjection\Compiler\AddProvidersPass; use Geocoder\Provider\BingMaps\BingMaps; use Geocoder\ProviderAggregator; -use Http\Mock\Client; use PHPUnit\Framework\TestCase; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\HttpClient\MockHttpClient; +use Symfony\Component\HttpClient\Psr18Client; final class AddProvidersPassTest extends TestCase { @@ -34,7 +35,7 @@ public function testRegistersProviders(): void $containerBuilder = new ContainerBuilder(); $containerBuilder->setDefinition(ProviderAggregator::class, new Definition(ProviderAggregator::class)); - $bing = $containerBuilder->setDefinition('bing_maps', new Definition(BingMaps::class, [new Client(), 'apikey'])); + $bing = $containerBuilder->setDefinition('bing_maps', new Definition(BingMaps::class, [new Psr18Client(new MockHttpClient()), 'apikey'])); $bing->addTag('bazinga_geocoder.provider'); $this->compilerPass->process($containerBuilder); diff --git a/tests/Functional/CustomTestKernel.php b/tests/Functional/CustomTestKernel.php index 523d04e..5af8981 100644 --- a/tests/Functional/CustomTestKernel.php +++ b/tests/Functional/CustomTestKernel.php @@ -14,6 +14,8 @@ use Nyholm\BundleTest\TestKernel; use Symfony\Component\Config\ConfigCache; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Dumper\Preloader; use Symfony\Component\ErrorHandler\DebugClassLoader; use Symfony\Component\HttpKernel\CacheWarmer\WarmableInterface; @@ -26,7 +28,7 @@ * the methods using it (reboot() and getKernelParameters() and setAnnotatedClassCache() ) therefore needed to be redeclared, in order * for them to have a correct value in it. */ -class CustomTestKernel extends TestKernel +class CustomTestKernel extends TestKernel implements CompilerPassInterface { private $warmupDir; @@ -93,6 +95,21 @@ public function setAnnotatedClassCache(array $annotatedClasses): void file_put_contents(($this->warmupDir ?: $this->getBuildDir()).'/annotations.map', sprintf('getDefinition('http_client') + ->setPublic(true); + } + + protected function build(ContainerBuilder $container): void + { + parent::build($container); + + $container->addCompilerPass($this); + } + /** * Initializes the service container. * diff --git a/tests/Functional/GeocoderListenerTest.php b/tests/Functional/GeocoderListenerTest.php index 72513e5..ab669de 100644 --- a/tests/Functional/GeocoderListenerTest.php +++ b/tests/Functional/GeocoderListenerTest.php @@ -21,15 +21,13 @@ use Doctrine\Bundle\DoctrineBundle\DoctrineBundle; use Doctrine\ORM\Configuration; use Doctrine\ORM\Tools\SchemaTool; -use Http\Message\RequestMatcher\RequestMatcher; -use Http\Mock\Client; use Nyholm\BundleTest\TestKernel; -use Psr\Http\Message\RequestInterface; -use Psr\Http\Message\ResponseInterface; -use Psr\Http\Message\StreamInterface; use Symfony\Bridge\Doctrine\ArgumentResolver\EntityValueResolver; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\HttpClient\MockHttpClient; +use Symfony\Component\HttpClient\Response\MockResponse; use Symfony\Component\HttpKernel\Kernel; use Symfony\Component\HttpKernel\KernelInterface; @@ -59,6 +57,14 @@ protected static function createKernel(array $options = []): KernelInterface $kernel = parent::createKernel($options); $kernel->addTestBundle(DoctrineBundle::class); $kernel->addTestBundle(BazingaGeocoderBundle::class); + $kernel->addTestCompilerPass(new class implements CompilerPassInterface { + public function process(ContainerBuilder $container): void + { + $container + ->getDefinition('http_client') + ->setPublic(true); + } + }); if (defined(ConnectionFactory::class.'::DEFAULT_SCHEME_MAP')) { $kernel->addTestConfig(static function (ContainerBuilder $container) { $container->prependExtensionConfig('doctrine', [ @@ -105,45 +111,7 @@ public function testPersistForProperty(): void }]); $container = self::getContainer(); - - $httpClient = $container->get(Client::class); - $httpClient->on(new RequestMatcher(), function (RequestInterface $request) { - if ('https://nominatim.openstreetmap.org/search?format=jsonv2&q=Berlin%2C%20Germany&addressdetails=1&extratags=1&limit=5' === (string) $request->getUri()) { - $stream = $this->createMock(StreamInterface::class); - $stream->expects(self::once()) - ->method('__toString') - ->willReturn('[{"place_id":159647018,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. http://osm.org/copyright","osm_type":"relation","osm_id":62422,"lat":"52.5170365","lon":"13.3888599","category":"boundary","type":"administrative","place_rank":8,"importance":0.7875390282491362,"addresstype":"city","name":"Berlin","display_name":"Berlin, Deutschland","address":{"city":"Berlin","ISO3166-2-lvl4":"DE-BE","country":"Deutschland","country_code":"de"},"extratags":{"ele": "35", "email": "info@berlin.de", "place": "city", "capital": "yes", "website": "http://www.berlin.de", "de:place": "city", "ref:nuts": "DE3;DE30;DE300", "wikidata": "Q64", "wikipedia": "de:Berlin", "population": "3769962", "ref:LOCODE": "DEBER", "ref:nuts:1": "DE3", "ref:nuts:2": "DE30", "ref:nuts:3": "DE300", "state_code": "BE", "name:prefix": "Land und Kreisfreie Stadt", "linked_place": "city", "official_status": "Land", "contact:facebook": "http://www.facebook.com/Berlin", "name:prefix:city": "Kreisfreie Stadt", "openGeoDB:loc_id": "14356", "capital_ISO3166-1": "yes", "name:prefix:state": "Land", "source:population": "https://download.statistik-berlin-brandenburg.de/fa93e3bd19a2e885/a5ecfb2fff6a/SB_A01-05-00_2020h02_BE.pdf", "license_plate_code": "B", "official_status:de": "Land", "official_status:en": "State", "official_status:ru": "земля", "geographical_region": "Barnim;Berliner Urstromtal;Teltow;Nauener Platte", "blind:description:de": "Auf www.berlinfuerblinde.de gibt es einen kostenlosen Audioguide und weitere Informationen.", "de:regionalschluessel": "110000000000", "openGeoDB:postal_codes": "10178,10115,10117,10119,10179,10243,10245,10247,10249,10315,10317,10318,10319,10365,10367,10369,10405,10407,10409,10435,10437,10439,10551,10553,10555,10557,10559,10585,10587,10589,10623,10625,10627,10629,10707,10709,10711,10713,10715,10717,10719,10777,10", "report_problems:website": "https://ordnungsamt.berlin.de/", "TMC:cid_58:tabcd_1:Class": "Area", "openGeoDB:license_plate_code": "B", "TMC:cid_58:tabcd_1:LCLversion": "12.0", "openGeoDB:telephone_area_code": "030", "TMC:cid_58:tabcd_1:LocationCode": "266", "de:amtlicher_gemeindeschluessel": "11000000", "openGeoDB:community_identification_number": "11000000"},"boundingbox":["52.3382448","52.6755087","13.0883450","13.7611609"]}]'); - - $response = $this->createMock(ResponseInterface::class); - $response->expects(self::once()) - ->method('getStatusCode') - ->willReturn(200); - $response->expects(self::once()) - ->method('getBody') - ->willReturn($stream); - - return $response; - } - - if ('https://nominatim.openstreetmap.org/search?format=jsonv2&q=Paris%2C%20France&addressdetails=1&extratags=1&limit=5' === (string) $request->getUri()) { - $stream = $this->createMock(StreamInterface::class); - $stream->expects(self::once()) - ->method('__toString') - ->willReturn('[{"place_id":115350921,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. http://osm.org/copyright","osm_type":"relation","osm_id":7444,"lat":"48.8588897","lon":"2.3200410217200766","category":"boundary","type":"administrative","place_rank":15,"importance":0.8317101715588673,"addresstype":"suburb","name":"Paris","display_name":"Paris, Île-de-France, France métropolitaine, France","address":{"suburb":"Paris","city_district":"Paris","city":"Paris","ISO3166-2-lvl6":"FR-75","state":"Île-de-France","ISO3166-2-lvl4":"FR-IDF","region":"France métropolitaine","country":"France","country_code":"fr"},"extratags":{"capital": "yes", "wikidata": "Q90", "ref:INSEE": "75056", "wikipedia": "fr:Paris", "population": "2187526", "ref:FR:MGP": "T1", "source:population": "INSEE 2020"},"boundingbox":["48.8155755","48.9021560","2.2241220","2.4697602"]},{"place_id":114827617,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. http://osm.org/copyright","osm_type":"relation","osm_id":71525,"lat":"48.8534951","lon":"2.3483915","category":"boundary","type":"administrative","place_rank":12,"importance":0.8317101715588673,"addresstype":"city","name":"Paris","display_name":"Paris, Île-de-France, France métropolitaine, France","address":{"city":"Paris","ISO3166-2-lvl6":"FR-75","state":"Île-de-France","ISO3166-2-lvl4":"FR-IDF","region":"France métropolitaine","country":"France","country_code":"fr"},"extratags":{"rank": "0", "capital": "yes", "ref:nuts": "FR101", "wikidata": "Q90", "ref:INSEE": "75", "wikipedia": "fr:Paris", "is_capital": "country", "population": "2165423", "ref:nuts:3": "FR101", "linked_place": "city", "source:name:oc": "ieo-bdtopoc", "contact:website": "http://www.paris.fr", "population:date": "2019", "capital_ISO3166-1": "yes", "source:population": "INSEE 2022"},"boundingbox":["48.8155755","48.9021560","2.2241220","2.4697602"]},{"place_id":114994164,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. http://osm.org/copyright","osm_type":"relation","osm_id":1641193,"lat":"48.8588897","lon":"2.3200410217200766","category":"boundary","type":"administrative","place_rank":14,"importance":0.4283953917728152,"addresstype":"city_district","name":"Paris","display_name":"Paris, Île-de-France, France métropolitaine, France","address":{"city_district":"Paris","city":"Paris","ISO3166-2-lvl6":"FR-75","state":"Île-de-France","ISO3166-2-lvl4":"FR-IDF","region":"France métropolitaine","country":"France","country_code":"fr"},"extratags":{"wikidata": "Q2863958", "ref:INSEE": "751", "wikipedia": "fr:Arrondissement de Paris"},"boundingbox":["48.8155755","48.9021560","2.2241220","2.4697602"]}]'); - - $response = $this->createMock(ResponseInterface::class); - $response->expects(self::once()) - ->method('getStatusCode') - ->willReturn(200); - $response->expects(self::once()) - ->method('getBody') - ->willReturn($stream); - - return $response; - } - - self::fail(sprintf('Unexpected http call "%s %s".', $request->getMethod(), (string) $request->getUri())); - }); + $container->set('http_client', self::createHttpClientForBerlinQuery()); $dummy = new DummyWithProperty(); $dummy->address = 'Berlin, Germany'; @@ -183,45 +151,7 @@ public function testPersistForGetter(): void }]); $container = self::getContainer(); - - $httpClient = $container->get(Client::class); - $httpClient->on(new RequestMatcher(), function (RequestInterface $request) { - if ('https://nominatim.openstreetmap.org/search?format=jsonv2&q=Berlin%2C%20Germany&addressdetails=1&extratags=1&limit=5' === (string) $request->getUri()) { - $stream = $this->createMock(StreamInterface::class); - $stream->expects(self::once()) - ->method('__toString') - ->willReturn('[{"place_id":159647018,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. http://osm.org/copyright","osm_type":"relation","osm_id":62422,"lat":"52.5170365","lon":"13.3888599","category":"boundary","type":"administrative","place_rank":8,"importance":0.7875390282491362,"addresstype":"city","name":"Berlin","display_name":"Berlin, Deutschland","address":{"city":"Berlin","ISO3166-2-lvl4":"DE-BE","country":"Deutschland","country_code":"de"},"extratags":{"ele": "35", "email": "info@berlin.de", "place": "city", "capital": "yes", "website": "http://www.berlin.de", "de:place": "city", "ref:nuts": "DE3;DE30;DE300", "wikidata": "Q64", "wikipedia": "de:Berlin", "population": "3769962", "ref:LOCODE": "DEBER", "ref:nuts:1": "DE3", "ref:nuts:2": "DE30", "ref:nuts:3": "DE300", "state_code": "BE", "name:prefix": "Land und Kreisfreie Stadt", "linked_place": "city", "official_status": "Land", "contact:facebook": "http://www.facebook.com/Berlin", "name:prefix:city": "Kreisfreie Stadt", "openGeoDB:loc_id": "14356", "capital_ISO3166-1": "yes", "name:prefix:state": "Land", "source:population": "https://download.statistik-berlin-brandenburg.de/fa93e3bd19a2e885/a5ecfb2fff6a/SB_A01-05-00_2020h02_BE.pdf", "license_plate_code": "B", "official_status:de": "Land", "official_status:en": "State", "official_status:ru": "земля", "geographical_region": "Barnim;Berliner Urstromtal;Teltow;Nauener Platte", "blind:description:de": "Auf www.berlinfuerblinde.de gibt es einen kostenlosen Audioguide und weitere Informationen.", "de:regionalschluessel": "110000000000", "openGeoDB:postal_codes": "10178,10115,10117,10119,10179,10243,10245,10247,10249,10315,10317,10318,10319,10365,10367,10369,10405,10407,10409,10435,10437,10439,10551,10553,10555,10557,10559,10585,10587,10589,10623,10625,10627,10629,10707,10709,10711,10713,10715,10717,10719,10777,10", "report_problems:website": "https://ordnungsamt.berlin.de/", "TMC:cid_58:tabcd_1:Class": "Area", "openGeoDB:license_plate_code": "B", "TMC:cid_58:tabcd_1:LCLversion": "12.0", "openGeoDB:telephone_area_code": "030", "TMC:cid_58:tabcd_1:LocationCode": "266", "de:amtlicher_gemeindeschluessel": "11000000", "openGeoDB:community_identification_number": "11000000"},"boundingbox":["52.3382448","52.6755087","13.0883450","13.7611609"]}]'); - - $response = $this->createMock(ResponseInterface::class); - $response->expects(self::once()) - ->method('getStatusCode') - ->willReturn(200); - $response->expects(self::once()) - ->method('getBody') - ->willReturn($stream); - - return $response; - } - - if ('https://nominatim.openstreetmap.org/search?format=jsonv2&q=Paris%2C%20France&addressdetails=1&extratags=1&limit=5' === (string) $request->getUri()) { - $stream = $this->createMock(StreamInterface::class); - $stream->expects(self::once()) - ->method('__toString') - ->willReturn('[{"place_id":115350921,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. http://osm.org/copyright","osm_type":"relation","osm_id":7444,"lat":"48.8588897","lon":"2.3200410217200766","category":"boundary","type":"administrative","place_rank":15,"importance":0.8317101715588673,"addresstype":"suburb","name":"Paris","display_name":"Paris, Île-de-France, France métropolitaine, France","address":{"suburb":"Paris","city_district":"Paris","city":"Paris","ISO3166-2-lvl6":"FR-75","state":"Île-de-France","ISO3166-2-lvl4":"FR-IDF","region":"France métropolitaine","country":"France","country_code":"fr"},"extratags":{"capital": "yes", "wikidata": "Q90", "ref:INSEE": "75056", "wikipedia": "fr:Paris", "population": "2187526", "ref:FR:MGP": "T1", "source:population": "INSEE 2020"},"boundingbox":["48.8155755","48.9021560","2.2241220","2.4697602"]},{"place_id":114827617,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. http://osm.org/copyright","osm_type":"relation","osm_id":71525,"lat":"48.8534951","lon":"2.3483915","category":"boundary","type":"administrative","place_rank":12,"importance":0.8317101715588673,"addresstype":"city","name":"Paris","display_name":"Paris, Île-de-France, France métropolitaine, France","address":{"city":"Paris","ISO3166-2-lvl6":"FR-75","state":"Île-de-France","ISO3166-2-lvl4":"FR-IDF","region":"France métropolitaine","country":"France","country_code":"fr"},"extratags":{"rank": "0", "capital": "yes", "ref:nuts": "FR101", "wikidata": "Q90", "ref:INSEE": "75", "wikipedia": "fr:Paris", "is_capital": "country", "population": "2165423", "ref:nuts:3": "FR101", "linked_place": "city", "source:name:oc": "ieo-bdtopoc", "contact:website": "http://www.paris.fr", "population:date": "2019", "capital_ISO3166-1": "yes", "source:population": "INSEE 2022"},"boundingbox":["48.8155755","48.9021560","2.2241220","2.4697602"]},{"place_id":114994164,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. http://osm.org/copyright","osm_type":"relation","osm_id":1641193,"lat":"48.8588897","lon":"2.3200410217200766","category":"boundary","type":"administrative","place_rank":14,"importance":0.4283953917728152,"addresstype":"city_district","name":"Paris","display_name":"Paris, Île-de-France, France métropolitaine, France","address":{"city_district":"Paris","city":"Paris","ISO3166-2-lvl6":"FR-75","state":"Île-de-France","ISO3166-2-lvl4":"FR-IDF","region":"France métropolitaine","country":"France","country_code":"fr"},"extratags":{"wikidata": "Q2863958", "ref:INSEE": "751", "wikipedia": "fr:Arrondissement de Paris"},"boundingbox":["48.8155755","48.9021560","2.2241220","2.4697602"]}]'); - - $response = $this->createMock(ResponseInterface::class); - $response->expects(self::once()) - ->method('getStatusCode') - ->willReturn(200); - $response->expects(self::once()) - ->method('getBody') - ->willReturn($stream); - - return $response; - } - - self::fail(sprintf('Unexpected http call "%s %s".', $request->getMethod(), (string) $request->getUri())); - }); + $container->set('http_client', self::createHttpClientForBerlinQuery()); $em = $container->get('doctrine.orm.entity_manager'); @@ -261,6 +191,9 @@ public function testPersistForInvalidGetter(): void }]); $container = self::getContainer(); + $container->set('http_client', new MockHttpClient(static function () { + self::fail('I shall not be called'); + })); $em = $container->get('doctrine.orm.entity_manager'); @@ -291,6 +224,9 @@ public function testPersistForEmptyProperty(): void }]); $container = self::getContainer(); + $container->set('http_client', new MockHttpClient(static function () { + self::fail('I shall not be called'); + })); $em = $container->get('doctrine.orm.entity_manager'); @@ -320,40 +256,10 @@ public function testDoesNotGeocodeIfAddressNotChanged(): void $kernel->addTestConfig(__DIR__.'/config/listener_'.(PHP_VERSION_ID >= 80000 ? 'php8' : 'php7').'.yml'); }]); - $container = self::getContainer(); - $httpRequests = 0; - $httpClient = $container->get(Client::class); - $httpClient->on(new RequestMatcher(), function (RequestInterface $request) use (&$httpRequests) { - $response = $this->createMock(ResponseInterface::class); - $response->expects(self::any()) - ->method('getStatusCode') - ->willReturn(200); - - if ('https://nominatim.openstreetmap.org/search?format=jsonv2&q=Frankfurt%2C%20Germany&addressdetails=1&extratags=1&limit=5' === (string) $request->getUri() && 0 === $httpRequests) { - $stream = $this->createMock(StreamInterface::class); - $stream->expects(self::once()) - ->method('__toString') - ->willReturn('[{"place_id":152571305,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. http://osm.org/copyright","osm_type":"relation","osm_id":62400,"lat":"50.1106444","lon":"8.6820917","category":"boundary","type":"administrative","place_rank":12,"importance":0.6941325622496303,"addresstype":"city","name":"Frankfurt am Main","display_name":"Frankfurt am Main, Hessen, Deutschland","address":{"city":"Frankfurt am Main","state":"Hessen","ISO3166-2-lvl4":"DE-HE","country":"Deutschland","country_code":"de"},"extratags":{"ele": "112", "flag": "File:Flag of Frankfurt am Main.svg", "logo": "File:Frankfurt am Main logo.svg", "de:place": "city", "nickname": "Europastadt", "wikidata": "Q1794", "wikipedia": "de:Frankfurt am Main", "population": "701350", "ref:LOCODE": "DEFRA", "ref:nuts:3": "DE712", "border_type": "county", "name:prefix": "Stadt", "nickname:de": "Europastadt", "nickname:la": "Urbem Europaeam", "nickname:nl": "Bankfurt", "coat_of_arms": "File:Wappen Frankfurt am Main.svg", "linked_place": "city", "wikimedia_commons": "Category:Frankfurt am Main", "license_plate_code": "F", "de:regionalschluessel": "064120000000", "TMC:cid_58:tabcd_1:Class": "Area", "TMC:cid_58:tabcd_1:LCLversion": "9.00", "TMC:cid_58:tabcd_1:LocationCode": "414", "de:amtlicher_gemeindeschluessel": "06412000"},"boundingbox":["50.0153529","50.2271424","8.4727605","8.8004049"]},{"place_id":160849350,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. http://osm.org/copyright","osm_type":"relation","osm_id":62523,"lat":"52.3412273","lon":"14.549452","category":"boundary","type":"administrative","place_rank":12,"importance":0.5626903004005709,"addresstype":"city","name":"Frankfurt (Oder)","display_name":"Frankfurt (Oder), Brandenburg, Deutschland","address":{"city":"Frankfurt (Oder)","state":"Brandenburg","ISO3166-2-lvl4":"DE-BB","country":"Deutschland","country_code":"de"},"extratags":{"ele": "28", "place": "city", "website": "https://www.frankfurt-oder.de/", "de:place": "city", "wikidata": "Q4024", "wikipedia": "de:Frankfurt (Oder)", "population": "61969", "ref:LOCODE": "DEFFO", "ref:nuts:3": "DE403", "name:prefix": "Kreisfreie Stadt", "linked_place": "town", "license_plate_code": "FF", "telephone_area_code": "0335", "de:regionalschluessel": "120530000000", "TMC:cid_58:tabcd_1:Class": "Area", "TMC:cid_58:tabcd_1:LCLversion": "8.00", "TMC:cid_58:tabcd_1:LocationCode": "415", "de:amtlicher_gemeindeschluessel": "12053000"},"boundingbox":["52.2528709","52.3980721","14.3948254","14.6013644"]}]'); - - $response->expects(self::once()) - ->method('getBody') - ->willReturn($stream); - } else { - $stream = $this->createMock(StreamInterface::class); - $stream->expects(self::once()) - ->method('__toString') - ->willReturn('[]'); - - $response->expects(self::once()) - ->method('getBody') - ->willReturn($stream); - } - ++$httpRequests; - - return $response; - }); + $container = self::getContainer(); + $container->set('http_client', self::createHttpClientForFrankfurtQuery($httpRequests)); $em = $container->get('doctrine.orm.entity_manager'); @@ -376,4 +282,38 @@ public function testDoesNotGeocodeIfAddressNotChanged(): void self::assertSame(0, $dummy->longitude); self::assertSame(1, $httpRequests); } + + private static function createHttpClientForBerlinQuery(): MockHttpClient + { + return new MockHttpClient(static function (string $method, string $url): MockResponse { + if ('https://nominatim.openstreetmap.org/search?format=jsonv2&q=Berlin%2C%20Germany&addressdetails=1&extratags=1&limit=5' === $url) { + self::assertSame('GET', $method); + + return new MockResponse('[{"place_id":159647018,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. http://osm.org/copyright","osm_type":"relation","osm_id":62422,"lat":"52.5170365","lon":"13.3888599","category":"boundary","type":"administrative","place_rank":8,"importance":0.7875390282491362,"addresstype":"city","name":"Berlin","display_name":"Berlin, Deutschland","address":{"city":"Berlin","ISO3166-2-lvl4":"DE-BE","country":"Deutschland","country_code":"de"},"extratags":{"ele": "35", "email": "info@berlin.de", "place": "city", "capital": "yes", "website": "http://www.berlin.de", "de:place": "city", "ref:nuts": "DE3;DE30;DE300", "wikidata": "Q64", "wikipedia": "de:Berlin", "population": "3769962", "ref:LOCODE": "DEBER", "ref:nuts:1": "DE3", "ref:nuts:2": "DE30", "ref:nuts:3": "DE300", "state_code": "BE", "name:prefix": "Land und Kreisfreie Stadt", "linked_place": "city", "official_status": "Land", "contact:facebook": "http://www.facebook.com/Berlin", "name:prefix:city": "Kreisfreie Stadt", "openGeoDB:loc_id": "14356", "capital_ISO3166-1": "yes", "name:prefix:state": "Land", "source:population": "https://download.statistik-berlin-brandenburg.de/fa93e3bd19a2e885/a5ecfb2fff6a/SB_A01-05-00_2020h02_BE.pdf", "license_plate_code": "B", "official_status:de": "Land", "official_status:en": "State", "official_status:ru": "земля", "geographical_region": "Barnim;Berliner Urstromtal;Teltow;Nauener Platte", "blind:description:de": "Auf www.berlinfuerblinde.de gibt es einen kostenlosen Audioguide und weitere Informationen.", "de:regionalschluessel": "110000000000", "openGeoDB:postal_codes": "10178,10115,10117,10119,10179,10243,10245,10247,10249,10315,10317,10318,10319,10365,10367,10369,10405,10407,10409,10435,10437,10439,10551,10553,10555,10557,10559,10585,10587,10589,10623,10625,10627,10629,10707,10709,10711,10713,10715,10717,10719,10777,10", "report_problems:website": "https://ordnungsamt.berlin.de/", "TMC:cid_58:tabcd_1:Class": "Area", "openGeoDB:license_plate_code": "B", "TMC:cid_58:tabcd_1:LCLversion": "12.0", "openGeoDB:telephone_area_code": "030", "TMC:cid_58:tabcd_1:LocationCode": "266", "de:amtlicher_gemeindeschluessel": "11000000", "openGeoDB:community_identification_number": "11000000"},"boundingbox":["52.3382448","52.6755087","13.0883450","13.7611609"]}]', ['response_headers' => ['content-type' => 'application/json']]); + } + + if ('https://nominatim.openstreetmap.org/search?format=jsonv2&q=Paris%2C%20France&addressdetails=1&extratags=1&limit=5' === $url) { + self::assertSame('GET', $method); + + return new MockResponse('[{"place_id":115350921,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. http://osm.org/copyright","osm_type":"relation","osm_id":7444,"lat":"48.8588897","lon":"2.3200410217200766","category":"boundary","type":"administrative","place_rank":15,"importance":0.8317101715588673,"addresstype":"suburb","name":"Paris","display_name":"Paris, Île-de-France, France métropolitaine, France","address":{"suburb":"Paris","city_district":"Paris","city":"Paris","ISO3166-2-lvl6":"FR-75","state":"Île-de-France","ISO3166-2-lvl4":"FR-IDF","region":"France métropolitaine","country":"France","country_code":"fr"},"extratags":{"capital": "yes", "wikidata": "Q90", "ref:INSEE": "75056", "wikipedia": "fr:Paris", "population": "2187526", "ref:FR:MGP": "T1", "source:population": "INSEE 2020"},"boundingbox":["48.8155755","48.9021560","2.2241220","2.4697602"]},{"place_id":114827617,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. http://osm.org/copyright","osm_type":"relation","osm_id":71525,"lat":"48.8534951","lon":"2.3483915","category":"boundary","type":"administrative","place_rank":12,"importance":0.8317101715588673,"addresstype":"city","name":"Paris","display_name":"Paris, Île-de-France, France métropolitaine, France","address":{"city":"Paris","ISO3166-2-lvl6":"FR-75","state":"Île-de-France","ISO3166-2-lvl4":"FR-IDF","region":"France métropolitaine","country":"France","country_code":"fr"},"extratags":{"rank": "0", "capital": "yes", "ref:nuts": "FR101", "wikidata": "Q90", "ref:INSEE": "75", "wikipedia": "fr:Paris", "is_capital": "country", "population": "2165423", "ref:nuts:3": "FR101", "linked_place": "city", "source:name:oc": "ieo-bdtopoc", "contact:website": "http://www.paris.fr", "population:date": "2019", "capital_ISO3166-1": "yes", "source:population": "INSEE 2022"},"boundingbox":["48.8155755","48.9021560","2.2241220","2.4697602"]},{"place_id":114994164,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. http://osm.org/copyright","osm_type":"relation","osm_id":1641193,"lat":"48.8588897","lon":"2.3200410217200766","category":"boundary","type":"administrative","place_rank":14,"importance":0.4283953917728152,"addresstype":"city_district","name":"Paris","display_name":"Paris, Île-de-France, France métropolitaine, France","address":{"city_district":"Paris","city":"Paris","ISO3166-2-lvl6":"FR-75","state":"Île-de-France","ISO3166-2-lvl4":"FR-IDF","region":"France métropolitaine","country":"France","country_code":"fr"},"extratags":{"wikidata": "Q2863958", "ref:INSEE": "751", "wikipedia": "fr:Arrondissement de Paris"},"boundingbox":["48.8155755","48.9021560","2.2241220","2.4697602"]}]', ['response_headers' => ['content-type' => 'application/json']]); + } + + self::fail(sprintf('Unexpected http call "%s %s".', $method, $url)); + }); + } + + private static function createHttpClientForFrankfurtQuery(int &$requestCount): MockHttpClient + { + return new MockHttpClient(static function (string $method, string $url) use (&$requestCount): MockResponse { + if ('https://nominatim.openstreetmap.org/search?format=jsonv2&q=Frankfurt%2C%20Germany&addressdetails=1&extratags=1&limit=5' === $url) { + self::assertSame('GET', $method); + + ++$requestCount; + + return new MockResponse('[{"place_id":152571305,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. http://osm.org/copyright","osm_type":"relation","osm_id":62400,"lat":"50.1106444","lon":"8.6820917","category":"boundary","type":"administrative","place_rank":12,"importance":0.6941325622496303,"addresstype":"city","name":"Frankfurt am Main","display_name":"Frankfurt am Main, Hessen, Deutschland","address":{"city":"Frankfurt am Main","state":"Hessen","ISO3166-2-lvl4":"DE-HE","country":"Deutschland","country_code":"de"},"extratags":{"ele": "112", "flag": "File:Flag of Frankfurt am Main.svg", "logo": "File:Frankfurt am Main logo.svg", "de:place": "city", "nickname": "Europastadt", "wikidata": "Q1794", "wikipedia": "de:Frankfurt am Main", "population": "701350", "ref:LOCODE": "DEFRA", "ref:nuts:3": "DE712", "border_type": "county", "name:prefix": "Stadt", "nickname:de": "Europastadt", "nickname:la": "Urbem Europaeam", "nickname:nl": "Bankfurt", "coat_of_arms": "File:Wappen Frankfurt am Main.svg", "linked_place": "city", "wikimedia_commons": "Category:Frankfurt am Main", "license_plate_code": "F", "de:regionalschluessel": "064120000000", "TMC:cid_58:tabcd_1:Class": "Area", "TMC:cid_58:tabcd_1:LCLversion": "9.00", "TMC:cid_58:tabcd_1:LocationCode": "414", "de:amtlicher_gemeindeschluessel": "06412000"},"boundingbox":["50.0153529","50.2271424","8.4727605","8.8004049"]},{"place_id":160849350,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. http://osm.org/copyright","osm_type":"relation","osm_id":62523,"lat":"52.3412273","lon":"14.549452","category":"boundary","type":"administrative","place_rank":12,"importance":0.5626903004005709,"addresstype":"city","name":"Frankfurt (Oder)","display_name":"Frankfurt (Oder), Brandenburg, Deutschland","address":{"city":"Frankfurt (Oder)","state":"Brandenburg","ISO3166-2-lvl4":"DE-BB","country":"Deutschland","country_code":"de"},"extratags":{"ele": "28", "place": "city", "website": "https://www.frankfurt-oder.de/", "de:place": "city", "wikidata": "Q4024", "wikipedia": "de:Frankfurt (Oder)", "population": "61969", "ref:LOCODE": "DEFFO", "ref:nuts:3": "DE403", "name:prefix": "Kreisfreie Stadt", "linked_place": "town", "license_plate_code": "FF", "telephone_area_code": "0335", "de:regionalschluessel": "120530000000", "TMC:cid_58:tabcd_1:Class": "Area", "TMC:cid_58:tabcd_1:LCLversion": "8.00", "TMC:cid_58:tabcd_1:LocationCode": "415", "de:amtlicher_gemeindeschluessel": "12053000"},"boundingbox":["52.2528709","52.3980721","14.3948254","14.6013644"]}]', ['response_headers' => ['content-type' => 'application/json']]); + } + + self::fail(sprintf('Unexpected http call "%s %s".', $method, $url)); + }); + } } diff --git a/tests/Functional/PluginInteractionTest.php b/tests/Functional/PluginInteractionTest.php index 3f7db7e..2a15b6b 100644 --- a/tests/Functional/PluginInteractionTest.php +++ b/tests/Functional/PluginInteractionTest.php @@ -14,14 +14,13 @@ use Bazinga\GeocoderBundle\BazingaGeocoderBundle; use Geocoder\Query\GeocodeQuery; -use Http\Message\RequestMatcher\RequestMatcher; -use Http\Mock\Client; use Nyholm\BundleTest\TestKernel; -use Psr\Http\Message\RequestInterface; -use Psr\Http\Message\ResponseInterface; -use Psr\Http\Message\StreamInterface; use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\HttpClient\MockHttpClient; +use Symfony\Component\HttpClient\Response\MockResponse; use Symfony\Component\HttpKernel\KernelInterface; final class PluginInteractionTest extends KernelTestCase @@ -40,6 +39,14 @@ protected static function createKernel(array $options = []): KernelInterface */ $kernel = parent::createKernel($options); $kernel->addTestBundle(BazingaGeocoderBundle::class); + $kernel->addTestCompilerPass(new class implements CompilerPassInterface { + public function process(ContainerBuilder $container): void + { + $container + ->getDefinition('http_client') + ->setPublic(true); + } + }); $kernel->handleOptions($options); return $kernel; @@ -61,27 +68,12 @@ public function testCachePluginUsesIpFromFakeIpPlugin(): void $kernel->setClearCacheAfterShutdown(false); $container = self::getContainer(); - $httpClient = $container->get(Client::class); - $httpClient->on(new RequestMatcher(), function (RequestInterface $request) { - if ('https://freegeoip.app/json/123.123.123.128' === (string) $request->getUri()) { - $stream = $this->createMock(StreamInterface::class); - $stream->expects(self::once()) - ->method('__toString') - ->willReturn('{"ip":"123.123.123.128","country_code":"CN","country_name":"China","region_code":"CN-BJ","region_name":"Beijing","city":"Beijing","zip_code":"100006","time_zone":"Asia\/Shanghai","latitude":39.907501220703125,"longitude":116.39710235595703,"metro_code":0}'); - - $response = $this->createMock(ResponseInterface::class); - $response->expects(self::once()) - ->method('getStatusCode') - ->willReturn(200); - $response->expects(self::once()) - ->method('getBody') - ->willReturn($stream); - - return $response; - } + $container->set('http_client', new MockHttpClient(static function (string $method, string $url): MockResponse { + self::assertSame('GET', $method); + self::assertSame('https://freegeoip.app/json/123.123.123.128', $url); - self::fail(sprintf('Unexpected http call "%s %s".', $request->getMethod(), (string) $request->getUri())); - }); + return new MockResponse('{"ip":"123.123.123.128","country_code":"CN","country_name":"China","region_code":"CN-BJ","region_name":"Beijing","city":"Beijing","zip_code":"100006","time_zone":"Asia\/Shanghai","latitude":39.907501220703125,"longitude":116.39710235595703,"metro_code":0}', ['response_headers' => ['content-type' => 'application-json']]); + })); $geoPluginGeocoder = $container->get('bazinga_geocoder.provider.geoPlugin'); $result = $geoPluginGeocoder->geocodeQuery(GeocodeQuery::create('::1')); @@ -102,27 +94,12 @@ public function testCachePluginUsesIpFromFakeIpPlugin(): void $kernel->setClearCacheAfterShutdown(false); $container = self::getContainer(); - $httpClient = $container->get(Client::class); - $httpClient->on(new RequestMatcher(), function (RequestInterface $request) { - if ('https://freegeoip.app/json/87.98.128.10' === (string) $request->getUri()) { - $stream = $this->createMock(StreamInterface::class); - $stream->expects(self::once()) - ->method('__toString') - ->willReturn('{"ip":"87.98.128.10","country_code":"FR","country_name":"France","region_code":null,"region_name":"Nord","city":"Roubaix","zip_code":"59100","time_zone":"Europe\/Paris","latitude":50.69371032714844,"longitude":3.174438953399658,"metro_code":0}'); - - $response = $this->createMock(ResponseInterface::class); - $response->expects(self::once()) - ->method('getStatusCode') - ->willReturn(200); - $response->expects(self::once()) - ->method('getBody') - ->willReturn($stream); - - return $response; - } + $container->set('http_client', new MockHttpClient(static function (string $method, string $url): MockResponse { + self::assertSame('GET', $method); + self::assertSame('https://freegeoip.app/json/87.98.128.10', $url); - self::fail(sprintf('Unexpected http call "%s %s".', $request->getMethod(), (string) $request->getUri())); - }); + return new MockResponse('{"ip":"87.98.128.10","country_code":"FR","country_name":"France","region_code":null,"region_name":"Nord","city":"Roubaix","zip_code":"59100","time_zone":"Europe\/Paris","latitude":50.69371032714844,"longitude":3.174438953399658,"metro_code":0}', ['response_headers' => ['content-type' => 'application-json']]); + })); $geoPluginGeocoder = $container->get('bazinga_geocoder.provider.geoPlugin'); $result = $geoPluginGeocoder->geocodeQuery(GeocodeQuery::create('::1')); diff --git a/tests/Functional/config/fakeip_with_cache_cn.yml b/tests/Functional/config/fakeip_with_cache_cn.yml index c9c0ee4..4c88e95 100644 --- a/tests/Functional/config/fakeip_with_cache_cn.yml +++ b/tests/Functional/config/fakeip_with_cache_cn.yml @@ -12,8 +12,3 @@ bazinga_geocoder: cache: 'app.simple_cache' cache_lifetime: 42 cache_precision: ~ - options: - http_client: '@Http\Mock\Client' - -services: - Http\Mock\Client: ~ diff --git a/tests/Functional/config/fakeip_with_cache_fr.yml b/tests/Functional/config/fakeip_with_cache_fr.yml index 0b7e85a..4aa3599 100644 --- a/tests/Functional/config/fakeip_with_cache_fr.yml +++ b/tests/Functional/config/fakeip_with_cache_fr.yml @@ -12,8 +12,3 @@ bazinga_geocoder: cache: 'app.simple_cache' cache_lifetime: 42 cache_precision: ~ - options: - http_client: '@Http\Mock\Client' - -services: - Http\Mock\Client: ~ diff --git a/tests/Functional/config/framework.yml b/tests/Functional/config/framework.yml index 47b05a2..97d232e 100644 --- a/tests/Functional/config/framework.yml +++ b/tests/Functional/config/framework.yml @@ -8,3 +8,5 @@ framework: storage_factory_id: session.storage.factory.native router: utf8: true + http_client: + enabled: true diff --git a/tests/Functional/config/listener.yml b/tests/Functional/config/listener.yml index 8fc0e6d..500d501 100644 --- a/tests/Functional/config/listener.yml +++ b/tests/Functional/config/listener.yml @@ -18,8 +18,3 @@ bazinga_geocoder: providers: acme: factory: Bazinga\GeocoderBundle\ProviderFactory\NominatimFactory - options: - http_client: '@Http\Mock\Client' - -services: - Http\Mock\Client: ~ diff --git a/tests/Functional/config/listener_php7.yml b/tests/Functional/config/listener_php7.yml index da02623..d13fa8c 100644 --- a/tests/Functional/config/listener_php7.yml +++ b/tests/Functional/config/listener_php7.yml @@ -15,7 +15,6 @@ bazinga_geocoder: acme: factory: Bazinga\GeocoderBundle\ProviderFactory\NominatimFactory options: - http_client: '@Http\Mock\Client' root_url: 'https://nominatim.openstreetmap.org' user_agent: 'geocoder-php test_suite' diff --git a/tests/Functional/config/listener_php8.yml b/tests/Functional/config/listener_php8.yml index 8673226..6057f6c 100644 --- a/tests/Functional/config/listener_php8.yml +++ b/tests/Functional/config/listener_php8.yml @@ -15,7 +15,6 @@ bazinga_geocoder: acme: factory: Bazinga\GeocoderBundle\ProviderFactory\NominatimFactory options: - http_client: '@Http\Mock\Client' root_url: 'https://nominatim.openstreetmap.org' user_agent: 'geocoder-php test_suite' diff --git a/tests/Validator/Constraint/AddressValidatorTest.php b/tests/Validator/Constraint/AddressValidatorTest.php index 268aa4a..be21135 100644 --- a/tests/Validator/Constraint/AddressValidatorTest.php +++ b/tests/Validator/Constraint/AddressValidatorTest.php @@ -15,11 +15,9 @@ use Bazinga\GeocoderBundle\Validator\Constraint\Address; use Bazinga\GeocoderBundle\Validator\Constraint\AddressValidator; use Geocoder\Provider\Nominatim\Nominatim; -use Http\Message\RequestMatcher\RequestMatcher; -use Http\Mock\Client; -use Psr\Http\Message\RequestInterface; -use Psr\Http\Message\ResponseInterface; -use Psr\Http\Message\StreamInterface; +use Symfony\Component\HttpClient\MockHttpClient; +use Symfony\Component\HttpClient\Psr18Client; +use Symfony\Component\HttpClient\Response\MockResponse; use Symfony\Component\Validator\Exception\UnexpectedValueException; use Symfony\Component\Validator\Test\ConstraintValidatorTestCase; @@ -27,47 +25,23 @@ final class AddressValidatorTest extends ConstraintValidatorTestCase { protected function createValidator(): AddressValidator { - $requestMatcher = new RequestMatcher('search', 'nominatim.openstreetmap.org', 'GET', 'https'); - - $httpClient = new Client(); - $httpClient->on($requestMatcher, function (RequestInterface $request) { - switch ((string) $request->getUri()) { - case 'https://nominatim.openstreetmap.org/search?format=jsonv2&q=Berlin%2C%20Germany&addressdetails=1&extratags=1&limit=5': - $stream = $this->createMock(StreamInterface::class); - $stream->expects(self::once()) - ->method('__toString') - ->willReturn('[{"place_id":159647018,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. http://osm.org/copyright","osm_type":"relation","osm_id":62422,"lat":"52.5170365","lon":"13.3888599","category":"boundary","type":"administrative","place_rank":8,"importance":0.7875390282491362,"addresstype":"city","name":"Berlin","display_name":"Berlin, Deutschland","address":{"city":"Berlin","ISO3166-2-lvl4":"DE-BE","country":"Deutschland","country_code":"de"},"extratags":{"ele": "35", "email": "info@berlin.de", "place": "city", "capital": "yes", "website": "http://www.berlin.de", "de:place": "city", "ref:nuts": "DE3;DE30;DE300", "wikidata": "Q64", "wikipedia": "de:Berlin", "population": "3769962", "ref:LOCODE": "DEBER", "ref:nuts:1": "DE3", "ref:nuts:2": "DE30", "ref:nuts:3": "DE300", "state_code": "BE", "name:prefix": "Land und Kreisfreie Stadt", "linked_place": "city", "official_status": "Land", "contact:facebook": "http://www.facebook.com/Berlin", "name:prefix:city": "Kreisfreie Stadt", "openGeoDB:loc_id": "14356", "capital_ISO3166-1": "yes", "name:prefix:state": "Land", "source:population": "https://download.statistik-berlin-brandenburg.de/fa93e3bd19a2e885/a5ecfb2fff6a/SB_A01-05-00_2020h02_BE.pdf", "license_plate_code": "B", "official_status:de": "Land", "official_status:en": "State", "official_status:ru": "земля", "geographical_region": "Barnim;Berliner Urstromtal;Teltow;Nauener Platte", "blind:description:de": "Auf www.berlinfuerblinde.de gibt es einen kostenlosen Audioguide und weitere Informationen.", "de:regionalschluessel": "110000000000", "openGeoDB:postal_codes": "10178,10115,10117,10119,10179,10243,10245,10247,10249,10315,10317,10318,10319,10365,10367,10369,10405,10407,10409,10435,10437,10439,10551,10553,10555,10557,10559,10585,10587,10589,10623,10625,10627,10629,10707,10709,10711,10713,10715,10717,10719,10777,10", "report_problems:website": "https://ordnungsamt.berlin.de/", "TMC:cid_58:tabcd_1:Class": "Area", "openGeoDB:license_plate_code": "B", "TMC:cid_58:tabcd_1:LCLversion": "12.0", "openGeoDB:telephone_area_code": "030", "TMC:cid_58:tabcd_1:LocationCode": "266", "de:amtlicher_gemeindeschluessel": "11000000", "openGeoDB:community_identification_number": "11000000"},"boundingbox":["52.3382448","52.6755087","13.0883450","13.7611609"]}]'); - - $response = $this->createMock(ResponseInterface::class); - $response->expects(self::once()) - ->method('getStatusCode') - ->willReturn(200); - $response->expects(self::once()) - ->method('getBody') - ->willReturn($stream); - - return $response; - case 'https://nominatim.openstreetmap.org/search?format=jsonv2&q=Bifrost%2C%20Nine%20Realms&addressdetails=1&extratags=1&limit=5': - $stream = $this->createMock(StreamInterface::class); - $stream->expects(self::once()) - ->method('__toString') - ->willReturn('[]'); - - $response = $this->createMock(ResponseInterface::class); - $response->expects(self::once()) - ->method('getStatusCode') - ->willReturn(200); - $response->expects(self::once()) - ->method('getBody') - ->willReturn($stream); - - return $response; + $httpClient = new MockHttpClient(static function (string $method, string $url) { + if ('https://nominatim.openstreetmap.org/search?format=jsonv2&q=Berlin%2C%20Germany&addressdetails=1&extratags=1&limit=5' === $url) { + self::assertSame('GET', $method); + + return new MockResponse('[{"place_id":159647018,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. http://osm.org/copyright","osm_type":"relation","osm_id":62422,"lat":"52.5170365","lon":"13.3888599","category":"boundary","type":"administrative","place_rank":8,"importance":0.7875390282491362,"addresstype":"city","name":"Berlin","display_name":"Berlin, Deutschland","address":{"city":"Berlin","ISO3166-2-lvl4":"DE-BE","country":"Deutschland","country_code":"de"},"extratags":{"ele": "35", "email": "info@berlin.de", "place": "city", "capital": "yes", "website": "http://www.berlin.de", "de:place": "city", "ref:nuts": "DE3;DE30;DE300", "wikidata": "Q64", "wikipedia": "de:Berlin", "population": "3769962", "ref:LOCODE": "DEBER", "ref:nuts:1": "DE3", "ref:nuts:2": "DE30", "ref:nuts:3": "DE300", "state_code": "BE", "name:prefix": "Land und Kreisfreie Stadt", "linked_place": "city", "official_status": "Land", "contact:facebook": "http://www.facebook.com/Berlin", "name:prefix:city": "Kreisfreie Stadt", "openGeoDB:loc_id": "14356", "capital_ISO3166-1": "yes", "name:prefix:state": "Land", "source:population": "https://download.statistik-berlin-brandenburg.de/fa93e3bd19a2e885/a5ecfb2fff6a/SB_A01-05-00_2020h02_BE.pdf", "license_plate_code": "B", "official_status:de": "Land", "official_status:en": "State", "official_status:ru": "земля", "geographical_region": "Barnim;Berliner Urstromtal;Teltow;Nauener Platte", "blind:description:de": "Auf www.berlinfuerblinde.de gibt es einen kostenlosen Audioguide und weitere Informationen.", "de:regionalschluessel": "110000000000", "openGeoDB:postal_codes": "10178,10115,10117,10119,10179,10243,10245,10247,10249,10315,10317,10318,10319,10365,10367,10369,10405,10407,10409,10435,10437,10439,10551,10553,10555,10557,10559,10585,10587,10589,10623,10625,10627,10629,10707,10709,10711,10713,10715,10717,10719,10777,10", "report_problems:website": "https://ordnungsamt.berlin.de/", "TMC:cid_58:tabcd_1:Class": "Area", "openGeoDB:license_plate_code": "B", "TMC:cid_58:tabcd_1:LCLversion": "12.0", "openGeoDB:telephone_area_code": "030", "TMC:cid_58:tabcd_1:LocationCode": "266", "de:amtlicher_gemeindeschluessel": "11000000", "openGeoDB:community_identification_number": "11000000"},"boundingbox":["52.3382448","52.6755087","13.0883450","13.7611609"]}]', ['response_headers' => ['content-type' => 'application-json']]); + } + + if ('https://nominatim.openstreetmap.org/search?format=jsonv2&q=Bifrost%2C%20Nine%20Realms&addressdetails=1&extratags=1&limit=5' === $url) { + self::assertSame('GET', $method); + + return new MockResponse('[]', ['response_headers' => ['content-type' => 'application-json']]); } - self::fail(sprintf('Unexpected http call "%s %s".', $request->getMethod(), (string) $request->getUri())); + self::fail(sprintf('Unexpected http call "%s %s".', $method, $url)); }); - $geocoder = Nominatim::withOpenStreetMapServer($httpClient, 'BazingaGeocoderBundle/Test'); + $geocoder = Nominatim::withOpenStreetMapServer(new Psr18Client($httpClient), 'BazingaGeocoderBundle/Test'); return new AddressValidator($geocoder); }