Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down
5 changes: 3 additions & 2 deletions tests/DependencyInjection/Compiler/AddProvidersPassTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand All @@ -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);
Expand Down
19 changes: 18 additions & 1 deletion tests/Functional/CustomTestKernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;

Expand Down Expand Up @@ -93,6 +95,21 @@ public function setAnnotatedClassCache(array $annotatedClasses): void
file_put_contents(($this->warmupDir ?: $this->getBuildDir()).'/annotations.map', sprintf('<?php return %s;', var_export($annotatedClasses, true)));
}

// Can be removed after dropping Symfony 5.4
public function process(ContainerBuilder $container): void
{
$container
->getDefinition('http_client')
->setPublic(true);
}

protected function build(ContainerBuilder $container): void
{
parent::build($container);

$container->addCompilerPass($this);
}

/**
* Initializes the service container.
*
Expand Down
170 changes: 55 additions & 115 deletions tests/Functional/GeocoderListenerTest.php

Large diffs are not rendered by default.

67 changes: 22 additions & 45 deletions tests/Functional/PluginInteractionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
Expand All @@ -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'));
Expand All @@ -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'));
Expand Down
5 changes: 0 additions & 5 deletions tests/Functional/config/fakeip_with_cache_cn.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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: ~
5 changes: 0 additions & 5 deletions tests/Functional/config/fakeip_with_cache_fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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: ~
2 changes: 2 additions & 0 deletions tests/Functional/config/framework.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ framework:
storage_factory_id: session.storage.factory.native
router:
utf8: true
http_client:
enabled: true
5 changes: 0 additions & 5 deletions tests/Functional/config/listener.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,3 @@ bazinga_geocoder:
providers:
acme:
factory: Bazinga\GeocoderBundle\ProviderFactory\NominatimFactory
options:
http_client: '@Http\Mock\Client'

services:
Http\Mock\Client: ~
1 change: 0 additions & 1 deletion tests/Functional/config/listener_php7.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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'

Expand Down
1 change: 0 additions & 1 deletion tests/Functional/config/listener_php8.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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'

Expand Down
58 changes: 16 additions & 42 deletions tests/Validator/Constraint/AddressValidatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,59 +15,33 @@
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;

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);
}
Expand Down