diff --git a/src/Service/TrackingInfoStructFactory.php b/src/Service/TrackingInfoStructFactory.php index 06cec1949..e7d732a48 100644 --- a/src/Service/TrackingInfoStructFactory.php +++ b/src/Service/TrackingInfoStructFactory.php @@ -8,6 +8,11 @@ class TrackingInfoStructFactory { + /** + * Mollie throws an error with length >= 100 + */ + const MAX_TRACKING_CODE_LENGTH = 99; + public function createFromDelivery(OrderDeliveryEntity $orderDeliveryEntity):?ShipmentTrackingInfoStruct { $trackingCodes = $orderDeliveryEntity->getTrackingCodes(); @@ -15,6 +20,11 @@ public function createFromDelivery(OrderDeliveryEntity $orderDeliveryEntity):?Sh if ($shippingMethod === null) { return null; } + /** + * mollie accepts only one tracking struct with code per shippment + * + * https://docs.mollie.com/reference/v2/shipments-api/create-shipment + */ if (count($trackingCodes) !== 1) { return null; } @@ -36,12 +46,20 @@ public function create(string $trackingCarrier, string $trackingCode, string $tr throw new \InvalidArgumentException('Missing Argument for Tracking Code!'); } - $trackingUrl = trim($trackingUrl . $trackingCode); + if (strpos($trackingUrl, '%s') === false) { + throw new \InvalidArgumentException('Missing %s as code placeholder in Tracking URL'); + } + + $trackingUrl = trim(sprintf($trackingUrl, $trackingCode)); if (filter_var($trackingUrl, FILTER_VALIDATE_URL) === false) { $trackingUrl = ''; } + if (mb_strlen($trackingCode) > self::MAX_TRACKING_CODE_LENGTH) { + $trackingUrl = ''; + } + /** * following characters are not allowed in the tracking URL {,},<,>,# */ diff --git a/tests/PHPUnit/Facade/MollieShipment/CreateTrackingStructTest.php b/tests/PHPUnit/Facade/MollieShipment/CreateTrackingStructTest.php index 5ca7dc9ae..49c03c301 100644 --- a/tests/PHPUnit/Facade/MollieShipment/CreateTrackingStructTest.php +++ b/tests/PHPUnit/Facade/MollieShipment/CreateTrackingStructTest.php @@ -123,6 +123,6 @@ public function testTrackingInfoStructWithCorrectData() $this->assertInstanceOf(ShipmentTrackingInfoStruct::class, $trackingInfoStruct); }); - $this->shipmentFacade->shipOrder($this->order, 'Mollie', '123456789', '', $this->context); + $this->shipmentFacade->shipOrder($this->order, 'Mollie', '123456789', 'https://foo.bar?code=%s', $this->context); } } diff --git a/tests/PHPUnit/Service/TrackingInfoStructFactoryTest.php b/tests/PHPUnit/Service/TrackingInfoStructFactoryTest.php index 4fee1cdcf..5ff22ff39 100644 --- a/tests/PHPUnit/Service/TrackingInfoStructFactoryTest.php +++ b/tests/PHPUnit/Service/TrackingInfoStructFactoryTest.php @@ -5,6 +5,8 @@ use Kiener\MolliePayments\Service\TrackingInfoStructFactory; use PHPUnit\Framework\TestCase; +use Shopware\Core\Checkout\Order\Aggregate\OrderDelivery\OrderDeliveryEntity; +use Shopware\Core\Checkout\Shipping\ShippingMethodEntity; /** * @coversDefaultClass \Kiener\MolliePayments\Service\TrackingInfoStructFactory @@ -21,26 +23,98 @@ public function setUp(): void $this->factory = new TrackingInfoStructFactory(); } + + public function testInfoStructCreatedByDelivery(): void + { + $expectedCode = '1234'; + $expectedCarrier = 'Test carrier'; + $expectedUrl = 'https://test.foo?code=1234'; + $deliveryEntity = new OrderDeliveryEntity(); + $deliveryEntity->setUniqueIdentifier('testDelivery'); + $deliveryEntity->setTrackingCodes([ + $expectedCode + ]); + + $shippingMethod = new ShippingMethodEntity(); + $shippingMethod->setName($expectedCarrier); + $shippingMethod->setUniqueIdentifier('testShippingMethod'); + $shippingMethod->setTrackingUrl('https://test.foo?code=%s'); + + $deliveryEntity->setShippingMethod($shippingMethod); + $trackingInfoStruct = $this->factory->createFromDelivery($deliveryEntity); + + $this->assertNotNull($trackingInfoStruct); + $this->assertSame($expectedCode, $trackingInfoStruct->getCode()); + $this->assertSame($expectedUrl, $trackingInfoStruct->getUrl()); + $this->assertSame($expectedCarrier, $trackingInfoStruct->getCarrier()); + } + + public function testOnlyOneCodeAccepted(): void + { + + $deliveryEntity = new OrderDeliveryEntity(); + $deliveryEntity->setUniqueIdentifier('testDelivery'); + $deliveryEntity->setTrackingCodes([ + '1234', + 'test' + ]); + + $shippingMethod = new ShippingMethodEntity(); + $shippingMethod->setName('Test carrier'); + $shippingMethod->setUniqueIdentifier('testShippingMethod'); + $shippingMethod->setTrackingUrl('https://test.foo?code=%s'); + + $deliveryEntity->setShippingMethod($shippingMethod); + $trackingInfoStruct = $this->factory->createFromDelivery($deliveryEntity); + $this->assertNull($trackingInfoStruct); + } + + public function testInfoStructCreatedByArguments(): void + { + $expectedCode = '1234'; + $expectedCarrier = 'Test carrier'; + $trackingInfoStruct = $this->factory->create($expectedCarrier, $expectedCode, 'https://test.foo?code=%s'); + $expectedUrl = 'https://test.foo?code=1234'; + + $this->assertNotNull($trackingInfoStruct); + $this->assertSame($expectedCode, $trackingInfoStruct->getCode()); + $this->assertSame($expectedUrl, $trackingInfoStruct->getUrl()); + $this->assertSame($expectedCarrier, $trackingInfoStruct->getCarrier()); + + } + + public function testExceptionIsThrownWithoutPlaceholderInUrl(): void + { + $this->expectException(\InvalidArgumentException::class); + $trackingInfoStruct = $this->factory->create('Test', 'testCode', 'https://test.foo?code'); + + $this->assertNull($trackingInfoStruct); + } + /** * @dataProvider invalidCodes * @param string $url * @param string $trackingCode * @return void */ - public function testInvalidTrackingCodeCharacter(string $trackingCode):void{ + public function testInvalidTrackingCodeCharacter(string $trackingCode): void + { - $trackingInfoStruct = $this->factory->create('test',$trackingCode,'https://foo.bar'); - $expected =''; - $this->assertSame($expected,$trackingInfoStruct->getUrl()); + $trackingInfoStruct = $this->factory->create('test', $trackingCode, 'https://foo.bar/%s'); + $expected = ''; + $this->assertSame($expected, $trackingInfoStruct->getUrl()); } - public function invalidCodes():array{ + + public function invalidCodes(): array + { return [ ['some{code'], ['some}code'], ['somecode'], ['some#code'], + [str_repeat('1', 200)], ]; } } \ No newline at end of file