Skip to content
This repository has been archived by the owner on Aug 13, 2019. It is now read-only.

Commit

Permalink
Merge pull request #47 from cultuurnet/feature/III-2906
Browse files Browse the repository at this point in the history
Add request parser for geo bounds
  • Loading branch information
bertramakers committed May 7, 2019
2 parents 928dd62 + e290c03 commit 77f88b9
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 0 deletions.
58 changes: 58 additions & 0 deletions src/Offer/RequestParser/GeoBoundsOfferRequestParser.php
@@ -0,0 +1,58 @@
<?php

namespace CultuurNet\UDB3\Search\Http\Offer\RequestParser;

use CultuurNet\Geocoding\Coordinate\Coordinates;
use CultuurNet\Geocoding\Coordinate\Latitude;
use CultuurNet\Geocoding\Coordinate\Longitude;
use CultuurNet\UDB3\Search\DistanceFactoryInterface;
use CultuurNet\UDB3\Search\GeoBoundsParameters;
use CultuurNet\UDB3\Search\GeoDistanceParameters;
use CultuurNet\UDB3\Search\Offer\OfferQueryBuilderInterface;
use Symfony\Component\HttpFoundation\Request;

class GeoBoundsOfferRequestParser implements OfferRequestParserInterface
{
private const BOUNDS_REGEX = '([0-9\.-]+),([0-9\.-]+)\|([0-9\.-]+),([0-9\.-]+)';

/**
* @param Request $request
* @param OfferQueryBuilderInterface $offerQueryBuilder
* @return OfferQueryBuilderInterface
*/
public function parse(Request $request, OfferQueryBuilderInterface $offerQueryBuilder)
{
$bounds = $request->query->get('bounds', false);
if (!$bounds) {
return $offerQueryBuilder;
}

$matches = [];
if (!preg_match('/' . self::BOUNDS_REGEX . '/', $bounds, $matches)) {
throw new \InvalidArgumentException(
'Bounds parameter should be in the "southWestLat,southWestLong|northEastLat,NorthEastLong" format.'
);
}

$southWestLat = (float) $matches[1];
$southWestLong = (float) $matches[2];
$northEastLat = (float) $matches[3];
$northEastLong = (float) $matches[4];

$southWest = new Coordinates(
new Latitude($southWestLat),
new Longitude($southWestLong)
);

$northEast = new Coordinates(
new Latitude($northEastLat),
new Longitude($northEastLong)
);

$offerQueryBuilder = $offerQueryBuilder->withGeoBoundsFilter(
new GeoBoundsParameters($northEast, $southWest)
);

return $offerQueryBuilder;
}
}
1 change: 1 addition & 0 deletions src/Parameters/OfferParameterWhiteList.php
Expand Up @@ -21,6 +21,7 @@ protected function getParameterWhiteList()
'regions',
'coordinates',
'distance',
'bounds',
'postalCode',
'addressCountry',
'minAge',
Expand Down
88 changes: 88 additions & 0 deletions tests/Offer/RequestParser/GeoBoundsOfferRequestParserTest.php
@@ -0,0 +1,88 @@
<?php

declare(strict_types=1);

namespace CultuurNet\UDB3\Search\Http\Offer\RequestParser;

use CultuurNet\Geocoding\Coordinate\Coordinates;
use CultuurNet\Geocoding\Coordinate\Latitude;
use CultuurNet\Geocoding\Coordinate\Longitude;
use CultuurNet\UDB3\Search\GeoBoundsParameters;
use CultuurNet\UDB3\Search\Offer\OfferQueryBuilderInterface;
use InvalidArgumentException;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;

final class GeoBoundsOfferRequestParserTest extends TestCase
{
/**
* @var GeoBoundsOfferRequestParser
*/
private $parser;

/**
* @var OfferQueryBuilderInterface|\PHPUnit_Framework_MockObject_MockObject
*/
private $offerQueryBuilder;

protected function setUp()
{
$this->parser = new GeoBoundsOfferRequestParser();
$this->offerQueryBuilder = $this->createMock(OfferQueryBuilderInterface::class);
}

/**
* @test
*/
public function it_should_not_add_a_bounds_filter_if_no_bounds_parameter_is_given()
{
$request = new Request([]);

$this->offerQueryBuilder->expects($this->never())
->method('withGeoBoundsFilter');

$this->parser->parse($request, $this->offerQueryBuilder);
}

/**
* @test
*/
public function it_should_throw_an_exception_if_the_bounds_parameter_value_is_invalid()
{
$this->expectException(InvalidArgumentException::class);
$request = new Request(['bounds' => '34.172684,-118.604794,34.236144,-118.500938']);
$this->parser->parse($request, $this->offerQueryBuilder);
}

/**
* @test
*/
public function it_should_add_a_bounds_filter_if_a_valid_bounds_parameter_is_given()
{
$request = new Request(
[
'bounds' => '34.172684,-118.604794|34.236144,-118.500938', // South-West | North-East
]
);

$this->offerQueryBuilder->expects($this->once())
->method('withGeoBoundsFilter')
->with(
new GeoBoundsParameters(
// North-East
new Coordinates(
new Latitude(34.236144),
new Longitude(-118.500938)
),
// South-West
new Coordinates(
new Latitude(34.172684),
new Longitude(-118.604794)
)
)
)
->willReturn($this->offerQueryBuilder);

$this->parser->parse($request, $this->offerQueryBuilder);
}
}

0 comments on commit 77f88b9

Please sign in to comment.