Skip to content

Commit 9c38cd7

Browse files
authored
Merge pull request #3 from Vendic/feature/improve-address-extraction
Improve address extraction and add tests
2 parents 43a3677 + 5136314 commit 9c38cd7

File tree

4 files changed

+195
-69
lines changed

4 files changed

+195
-69
lines changed

.github/workflows/integration.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
name: Integration Test
2+
3+
on: [push]
4+
5+
jobs:
6+
compute_matrix:
7+
runs-on: ubuntu-latest
8+
outputs:
9+
matrix: ${{ steps.supported-version.outputs.matrix }}
10+
steps:
11+
- uses: mage-os/github-actions/supported-version@main
12+
id: supported-version
13+
with:
14+
kind: latest
15+
- run: echo ${{ steps.supported-version.outputs.matrix }}
16+
17+
integration-workflow:
18+
needs: compute_matrix
19+
uses: mage-os/github-actions/.github/workflows/integration.yaml@main
20+
with:
21+
package_name: vendic/magento2-postnl-api
22+
matrix: ${{ needs.compute_matrix.outputs.matrix }}
23+
test_command: ../../../vendor/bin/phpunit ../../../vendor/vendic/magento2-postnl-api/Test/Integration
24+
fail-fast: false
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<?php declare(strict_types=1);
2+
/**
3+
* @copyright Copyright (c) Vendic B.V https://vendic.nl/
4+
*/
5+
6+
namespace Vendic\PostnlApi\Test\Integration\RequestBuilder;
7+
8+
use Magento\Framework\ObjectManagerInterface;
9+
use Magento\TestFramework\Helper\Bootstrap;
10+
use Magento\Quote\Model\Quote\Address as QuoteAddress;
11+
use PHPUnit\Framework\TestCase;
12+
use Vendic\PostnlApi\Api\Data\PostnlRequestInterface;
13+
use Vendic\PostnlApi\Utils\RequestBuilder;
14+
15+
class LocationsRequestTest extends TestCase
16+
{
17+
public function testForAddressWithAddition(): void
18+
{
19+
$quoteAddress = $this->buildQuoteAddress(
20+
[
21+
'street' => "Nederlandsestraat\n15\nB",
22+
'postcode' => '1234AB',
23+
'city' => 'Deventer',
24+
'country_id' => 'NL'
25+
]
26+
);
27+
28+
$request = $this->buildRequestForQuoteAddress($quoteAddress);
29+
30+
$this->assertEquals('NL', $request->getAddress()['country']);
31+
$this->assertEquals('Nederlandsestraat', $request->getAddress()['street']);
32+
$this->assertEquals('1234AB', $request->getAddress()['postcode']);
33+
$this->assertEquals('15 B', $request->getAddress()['housenumber']);
34+
}
35+
36+
public function testForAddressWithoutAddition(): void
37+
{
38+
$quoteAddress = $this->buildQuoteAddress(
39+
[
40+
'street' => "Nederlandsestraat\n15",
41+
'postcode' => '1234AB',
42+
'city' => 'Deventer',
43+
'country_id' => 'NL'
44+
]
45+
);
46+
47+
$request = $this->buildRequestForQuoteAddress($quoteAddress);
48+
49+
$this->assertEquals('NL', $request->getAddress()['country']);
50+
$this->assertEquals('Nederlandsestraat', $request->getAddress()['street']);
51+
$this->assertEquals('1234AB', $request->getAddress()['postcode']);
52+
$this->assertEquals('15', $request->getAddress()['housenumber']);
53+
}
54+
55+
public function testWithStreetArray(): void
56+
{
57+
$quoteAddress = $this->buildQuoteAddress(
58+
[
59+
'street' => [
60+
'Nederlandsestraat',
61+
'15',
62+
'B'
63+
],
64+
'postcode' => '1234AB',
65+
'city' => 'Deventer',
66+
'country_id' => 'NL'
67+
]
68+
);
69+
70+
$request = $this->buildRequestForQuoteAddress($quoteAddress);
71+
72+
$this->assertEquals('NL', $request->getAddress()['country']);
73+
$this->assertEquals('Nederlandsestraat', $request->getAddress()['street']);
74+
$this->assertEquals('1234AB', $request->getAddress()['postcode']);
75+
$this->assertEquals('15 B', $request->getAddress()['housenumber']);
76+
}
77+
78+
public function testWithSingleLineStreet() : void
79+
{
80+
$quoteAddress = $this->buildQuoteAddress(
81+
[
82+
'street' => '1e Nederlandsestraat 15 B',
83+
'postcode' => '1234AB',
84+
'city' => 'Deventer',
85+
'country_id' => 'NL'
86+
]
87+
);
88+
89+
$request = $this->buildRequestForQuoteAddress($quoteAddress);
90+
91+
$this->assertEquals('NL', $request->getAddress()['country']);
92+
$this->assertEquals('1e Nederlandsestraat', $request->getAddress()['street']);
93+
$this->assertEquals('1234AB', $request->getAddress()['postcode']);
94+
$this->assertEquals('15 B', $request->getAddress()['housenumber']);
95+
}
96+
97+
private function buildQuoteAddress(array $data): QuoteAddress
98+
{
99+
return Bootstrap::getObjectManager()->create(QuoteAddress::class, ['data' => $data]);
100+
}
101+
102+
private function buildRequestForQuoteAddress(QuoteAddress $quoteAddress): PostnlRequestInterface
103+
{
104+
$objectManager = Bootstrap::getObjectManager();
105+
106+
$requestBuilder = $objectManager->get(RequestBuilder::class);
107+
return $requestBuilder->buildForLocations($quoteAddress);
108+
}
109+
110+
}

Test/Integration/RequestBuilderTest.php

Lines changed: 0 additions & 42 deletions
This file was deleted.

Utils/RequestBuilder.php

Lines changed: 61 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,9 @@ public function buildForPickupSave(Address $billingAddress, LocationInterface $l
6868
// Extract street and housenumber from street array
6969
/** @var string|array $street */
7070
$street = $billingAddress->getStreet();
71-
$streetString = is_array($street) ?
72-
implode(' ', $street) :
73-
$street;
74-
$streetWithoutNumber = preg_match('/^(.*?)(?=\d)/', $streetString, $matches) ? $matches[0] : $streetString;
75-
$houseNumber = preg_match('/\d(.*)/', $streetString, $matches) ? $matches[0] : '';
71+
72+
$streetWithoutNumber = $this->getStreetWithoutHouseNumber($billingAddress);
73+
$houseNumber = $this->getHousenumber($billingAddress);
7674

7775
// Customer data
7876
$request->setCustomerData(
@@ -123,15 +121,9 @@ public function buildForDeliverySave(
123121
// Extract street and housenumber from street array
124122
/** @var string|array $street */
125123
$street = $shippingAddress->getStreet();
126-
$streetString = is_array($street) ?
127-
implode(' ', $street) :
128-
$street;
129-
$streetWithoutNumber = preg_match('/^(.*?)(?=\d)/', $streetString, $matches) ?
130-
$matches[0] :
131-
$streetString;
132-
$houseNumber = preg_match('/\d(.*)/', $streetString, $matches) ?
133-
$matches[0] :
134-
'';
124+
125+
$streetWithoutNumber = $this->getStreetWithoutHouseNumber($shippingAddress);
126+
$houseNumber = $this->getHousenumber($shippingAddress);
135127

136128
$request->setAddress(
137129
[
@@ -178,23 +170,13 @@ public function buildForLocations(Address $shippingAddress): PostnlRequestInterf
178170
/** @var string|array $street */
179171
$street = $shippingAddress->getStreet();
180172

181-
$streetWithoutNumber = '';
182-
$houseNumber = '';
183-
if (is_array($street) && count($street) >= 2) {
184-
$street = array_values(array_filter($street));
185-
$streetWithoutNumber = $street[0] ?? '';
186-
$houseNumber = $street[1] ?? '';
187-
}
188-
189-
if (is_string($street)) {
190-
$streetWithoutNumber = preg_match('/^(.*?)(?=\d)/', $street, $matches) ? $matches[0] : $street;
191-
$houseNumber = preg_match('/\d(.*)/', $street, $matches) ? $matches[0] : '';
192-
}
173+
$streetWithoutNumber = $this->getStreetWithoutHouseNumber($shippingAddress);
174+
$houseNumber = $this->getHousenumber($shippingAddress);
193175

194176
// Location address data
195177
$request->setAddress([
196178
'country' => $shippingAddress->getCountryId(),
197-
'street' => trim((string) $streetWithoutNumber),
179+
'street' => $streetWithoutNumber,
198180
'postcode' => $shippingAddress->getPostcode(),
199181
'housenumber' => $houseNumber,
200182
'firstname' => $shippingAddress->getFirstname(),
@@ -223,4 +205,56 @@ public function buildforTimeframes(Address $address): PostnlRequestInterface
223205
// The request for timeframes is identical to locations.
224206
return $this->buildForLocations($address);
225207
}
208+
209+
private function getStreetWithoutHouseNumber(Address $address): string
210+
{
211+
$street = $address->getStreet();
212+
if (!is_array($street)) {
213+
throw new LocalizedException(__('Street should be an array'));
214+
}
215+
216+
// Get the first street, containing the street name
217+
$firstStreetItem = reset($street);
218+
219+
// Check if we're dealing with a single line street. If that's the case we'll extract the street using regex.
220+
if (count($street) === 1) {
221+
preg_match('/^(?:\b\d\w*\b\s*)?(\b[a-zA-Z]\w*\b\s*)*/', $firstStreetItem, $matches);
222+
223+
// Get the first street, containing the street name
224+
return trim($matches[0]);
225+
}
226+
227+
// If we're dealing with a multi line street, just return the first line.
228+
return trim($firstStreetItem);
229+
}
230+
231+
private function getHousenumber(Address $address): string
232+
{
233+
$street = $address->getStreet();
234+
if (!$street) {
235+
throw new LocalizedException(__('Street should be an array'));
236+
}
237+
238+
// Trim spaces from all lines
239+
$trimmedStreet = array_map(
240+
static function ($line) {
241+
return trim($line);
242+
},
243+
$street
244+
);
245+
246+
// Check if we're dealing with a single line street. If that's the case we'll extract the street using regex.
247+
$streetWithNumberPattern = '/\s(\d+[A-Za-z\s-]*)/';
248+
$firstStreetItem = reset($street);
249+
if (count($street) === 1 && preg_match($streetWithNumberPattern, $firstStreetItem, $matches)) {
250+
// Get the first street, containing the street name
251+
return trim($matches[0]);
252+
}
253+
254+
// Remove first item
255+
array_shift($trimmedStreet);
256+
257+
// And return as string
258+
return trim(implode(' ', $trimmedStreet));
259+
}
226260
}

0 commit comments

Comments
 (0)