diff --git a/src/Event/MollieOrderShipmentTrackingEvent.php b/src/Event/MollieOrderShipmentTrackingEvent.php
deleted file mode 100644
index 645816ba2..000000000
--- a/src/Event/MollieOrderShipmentTrackingEvent.php
+++ /dev/null
@@ -1,128 +0,0 @@
-orderId = $orderId;
- $this->context = $context;
- $this->trackingCarrier = $trackingCarrier;
- $this->trackingCode = $trackingCode;
- $this->trackingUrl = $trackingUrl;
- }
-
- /**
- * @return string
- */
- public function getOrderId(): string
- {
- return $this->orderId;
- }
-
- /**
- * @param string $orderId
- */
- public function setOrderId(string $orderId): void
- {
- $this->orderId = $orderId;
- }
-
- /**
- * @return Context
- */
- public function getContext(): Context
- {
- return $this->context;
- }
-
- /**
- * @param Context $context
- */
- public function setContext(Context $context): void
- {
- $this->context = $context;
- }
-
- /**
- * @return string
- */
- public function getTrackingCarrier(): string
- {
- return $this->trackingCarrier;
- }
-
- /**
- * @param string $trackingCarrier
- */
- public function setTrackingCarrier(string $trackingCarrier): void
- {
- $this->trackingCarrier = $trackingCarrier;
- }
-
- /**
- * @return string
- */
- public function getTrackingCode(): string
- {
- return $this->trackingCode;
- }
-
- /**
- * @param string $trackingCode
- */
- public function setTrackingCode(string $trackingCode): void
- {
- $this->trackingCode = $trackingCode;
- }
-
- /**
- * @return string
- */
- public function getTrackingUrl(): string
- {
- return $this->trackingUrl;
- }
-
- /**
- * @param string $trackingUrl
- */
- public function setTrackingUrl(string $trackingUrl): void
- {
- $this->trackingUrl = $trackingUrl;
- }
-}
diff --git a/src/Facade/MollieShipment.php b/src/Facade/MollieShipment.php
index b6bf37498..1021bf181 100644
--- a/src/Facade/MollieShipment.php
+++ b/src/Facade/MollieShipment.php
@@ -11,6 +11,7 @@
use Kiener\MolliePayments\Service\MolliePaymentExtractor;
use Kiener\MolliePayments\Service\OrderDeliveryService;
use Kiener\MolliePayments\Service\OrderService;
+use Kiener\MolliePayments\Service\TrackingInfoStructFactory;
use Kiener\MolliePayments\Service\Transition\DeliveryTransitionServiceInterface;
use Kiener\MolliePayments\Struct\MollieApi\ShipmentTrackingInfoStruct;
use Psr\Log\LoggerInterface;
@@ -20,6 +21,7 @@
use Shopware\Core\Checkout\Order\Aggregate\OrderLineItem\OrderLineItemEntity;
use Shopware\Core\Checkout\Order\Aggregate\OrderTransaction\OrderTransactionEntity;
use Shopware\Core\Checkout\Order\OrderEntity;
+use Shopware\Core\Checkout\Shipping\ShippingMethodEntity;
use Shopware\Core\Content\Product\ProductEntity;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\Uuid\Uuid;
@@ -61,11 +63,17 @@ class MollieShipment implements MollieShipmentInterface
*/
private $orderDataExtractor;
+ /**
+ * @var TrackingInfoStructFactory
+ */
+ private $trackingInfoStructFactory;
+
/**
* @var LoggerInterface
*/
private $logger;
+
/**
* @param MolliePaymentExtractor $extractor
* @param DeliveryTransitionServiceInterface $deliveryTransitionService
@@ -76,7 +84,7 @@ class MollieShipment implements MollieShipmentInterface
* @param OrderDataExtractor $orderDataExtractor
* @param LoggerInterface $logger
*/
- public function __construct(MolliePaymentExtractor $extractor, DeliveryTransitionServiceInterface $deliveryTransitionService, Order $mollieApiOrderService, Shipment $mollieApiShipmentService, OrderDeliveryService $orderDeliveryService, OrderService $orderService, OrderDataExtractor $orderDataExtractor, LoggerInterface $logger)
+ public function __construct(MolliePaymentExtractor $extractor, DeliveryTransitionServiceInterface $deliveryTransitionService, Order $mollieApiOrderService, Shipment $mollieApiShipmentService, OrderDeliveryService $orderDeliveryService, OrderService $orderService, OrderDataExtractor $orderDataExtractor, TrackingInfoStructFactory $trackingInfoStructFactory, LoggerInterface $logger)
{
$this->extractor = $extractor;
$this->deliveryTransitionService = $deliveryTransitionService;
@@ -86,6 +94,7 @@ public function __construct(MolliePaymentExtractor $extractor, DeliveryTransitio
$this->orderService = $orderService;
$this->orderDataExtractor = $orderDataExtractor;
$this->logger = $logger;
+ $this->trackingInfoStructFactory = $trackingInfoStructFactory;
}
/**
@@ -170,7 +179,9 @@ public function setShipment(string $orderDeliveryId, Context $context): bool
return false;
}
- $addedMollieShipment = $this->mollieApiOrderService->setShipment($mollieOrderId, $order->getSalesChannelId());
+ $trackingInfoStruct = $this->trackingInfoStructFactory->createFromDelivery($delivery);
+
+ $addedMollieShipment = $this->mollieApiOrderService->setShipment($mollieOrderId, $trackingInfoStruct, $order->getSalesChannelId());
if ($addedMollieShipment) {
$values = [CustomFieldsInterface::DELIVERY_SHIPPED => true];
@@ -250,7 +261,7 @@ public function shipOrder(
$shipment = $this->mollieApiShipmentService->shipOrder(
$mollieOrderId,
$order->getSalesChannelId(),
- $this->createTrackingInfoStruct($trackingCarrier, $trackingCode, $trackingUrl)
+ $this->trackingInfoStructFactory->create($trackingCarrier, $trackingCode, $trackingUrl)
);
$delivery = $this->orderDataExtractor->extractDelivery($order, $context);
@@ -371,7 +382,7 @@ public function shipItem(
$order->getSalesChannelId(),
$mollieOrderLineId,
$quantity,
- $this->createTrackingInfoStruct($trackingCarrier, $trackingCode, $trackingUrl)
+ $this->trackingInfoStructFactory->create($trackingCarrier, $trackingCode, $trackingUrl)
);
$delivery = $this->orderDataExtractor->extractDelivery($order, $context);
@@ -463,21 +474,4 @@ private function findMatchingLineItems(OrderEntity $order, string $itemIdentifie
return false;
});
}
-
- private function createTrackingInfoStruct(string $trackingCarrier, string $trackingCode, string $trackingUrl): ?ShipmentTrackingInfoStruct
- {
- if (empty($trackingCarrier) && empty($trackingCode)) {
- return null;
- }
-
- if (empty($trackingCarrier)) {
- throw new \InvalidArgumentException('Missing Argument for Tracking Carrier!');
- }
-
- if (empty($trackingCode)) {
- throw new \InvalidArgumentException('Missing Argument for Tracking Code!');
- }
-
- return new ShipmentTrackingInfoStruct($trackingCarrier, $trackingCode, $trackingUrl);
- }
}
diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml
index f822b00ad..1c529d7fd 100644
--- a/src/Resources/config/services.xml
+++ b/src/Resources/config/services.xml
@@ -178,6 +178,9 @@
%env(default::APP_URL)%
+
+
+
diff --git a/src/Resources/config/services/facades.xml b/src/Resources/config/services/facades.xml
index b9b93894d..941f4edef 100644
--- a/src/Resources/config/services/facades.xml
+++ b/src/Resources/config/services/facades.xml
@@ -13,9 +13,11 @@
+
+
diff --git a/src/Resources/config/services/subscriber.xml b/src/Resources/config/services/subscriber.xml
index eb89fc689..e76ae36f7 100644
--- a/src/Resources/config/services/subscriber.xml
+++ b/src/Resources/config/services/subscriber.xml
@@ -21,11 +21,6 @@
-
-
-
-
-
diff --git a/src/Service/MollieApi/Order.php b/src/Service/MollieApi/Order.php
index a329c4764..3e1a7e145 100644
--- a/src/Service/MollieApi/Order.php
+++ b/src/Service/MollieApi/Order.php
@@ -14,6 +14,7 @@
use Kiener\MolliePayments\Service\MollieApi\RequestAnonymizer\MollieRequestAnonymizer;
use Kiener\MolliePayments\Service\Router\RoutingBuilder;
use Kiener\MolliePayments\Service\SettingsService;
+use Kiener\MolliePayments\Struct\MollieApi\ShipmentTrackingInfoStruct;
use Mollie\Api\Exceptions\ApiException;
use Mollie\Api\Resources\Order as MollieOrder;
use Mollie\Api\Resources\OrderLine;
@@ -25,7 +26,9 @@
use Psr\Log\LoggerInterface;
use RuntimeException;
use Shopware\Core\Checkout\Customer\CustomerEntity;
+use Shopware\Core\Checkout\Order\Aggregate\OrderDelivery\OrderDeliveryEntity;
use Shopware\Core\Checkout\Order\OrderEntity;
+use Shopware\Core\Checkout\Shipping\ShippingMethodEntity;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
class Order
@@ -391,14 +394,17 @@ public function getPaymentUrl(string $mollieOrderId, string $salesChannelId): ?s
return $mollieOrder->status === 'created' ? $mollieOrder->getCheckoutUrl() : null;
}
- public function setShipment(string $mollieOrderId, string $salesChannelId): bool
+ public function setShipment(string $mollieOrderId, ?ShipmentTrackingInfoStruct $trackingInfoStruct, string $salesChannelId): bool
{
$mollieOrder = $this->getMollieOrder($mollieOrderId, $salesChannelId);
-
+ $shipment = [];
+ if ($trackingInfoStruct instanceof ShipmentTrackingInfoStruct) {
+ $shipment['tracking'] = $trackingInfoStruct->toArray();
+ }
/** @var OrderLine $orderLine */
foreach ($mollieOrder->lines() as $orderLine) {
if ($orderLine->shippableQuantity > 0) {
- $mollieOrder->shipAll();
+ $mollieOrder->shipAll($shipment);
return true;
}
diff --git a/src/Service/OrderDeliveryService.php b/src/Service/OrderDeliveryService.php
index 0d50472c0..fb3eaad9e 100644
--- a/src/Service/OrderDeliveryService.php
+++ b/src/Service/OrderDeliveryService.php
@@ -27,6 +27,7 @@ public function getDelivery(string $orderDeliveryId, Context $context): ?OrderDe
{
$criteria = new Criteria([$orderDeliveryId]);
$criteria->addAssociation('order.transactions.paymentMethod');
+ $criteria->addAssociation('shippingMethod');
$result = $this->orderDeliveryRepository->search($criteria, $context);
return $result->first();
diff --git a/src/Service/TrackingInfoStructFactory.php b/src/Service/TrackingInfoStructFactory.php
new file mode 100644
index 000000000..2a5158a58
--- /dev/null
+++ b/src/Service/TrackingInfoStructFactory.php
@@ -0,0 +1,86 @@
+= 100
+ */
+ const MAX_TRACKING_CODE_LENGTH = 99;
+
+ public function createFromDelivery(OrderDeliveryEntity $orderDeliveryEntity): ?ShipmentTrackingInfoStruct
+ {
+ $trackingCodes = $orderDeliveryEntity->getTrackingCodes();
+ $shippingMethod = $orderDeliveryEntity->getShippingMethod();
+ if ($shippingMethod === null) {
+ return null;
+ }
+ /**
+ * Currently we create one shipping in mollie for one order. one shipping object can have only one tracking code.
+ * When we have multiple Tracking Codes, we do not know which tracking code we should send to mollie. So we just dont send any tracking information at all
+ *
+ * https://docs.mollie.com/reference/v2/shipments-api/create-shipment
+ */
+ if (count($trackingCodes) !== 1) {
+ return null;
+ }
+
+ return $this->createInfoStruct((string)$shippingMethod->getName(), $trackingCodes[0], (string)$shippingMethod->getTrackingUrl());
+ }
+
+ public function create(string $trackingCarrier, string $trackingCode, string $trackingUrl): ?ShipmentTrackingInfoStruct
+ {
+ return $this->createInfoStruct($trackingCarrier, $trackingCode, $trackingUrl);
+ }
+
+ private function createInfoStruct(string $trackingCarrier, string $trackingCode, string $trackingUrl): ?ShipmentTrackingInfoStruct
+ {
+ if (empty($trackingCarrier) && empty($trackingCode)) {
+ return null;
+ }
+
+ if (empty($trackingCarrier)) {
+ throw new \InvalidArgumentException('Missing Argument for Tracking Carrier!');
+ }
+
+ if (empty($trackingCode)) {
+ throw new \InvalidArgumentException('Missing Argument for Tracking Code!');
+ }
+
+ # we just have to completely remove those codes, so that no tracking happens, but a shipping works.
+ # still, if we find multiple codes (because separators exist), then we use the first one only
+ if (mb_strlen($trackingCode) > self::MAX_TRACKING_CODE_LENGTH) {
+ if (strpos($trackingCode, ',') !== false) {
+ $trackingCode = trim(explode(',', $trackingCode)[0]);
+ } elseif (strpos($trackingCode, ';') !== false) {
+ $trackingCode = trim(explode(';', $trackingCode)[0]);
+ }
+
+ # if we are still too long, then simply remove the code
+ if (mb_strlen($trackingCode) > self::MAX_TRACKING_CODE_LENGTH) {
+ return new ShipmentTrackingInfoStruct($trackingCarrier, '', '');
+ }
+ }
+
+
+ $trackingUrl = trim(sprintf($trackingUrl, $trackingCode));
+
+ if (filter_var($trackingUrl, FILTER_VALIDATE_URL) === false) {
+ $trackingUrl = '';
+ }
+
+ /**
+ * following characters are not allowed in the tracking URL {,},<,>,#
+ */
+ if (preg_match_all('/[{}<>#]/m', $trackingUrl)) {
+ $trackingUrl = '';
+ }
+
+ return new ShipmentTrackingInfoStruct($trackingCarrier, $trackingCode, $trackingUrl);
+ }
+}
diff --git a/src/Subscriber/ShippingSubscriber.php b/src/Subscriber/ShippingSubscriber.php
deleted file mode 100644
index 0afdd4f33..000000000
--- a/src/Subscriber/ShippingSubscriber.php
+++ /dev/null
@@ -1,79 +0,0 @@
-shipmentFacade = $shipmentFacade;
- $this->logger = $logger;
- }
-
- public static function getSubscribedEvents()
- {
- return [
- MollieOrderShipmentTrackingEvent::class => 'onShipOrderWithTracking',
- ];
- }
-
- /**
- * @param MollieOrderShipmentTrackingEvent $event
- */
- public function onShipOrderWithTracking(MollieOrderShipmentTrackingEvent $event): void
- {
- try {
- $this->shipmentFacade->shipOrderByOrderId(
- $event->getOrderId(),
- $event->getTrackingCarrier(),
- $event->getTrackingCode(),
- $event->getTrackingUrl(),
- $event->getContext()
- );
- } catch (CouldNotExtractMollieOrderIdException $e) {
- // We need to catch CouldNotExtractMollieOrderIdException, because if it's not a Mollie Order
- // it obviously cannot get shipped with Mollie. We also don't have to log this, except for debugging.
- // But if we don't catch it, the rest of the process might break.
- $this->logger->debug($e->getMessage(), [
- 'orderId' => $event->getOrderId(),
- 'trackingCarrier' => $event->getTrackingCarrier(),
- 'trackingCode' => $event->getTrackingCode(),
- 'trackingUrl' => $event->getTrackingUrl(),
- ]);
- } catch (\Exception $e) {
- // We log the error, but don't rethrow so the rest of the proces can continue.
- $this->logger->error(
- sprintf(
- "Error when shipping order from Mollie Event: \"%s\" in \"%s\" on line %s",
- $e->getMessage(),
- $e->getFile(),
- $e->getLine()
- ),
- [
- 'orderId' => $event->getOrderId(),
- 'trackingCarrier' => $event->getTrackingCarrier(),
- 'trackingCode' => $event->getTrackingCode(),
- 'trackingUrl' => $event->getTrackingUrl(),
- ]
- );
- }
- }
-}
diff --git a/tests/PHPUnit/Facade/MollieShipment/CreateTrackingStructTest.php b/tests/PHPUnit/Facade/MollieShipment/CreateTrackingStructTest.php
index 0664c1208..49c03c301 100644
--- a/tests/PHPUnit/Facade/MollieShipment/CreateTrackingStructTest.php
+++ b/tests/PHPUnit/Facade/MollieShipment/CreateTrackingStructTest.php
@@ -10,6 +10,7 @@
use Kiener\MolliePayments\Service\MolliePaymentExtractor;
use Kiener\MolliePayments\Service\OrderDeliveryService;
use Kiener\MolliePayments\Service\OrderService;
+use Kiener\MolliePayments\Service\TrackingInfoStructFactory;
use Kiener\MolliePayments\Service\Transition\DeliveryTransitionService;
use Kiener\MolliePayments\Struct\MollieApi\ShipmentTrackingInfoStruct;
use Mollie\Api\Resources\Shipment as ShipmentResource;
@@ -71,6 +72,7 @@ public function setUp(): void
'extractDelivery' => $this->delivery
]);
+
$this->shipmentFacade = new MollieShipment(
$this->createMock(MolliePaymentExtractor::class),
$this->createMock(DeliveryTransitionService::class),
@@ -79,6 +81,7 @@ public function setUp(): void
$this->createMock(OrderDeliveryService::class),
$this->orderService,
$this->orderDataExtractor,
+ new TrackingInfoStructFactory(),
new NullLogger(),
);
@@ -120,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/Facade/MollieShipment/SetShipmentTest.php b/tests/PHPUnit/Facade/MollieShipment/SetShipmentTest.php
index 3530ddde3..bef93d763 100644
--- a/tests/PHPUnit/Facade/MollieShipment/SetShipmentTest.php
+++ b/tests/PHPUnit/Facade/MollieShipment/SetShipmentTest.php
@@ -11,6 +11,7 @@
use Kiener\MolliePayments\Service\MolliePaymentExtractor;
use Kiener\MolliePayments\Service\OrderDeliveryService;
use Kiener\MolliePayments\Service\OrderService;
+use Kiener\MolliePayments\Service\TrackingInfoStructFactory;
use Kiener\MolliePayments\Service\Transition\DeliveryTransitionService;
use Monolog\Logger;
use PHPUnit\Framework\TestCase;
@@ -100,6 +101,8 @@ public function setup(): void
$this->createMock(CustomerService::class)
);
+ $trackingStructFactory = new TrackingInfoStructFactory();
+
$this->mollieShipment = new MollieShipment(
$this->extractor,
$this->deliveryTransitionService,
@@ -108,6 +111,7 @@ public function setup(): void
$this->orderDeliveryService,
$this->orderService,
$this->orderDataExtractor,
+ $trackingStructFactory,
$this->logger
);
$this->orderNumber = 'fooOrderNumber';
@@ -188,7 +192,7 @@ public function testThatOrderDeliveryCustomFieldsAreNotWrittenWhenApiCallUnsucce
$deliveryId = $delivery->getId();
$this->orderDeliveryService->method('getDelivery')->willReturn($delivery);
$this->mollieApiOrderService->method('setShipment')
- ->with($mollieOrderId, $salesChannelId)
+ ->with($mollieOrderId, null, $salesChannelId)
->willReturn(false);
// custom fields for shipping are never written
@@ -201,6 +205,7 @@ public function testThatOrderDeliveryCustomFieldsAreNotWrittenWhenApiCallUnsucce
public function testThatOrderDeliveryCustomFieldsAreWrittenWhenApiCallSuccessful(): void
{
$transaction = $this->createTransaction('Kiener\MolliePayments\Handler\Method\FooMethod');
+
$order = $this->createOrder($transaction);
$mollieOrderId = 'foo';
$customFields[CustomFieldsInterface::MOLLIE_KEY][CustomFieldsInterface::ORDER_KEY] = $mollieOrderId;
@@ -211,10 +216,11 @@ public function testThatOrderDeliveryCustomFieldsAreWrittenWhenApiCallSuccessful
$order->setSalesChannel($salesChannel);
$order->setSalesChannelId($salesChannelId);
$delivery = $this->createDelivery($order);
+
$deliveryId = $delivery->getId();
$this->orderDeliveryService->method('getDelivery')->willReturn($delivery);
$this->mollieApiOrderService->method('setShipment')
- ->with($mollieOrderId, $salesChannelId)
+ ->with($mollieOrderId, null,$salesChannelId)
->willReturn(true);
// custom fields for shipping are written
@@ -236,7 +242,7 @@ private function createDelivery(?OrderEntity $order): OrderDeliveryEntity
{
$delivery = new OrderDeliveryEntity();
$delivery->setId(Uuid::randomHex());
-
+ $delivery->setTrackingCodes([]);
if ($order instanceof OrderEntity) {
$delivery->setOrder($order);
}
diff --git a/tests/PHPUnit/Service/TrackingInfoStructFactoryTest.php b/tests/PHPUnit/Service/TrackingInfoStructFactoryTest.php
new file mode 100644
index 000000000..b747f326a
--- /dev/null
+++ b/tests/PHPUnit/Service/TrackingInfoStructFactoryTest.php
@@ -0,0 +1,170 @@
+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 testUrlWithCodeIsInvalid(): void
+ {
+ $expectedCode = '/123 4%foo=bar?test';
+ $expectedCarrier = 'Test carrier';
+ $trackingInfoStruct = $this->factory->create($expectedCarrier, $expectedCode, 'https://test.foo?code=%s');
+ $expectedUrl = '';
+
+ $this->assertNotNull($trackingInfoStruct);
+ $this->assertSame($expectedCode, $trackingInfoStruct->getCode());
+ $this->assertSame($expectedUrl, $trackingInfoStruct->getUrl());
+ $this->assertSame($expectedCarrier, $trackingInfoStruct->getCarrier());
+ }
+
+ public function testInfoStructWithCommaSeparator(): void
+ {
+ $expectedCode = '1234';
+ $givenCode = $expectedCode . ',' . str_repeat('-', 100);
+ $expectedCarrier = 'Test carrier';
+ $trackingInfoStruct = $this->factory->create($expectedCarrier, $givenCode, '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 testInfoStructWithSemicolonSeparator(): void
+ {
+ $expectedCode = '1234';
+ $givenCode = $expectedCode . ';' . str_repeat('-', 100);
+ $expectedCarrier = 'Test carrier';
+ $trackingInfoStruct = $this->factory->create($expectedCarrier, $givenCode, '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 testCommaSeparatorHasHigherPriority(): void
+ {
+ $expectedCode = '1234';
+ $givenCode = $expectedCode . ',5678;' . str_repeat('-', 100);
+ $expectedCarrier = 'Test carrier';
+ $trackingInfoStruct = $this->factory->create($expectedCarrier, $givenCode, '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());
+ }
+
+ /**
+ * @dataProvider invalidCodes
+ * @param string $url
+ * @param string $trackingCode
+ * @return void
+ */
+ public function testInvalidTrackingCodeCharacter(string $trackingCode): void
+ {
+
+ $trackingInfoStruct = $this->factory->create('test', $trackingCode, 'https://foo.bar/%s');
+ $expected = '';
+
+ $this->assertSame($expected, $trackingInfoStruct->getUrl());
+
+ }
+
+ public function invalidCodes(): array
+ {
+ return [
+ ['some{code'],
+ ['some}code'],
+ ['somecode'],
+ ['some#code'],
+ ['some#<>{},' . str_repeat('1', 200)],
+ [str_repeat('1', 200)],
+ ];
+ }
+}
\ No newline at end of file