From 3c417b103c4185a834ccbe6bb0ec1d29e4766c48 Mon Sep 17 00:00:00 2001 From: Yevhenii Kovalenko Date: Thu, 1 Feb 2024 08:21:01 +0100 Subject: [PATCH] Added support for Italy parcel points --- src/Client/Client.php | 12 +- src/Command/FindPoints.php | 30 +++-- src/ConfigProvider.php | 11 -- .../DeliveryCountryInterface.php | 10 ++ src/DeliveryCountry/DeliveryItaly.php | 19 +++ src/DeliveryCountry/DeliveryPoland.php | 19 +++ src/Enum/PointType.php | 1 + src/Response/FindPointsResponse.php | 2 +- tests/Integration/Command/FindPointsTest.php | 82 ++++++++++-- .../Command/data/exampleResponse.json | 68 ---------- .../Command/data/exampleResponse_Italy.json | 126 ++++++++++++++++++ .../Command/data/exampleResponse_Poland.json | 68 ++++++++++ 12 files changed, 334 insertions(+), 114 deletions(-) delete mode 100644 src/ConfigProvider.php create mode 100644 src/DeliveryCountry/DeliveryCountryInterface.php create mode 100644 src/DeliveryCountry/DeliveryItaly.php create mode 100644 src/DeliveryCountry/DeliveryPoland.php delete mode 100644 tests/Integration/Command/data/exampleResponse.json create mode 100644 tests/Integration/Command/data/exampleResponse_Italy.json create mode 100644 tests/Integration/Command/data/exampleResponse_Poland.json diff --git a/src/Client/Client.php b/src/Client/Client.php index 7abedb6..585ca04 100644 --- a/src/Client/Client.php +++ b/src/Client/Client.php @@ -4,7 +4,6 @@ namespace Answear\InpostBundle\Client; -use Answear\InpostBundle\ConfigProvider; use Answear\InpostBundle\Exception\ServiceUnavailableException; use GuzzleHttp\Client as GuzzleClient; use GuzzleHttp\ClientInterface; @@ -16,14 +15,9 @@ class Client { private ClientInterface $client; - public function __construct( - ?ClientInterface $client = null, - ) { - $this->client = $client ?? new GuzzleClient( - [ - 'base_uri' => ConfigProvider::BASE_URL, - ] - ); + public function __construct(?ClientInterface $client = null) + { + $this->client = $client ?? new GuzzleClient(); } public function request(Request $request): ResponseInterface diff --git a/src/Command/FindPoints.php b/src/Command/FindPoints.php index b21634c..7b96146 100644 --- a/src/Command/FindPoints.php +++ b/src/Command/FindPoints.php @@ -6,7 +6,7 @@ use Answear\InpostBundle\Client\Client; use Answear\InpostBundle\Client\Serializer; -use Answear\InpostBundle\ConfigProvider; +use Answear\InpostBundle\DeliveryCountry\DeliveryCountryInterface; use Answear\InpostBundle\Request\FindPointsRequest; use Answear\InpostBundle\Response\FindPointsResponse; use GuzzleHttp\Psr7\Request as HttpRequest; @@ -14,20 +14,28 @@ class FindPoints extends AbstractCommand { - private Client $client; - private Serializer $serializer; - - public function __construct(Client $client, Serializer $serializer) - { - $this->client = $client; - $this->serializer = $serializer; + public function __construct( + private Client $client, + private Serializer $serializer, + ) { } - public function findPoints(FindPointsRequest $request): FindPointsResponse - { + public function findPoints( + DeliveryCountryInterface $deliveryCountry, + FindPointsRequest $request, + ): FindPointsResponse { + $url = new Uri( + sprintf( + '%s%s%s', + $deliveryCountry->getEndpoint(), + $deliveryCountry->getApiVersion(), + $request->getRequestUrl() + ) + ); + $httpRequest = new HttpRequest( $request->getMethod(), - new Uri(ConfigProvider::API_VERSION . $request->getRequestUrl()), + $url, [ 'Content-type' => 'application/json', ], diff --git a/src/ConfigProvider.php b/src/ConfigProvider.php deleted file mode 100644 index 15ca236..0000000 --- a/src/ConfigProvider.php +++ /dev/null @@ -1,11 +0,0 @@ - Item::fromArray($pointData), + static fn($pointData) => Item::fromArray($pointData), $arrayResponse['items'] ) ), diff --git a/tests/Integration/Command/FindPointsTest.php b/tests/Integration/Command/FindPointsTest.php index 802c4a4..919967a 100644 --- a/tests/Integration/Command/FindPointsTest.php +++ b/tests/Integration/Command/FindPointsTest.php @@ -7,6 +7,9 @@ use Answear\InpostBundle\Client\Client; use Answear\InpostBundle\Client\Serializer; use Answear\InpostBundle\Command\FindPoints; +use Answear\InpostBundle\DeliveryCountry\DeliveryCountryInterface; +use Answear\InpostBundle\DeliveryCountry\DeliveryItaly; +use Answear\InpostBundle\DeliveryCountry\DeliveryPoland; use Answear\InpostBundle\Enum\PointFunctionsType; use Answear\InpostBundle\Enum\PointType; use Answear\InpostBundle\Request\FindPointsRequest; @@ -25,6 +28,9 @@ class FindPointsTest extends TestCase private Client $client; + private const POLAND = 'Poland'; + private const ITALY = 'Italy'; + public function setUp(): void { parent::setUp(); @@ -34,20 +40,25 @@ public function setUp(): void /** * @test + * @dataProvider getCountries */ - public function successfulFindPoints(): void + public function successfulFindPoints(DeliveryCountryInterface $deliveryCountry, string $countryCode): void { $command = $this->getCommand(); - $this->mockGuzzleResponse(new Response(200, [], $this->getSuccessfulBody())); - $response = $command->findPoints(new FindPointsRequest()); + $responseFile = file_get_contents(__DIR__ . sprintf('/data/exampleResponse_%s.json', $countryCode)); + + $this->mockGuzzleResponse(new Response(200, [], $responseFile)); + + $response = $command->findPoints($deliveryCountry, new FindPointsRequest()); $this->assertCount(1, $response->getItems()); $this->assertSame(1, $response->getTotalItemsCount()); - $this->assertPoint($response); + + call_user_func([$this, 'assertPointFor' . $countryCode], $response); } - private function assertPoint(FindPointsResponse $response): void + private function assertPointForPoland(FindPointsResponse $response): void { /** @var Item $point */ $point = $response->getItems()->get(0); @@ -66,7 +77,6 @@ private function assertPoint(FindPointsResponse $response): void $this->assertNull($point->locationDescription2); $this->assertNull($point->distance); $this->assertSame($point->openingHours, '24/7'); - $this->assertSame($point->openingHours, '24/7'); $this->assertInstanceOf(ItemAddress::class, $point->address); $this->assertSame($point->address->line1, 'Kościuszki 27'); $this->assertSame($point->address->line2, '21-412 Adamów'); @@ -89,17 +99,61 @@ private function assertPoint(FindPointsResponse $response): void $this->assertTrue($point->location247); } - private function getCommand(): FindPoints + private function assertPointForItaly(FindPointsResponse $response): void { - return new FindPoints($this->client, new Serializer()); + /** @var Item $point */ + $point = $response->getItems()->get(0); + + $this->assertNotNull($point); + $this->assertSame($point->id, 'ITAAQ01570P'); + $this->assertSame($point->name, 'ITAAQ01570P'); + $this->assertSame($point->type, [PointType::Pok, PointType::Pop]); + $this->assertSame($point->status, 'Operating'); + $this->assertInstanceOf(ItemLocation::class, $point->location); + $this->assertSame($point->location->longitude, 13.47289); + $this->assertSame($point->location->latitude, 42.35751); + $this->assertSame($point->locationType, 'Indoor'); + $this->assertSame($point->locationDescription, 'presso Dottor Tech'); + $this->assertNull($point->locationDescription1); + $this->assertNull($point->locationDescription2); + $this->assertNull($point->distance); + $this->assertSame($point->openingHours, 'Lun-Ven: 10:00 - 13:00 - 16:00 - 19:00 '); + $this->assertInstanceOf(ItemAddress::class, $point->address); + $this->assertSame($point->address->line1, 'Via Ten. Antonio Rossi Tascione in Str. Vicinale di Paganica 7'); + $this->assertSame($point->address->line2, '67100 L\'Aquila'); + $this->assertInstanceOf(ItemAddressDetails::class, $point->addressDetails); + $this->assertSame($point->addressDetails->city, 'L\'Aquila'); + $this->assertSame($point->addressDetails->province, 'AQ'); + $this->assertSame($point->addressDetails->postCode, '67100'); + $this->assertSame($point->addressDetails->street, 'Via Ten. Antonio Rossi Tascione in Str. Vicinale di Paganica'); + $this->assertSame($point->addressDetails->buildingNumber, '7'); + $this->assertNull($point->addressDetails->flatNumber); + $this->assertNull($point->phoneNumber); + $this->assertSame($point->paymentPointDescr, ''); + $this->assertSame($point->functions, [ + PointFunctionsType::Parcel, + PointFunctionsType::ParcelCollect, + PointFunctionsType::ParcelReverseReturnSend, + PointFunctionsType::ParcelSend, + PointFunctionsType::StandardCourierSend, + ]); + $this->assertSame($point->partnerId, 1); + $this->assertFalse($point->isNext); + $this->assertTrue($point->paymentAvailable); + $this->assertSame($point->paymentType, ['3' => 'Payment by cash and card']); + $this->assertSame($point->virtual, '3'); + $this->assertNull($point->recommendedLowInterestBoxMachinesList); + $this->assertFalse($point->location247); } - private function getSuccessfulBody(): string + private function getCountries(): \Generator { - try { - return file_get_contents(__DIR__ . '/data/exampleResponse.json'); - } catch (\Throwable) { - throw new \RuntimeException('Cannot read example response file'); - } + yield 'Poland' => [new DeliveryPoland(), self::POLAND]; + yield 'Italy' => [new DeliveryItaly(), self::ITALY]; + } + + private function getCommand(): FindPoints + { + return new FindPoints($this->client, new Serializer()); } } diff --git a/tests/Integration/Command/data/exampleResponse.json b/tests/Integration/Command/data/exampleResponse.json deleted file mode 100644 index 4f3bb30..0000000 --- a/tests/Integration/Command/data/exampleResponse.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "href": "https://api-pl-points.easypack24.net/v1/points", - "count": 1, - "page": 1, - "per_page": 25, - "total_pages": 1, - "items": [ - { - "href": "https://api-pl-points.easypack24.net/v1/points/ADA01M", - "name": "ADA01M", - "type": [ - "parcel_locker" - ], - "status": "Operating", - "location": { - "longitude": 22.264049625, - "latitude": 51.73834066 - }, - "location_type": "Outdoor", - "location_date": null, - "location_description": "Przy sklepie Lewiatan", - "location_description_1": null, - "location_description_2": null, - "distance": null, - "opening_hours": "24/7", - "address": { - "line1": "Kościuszki 27", - "line2": "21-412 Adamów" - }, - "address_details": { - "city": "Adamów", - "province": "lubelskie", - "post_code": "21-412", - "street": "Kościuszki", - "building_number": "27", - "flat_number": null - }, - "phone_number": null, - "payment_point_descr": "Płatność internetowa PayByLink oraz Blik", - "functions": [ - "parcel_collect", - "parcel_send" - ], - "partner_id": 0, - "is_next": false, - "payment_available": true, - "payment_type": { - "0": "Payments are not supported" - }, - "virtual": "0", - "recommended_low_interest_box_machines_list": null, - "apm_doubled": null, - "location_247": true, - "operating_hours_extended": { - "customer": null - }, - "agency": "IPM4633224", - "image_url": "https://static.easypack24.net/points/pl/images/ADA01M.jpg" - } - ], - "meta": { - "href": "https://api-pl-points.easypack24.net/v1/points", - "count": 1, - "page": 1, - "per_page": 25, - "total_pages": 1 - } -} \ No newline at end of file diff --git a/tests/Integration/Command/data/exampleResponse_Italy.json b/tests/Integration/Command/data/exampleResponse_Italy.json new file mode 100644 index 0000000..b914af2 --- /dev/null +++ b/tests/Integration/Command/data/exampleResponse_Italy.json @@ -0,0 +1,126 @@ +{ + "href": "https://api-it-points.easypack24.net/v1/points", + "count": 1, + "page": 1, + "per_page": 25, + "total_pages": 1, + "items": [ + { + "href": "https://api-it-points.easypack24.net/v1/points/ITAAQ01570P", + "name": "ITAAQ01570P", + "type": [ + "pok", + "pop" + ], + "status": "Operating", + "location": { + "longitude": 13.47289, + "latitude": 42.35751 + }, + "location_type": "Indoor", + "location_date": null, + "location_description": "presso Dottor Tech", + "location_description_1": null, + "location_description_2": null, + "distance": null, + "opening_hours": "Lun-Ven: 10:00 - 13:00 - 16:00 - 19:00 ", + "address": { + "line1": "Via Ten. Antonio Rossi Tascione in Str. Vicinale di Paganica 7", + "line2": "67100 L'Aquila" + }, + "address_details": { + "city": "L'Aquila", + "province": "AQ", + "post_code": "67100", + "street": "Via Ten. Antonio Rossi Tascione in Str. Vicinale di Paganica", + "building_number": "7", + "flat_number": null + }, + "phone_number": null, + "payment_point_descr": "", + "functions": [ + "parcel", + "parcel_collect", + "parcel_reverse_return_send", + "parcel_send", + "standard_courier_send" + ], + "partner_id": 1, + "is_next": false, + "payment_available": true, + "payment_type": { + "3": "Payment by cash and card" + }, + "virtual": "3", + "recommended_low_interest_box_machines_list": null, + "apm_doubled": null, + "location_247": false, + "operating_hours_extended": { + "customer": { + "monday": [ + { + "start": 600, + "end": 780 + }, + { + "start": 960, + "end": 1140 + } + ], + "tuesday": [ + { + "start": 600, + "end": 780 + }, + { + "start": 960, + "end": 1140 + } + ], + "wednesday": [ + { + "start": 600, + "end": 780 + }, + { + "start": 960, + "end": 1140 + } + ], + "thursday": [ + { + "start": 600, + "end": 780 + }, + { + "start": 960, + "end": 1140 + } + ], + "friday": [ + { + "start": 600, + "end": 780 + }, + { + "start": 960, + "end": 1140 + } + ], + "saturday": [], + "sunday": [] + } + }, + "agency": "PES", + "image_url": "https://static.easypack24.net/points/it/images/ITAAQ01570P.jpg", + "easy_access_zone": false + } + ], + "meta": { + "href": "https://api-it-points.easypack24.net/v1/points", + "count": 6834, + "page": 1, + "per_page": 25, + "total_pages": 274 + } +} \ No newline at end of file diff --git a/tests/Integration/Command/data/exampleResponse_Poland.json b/tests/Integration/Command/data/exampleResponse_Poland.json new file mode 100644 index 0000000..003ab0e --- /dev/null +++ b/tests/Integration/Command/data/exampleResponse_Poland.json @@ -0,0 +1,68 @@ +{ + "href": "https://api-pl-points.easypack24.net/v1/points", + "count": 1, + "page": 1, + "per_page": 25, + "total_pages": 1, + "items": [ + { + "href": "https://api-pl-points.easypack24.net/v1/points/ADA01M", + "name": "ADA01M", + "type": [ + "parcel_locker" + ], + "status": "Operating", + "location": { + "longitude": 22.264049625, + "latitude": 51.73834066 + }, + "location_type": "Outdoor", + "location_date": null, + "location_description": "Przy sklepie Lewiatan", + "location_description_1": null, + "location_description_2": null, + "distance": null, + "opening_hours": "24/7", + "address": { + "line1": "Kościuszki 27", + "line2": "21-412 Adamów" + }, + "address_details": { + "city": "Adamów", + "province": "lubelskie", + "post_code": "21-412", + "street": "Kościuszki", + "building_number": "27", + "flat_number": null + }, + "phone_number": null, + "payment_point_descr": "Płatność internetowa PayByLink oraz Blik", + "functions": [ + "parcel_collect", + "parcel_send" + ], + "partner_id": 0, + "is_next": false, + "payment_available": true, + "payment_type": { + "0": "Payments are not supported" + }, + "virtual": "0", + "recommended_low_interest_box_machines_list": null, + "apm_doubled": null, + "location_247": true, + "operating_hours_extended": { + "customer": null + }, + "agency": "IPM4633224", + "image_url": "https://static.easypack24.net/points/pl/images/ADA01M.jpg" + } + ], + "meta": { + "href": "https://api-pl-points.easypack24.net/v1/points", + "count": 1, + "page": 1, + "per_page": 25, + "total_pages": 1 + } +} \ No newline at end of file