diff --git a/composer.json b/composer.json index 13487cb..f138b67 100644 --- a/composer.json +++ b/composer.json @@ -17,17 +17,17 @@ }, "require": { "php": "~8.1.0 || ~8.2.0 || ~8.3.0", - "lcobucci/jwt": "^4.0 || ^5.0", "lcobucci/clock": "^3", + "lcobucci/jwt": "^4.0 || ^5.0", "php-http/discovery": "^1.17", + "psr/clock-implementation": "*", "psr/event-dispatcher": "^1.0", "psr/http-client": "^1.0", "psr/http-client-implementation": "*", "psr/http-factory": "^1.0", "psr/http-factory-implementation": "*", "psr/http-message": "^1.0 || ^2.0", - "psr/simple-cache": "^3.0", - "psr/clock-implementation": "*" + "psr/simple-cache": "^3.0" }, "require-dev": { "friendsofphp/php-cs-fixer": "^3.16", diff --git a/infection.json5 b/infection.json5 index a28c08b..231eb79 100644 --- a/infection.json5 +++ b/infection.json5 @@ -30,6 +30,6 @@ 'Shopware\\App\\SDK\\Registration\\RegistrationService::registerConfirm', 'Shopware\\App\\SDK\\Shop\\ShopResolver::resolveFromSource' ] - } + }, } } \ No newline at end of file diff --git a/phpunit.xml b/phpunit.xml index 1879ab8..971108d 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -5,7 +5,6 @@ cacheDirectory=".phpunit.cache" executionOrder="depends,defects" requireCoverageMetadata="true" - beStrictAboutCoverageMetadata="true" beStrictAboutOutputDuringTests="true" failOnRisky="true" failOnWarning="true"> diff --git a/src/Authentication/RequestVerifier.php b/src/Authentication/RequestVerifier.php index 978030c..aaf43fa 100644 --- a/src/Authentication/RequestVerifier.php +++ b/src/Authentication/RequestVerifier.php @@ -115,19 +115,15 @@ public function authenticateStorefrontRequest(RequestInterface $request, ShopInt */ private function getSignatureFromQuery(RequestInterface $request): string { - parse_str($request->getUri()->getQuery(), $queries); + \parse_str($request->getUri()->getQuery(), $queries); if (!isset($queries[self::SHOPWARE_SHOP_SIGNATURE_HEADER])) { throw new SignatureNotFoundException($request); } + /** @var string $header */ $header = $queries[self::SHOPWARE_SHOP_SIGNATURE_HEADER]; - if (!is_string($header)) { - /** @infection-ignore-all */ - throw new SignatureNotFoundException($request); - } - return $header; } diff --git a/src/Context/ArrayStruct.php b/src/Context/ArrayStruct.php index 6ce89a0..6a8348f 100644 --- a/src/Context/ArrayStruct.php +++ b/src/Context/ArrayStruct.php @@ -4,7 +4,7 @@ namespace Shopware\App\SDK\Context; -abstract class ArrayStruct +abstract class ArrayStruct implements \JsonSerializable { /** * @param array $data @@ -20,4 +20,12 @@ public function toArray(): array { return $this->data; } + + /** + * @return array + */ + public function jsonSerialize(): array + { + return $this->toArray(); + } } diff --git a/src/Context/Cart/CalculatedPrice.php b/src/Context/Cart/CalculatedPrice.php index 997f837..b24bc40 100644 --- a/src/Context/Cart/CalculatedPrice.php +++ b/src/Context/Cart/CalculatedPrice.php @@ -5,6 +5,7 @@ namespace Shopware\App\SDK\Context\Cart; use Shopware\App\SDK\Context\ArrayStruct; +use Shopware\App\SDK\Framework\Collection; class CalculatedPrice extends ArrayStruct { @@ -27,38 +28,57 @@ public function getQuantity(): int } /** - * @return array + * @return Collection */ - public function getCalculatedTaxes(): array + public function getCalculatedTaxes(): Collection { \assert(is_array($this->data['calculatedTaxes'])); - return array_map(static function (array $calculatedTax): CalculatedTax { - return new CalculatedTax($calculatedTax); - }, $this->data['calculatedTaxes']); + + return new Collection( + \array_map( + static fn (array $tax) => new CalculatedTax($tax), + $this->data['calculatedTaxes'] + ) + ); } /** - * @return array + * @return Collection */ - public function getTaxRules(): array + public function getTaxRules(): Collection { \assert(is_array($this->data['taxRules'])); - return array_map(static function (array $taxRule): TaxRule { - return new TaxRule($taxRule); - }, $this->data['taxRules']); + + return new Collection( + \array_map( + static fn (array $rule) => new TaxRule($rule), + $this->data['taxRules'] + ) + ); } /** - * @param array $prices + * @param Collection $prices */ - public static function sum(array $prices): CalculatedPrice + public static function sum(Collection $prices): CalculatedPrice { + /** @var array> $allTaxes */ + $allTaxes = $prices->map(static fn (CalculatedPrice $price) => $price->getCalculatedTaxes()->all()); + + $taxSum = CalculatedTax::sum(new Collection(array_merge(...$allTaxes))); + + $rules = []; + + foreach ($prices as $price) { + $rules = array_merge($rules, $price->getTaxRules()->jsonSerialize()); + } + return new CalculatedPrice([ - 'unitPrice' => array_sum(array_map(static fn (CalculatedPrice $price): float => $price->getUnitPrice(), $prices)), - 'totalPrice' => array_sum(array_map(static fn (CalculatedPrice $price): float => $price->getTotalPrice(), $prices)), + 'unitPrice' => \array_sum($prices->map(static fn (CalculatedPrice $price): float => $price->getUnitPrice())), + 'totalPrice' => \array_sum($prices->map(static fn (CalculatedPrice $price): float => $price->getTotalPrice())), 'quantity' => 1, - 'calculatedTaxes' => array_map(static fn (CalculatedTax $tax) => $tax->toArray(), CalculatedTax::sum(array_merge(...array_map(static fn (CalculatedPrice $price): array => $price->getCalculatedTaxes(), $prices)))), - 'taxRules' => array_map(static fn (TaxRule $rule) => $rule->toArray(), array_merge(...array_map(static fn (CalculatedPrice $price): array => $price->getTaxRules(), $prices))), + 'calculatedTaxes' => $taxSum->map(static fn (CalculatedTax $tax) => $tax->toArray()), + 'taxRules' => $rules, ]); } } diff --git a/src/Context/Cart/CalculatedTax.php b/src/Context/Cart/CalculatedTax.php index f66ba5c..a5801c2 100644 --- a/src/Context/Cart/CalculatedTax.php +++ b/src/Context/Cart/CalculatedTax.php @@ -5,6 +5,7 @@ namespace Shopware\App\SDK\Context\Cart; use Shopware\App\SDK\Context\ArrayStruct; +use Shopware\App\SDK\Framework\Collection; class CalculatedTax extends ArrayStruct { @@ -27,10 +28,10 @@ public function getTax(): float } /** - * @param array $calculatedTaxes - * @return array + * @param Collection $calculatedTaxes + * @return Collection */ - public static function sum(array $calculatedTaxes): array + public static function sum(Collection $calculatedTaxes): Collection { $new = []; @@ -49,6 +50,6 @@ public static function sum(array $calculatedTaxes): array ]); } - return $new; + return new Collection($new); } } diff --git a/src/Context/Cart/Cart.php b/src/Context/Cart/Cart.php index 03c5105..5a8c2c4 100644 --- a/src/Context/Cart/Cart.php +++ b/src/Context/Cart/Cart.php @@ -5,6 +5,7 @@ namespace Shopware\App\SDK\Context\Cart; use Shopware\App\SDK\Context\ArrayStruct; +use Shopware\App\SDK\Framework\Collection; class Cart extends ArrayStruct { @@ -33,39 +34,42 @@ public function getCampaignCode(): ?string } /** - * @return array + * @return Collection */ - public function getLineItems(): array + public function getLineItems(): Collection { - \assert(is_array($this->data['lineItems'])); - return array_map( + \assert(\is_array($this->data['lineItems'])); + + return new Collection(\array_map( static fn (array $lineItem) => new LineItem($lineItem), $this->data['lineItems'] - ); + )); } /** - * @return array + * @return Collection */ - public function getDeliveries(): array + public function getDeliveries(): Collection { - \assert(is_array($this->data['deliveries'])); - return array_map( + \assert(\is_array($this->data['deliveries'])); + + return new Collection(\array_map( static fn (array $delivery) => new Delivery($delivery), $this->data['deliveries'] - ); + )); } /** - * @return array + * @return Collection */ - public function getTransactions(): array + public function getTransactions(): Collection { - \assert(is_array($this->data['transactions'])); - return array_map( + \assert(\is_array($this->data['transactions'])); + + return new Collection(\array_map( static fn (array $transaction) => new CartTransaction($transaction), $this->data['transactions'] - ); + )); } public function getPrice(): CartPrice diff --git a/src/Context/Cart/CartPrice.php b/src/Context/Cart/CartPrice.php index 58db91a..53720ef 100644 --- a/src/Context/Cart/CartPrice.php +++ b/src/Context/Cart/CartPrice.php @@ -5,6 +5,7 @@ namespace Shopware\App\SDK\Context\Cart; use Shopware\App\SDK\Context\ArrayStruct; +use Shopware\App\SDK\Framework\Collection; class CartPrice extends ArrayStruct { @@ -25,14 +26,15 @@ public function getTotalPrice(): float } /** - * @return array + * @return Collection */ - public function getCalculatedTaxes(): array + public function getCalculatedTaxes(): Collection { \assert(is_array($this->data['calculatedTaxes'])); - return array_map(static function (array $calculatedTax): CalculatedTax { + + return new Collection(\array_map(static function (array $calculatedTax): CalculatedTax { return new CalculatedTax($calculatedTax); - }, $this->data['calculatedTaxes']); + }, $this->data['calculatedTaxes'])); } public function getTaxStatus(): string @@ -42,15 +44,15 @@ public function getTaxStatus(): string } /** - * @return array + * @return Collection */ - public function getTaxRules(): array + public function getTaxRules(): Collection { - \assert(is_array($this->data['taxRules'])); + \assert(\is_array($this->data['taxRules'])); - return array_map(static function (array $taxRule): TaxRule { + return new Collection(\array_map(static function (array $taxRule): TaxRule { return new TaxRule($taxRule); - }, $this->data['taxRules']); + }, $this->data['taxRules'])); } public function getPositionPrice(): float diff --git a/src/Context/Cart/Delivery.php b/src/Context/Cart/Delivery.php index 2970d0b..1fd867c 100644 --- a/src/Context/Cart/Delivery.php +++ b/src/Context/Cart/Delivery.php @@ -7,19 +7,20 @@ use Shopware\App\SDK\Context\ArrayStruct; use Shopware\App\SDK\Context\SalesChannelContext\ShippingLocation; use Shopware\App\SDK\Context\SalesChannelContext\ShippingMethod; +use Shopware\App\SDK\Framework\Collection; class Delivery extends ArrayStruct { /** - * @return array + * @return Collection */ - public function getPositions(): array + public function getPositions(): Collection { \assert(is_array($this->data['positions'])); - return array_map(static function (array $position) { + return new Collection(\array_map(static function (array $position) { return new DeliveryPosition($position); - }, $this->data['positions']); + }, $this->data['positions'])); } public function getLocation(): ShippingLocation diff --git a/src/Context/Cart/Error.php b/src/Context/Cart/Error.php new file mode 100644 index 0000000..0b6268e --- /dev/null +++ b/src/Context/Cart/Error.php @@ -0,0 +1,12 @@ + + * @return Collection */ - public function getChildren(): array + public function getChildren(): Collection { \assert(is_array($this->data['children'])); - return array_map(static fn (array $child): LineItem => new LineItem($child), $this->data['children']); + return new Collection(\array_map(static fn (array $child): LineItem => new LineItem($child), $this->data['children'])); } } diff --git a/src/Context/ContextResolver.php b/src/Context/ContextResolver.php index da6d842..809147d 100644 --- a/src/Context/ContextResolver.php +++ b/src/Context/ContextResolver.php @@ -8,6 +8,7 @@ use Psr\Http\Message\RequestInterface; use Shopware\App\SDK\Context\ActionButton\ActionButtonAction; use Shopware\App\SDK\Context\Cart\Cart; +use Shopware\App\SDK\Context\Gateway\Checkout\CheckoutGatewayAction; use Shopware\App\SDK\Context\Module\ModuleAction; use Shopware\App\SDK\Context\Order\Order; use Shopware\App\SDK\Context\Order\OrderTransaction; @@ -25,6 +26,7 @@ use Shopware\App\SDK\Context\TaxProvider\TaxProviderAction; use Shopware\App\SDK\Context\Webhook\WebhookAction; use Shopware\App\SDK\Exception\MalformedWebhookBodyException; +use Shopware\App\SDK\Framework\Collection; use Shopware\App\SDK\Shop\ShopInterface; class ContextResolver @@ -234,6 +236,25 @@ public function assembleStorefrontRequest(RequestInterface $request, ShopInterfa ); } + public function assembleCheckoutGatewayRequest(RequestInterface $request, ShopInterface $shop): CheckoutGatewayAction + { + $body = \json_decode($request->getBody()->getContents(), true, flags: \JSON_THROW_ON_ERROR); + $request->getBody()->rewind(); + + if (!\is_array($body) || !isset($body['source']) || !\is_array($body['source'])) { + throw new MalformedWebhookBodyException(); + } + + return new CheckoutGatewayAction( + $shop, + $this->parseSource($body['source']), + new Cart($body['cart']), + new SalesChannelContext($body['salesChannelContext']), + new Collection(\array_flip($body['paymentMethods'])), + new Collection(\array_flip($body['shippingMethods'])), + ); + } + /** * @param array $source * @return ActionSource diff --git a/src/Context/Gateway/Checkout/CheckoutGatewayAction.php b/src/Context/Gateway/Checkout/CheckoutGatewayAction.php new file mode 100644 index 0000000..5be018c --- /dev/null +++ b/src/Context/Gateway/Checkout/CheckoutGatewayAction.php @@ -0,0 +1,28 @@ + $paymentMethods + * @param Collection $shippingMethods + */ + public function __construct( + public readonly ShopInterface $shop, + public readonly ActionSource $source, + public readonly Cart $cart, + public readonly SalesChannelContext $context, + public readonly Collection $paymentMethods, + public readonly Collection $shippingMethods, + ) { + } +} diff --git a/src/Context/Order/Order.php b/src/Context/Order/Order.php index 0f8d018..cfbe574 100644 --- a/src/Context/Order/Order.php +++ b/src/Context/Order/Order.php @@ -11,6 +11,7 @@ use Shopware\App\SDK\Context\SalesChannelContext\Currency; use Shopware\App\SDK\Context\SalesChannelContext\RoundingConfig; use Shopware\App\SDK\Context\Trait\CustomFieldsAware; +use Shopware\App\SDK\Framework\Collection; class Order extends ArrayStruct { @@ -101,14 +102,15 @@ public function getBillingAddress(): Address } /** - * @return array + * @return Collection */ - public function getLineItems(): array + public function getLineItems(): Collection { \assert(\is_array($this->data['lineItems'])); - return array_map(static function (array $lineItem): OrderLineItem { + + return new Collection(\array_map(static function (array $lineItem): OrderLineItem { return new OrderLineItem($lineItem); - }, $this->data['lineItems']); + }, $this->data['lineItems'])); } public function getItemRounding(): RoundingConfig @@ -136,24 +138,26 @@ public function getSalesChannelId(): string } /** - * @return array + * @return Collection */ - public function getDeliveries(): array + public function getDeliveries(): Collection { \assert(\is_array($this->data['deliveries'])); - return array_map(static function (array $delivery): OrderDelivery { + + return new Collection(\array_map(static function (array $delivery): OrderDelivery { return new OrderDelivery($delivery); - }, $this->data['deliveries']); + }, $this->data['deliveries'])); } /** - * @return array + * @return Collection */ - public function getTransactions(): array + public function getTransactions(): Collection { \assert(\is_array($this->data['transactions'])); - return array_map(static function (array $transaction): OrderTransaction { + + return new Collection(\array_map(static function (array $transaction): OrderTransaction { return new OrderTransaction($transaction); - }, $this->data['transactions']); + }, $this->data['transactions'])); } } diff --git a/src/Context/Payment/PaymentPayAction.php b/src/Context/Payment/PaymentPayAction.php index 0024ab5..48e4947 100644 --- a/src/Context/Payment/PaymentPayAction.php +++ b/src/Context/Payment/PaymentPayAction.php @@ -23,7 +23,7 @@ public function __construct( public readonly ActionSource $source, public readonly Order $order, public readonly OrderTransaction $orderTransaction, - public readonly ?string $returnUrl, + public readonly ?string $returnUrl = null, public readonly ?RecurringData $recurring = null, public readonly array $requestData = [], ) { diff --git a/src/Context/SalesChannelContext/SalesChannel.php b/src/Context/SalesChannelContext/SalesChannel.php index 77bef48..5b77558 100644 --- a/src/Context/SalesChannelContext/SalesChannel.php +++ b/src/Context/SalesChannelContext/SalesChannel.php @@ -5,6 +5,7 @@ namespace Shopware\App\SDK\Context\SalesChannelContext; use Shopware\App\SDK\Context\ArrayStruct; +use Shopware\App\SDK\Framework\Collection; class SalesChannel extends ArrayStruct { @@ -39,13 +40,14 @@ public function getCurrency(): Currency } /** - * @return array + * @return Collection */ - public function getDomains(): array + public function getDomains(): Collection { \assert(is_array($this->data['domains'])); - return array_map(static function (array $domain): SalesChannelDomain { + + return new Collection(\array_map(static function (array $domain): SalesChannelDomain { return new SalesChannelDomain($domain); - }, $this->data['domains']); + }, $this->data['domains'])); } } diff --git a/src/Context/TaxProvider/TaxProviderAction.php b/src/Context/TaxProvider/TaxProviderAction.php index 216e207..a098f5e 100644 --- a/src/Context/TaxProvider/TaxProviderAction.php +++ b/src/Context/TaxProvider/TaxProviderAction.php @@ -12,10 +12,10 @@ class TaxProviderAction { public function __construct( - public readonly ShopInterface $shop, - public readonly ActionSource $source, + public readonly ShopInterface $shop, + public readonly ActionSource $source, public readonly SalesChannelContext $context, - public readonly Cart $cart, + public readonly Cart $cart, ) { } } diff --git a/src/Framework/Collection.php b/src/Framework/Collection.php new file mode 100644 index 0000000..36be3a0 --- /dev/null +++ b/src/Framework/Collection.php @@ -0,0 +1,155 @@ + + */ +final class Collection implements Countable, IteratorAggregate, JsonSerializable +{ + /** + * @var array + */ + protected array $elements = []; + + /** + * @param iterable $elements + */ + public function __construct(iterable $elements = []) + { + /** + * @var array-key|null $key + */ + foreach ($elements as $key => $element) { + $this->set($key, $element); + } + } + + /** + * @return array + */ + public function all(): array + { + return $this->elements; + } + + /** + * @param array-key|null $key + * @param TElement $element + */ + public function set(int|string|null $key, $element): void + { + $key === null ? $this->elements[] = $element : $this->elements[$key] = $element; + } + + /** + * @param TElement $element + */ + public function add($element): void + { + $this->elements[] = $element; + } + + /** + * @param array-key $key + * + * @return TElement|null + */ + public function get(int|string $key): mixed + { + if ($this->has($key)) { + return $this->elements[$key]; + } + + return null; + } + + /** + * @return TElement|null + */ + public function first(): mixed + { + return $this->elements[\array_key_first($this->elements)] ?? null; + } + + /** + * @return TElement|null + */ + public function last(): mixed + { + return $this->elements[array_key_last($this->elements)] ?? null; + } + + /** + * @param array-key $key + */ + public function remove(int|string $key): void + { + unset($this->elements[$key]); + } + + /** + * @param array-key $key + */ + public function has(int|string $key): bool + { + return \array_key_exists($key, $this->elements); + } + + /** + * @return array + */ + public function map(\Closure $closure): array + { + return \array_map($closure, $this->elements); + } + + /** + * @return self + */ + public function filter(\Closure $closure): self + { + return new Collection(\array_filter($this->elements, $closure)); + } + + /** + * @return Traversable + */ + public function getIterator(): Traversable + { + yield from $this->elements; + } + + public function count(): int + { + return \count($this->elements); + } + + /** + * @return array + */ + public function jsonSerialize(): array + { + $result = []; + + foreach ($this->elements as $key => $element) { + if ($element instanceof JsonSerializable) { + $result[$key] = $element->jsonSerialize(); + continue; + } + + $result[$key] = $element; + } + + return $result; + } +} diff --git a/src/Gateway/Checkout/CheckoutGatewayCommand.php b/src/Gateway/Checkout/CheckoutGatewayCommand.php new file mode 100644 index 0000000..356d691 --- /dev/null +++ b/src/Gateway/Checkout/CheckoutGatewayCommand.php @@ -0,0 +1,45 @@ + + */ + public array $payload = []; + + public string $keyName; + + public function setPayloadValue(string $key, mixed $value): void + { + $this->payload[$key] = $value; + } + + public function hasPayloadValue(string $key): bool + { + return isset($this->payload[$key]); + } + + public function getPayloadValue(string $key): mixed + { + if (!$this->hasPayloadValue($key)) { + return null; + } + + return $this->payload[$key]; + } + + /** + * @return array{command: string, payload: array} + */ + public function jsonSerialize(): array + { + return [ + 'command' => $this->keyName, + 'payload' => $this->payload, + ]; + } +} diff --git a/src/Gateway/Checkout/Command/AddCartErrorCommand.php b/src/Gateway/Checkout/Command/AddCartErrorCommand.php new file mode 100644 index 0000000..b86ef1a --- /dev/null +++ b/src/Gateway/Checkout/Command/AddCartErrorCommand.php @@ -0,0 +1,34 @@ +keyName = self::KEY; + $this->setPayloadValue('message', $message); + $this->setPayloadValue('blocking', $blocking); + $this->setPayloadValue('level', $level); + } +} diff --git a/src/Gateway/Checkout/Command/AddPaymentMethodCommand.php b/src/Gateway/Checkout/Command/AddPaymentMethodCommand.php new file mode 100644 index 0000000..bcdaf94 --- /dev/null +++ b/src/Gateway/Checkout/Command/AddPaymentMethodCommand.php @@ -0,0 +1,21 @@ +keyName = self::KEY; + $this->setPayloadValue('paymentMethodTechnicalName', $paymentMethodTechnicalName); + } +} diff --git a/src/Gateway/Checkout/Command/AddPaymentMethodExtensionCommand.php b/src/Gateway/Checkout/Command/AddPaymentMethodExtensionCommand.php new file mode 100644 index 0000000..51e4e21 --- /dev/null +++ b/src/Gateway/Checkout/Command/AddPaymentMethodExtensionCommand.php @@ -0,0 +1,32 @@ + $extensionsPayload - The payload of the newly to be added extension + */ + public function __construct( + public readonly string $paymentMethodTechnicalName, + public readonly string $extensionKey, + public readonly array $extensionsPayload, + ) { + $this->keyName = self::KEY; + $this->setPayloadValue('paymentMethodTechnicalName', $paymentMethodTechnicalName); + $this->setPayloadValue('extensionKey', $extensionKey); + $this->setPayloadValue('extensionsPayload', $extensionsPayload); + } +} diff --git a/src/Gateway/Checkout/Command/AddShippingMethodCommand.php b/src/Gateway/Checkout/Command/AddShippingMethodCommand.php new file mode 100644 index 0000000..f272c57 --- /dev/null +++ b/src/Gateway/Checkout/Command/AddShippingMethodCommand.php @@ -0,0 +1,21 @@ +keyName = self::KEY; + $this->setPayloadValue('shippingMethodTechnicalName', $shippingMethodTechnicalName); + } +} diff --git a/src/Gateway/Checkout/Command/AddShippingMethodExtensionCommand.php b/src/Gateway/Checkout/Command/AddShippingMethodExtensionCommand.php new file mode 100644 index 0000000..58489ba --- /dev/null +++ b/src/Gateway/Checkout/Command/AddShippingMethodExtensionCommand.php @@ -0,0 +1,32 @@ + $extensionsPayload - The payload of the newly to be added extension + */ + public function __construct( + public readonly string $shippingMethodTechnicalName, + public readonly string $extensionKey, + public readonly array $extensionsPayload, + ) { + $this->keyName = self::KEY; + $this->setPayloadValue('shippingMethodTechnicalName', $shippingMethodTechnicalName); + $this->setPayloadValue('extensionKey', $extensionKey); + $this->setPayloadValue('extensionsPayload', $extensionsPayload); + } +} diff --git a/src/Gateway/Checkout/Command/RemovePaymentMethodCommand.php b/src/Gateway/Checkout/Command/RemovePaymentMethodCommand.php new file mode 100644 index 0000000..400bbe4 --- /dev/null +++ b/src/Gateway/Checkout/Command/RemovePaymentMethodCommand.php @@ -0,0 +1,26 @@ +keyName = self::KEY; + $this->setPayloadValue('paymentMethodTechnicalName', $paymentMethodTechnicalName); + } +} diff --git a/src/Gateway/Checkout/Command/RemoveShippingMethodCommand.php b/src/Gateway/Checkout/Command/RemoveShippingMethodCommand.php new file mode 100644 index 0000000..47837e3 --- /dev/null +++ b/src/Gateway/Checkout/Command/RemoveShippingMethodCommand.php @@ -0,0 +1,26 @@ +keyName = self::KEY; + $this->setPayloadValue('shippingMethodTechnicalName', $shippingMethodTechnicalName); + } +} diff --git a/src/Response/GatewayResponse.php b/src/Response/GatewayResponse.php new file mode 100644 index 0000000..8c19f8c --- /dev/null +++ b/src/Response/GatewayResponse.php @@ -0,0 +1,34 @@ + $checkoutCommands + */ + public static function createCheckoutGatewayResponse(Collection $checkoutCommands): ResponseInterface + { + return self::createResponse($checkoutCommands->jsonSerialize()); + } + + /** + * @param array $data + */ + private static function createResponse(array $data): ResponseInterface + { + $psr = new Psr17Factory(); + + return $psr + ->createResponse(200) + ->withHeader('Content-Type', 'application/json') + ->withBody($psr->createStream(\json_encode($data, \JSON_THROW_ON_ERROR))); + } +} diff --git a/src/TaxProvider/CalculatedTax.php b/src/TaxProvider/CalculatedTax.php index caf9790..f5870ee 100644 --- a/src/TaxProvider/CalculatedTax.php +++ b/src/TaxProvider/CalculatedTax.php @@ -18,6 +18,6 @@ public function __construct( */ public function jsonSerialize(): array { - return get_object_vars($this); + return \get_object_vars($this); } } diff --git a/src/TaxProvider/TaxProviderResponseBuilder.php b/src/TaxProvider/TaxProviderResponseBuilder.php index 99cc7ab..456ece1 100644 --- a/src/TaxProvider/TaxProviderResponseBuilder.php +++ b/src/TaxProvider/TaxProviderResponseBuilder.php @@ -6,52 +6,58 @@ use Http\Discovery\Psr17Factory; use Psr\Http\Message\ResponseInterface; +use Shopware\App\SDK\Framework\Collection; class TaxProviderResponseBuilder { /** - * @var array> + * @var Collection */ - protected array $lineItemTaxes = []; + protected Collection $lineItemTaxes; /** - * @var array> + * @var Collection */ - protected array $deliveryTaxes = []; + protected Collection $deliveryTaxes; /** - * @var array + * @var Collection */ - protected array $cartPriceTaxes = []; + protected Collection $cartPriceTaxes; public function __construct() { + $this->cartPriceTaxes = new Collection(); + $this->deliveryTaxes = new Collection(); + $this->lineItemTaxes = new Collection(); } public function addLineItemTax(string $uniqueIdentifier, CalculatedTax $tax): self { - $this->lineItemTaxes[$uniqueIdentifier][] = $tax; + $this->lineItemTaxes->set($uniqueIdentifier, $tax); return $this; } public function addDeliveryTax(string $uniqueIdentifier, CalculatedTax $tax): self { - $this->deliveryTaxes[$uniqueIdentifier][] = $tax; + $this->deliveryTaxes->set($uniqueIdentifier, $tax); return $this; } public function addCartTax(CalculatedTax $tax): self { - $this->cartPriceTaxes[] = $tax; - + $this->cartPriceTaxes->add($tax); return $this; } public function buildPayload(): string { - return \json_encode(get_object_vars($this), JSON_THROW_ON_ERROR); + return \json_encode(\get_object_vars($this), \JSON_THROW_ON_ERROR); } + /** + * @throws \JsonException + */ public function build(): ResponseInterface { $psrFactory = new Psr17Factory(); diff --git a/tests/AppLifecycleTest.php b/tests/AppLifecycleTest.php index bd00653..b5f4f7d 100644 --- a/tests/AppLifecycleTest.php +++ b/tests/AppLifecycleTest.php @@ -13,31 +13,18 @@ use Shopware\App\SDK\AppLifecycle; use PHPUnit\Framework\TestCase; use Shopware\App\SDK\Authentication\RequestVerifier; -use Shopware\App\SDK\Event\AbstractAppLifecycleEvent; use Shopware\App\SDK\Event\BeforeShopActivateEvent; use Shopware\App\SDK\Event\BeforeShopDeactivatedEvent; use Shopware\App\SDK\Event\BeforeShopDeletionEvent; use Shopware\App\SDK\Event\ShopActivatedEvent; use Shopware\App\SDK\Event\ShopDeactivatedEvent; use Shopware\App\SDK\Event\ShopDeletedEvent; -use Shopware\App\SDK\Exception\ShopNotFoundException; use Shopware\App\SDK\Registration\RegistrationService; use Shopware\App\SDK\Shop\ShopResolver; use Shopware\App\SDK\Test\MockShop; use Shopware\App\SDK\Test\MockShopRepository; #[CoversClass(AppLifecycle::class)] -#[CoversClass(ShopNotFoundException::class)] -#[CoversClass(AbstractAppLifecycleEvent::class)] -#[CoversClass(BeforeShopDeletionEvent::class)] -#[CoversClass(ShopDeletedEvent::class)] -#[CoversClass(BeforeShopActivateEvent::class)] -#[CoversClass(BeforeShopDeactivatedEvent::class)] -#[CoversClass(ShopDeactivatedEvent::class)] -#[CoversClass(ShopActivatedEvent::class)] -#[CoversClass(ShopResolver::class)] -#[CoversClass(MockShop::class)] -#[CoversClass(MockShopRepository::class)] class AppLifecycleTest extends TestCase { private MockShopRepository $shopRepository; diff --git a/tests/Authentication/RequestVerifierTest.php b/tests/Authentication/RequestVerifierTest.php index 955e2df..f888730 100644 --- a/tests/Authentication/RequestVerifierTest.php +++ b/tests/Authentication/RequestVerifierTest.php @@ -20,11 +20,6 @@ use Shopware\App\SDK\Test\MockShop; #[CoversClass(RequestVerifier::class)] -#[CoversClass(SignatureNotFoundException::class)] -#[CoversClass(SignatureInvalidException::class)] -#[CoversClass(ShopNotFoundException::class)] -#[CoversClass(MockShop::class)] -#[CoversClass(AppConfiguration::class)] class RequestVerifierTest extends TestCase { public function testAuthenticateRegistrationRequestMissingHeader(): void diff --git a/tests/Authentication/ResponseSignerTest.php b/tests/Authentication/ResponseSignerTest.php index 8167c70..e0edaf7 100644 --- a/tests/Authentication/ResponseSignerTest.php +++ b/tests/Authentication/ResponseSignerTest.php @@ -13,8 +13,6 @@ use Shopware\App\SDK\Test\MockShop; #[CoversClass(ResponseSigner::class)] -#[CoversClass(AppConfiguration::class)] -#[CoversClass(MockShop::class)] class ResponseSignerTest extends TestCase { private ResponseSigner $signer; diff --git a/tests/Context/ActionButton/ActionButtonActionTest.php b/tests/Context/ActionButton/ActionButtonActionTest.php new file mode 100644 index 0000000..d081bdf --- /dev/null +++ b/tests/Context/ActionButton/ActionButtonActionTest.php @@ -0,0 +1,38 @@ +createMock(ShopInterface::class); + $mockActionSource = $this->createMock(ActionSource::class); + $ids = ['1', '2', '3']; + $entity = 'testEntity'; + $action = 'testAction'; + + $actionButtonAction = new ActionButtonAction( + $mockShop, + $mockActionSource, + $ids, + $entity, + $action + ); + + static::assertSame($mockShop, $actionButtonAction->shop); + static::assertSame($mockActionSource, $actionButtonAction->source); + static::assertSame($ids, $actionButtonAction->ids); + static::assertSame($entity, $actionButtonAction->entity); + static::assertSame($action, $actionButtonAction->action); + } +} diff --git a/tests/Context/ActionSourceTest.php b/tests/Context/ActionSourceTest.php new file mode 100644 index 0000000..a031081 --- /dev/null +++ b/tests/Context/ActionSourceTest.php @@ -0,0 +1,24 @@ +url); + static::assertSame($version, $source->appVersion); + } +} diff --git a/tests/Context/ArrayStructTest.php b/tests/Context/ArrayStructTest.php new file mode 100644 index 0000000..83e92a8 --- /dev/null +++ b/tests/Context/ArrayStructTest.php @@ -0,0 +1,21 @@ + 'bar', 'baz' => 'bax']) extends ArrayStruct {}; + + static::assertSame(['foo' => 'bar', 'baz' => 'bax'], $struct->toArray()); + static::assertSame(['foo' => 'bar', 'baz' => 'bax'], $struct->jsonSerialize()); + } +} diff --git a/tests/Context/Cart/CalculatedPriceTest.php b/tests/Context/Cart/CalculatedPriceTest.php index 7b16cdd..dc4acd2 100644 --- a/tests/Context/Cart/CalculatedPriceTest.php +++ b/tests/Context/Cart/CalculatedPriceTest.php @@ -5,15 +5,11 @@ namespace Shopware\App\SDK\Tests\Context\Cart; use PHPUnit\Framework\Attributes\CoversClass; -use PHPUnit\Framework\Attributes\UsesClass; use PHPUnit\Framework\TestCase; -use Shopware\App\SDK\Context\ArrayStruct; use Shopware\App\SDK\Context\Cart\CalculatedPrice; -use Shopware\App\SDK\Context\Cart\CalculatedTax; +use Shopware\App\SDK\Framework\Collection; #[CoversClass(CalculatedPrice::class)] -#[CoversClass(CalculatedTax::class)] -#[UsesClass(ArrayStruct::class)] class CalculatedPriceTest extends TestCase { public function testSum(): void @@ -66,22 +62,28 @@ public function testSum(): void ] ]); - - $sum = CalculatedPrice::sum([ + $sum = CalculatedPrice::sum(new Collection([ $calculatedPrice1, $calculatedPrice2, - ]); + ])); static::assertSame(25.0, $sum->getUnitPrice()); static::assertSame(65.0, $sum->getTotalPrice()); static::assertSame(1, $sum->getQuantity()); static::assertCount(2, $sum->getCalculatedTaxes()); - static::assertSame(19.0, $sum->getCalculatedTaxes()[19.0]->getTaxRate()); - static::assertSame(2.75, $sum->getCalculatedTaxes()[19.0]->getTax()); - static::assertSame(15.0, $sum->getCalculatedTaxes()[19.0]->getPrice()); - static::assertSame(7.0, $sum->getCalculatedTaxes()[7.0]->getTaxRate()); - static::assertSame(0.7, $sum->getCalculatedTaxes()[7.0]->getTax()); - static::assertSame(10.0, $sum->getCalculatedTaxes()[7.0]->getPrice()); + static::assertSame(19.0, $sum->getCalculatedTaxes()->get('19')?->getTaxRate()); + static::assertSame(2.75, $sum->getCalculatedTaxes()->get('19')?->getTax()); + static::assertSame(15.0, $sum->getCalculatedTaxes()->get('19')?->getPrice()); + static::assertSame(7.0, $sum->getCalculatedTaxes()->get('7')?->getTaxRate()); + static::assertSame(0.7, $sum->getCalculatedTaxes()->get('7')?->getTax()); + static::assertSame(10.0, $sum->getCalculatedTaxes()->get('7')?->getPrice()); + static::assertCount(3, $sum->getTaxRules()); + static::assertSame(19.0, $sum->getTaxRules()->get(0)?->getTaxRate()); + static::assertSame(100.0, $sum->getTaxRules()->get(0)?->getPercentage()); + static::assertSame(19.0, $sum->getTaxRules()->get(1)?->getTaxRate()); + static::assertSame(33.3, $sum->getTaxRules()->get(1)?->getPercentage()); + static::assertSame(7.0, $sum->getTaxRules()->get(2)?->getTaxRate()); + static::assertSame(66.7, $sum->getTaxRules()->get(2)?->getPercentage()); } } diff --git a/tests/Context/Cart/CalculatedTaxTest.php b/tests/Context/Cart/CalculatedTaxTest.php new file mode 100644 index 0000000..ece5644 --- /dev/null +++ b/tests/Context/Cart/CalculatedTaxTest.php @@ -0,0 +1,62 @@ + 19.0, + 'price' => 10.0, + 'tax' => 1.9, + ]); + + static::assertSame(19.0, $calculatedTax->getTaxRate()); + static::assertSame(10.0, $calculatedTax->getPrice()); + static::assertSame(1.9, $calculatedTax->getTax()); + } + + public function testSum(): void + { + $calculatedTaxes = new Collection([ + new CalculatedTax([ + 'taxRate' => 19.0, + 'price' => 10.0, + 'tax' => 1.9, + ]), + new CalculatedTax([ + 'taxRate' => 19.0, + 'price' => 5.0, + 'tax' => 0.85, + ]), + new CalculatedTax([ + 'taxRate' => 7.0, + 'price' => 10.0, + 'tax' => 0.7, + ]), + ]); + + $sum = CalculatedTax::sum($calculatedTaxes); + + static::assertCount(2, $sum); + + $tax19 = $sum->get('19'); + static::assertSame(19.0, $tax19->getTaxRate()); + static::assertSame(15.0, $tax19->getPrice()); + static::assertSame(2.75, $tax19->getTax()); + + $tax7 = $sum->get('7'); + static::assertSame(7.0, $tax7->getTaxRate()); + static::assertSame(10.0, $tax7->getPrice()); + static::assertSame(0.7, $tax7->getTax()); + } +} diff --git a/tests/Context/Cart/CartPriceTest.php b/tests/Context/Cart/CartPriceTest.php new file mode 100644 index 0000000..6936c67 --- /dev/null +++ b/tests/Context/Cart/CartPriceTest.php @@ -0,0 +1,50 @@ + 100.0, + 'totalPrice' => 100.0, + 'calculatedTaxes' => [ + [ + 'taxRate' => 19.0, + 'tax' => 19.0, + 'price' => 100.0, + ], + ], + 'taxStatus' => 'gross', + 'taxRules' => [ + [ + 'taxRate' => 19.0, + 'percentage' => 19.0, + ], + ], + 'positionPrice' => 100.0, + 'rawTotal' => 100.0, + ]); + + static::assertSame(100.0, $cartPrice->getTotalPrice()); + static::assertSame(100.0, $cartPrice->getNetPrice()); + static::assertCount(1, $cartPrice->getCalculatedTaxes()); + static::assertSame(19.0, $cartPrice->getCalculatedTaxes()->first()?->getTaxRate()); + static::assertSame(19.0, $cartPrice->getCalculatedTaxes()->first()?->getTax()); + static::assertSame(100.0, $cartPrice->getCalculatedTaxes()->first()?->getPrice()); + static::assertSame('gross', $cartPrice->getTaxStatus()); + static::assertCount(1, $cartPrice->getTaxRules()); + static::assertSame(19.0, $cartPrice->getTaxRules()->first()?->getTaxRate()); + static::assertSame(19.0, $cartPrice->getTaxRules()->first()?->getPercentage()); + static::assertSame(100.0, $cartPrice->getPositionPrice()); + static::assertSame(100.0, $cartPrice->getRawTotal()); + } +} diff --git a/tests/Context/Cart/CartTest.php b/tests/Context/Cart/CartTest.php new file mode 100644 index 0000000..1b4d983 --- /dev/null +++ b/tests/Context/Cart/CartTest.php @@ -0,0 +1,42 @@ + 'testToken', + 'customerComment' => 'testCustomerComment', + 'affiliateCode' => 'testAffiliateCode', + 'campaignCode' => 'testCampaignCode', + 'lineItems' => [['id' => 'foo']], + 'deliveries' => [['deliveryDate' => ['earliest' => '2021-01-01T00:00:00Z', 'latest' => '2021-01-02T00:00:00Z']]], + 'transactions' => [['paymentMethodId' => 'baz']], + 'price' => [ + 'netPrice' => 100.0, + ], + ]); + + self::assertSame('testToken', $cart->getToken()); + self::assertSame('testCustomerComment', $cart->getCustomerComment()); + self::assertSame('testAffiliateCode', $cart->getAffiliateCode()); + self::assertSame('testCampaignCode', $cart->getCampaignCode()); + self::assertCount(1, $cart->getLineItems()); + static::assertSame('foo', $cart->getLineItems()->first()?->getId()); + self::assertCount(1, $cart->getDeliveries()); + static::assertSame('2021-01-01T00:00:00+00:00', $cart->getDeliveries()->first()?->getDeliveryDate()->getEarliest()->format(\DateTime::ATOM)); + static::assertSame('2021-01-02T00:00:00+00:00', $cart->getDeliveries()->first()?->getDeliveryDate()->getLatest()->format(\DateTime::ATOM)); + self::assertCount(1, $cart->getTransactions()); + static::assertSame('baz', $cart->getTransactions()->first()?->getPaymentMethodId()); + self::assertSame(100.0, $cart->getPrice()->getNetPrice()); + } +} diff --git a/tests/Context/Cart/CartTransactionTest.php b/tests/Context/Cart/CartTransactionTest.php new file mode 100644 index 0000000..6facd4c --- /dev/null +++ b/tests/Context/Cart/CartTransactionTest.php @@ -0,0 +1,26 @@ + 'baz', + 'amount' => [ + 'unitPrice' => 100.0, + ], + ]); + + static::assertSame('baz', $cartTransaction->getPaymentMethodId()); + static::assertSame(100.0, $cartTransaction->getAmount()->getUnitPrice()); + } +} diff --git a/tests/Context/Cart/DeliveryDateTest.php b/tests/Context/Cart/DeliveryDateTest.php new file mode 100644 index 0000000..f5dd65c --- /dev/null +++ b/tests/Context/Cart/DeliveryDateTest.php @@ -0,0 +1,24 @@ + '2024-01-01T00:00:00+00:00', + 'latest' => '2024-01-02T00:00:00+00:00', + ]); + + static::assertSame('2024-01-01T00:00:00+00:00', $deliveryDate->getEarliest()->format(\DateTime::ATOM)); + static::assertSame('2024-01-02T00:00:00+00:00', $deliveryDate->getLatest()->format(\DateTime::ATOM)); + } +} diff --git a/tests/Context/Cart/DeliveryPositionTest.php b/tests/Context/Cart/DeliveryPositionTest.php new file mode 100644 index 0000000..aaa7fb7 --- /dev/null +++ b/tests/Context/Cart/DeliveryPositionTest.php @@ -0,0 +1,31 @@ + 'bar', + 'lineItem' => ['id' => 'foo'], + 'quantity' => 1, + 'deliveryDate' => ['earliest' => '2024-01-01T00:00:00+00:00', 'latest' => '2024-01-02T00:00:00+00:00'], + 'price' => ['unitPrice' => 100.0], + ]); + + static::assertSame('bar', $deliveryPosition->getIdentifier()); + static::assertSame('foo', $deliveryPosition->getLineItem()->getId()); + static::assertSame(1, $deliveryPosition->getQuantity()); + static::assertSame('2024-01-01T00:00:00+00:00', $deliveryPosition->getDeliveryDate()->getEarliest()->format(\DateTime::ATOM)); + static::assertSame('2024-01-02T00:00:00+00:00', $deliveryPosition->getDeliveryDate()->getLatest()->format(\DateTime::ATOM)); + static::assertSame(100.0, $deliveryPosition->getPrice()->getUnitPrice()); + } +} diff --git a/tests/Context/Cart/DeliveryTest.php b/tests/Context/Cart/DeliveryTest.php new file mode 100644 index 0000000..31bbacf --- /dev/null +++ b/tests/Context/Cart/DeliveryTest.php @@ -0,0 +1,45 @@ + [ + [ + 'identifier' => 'bar', + ], + ], + 'location' => [ + 'country' => [ + 'name' => 'bar', + ], + ], + 'shippingMethod' => [ + 'id' => 'bar', + ], + 'deliveryDate' => [ + 'earliest' => '2024-01-01T00:00:00+00:00', + ], + 'shippingCosts' => [ + 'unitPrice' => 100.0, + ], + ]); + + static::assertCount(1, $delivery->getPositions()); + static::assertSame('bar', $delivery->getPositions()->first()?->getIdentifier()); + static::assertSame('bar', $delivery->getLocation()->getCountry()->getName()); + static::assertSame('bar', $delivery->getShippingMethod()->getId()); + static::assertSame('2024-01-01T00:00:00+00:00', $delivery->getDeliveryDate()->getEarliest()->format(\DateTime::ATOM)); + static::assertSame(100.0, $delivery->getShippingCosts()->getUnitPrice()); + } +} diff --git a/tests/Context/Cart/ErrorTest.php b/tests/Context/Cart/ErrorTest.php new file mode 100644 index 0000000..e916abe --- /dev/null +++ b/tests/Context/Cart/ErrorTest.php @@ -0,0 +1,20 @@ + 'foo', + 'uniqueIdentifier' => 'bar', + 'type' => 'baz', + 'referencedId' => 'qux', + 'label' => 'quux', + 'description' => 'quuz', + 'good' => true, + 'quantity' => 42, + 'payload' => ['foo' => 'bar'], + 'price' => [ + 'unitPrice' => 10.0, + 'quantity' => 2, + 'totalPrice' => 20.0, + 'calculatedTaxes' => [ + [ + 'taxRate' => 19.0, + 'price' => 10.0, + 'tax' => 1.9, + ], + ], + 'taxRules' => [ + [ + 'taxRate' => 19.0, + 'percentage' => 100.0, + ], + ], + ], + 'states' => [ + 'foo' => 'bar', + ], + ] + ); + + static::assertSame('foo', $lineItem->getId()); + static::assertSame('bar', $lineItem->getUniqueIdentifier()); + static::assertSame('baz', $lineItem->getType()); + static::assertSame('qux', $lineItem->getReferencedId()); + static::assertSame('quux', $lineItem->getLabel()); + static::assertSame('quuz', $lineItem->getDescription()); + static::assertTrue($lineItem->isGood()); + static::assertSame(42, $lineItem->getQuantity()); + static::assertSame(['foo' => 'bar'], $lineItem->getPayload()); + static::assertSame(10.0, $lineItem->getPrice()->getUnitPrice()); + static::assertSame(2, $lineItem->getPrice()->getQuantity()); + static::assertSame(20.0, $lineItem->getPrice()->getTotalPrice()); + static::assertCount(1, $lineItem->getPrice()->getCalculatedTaxes()); + static::assertCount(1, $lineItem->getPrice()->getTaxRules()); + static::assertSame(['foo' => 'bar'], $lineItem->getStates()); + } + public function testGetChildren(): void { $lineItem = new LineItem( @@ -33,13 +85,13 @@ public function testGetChildren(): void $children = $lineItem->getChildren(); static::assertCount(2, $children); - static::assertInstanceOf(LineItem::class, $children[0]); - static::assertInstanceOf(LineItem::class, $children[1]); + static::assertInstanceOf(LineItem::class, $children->first()); + static::assertInstanceOf(LineItem::class, $children->last()); - static::assertSame('foo', $children[0]->getId()); - static::assertTrue($children[0]->isGood()); + static::assertSame('foo', $children->first()->getId()); + static::assertTrue($children->first()->isGood()); - static::assertSame('bar', $children[1]->getId()); - static::assertFalse($children[1]->isGood()); + static::assertSame('bar', $children->last()->getId()); + static::assertFalse($children->last()->isGood()); } } diff --git a/tests/Context/Cart/TaxRuleTest.php b/tests/Context/Cart/TaxRuleTest.php new file mode 100644 index 0000000..af3079e --- /dev/null +++ b/tests/Context/Cart/TaxRuleTest.php @@ -0,0 +1,24 @@ + 0.19, + 'percentage' => 19, + ]); + + static::assertSame(0.19, $taxRule->getTaxRate()); + static::assertSame(19.0, $taxRule->getPercentage()); + } +} diff --git a/tests/Context/ContextResolverTest.php b/tests/Context/ContextResolverTest.php index 049ebf7..12d019c 100644 --- a/tests/Context/ContextResolverTest.php +++ b/tests/Context/ContextResolverTest.php @@ -9,109 +9,17 @@ use PHPUnit\Framework\Attributes\DataProvider; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\StreamInterface; -use Shopware\App\SDK\Context\ActionButton\ActionButtonAction; -use Shopware\App\SDK\Context\ActionSource; -use Shopware\App\SDK\Context\ArrayStruct; -use Shopware\App\SDK\Context\Cart\CalculatedTax; -use Shopware\App\SDK\Context\Cart\Cart; -use Shopware\App\SDK\Context\Cart\CartPrice; -use Shopware\App\SDK\Context\Cart\CartTransaction; -use Shopware\App\SDK\Context\Cart\Delivery; -use Shopware\App\SDK\Context\Cart\DeliveryDate; -use Shopware\App\SDK\Context\Cart\DeliveryPosition; -use Shopware\App\SDK\Context\Cart\LineItem; -use Shopware\App\SDK\Context\Cart\CalculatedPrice; -use Shopware\App\SDK\Context\Cart\TaxRule; use Shopware\App\SDK\Context\ContextResolver; use PHPUnit\Framework\TestCase; -use Shopware\App\SDK\Context\Module\ModuleAction; -use Shopware\App\SDK\Context\Order\Order; -use Shopware\App\SDK\Context\Order\OrderCustomer; -use Shopware\App\SDK\Context\Order\OrderDelivery; -use Shopware\App\SDK\Context\Order\OrderLineItem; -use Shopware\App\SDK\Context\Order\OrderTransaction; -use Shopware\App\SDK\Context\Order\StateMachineState; use Shopware\App\SDK\Context\Payment\PaymentCaptureAction; use Shopware\App\SDK\Context\Payment\PaymentFinalizeAction; use Shopware\App\SDK\Context\Payment\PaymentPayAction; use Shopware\App\SDK\Context\Payment\PaymentRecurringAction; -use Shopware\App\SDK\Context\Payment\PaymentValidateAction; -use Shopware\App\SDK\Context\Payment\RecurringData; -use Shopware\App\SDK\Context\Payment\Refund; -use Shopware\App\SDK\Context\Payment\RefundAction; -use Shopware\App\SDK\Context\Payment\RefundTransactionCapture; -use Shopware\App\SDK\Context\SalesChannelContext\Address; -use Shopware\App\SDK\Context\SalesChannelContext\Country; -use Shopware\App\SDK\Context\SalesChannelContext\CountryState; -use Shopware\App\SDK\Context\SalesChannelContext\Currency; -use Shopware\App\SDK\Context\SalesChannelContext\Customer; -use Shopware\App\SDK\Context\SalesChannelContext\PaymentMethod; -use Shopware\App\SDK\Context\SalesChannelContext\RoundingConfig; -use Shopware\App\SDK\Context\SalesChannelContext\SalesChannel; -use Shopware\App\SDK\Context\SalesChannelContext\SalesChannelContext; -use Shopware\App\SDK\Context\SalesChannelContext\SalesChannelDomain; -use Shopware\App\SDK\Context\SalesChannelContext\Salutation; -use Shopware\App\SDK\Context\SalesChannelContext\ShippingLocation; -use Shopware\App\SDK\Context\SalesChannelContext\ShippingMethod; -use Shopware\App\SDK\Context\SalesChannelContext\TaxInfo; -use Shopware\App\SDK\Context\Storefront\StorefrontAction; -use Shopware\App\SDK\Context\Storefront\StorefrontClaims; -use Shopware\App\SDK\Context\TaxProvider\TaxProviderAction; -use Shopware\App\SDK\Context\Webhook\WebhookAction; use Shopware\App\SDK\Exception\MalformedWebhookBodyException; use Shopware\App\SDK\Shop\ShopInterface; use Shopware\App\SDK\Test\MockShop; #[CoversClass(ContextResolver::class)] -#[CoversClass(ActionSource::class)] -#[CoversClass(WebhookAction::class)] -#[CoversClass(ActionButtonAction::class)] -#[CoversClass(ModuleAction::class)] -#[CoversClass(MockShop::class)] -#[CoversClass(MalformedWebhookBodyException::class)] -#[CoversClass(ArrayStruct::class)] -#[CoversClass(Cart::class)] -#[CoversClass(LineItem::class)] -#[CoversClass(CalculatedPrice::class)] -#[CoversClass(TaxProviderAction::class)] -#[CoversClass(CalculatedTax::class)] -#[CoversClass(TaxRule::class)] -#[CoversClass(CartPrice::class)] -#[CoversClass(Delivery::class)] -#[CoversClass(ShippingMethod::class)] -#[CoversClass(DeliveryDate::class)] -#[CoversClass(DeliveryPosition::class)] -#[CoversClass(Country::class)] -#[CoversClass(ShippingLocation::class)] -#[CoversClass(CartTransaction::class)] -#[CoversClass(SalesChannelContext::class)] -#[CoversClass(Currency::class)] -#[CoversClass(RoundingConfig::class)] -#[CoversClass(PaymentMethod::class)] -#[CoversClass(Customer::class)] -#[CoversClass(Salutation::class)] -#[CoversClass(Address::class)] -#[CoversClass(CountryState::class)] -#[CoversClass(TaxInfo::class)] -#[CoversClass(SalesChannel::class)] -#[CoversClass(SalesChannelDomain::class)] -#[CoversClass(PaymentPayAction::class)] -#[CoversClass(Order::class)] -#[CoversClass(OrderDelivery::class)] -#[CoversClass(OrderLineItem::class)] -#[CoversClass(OrderTransaction::class)] -#[CoversClass(StateMachineState::class)] -#[CoversClass(PaymentFinalizeAction::class)] -#[CoversClass(PaymentCaptureAction::class)] -#[CoversClass(PaymentValidateAction::class)] -#[CoversClass(PaymentRecurringAction::class)] -#[CoversClass(RefundAction::class)] -#[CoversClass(Refund::class)] -#[CoversClass(RefundTransactionCapture::class)] -#[CoversClass(RecurringData::class)] -#[CoversClass(StorefrontAction::class)] -#[CoversClass(StorefrontClaims::class)] -#[CoversClass(OrderCustomer::class)] class ContextResolverTest extends TestCase { public function testAssembleWebhookMalformed(): void @@ -252,20 +160,19 @@ public function testAssembleTaxProvider(): void $lineItems = $tax->cart->getLineItems(); static::assertCount(1, $lineItems); - static::assertArrayHasKey('0', $lineItems); - static::assertSame('91298e263c5b4bb88c3f51c873d7e76e', $lineItems['0']->getId()); - static::assertSame('a5209fb05f4f473f9702c3868ea2deac', $lineItems['0']->getUniqueIdentifier()); - static::assertSame('product', $lineItems['0']->getType()); - static::assertIsArray($lineItems['0']->getPayload()); - static::assertSame(1, $lineItems['0']->getQuantity()); - static::assertSame('Aerodynamic Bronze Resorcerer', $lineItems['0']->getLabel()); - static::assertSame(['is-physical'], $lineItems['0']->getStates()); - static::assertSame('91298e263c5b4bb88c3f51c873d7e76e', $lineItems['0']->getReferencedId()); - static::assertSame(true, $lineItems['0']->isGood()); - static::assertSame("A description", $lineItems['0']->getDescription()); - static::assertSame([], $lineItems['0']->getChildren()); - - $price = $lineItems['0']->getPrice(); + static::assertSame('91298e263c5b4bb88c3f51c873d7e76e', $lineItems->first()?->getId()); + static::assertSame('a5209fb05f4f473f9702c3868ea2deac', $lineItems->first()?->getUniqueIdentifier()); + static::assertSame('product', $lineItems->first()?->getType()); + static::assertIsArray($lineItems->first()?->getPayload()); + static::assertSame(1, $lineItems->first()?->getQuantity()); + static::assertSame('Aerodynamic Bronze Resorcerer', $lineItems->first()?->getLabel()); + static::assertSame(['is-physical'], $lineItems->first()?->getStates()); + static::assertSame('91298e263c5b4bb88c3f51c873d7e76e', $lineItems->first()?->getReferencedId()); + static::assertSame(true, $lineItems->first()?->isGood()); + static::assertSame("A description", $lineItems->first()?->getDescription()); + static::assertEmpty($lineItems->first()?->getChildren()); + + $price = $lineItems->first()?->getPrice(); static::assertSame(623.53, $price->getTotalPrice()); static::assertSame(623.53, $price->getUnitPrice()); @@ -273,18 +180,16 @@ public function testAssembleTaxProvider(): void $calculatedTaxes = $price->getCalculatedTaxes(); static::assertCount(1, $calculatedTaxes); - static::assertArrayHasKey('0', $calculatedTaxes); - static::assertSame(0.0, $calculatedTaxes['0']->getTaxRate()); - static::assertSame(0.0, $calculatedTaxes['0']->getTax()); - static::assertSame(623.53, $calculatedTaxes['0']->getPrice()); + static::assertSame(0.0, $calculatedTaxes->first()?->getTaxRate()); + static::assertSame(0.0, $calculatedTaxes->first()?->getTax()); + static::assertSame(623.53, $calculatedTaxes->first()?->getPrice()); $taxRules = $price->getTaxRules(); static::assertCount(1, $taxRules); - static::assertArrayHasKey('0', $taxRules); - $taxRule = $taxRules['0']; - static::assertSame(0.0, $taxRule->getTaxRate()); - static::assertSame(100.0, $taxRule->getPercentage()); + $taxRule = $taxRules->first(); + static::assertSame(0.0, $taxRule?->getTaxRate()); + static::assertSame(100.0, $taxRule?->getPercentage()); $price = $tax->cart->getPrice(); @@ -296,48 +201,45 @@ public function testAssembleTaxProvider(): void $taxRules = $price->getTaxRules(); static::assertCount(1, $taxRules); - static::assertArrayHasKey('0', $taxRules); - $taxRule = $taxRules['0']; - static::assertSame(0.0, $taxRule->getTaxRate()); - static::assertSame(100.0, $taxRule->getPercentage()); + $taxRule = $taxRules->first(); + + static::assertSame(0.0, $taxRule?->getTaxRate()); + static::assertSame(100.0, $taxRule?->getPercentage()); $taxRules = $price->getCalculatedTaxes(); static::assertCount(1, $taxRules); - static::assertArrayHasKey('0', $taxRules); - $taxRule = $taxRules['0']; + $taxRule = $taxRules->first(); - static::assertSame(0.0, $taxRule->getTaxRate()); - static::assertSame(0.0, $taxRule->getTax()); - static::assertSame(623.53, $taxRule->getPrice()); + static::assertSame(0.0, $taxRule?->getTaxRate()); + static::assertSame(0.0, $taxRule?->getTax()); + static::assertSame(623.53, $taxRule?->getPrice()); $deliveries = $tax->cart->getDeliveries(); static::assertCount(1, $deliveries); - static::assertArrayHasKey('0', $deliveries); - $delivery = $deliveries['0']; + $delivery = $deliveries->first(); - static::assertSame('Standard', $delivery->getShippingMethod()->getName()); + static::assertSame('Standard', $delivery?->getShippingMethod()->getName()); - $deliveryDate = $delivery->getDeliveryDate(); - static::assertSame('2023-05-03T16:00:00+00:00', $deliveryDate->getEarliest()->format(\DATE_ATOM)); - static::assertSame('2023-05-05T16:00:00+00:00', $deliveryDate->getLatest()->format(\DATE_ATOM)); + $deliveryDate = $delivery?->getDeliveryDate(); + static::assertSame('2023-05-03T16:00:00+00:00', $deliveryDate?->getEarliest()->format(\DATE_ATOM)); + static::assertSame('2023-05-05T16:00:00+00:00', $deliveryDate?->getLatest()->format(\DATE_ATOM)); $positions = $delivery->getPositions(); static::assertCount(1, $positions); - static::assertArrayHasKey('0', $positions); - $position = $positions['0']; + $position = $positions->first(); - static::assertSame('91298e263c5b4bb88c3f51c873d7e76e', $position->getIdentifier()); - static::assertSame(1, $position->getQuantity()); - static::assertSame(1683129600, $position->getDeliveryDate()->getEarliest()->getTimestamp()); - static::assertSame(1683302400, $position->getDeliveryDate()->getLatest()->getTimestamp()); + static::assertSame('91298e263c5b4bb88c3f51c873d7e76e', $position?->getIdentifier()); + static::assertSame(1, $position?->getQuantity()); + static::assertSame(1683129600, $position?->getDeliveryDate()->getEarliest()->getTimestamp()); + static::assertSame(1683302400, $position?->getDeliveryDate()->getLatest()->getTimestamp()); - static::assertSame('Aerodynamic Bronze Resorcerer', $position->getLineItem()->getLabel()); - static::assertSame(1, $position->getPrice()->getQuantity()); + static::assertSame('Aerodynamic Bronze Resorcerer', $position?->getLineItem()->getLabel()); + static::assertSame(1, $position?->getPrice()->getQuantity()); $location = $delivery->getLocation(); @@ -351,28 +253,26 @@ public function testAssembleTaxProvider(): void $calculatedTaxes = $shippingCosts->getCalculatedTaxes(); static::assertCount(1, $calculatedTaxes); - static::assertArrayHasKey('0', $calculatedTaxes); - static::assertSame(0.0, $calculatedTaxes['0']->getTaxRate()); - static::assertSame(0.0, $calculatedTaxes['0']->getTax()); - static::assertSame(0.0, $calculatedTaxes['0']->getPrice()); + + static::assertSame(0.0, $calculatedTaxes->first()?->getTaxRate()); + static::assertSame(0.0, $calculatedTaxes->first()?->getTax()); + static::assertSame(0.0, $calculatedTaxes->first()?->getPrice()); $taxRules = $shippingCosts->getTaxRules(); static::assertCount(1, $taxRules); - static::assertArrayHasKey('0', $taxRules); - $taxRule = $taxRules['0']; - static::assertSame(0.0, $taxRule->getTaxRate()); - static::assertSame(100.0, $taxRule->getPercentage()); + $taxRule = $taxRules->first(); + static::assertSame(0.0, $taxRule?->getTaxRate()); + static::assertSame(100.0, $taxRule?->getPercentage()); $transactions = $tax->cart->getTransactions(); static::assertCount(1, $transactions); - static::assertArrayHasKey('0', $transactions); - $transaction = $transactions['0']; + $transaction = $transactions->first(); - static::assertSame(623.53, $transaction->getAmount()->getTotalPrice()); - static::assertSame('20c5b5b9ec9d4f39b36816488cd58133', $transaction->getPaymentMethodId()); + static::assertSame(623.53, $transaction?->getAmount()->getTotalPrice()); + static::assertSame('20c5b5b9ec9d4f39b36816488cd58133', $transaction?->getPaymentMethodId()); $context = $tax->context; @@ -424,6 +324,7 @@ public function testAssembleTaxProvider(): void static::assertSame('::', $customer->getRemoteAddress()); static::assertSame('Max', $customer->getFirstName()); static::assertSame('Mustermann', $customer->getLastName()); + static::assertNotNull($customer->getSalutation()); static::assertSame('c0928c9d2c264e3aade1fab28a9262dd', $customer->getSalutation()->getId()); static::assertSame('mr', $customer->getSalutation()->getSalutationKey()); static::assertSame('Mr.', $customer->getSalutation()->getDisplayName()); @@ -461,6 +362,7 @@ public function testAssembleTaxProvider(): void static::assertSame(false, $billingAddress->getCountry()->getCustomerTax()->isEnabled()); static::assertSame(false, $billingAddress->getCountry()->getCompanyTax()->isEnabled()); static::assertSame('040cbcada23440ebb4f6e1bebc62e421', $billingAddress->getCountryState()?->getId()); + static::assertNotNull($billingAddress->getCountryState()); static::assertSame('Pennsylvania', $billingAddress->getCountryState()?->getName()); static::assertSame([], $billingAddress->getCountryState()?->getCustomFields()); static::assertSame(1, $billingAddress->getCountryState()?->getPosition()); @@ -475,12 +377,12 @@ public function testAssembleTaxProvider(): void $domains = $salesChannel->getDomains(); static::assertCount(1, $domains); - static::assertSame('ef8e67662fdb4b0fb9241d7bd75fe8bb', $domains[0]->getId()); - static::assertSame('http://localhost:8000', $domains[0]->getUrl()); - static::assertSame('b7d2554b0ce847cd82f3ac9bd1c0dfca', $domains[0]->getCurrencyId()); - static::assertSame([], $domains[0]->getCustomFields()); - static::assertSame('2fbb5fe2e29a4d70aa5854ce7ce3e20b', $domains[0]->getLanguageId()); - static::assertSame('684f9a80c59846228223cb76d7cb3577', $domains[0]->getSnippetSetId()); + static::assertSame('ef8e67662fdb4b0fb9241d7bd75fe8bb', $domains->first()?->getId()); + static::assertSame('http://localhost:8000', $domains->first()?->getUrl()); + static::assertSame('b7d2554b0ce847cd82f3ac9bd1c0dfca', $domains->first()?->getCurrencyId()); + static::assertSame([], $domains->first()?->getCustomFields()); + static::assertSame('2fbb5fe2e29a4d70aa5854ce7ce3e20b', $domains->first()?->getLanguageId()); + static::assertSame('684f9a80c59846228223cb76d7cb3577', $domains->first()?->getSnippetSetId()); $rounding = $context->getRounding(); static::assertSame(2, $rounding->getDecimals()); @@ -723,16 +625,17 @@ public function testResolvePay(): void $lineItems = $order->getLineItems(); static::assertCount(1, $lineItems); - static::assertSame('5567f5758b414a2686afa1c6492c63a1', $lineItems[0]->getId()); - static::assertSame('Aerodynamic Bronze Slo-Cooked Prawns', $lineItems[0]->getLabel()); - static::assertSame(1, $lineItems[0]->getPosition()); - static::assertSame(null, $lineItems[0]->getParentId()); + static::assertSame('5567f5758b414a2686afa1c6492c63a1', $lineItems->first()?->getId()); + static::assertSame('Aerodynamic Bronze Slo-Cooked Prawns', $lineItems->first()?->getLabel()); + static::assertSame(1, $lineItems->first()?->getPosition()); + static::assertSame(null, $lineItems->first()?->getParentId()); $deliveries = $order->getDeliveries(); static::assertCount(1, $deliveries); - $delivery = $deliveries[0]; + $delivery = $deliveries->first(); + static::assertNotNull($delivery); static::assertSame([], $delivery->getTrackingCodes()); static::assertSame(0.0, $delivery->getShippingCosts()->getTotalPrice()); static::assertSame('Max', $delivery->getShippingOrderAddress()->getFirstName()); @@ -744,8 +647,9 @@ public function testResolvePay(): void $transactions = $order->getTransactions(); static::assertCount(1, $transactions); - $transaction = $transactions[0]; + $transaction = $transactions->first(); + static::assertNotNull($transaction); static::assertSame('55e858b413b54f8a97c64a040610b359', $transaction->getId()); static::assertSame(395.01, $transaction->getAmount()->getTotalPrice()); static::assertSame('open', $transaction->getStateMachineState()->getTechnicalName()); @@ -906,6 +810,54 @@ public function testAssembleStorefrontRequestWithEmptyTokenThrows(): void ); } + public function testAssembleCheckoutGatewayRequest(): void + { + $contextResolver = new ContextResolver(); + + $body = [ + 'source' => [ + 'url' => 'https://example.com', + 'appVersion' => 'foo', + ], + 'cart' => [ + 'token' => 'cart-token', + ], + 'salesChannelContext' => [ + 'salesChannel' => [ + 'id' => 'sales-channel-id' + ], + ], + 'paymentMethods' => [ + 'id1' => 'technicalName1', + 'id2' => 'technicalName2', + ], + 'shippingMethods' => [ + 'id1' => 'technicalName1', + 'id2' => 'technicalName2', + ], + ]; + + $request = new Request('POST', '/', [], \json_encode($body, \JSON_THROW_ON_ERROR)); + $request = $request->withHeader('shopware-app-token', 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJGcWFIV1VzQ1JOc3JaOWtRIiwiaWF0IjoxNjg5ODM3MDkyLjI3ODMyOSwibmJmIjoxNjg5ODM3MDkyLjI3ODMyOSwiZXhwIjoxNjg5ODQwNjkyLjI3ODI0Mywic2FsZXNDaGFubmVsSWQiOiIwMTg5NjQwNTU0YjU3MDBjODBjMmM0YTIwMmUyNDAxZCJ9.g8Da0bN3bkkmEdzMeXmI8wlDQEZMCDiKJvqS288B4JI'); + + $action = $contextResolver->assembleCheckoutGatewayRequest($request, $this->getShop()); + + static::assertSame('https://example.com', $action->source->url); + static::assertSame('foo', $action->source->appVersion); + static::assertSame('cart-token', $action->cart->getToken()); + static::assertSame('sales-channel-id', $action->context->getSalesChannel()->getId()); + + $paymentMethods = $action->paymentMethods; + static::assertCount(2, $paymentMethods); + static::assertSame('id1', $paymentMethods->get('technicalName1')); + static::assertSame('id2', $paymentMethods->get('technicalName2')); + + $shippingMethods = $action->shippingMethods; + static::assertCount(2, $shippingMethods); + static::assertSame('id1', $shippingMethods->get('technicalName1')); + static::assertSame('id2', $shippingMethods->get('technicalName2')); + } + /** * @dataProvider methodsProvider */ @@ -976,6 +928,7 @@ public static function methodsProvider(): iterable yield ['assemblePaymentValidate']; yield ['assemblePaymentRefund']; yield ['assemblePaymentRecurringCapture']; + yield ['assembleCheckoutGatewayRequest']; } /** diff --git a/tests/Context/Gateway/Checkout/CheckoutGatewayActionTest.php b/tests/Context/Gateway/Checkout/CheckoutGatewayActionTest.php new file mode 100644 index 0000000..cf64fd9 --- /dev/null +++ b/tests/Context/Gateway/Checkout/CheckoutGatewayActionTest.php @@ -0,0 +1,37 @@ + 'bar']); + $shippingMethods = new Collection(['baz' => 'bax']); + + $action = new CheckoutGatewayAction($shop, $source, $cart, $context, $paymentMethods, $shippingMethods); + + static::assertSame($shop, $action->shop); + static::assertSame($source, $action->source); + static::assertSame($cart, $action->cart); + static::assertSame($context, $action->context); + static::assertSame($paymentMethods, $action->paymentMethods); + static::assertSame($shippingMethods, $action->shippingMethods); + } +} diff --git a/tests/Context/Module/ModuleActionTest.php b/tests/Context/Module/ModuleActionTest.php new file mode 100644 index 0000000..f6a27f5 --- /dev/null +++ b/tests/Context/Module/ModuleActionTest.php @@ -0,0 +1,31 @@ +shop->getShopId()); + static::assertSame('https://example.com', $action->shop->getShopUrl()); + static::assertSame('secret', $action->shop->getShopSecret()); + static::assertSame('1.0.0', $action->shopwareVersion); + static::assertSame('de-DE', $action->contentLanguage); + static::assertSame('en-GB', $action->userLanguage); + } +} diff --git a/tests/Context/Order/OrderCustomerTest.php b/tests/Context/Order/OrderCustomerTest.php index edd0382..fecd047 100644 --- a/tests/Context/Order/OrderCustomerTest.php +++ b/tests/Context/Order/OrderCustomerTest.php @@ -5,17 +5,10 @@ namespace Shopware\App\SDK\Tests\Context\Order; use PHPUnit\Framework\Attributes\CoversClass; -use PHPUnit\Framework\Attributes\UsesClass; use PHPUnit\Framework\TestCase; -use Shopware\App\SDK\Context\ArrayStruct; use Shopware\App\SDK\Context\Order\OrderCustomer; -use Shopware\App\SDK\Context\SalesChannelContext\Customer; -use Shopware\App\SDK\Context\SalesChannelContext\Salutation; #[CoversClass(OrderCustomer::class)] -#[UsesClass(ArrayStruct::class)] -#[UsesClass(Customer::class)] -#[UsesClass(Salutation::class)] class OrderCustomerTest extends TestCase { public function testGetId(): void @@ -69,9 +62,13 @@ public function testGetCustomerNumber(): void public function testGetSalutation(): void { $customer = new OrderCustomer(['salutation' => ['id' => 'foo']]); - $salutation = $customer->getSalutation(); + static::assertSame('foo', $customer->getSalutation()?->getId()); + } - static::assertSame('foo', $customer->getSalutation()->getId()); + public function testNullSalutation(): void + { + $customer = new OrderCustomer(['salutation' => null]); + static::assertNull($customer->getSalutation()); } public function testGetCustomer(): void diff --git a/tests/Context/Order/OrderDeliveryTest.php b/tests/Context/Order/OrderDeliveryTest.php new file mode 100644 index 0000000..505ea5e --- /dev/null +++ b/tests/Context/Order/OrderDeliveryTest.php @@ -0,0 +1,32 @@ + ['foo', 'bar'], + 'shippingCosts' => ['unitPrice' => 100.0], + 'shippingOrderAddress' => ['city' => 'bar'], + 'stateMachineState' => ['technicalName' => 'bar'], + 'shippingDateEarliest' => '2024-01-01T00:00:00+00:00', + 'shippingDateLatest' => '2024-01-01T00:00:00+00:00', + ]); + + static::assertSame(['foo', 'bar'], $orderDelivery->getTrackingCodes()); + static::assertSame(100.0, $orderDelivery->getShippingCosts()->getUnitPrice()); + static::assertSame('bar', $orderDelivery->getShippingOrderAddress()->getCity()); + static::assertSame('bar', $orderDelivery->getStateMachineState()->getTechnicalName()); + static::assertSame('2024-01-01T00:00:00+00:00', $orderDelivery->getShippingDateEarliest()->format(\DateTime::ATOM)); + static::assertSame('2024-01-01T00:00:00+00:00', $orderDelivery->getShippingDateLatest()->format(\DateTime::ATOM)); + } +} diff --git a/tests/Context/Order/OrderLineItemTest.php b/tests/Context/Order/OrderLineItemTest.php new file mode 100644 index 0000000..ed1f098 --- /dev/null +++ b/tests/Context/Order/OrderLineItemTest.php @@ -0,0 +1,24 @@ + 'parent-id', + 'position' => 1, + ]); + + static::assertSame('parent-id', $orderLineItem->getParentId()); + static::assertSame(1, $orderLineItem->getPosition()); + } +} diff --git a/tests/Context/Order/OrderTest.php b/tests/Context/Order/OrderTest.php new file mode 100644 index 0000000..cad0df2 --- /dev/null +++ b/tests/Context/Order/OrderTest.php @@ -0,0 +1,65 @@ + 'order-id', + 'orderNumber' => 'order-number', + 'currencyFactor' => 1.2, + 'orderDateTime' => '2024-01-01T00:00:00+00:00', + 'price' => ['netPrice' => 100.0], + 'amountTotal' => 100.0, + 'amountNet' => 100.0, + 'positionPrice' => 100.0, + 'taxStatus' => 'gross', + 'shippingTotal' => 10.0, + 'shippingCosts' => ['unitPrice' => 10.0], + 'orderCustomer' => ['id' => 'order-customer-id'], + 'currency' => ['id' => 'currency-id'], + 'billingAddress' => ['id' => 'billing-address-id'], + 'lineItems' => [['id' => 'line-item-id']], + 'itemRounding' => ['decimals' => 2], + 'totalRounding' => ['decimals' => 2], + 'deepLinkCode' => 'deep-link-code', + 'salesChannelId' => 'sales-channel-id', + 'deliveries' => [['trackingCodes' => ['tracking-code']]], + 'transactions' => [['id' => 'transaction-id']], + ]); + + static::assertSame('order-id', $order->getId()); + static::assertSame('order-number', $order->getOrderNumber()); + static::assertSame(1.2, $order->getCurrencyFactor()); + static::assertSame('2024-01-01T00:00:00+00:00', $order->getOrderDate()->format(\DateTime::ATOM)); + static::assertSame(100.0, $order->getPrice()->getNetPrice()); + static::assertSame(100.0, $order->getAmountTotal()); + static::assertSame(100.0, $order->getAmountNet()); + static::assertSame(100.0, $order->getPositionPrice()); + static::assertSame('gross', $order->getTaxStatus()); + static::assertSame(10.0, $order->getShippingTotal()); + static::assertSame(10.0, $order->getShippingCosts()->getUnitPrice()); + static::assertSame('order-customer-id', $order->getOrderCustomer()->getId()); + static::assertSame('currency-id', $order->getCurrency()->getId()); + static::assertSame('billing-address-id', $order->getBillingAddress()->getId()); + static::assertCount(1, $order->getLineItems()); + static::assertSame('line-item-id', $order->getLineItems()->first()?->getId()); + static::assertSame(2, $order->getItemRounding()->getDecimals()); + static::assertSame(2, $order->getTotalRounding()->getDecimals()); + static::assertSame('deep-link-code', $order->getDeepLinkCode()); + static::assertSame('sales-channel-id', $order->getSalesChannelId()); + static::assertCount(1, $order->getDeliveries()); + static::assertSame(['tracking-code'], $order->getDeliveries()->first()?->getTrackingCodes()); + static::assertCount(1, $order->getTransactions()); + static::assertSame('transaction-id', $order->getTransactions()->first()?->getId()); + } +} diff --git a/tests/Context/Order/OrderTransactionTest.php b/tests/Context/Order/OrderTransactionTest.php new file mode 100644 index 0000000..3888af1 --- /dev/null +++ b/tests/Context/Order/OrderTransactionTest.php @@ -0,0 +1,43 @@ + 'transaction-id', + 'amount' => [ + 'unitPrice' => 10.0, + ], + 'paymentMethod' => [ + 'name' => 'paypal', + ], + 'stateMachineState' => [ + 'technicalName' => 'open', + ], + 'order' => [ + 'id' => 'order-id', + ], + 'customFields' => [ + 'key' => 'value', + ], + ]); + + static::assertSame('transaction-id', $orderTransaction->getId()); + static::assertSame(10.0, $orderTransaction->getAmount()->getUnitPrice()); + static::assertSame('paypal', $orderTransaction->getPaymentMethod()->getName()); + static::assertSame('open', $orderTransaction->getStateMachineState()->getTechnicalName()); + static::assertSame('order-id', $orderTransaction->getOrder()->getId()); + static::assertArrayHasKey('key', $orderTransaction->getCustomFields()); + static::assertSame('value', $orderTransaction->getCustomFields()['key']); + } +} diff --git a/tests/Context/Order/StateMachineStateTest.php b/tests/Context/Order/StateMachineStateTest.php new file mode 100644 index 0000000..2edb542 --- /dev/null +++ b/tests/Context/Order/StateMachineStateTest.php @@ -0,0 +1,24 @@ + 'state-id', + 'technicalName' => 'technical-name', + ]); + + static::assertSame('state-id', $stateMachineState->getId()); + static::assertSame('technical-name', $stateMachineState->getTechnicalName()); + } +} diff --git a/tests/Context/Payment/PaymentCaptureActionTest.php b/tests/Context/Payment/PaymentCaptureActionTest.php new file mode 100644 index 0000000..7ea1a45 --- /dev/null +++ b/tests/Context/Payment/PaymentCaptureActionTest.php @@ -0,0 +1,54 @@ + 'order-id']); + $orderTransaction = new OrderTransaction(['id' => 'order-transaction-id']); + + $action = new PaymentCaptureAction($shop, $source, $order, $orderTransaction); + + static::assertSame($shop, $action->shop); + static::assertSame($source, $action->source); + static::assertSame($order, $action->order); + static::assertSame($orderTransaction, $action->orderTransaction); + static::assertNull($action->recurring); + static::assertSame([], $action->requestData); + } + + public function testConstruct(): void + { + $shop = new MockShop('shop-id', 'https://shop-url.com', 'shop-secret'); + $source = new ActionSource('https://shop-url.com', '1.0.0'); + $order = new Order(['id' => 'order-id']); + $orderTransaction = new OrderTransaction(['id' => 'order-transaction-id']); + $recurring = new RecurringData(['subscriptionId' => 'recurring-id']); + $requestData = ['foo' => 'bar']; + + $action = new PaymentCaptureAction($shop, $source, $order, $orderTransaction, $recurring, $requestData); + + static::assertSame($shop, $action->shop); + static::assertSame($source, $action->source); + static::assertSame($order, $action->order); + static::assertSame($orderTransaction, $action->orderTransaction); + static::assertSame($recurring, $action->recurring); + static::assertSame($requestData, $action->requestData); + } +} diff --git a/tests/Context/Payment/PaymentFinalizeActionTest.php b/tests/Context/Payment/PaymentFinalizeActionTest.php new file mode 100644 index 0000000..50d4333 --- /dev/null +++ b/tests/Context/Payment/PaymentFinalizeActionTest.php @@ -0,0 +1,49 @@ + 'order-transaction-id']); + + $action = new PaymentFinalizeAction($shop, $source, $orderTransaction); + + static::assertSame($shop, $action->shop); + static::assertSame($source, $action->source); + static::assertSame($orderTransaction, $action->orderTransaction); + static::assertNull($action->recurring); + static::assertSame([], $action->queryParameters); + } + + public function testConstruct(): void + { + $shop = new MockShop('shop-id', 'https://shop-url.com', 'shop-secret'); + $source = new ActionSource('https://shop-url.com', '1.0.0'); + $orderTransaction = new OrderTransaction(['id' => 'order-transaction-id']); + $recurring = new RecurringData(['subscriptionId' => 'recurring-id']); + $queryParameters = ['foo' => 'bar']; + + $action = new PaymentFinalizeAction($shop, $source, $orderTransaction, $recurring, $queryParameters); + + static::assertSame($shop, $action->shop); + static::assertSame($source, $action->source); + static::assertSame($orderTransaction, $action->orderTransaction); + static::assertSame($recurring, $action->recurring); + static::assertSame($queryParameters, $action->queryParameters); + } +} diff --git a/tests/Context/Payment/PaymentPayActionTest.php b/tests/Context/Payment/PaymentPayActionTest.php new file mode 100644 index 0000000..d895655 --- /dev/null +++ b/tests/Context/Payment/PaymentPayActionTest.php @@ -0,0 +1,57 @@ + 'order-id']); + $orderTransaction = new OrderTransaction(['id' => 'order-transaction-id']); + + $action = new PaymentPayAction($shop, $source, $order, $orderTransaction); + + static::assertSame($shop, $action->shop); + static::assertSame($source, $action->source); + static::assertSame($order, $action->order); + static::assertSame($orderTransaction, $action->orderTransaction); + static::assertNull($action->returnUrl); + static::assertNull($action->recurring); + static::assertSame([], $action->requestData); + } + + public function testConstruct(): void + { + $shop = new MockShop('shop-id', 'https://shop-url.com', 'shop-secret'); + $source = new ActionSource('https://shop-url.com', '1.0.0'); + $order = new Order(['id' => 'order-id']); + $orderTransaction = new OrderTransaction(['id' => 'order-transaction-id']); + $returnUrl = 'https://return-url.com'; + $recurring = new RecurringData(['subscriptionId' => 'recurring-id']); + $requestData = ['foo' => 'bar']; + + $action = new PaymentPayAction($shop, $source, $order, $orderTransaction, $returnUrl, $recurring, $requestData); + + static::assertSame($shop, $action->shop); + static::assertSame($source, $action->source); + static::assertSame($order, $action->order); + static::assertSame($orderTransaction, $action->orderTransaction); + static::assertSame($returnUrl, $action->returnUrl); + static::assertSame($recurring, $action->recurring); + static::assertSame($requestData, $action->requestData); + } +} diff --git a/tests/Context/Payment/PaymentRecurringActionTest.php b/tests/Context/Payment/PaymentRecurringActionTest.php new file mode 100644 index 0000000..03790c3 --- /dev/null +++ b/tests/Context/Payment/PaymentRecurringActionTest.php @@ -0,0 +1,32 @@ + 'order-id']); + $orderTransaction = new OrderTransaction(['id' => 'order-transaction-id']); + + $action = new PaymentRecurringAction($shop, $source, $order, $orderTransaction); + + static::assertSame($shop, $action->shop); + static::assertSame($source, $action->source); + static::assertSame($order, $action->order); + static::assertSame($orderTransaction, $action->orderTransaction); + } +} diff --git a/tests/Context/Payment/PaymentValidateActionTest.php b/tests/Context/Payment/PaymentValidateActionTest.php new file mode 100644 index 0000000..42bff12 --- /dev/null +++ b/tests/Context/Payment/PaymentValidateActionTest.php @@ -0,0 +1,34 @@ + 'cart-token']); + $salesChannelContext = new SalesChannelContext(['token' => 'context-token']); + $requestData = ['foo' => 'bar']; + + $action = new PaymentValidateAction($shop, $source, $cart, $salesChannelContext, $requestData); + + static::assertSame($shop, $action->shop); + static::assertSame($source, $action->source); + static::assertSame($cart, $action->cart); + static::assertSame($salesChannelContext, $action->salesChannelContext); + static::assertSame($requestData, $action->requestData); + } +} diff --git a/tests/Context/Payment/RecurringDataTest.php b/tests/Context/Payment/RecurringDataTest.php new file mode 100644 index 0000000..e3368ac --- /dev/null +++ b/tests/Context/Payment/RecurringDataTest.php @@ -0,0 +1,26 @@ + '123', + 'nextSchedule' => '2021-01-01T00:00:00Z', + ]; + + $recurringData = new RecurringData($data); + + static::assertSame('123', $recurringData->getSubscriptionId()); + static::assertEquals(new \DateTime('2021-01-01T00:00:00Z'), $recurringData->getNextSchedule()); + } +} diff --git a/tests/Context/Payment/RefundActionTest.php b/tests/Context/Payment/RefundActionTest.php new file mode 100644 index 0000000..985d0bf --- /dev/null +++ b/tests/Context/Payment/RefundActionTest.php @@ -0,0 +1,32 @@ + 'order-id']); + $refund = new Refund(['externalReference' => 'reference-id']); + + $action = new RefundAction($shop, $source, $order, $refund); + + static::assertSame($shop, $action->shop); + static::assertSame($source, $action->source); + static::assertSame($order, $action->order); + static::assertSame($refund, $action->refund); + } +} diff --git a/tests/Context/Payment/RefundTest.php b/tests/Context/Payment/RefundTest.php new file mode 100644 index 0000000..30bf58f --- /dev/null +++ b/tests/Context/Payment/RefundTest.php @@ -0,0 +1,62 @@ + 'refund-id', + 'reason' => 'reason', + 'amount' => [ + 'totalPrice' => 100, + ], + 'stateMachineState' => [ + 'technicalName' => 'open', + ], + 'transactionCapture' => [ + 'externalReference' => 'reference-id', + ], + ]; + + $refund = new Refund($data); + + static::assertSame('refund-id', $refund->getId()); + static::assertSame('reason', $refund->getReason()); + static::assertSame(100.0, $refund->getAmount()->getTotalPrice()); + static::assertSame('open', $refund->getStateMachineState()->getTechnicalName()); + static::assertSame('reference-id', $refund->getTransactionCapture()->getExternalReference()); + } + + public function testConstructWithNullReason(): void + { + $data = [ + 'id' => 'refund-id', + 'reason' => null, + 'amount' => [ + 'totalPrice' => 100, + ], + 'stateMachineState' => [ + 'technicalName' => 'open', + ], + 'transactionCapture' => [ + 'externalReference' => 'reference-id', + ], + ]; + + $refund = new Refund($data); + + static::assertNull($refund->getReason()); + static::assertSame(100.0, $refund->getAmount()->getTotalPrice()); + static::assertSame('open', $refund->getStateMachineState()->getTechnicalName()); + static::assertSame('reference-id', $refund->getTransactionCapture()->getExternalReference()); + } +} diff --git a/tests/Context/Payment/RefundTransactionCaptureTest.php b/tests/Context/Payment/RefundTransactionCaptureTest.php new file mode 100644 index 0000000..4a78621 --- /dev/null +++ b/tests/Context/Payment/RefundTransactionCaptureTest.php @@ -0,0 +1,82 @@ + 'reference-id', + 'amount' => [ + 'totalPrice' => 100, + ], + 'transaction' => [ + 'id' => 'transaction-id', + ], + 'customFields' => [ + 'custom-field' => 'custom-value', + ], + ]; + + $refundTransactionCapture = new RefundTransactionCapture($data); + + static::assertSame('reference-id', $refundTransactionCapture->getExternalReference()); + static::assertSame(100.0, $refundTransactionCapture->getAmount()->getTotalPrice()); + static::assertSame('transaction-id', $refundTransactionCapture->getTransaction()->getId()); + static::assertArrayHasKey('custom-field', $refundTransactionCapture->getCustomFields()); + static::assertSame('custom-value', $refundTransactionCapture->getCustomFields()['custom-field']); + } + + public function testConstructWithNullExternalReference(): void + { + $data = [ + 'externalReference' => null, + 'amount' => [ + 'totalPrice' => 100, + ], + 'transaction' => [ + 'id' => 'transaction-id', + ], + 'customFields' => [ + 'custom-field' => 'custom-value', + ], + ]; + + $refundTransactionCapture = new RefundTransactionCapture($data); + + static::assertNull($refundTransactionCapture->getExternalReference()); + static::assertSame(100.0, $refundTransactionCapture->getAmount()->getTotalPrice()); + static::assertSame('transaction-id', $refundTransactionCapture->getTransaction()->getId()); + static::assertArrayHasKey('custom-field', $refundTransactionCapture->getCustomFields()); + static::assertSame('custom-value', $refundTransactionCapture->getCustomFields()['custom-field']); + } + + public function testConstructWithNullCustomFields(): void + { + $data = [ + 'externalReference' => 'reference-id', + 'amount' => [ + 'totalPrice' => 100, + ], + 'transaction' => [ + 'id' => 'transaction-id', + ], + 'customFields' => null, + ]; + + $refundTransactionCapture = new RefundTransactionCapture($data); + + static::assertSame('reference-id', $refundTransactionCapture->getExternalReference()); + static::assertSame(100.0, $refundTransactionCapture->getAmount()->getTotalPrice()); + static::assertSame('transaction-id', $refundTransactionCapture->getTransaction()->getId()); + static::assertEmpty($refundTransactionCapture->getCustomFields()); + } +} diff --git a/tests/Context/SalesChannelContext/AddressTest.php b/tests/Context/SalesChannelContext/AddressTest.php index d0157a3..9dff271 100644 --- a/tests/Context/SalesChannelContext/AddressTest.php +++ b/tests/Context/SalesChannelContext/AddressTest.php @@ -5,14 +5,78 @@ namespace Shopware\App\SDK\Tests\Context\SalesChannelContext; use PHPUnit\Framework\Attributes\CoversClass; -use Shopware\App\SDK\Context\ArrayStruct; use Shopware\App\SDK\Context\SalesChannelContext\Address; use PHPUnit\Framework\TestCase; #[CoversClass(Address::class)] -#[CoversClass(ArrayStruct::class)] class AddressTest extends TestCase { + public function testConstruct(): void + { + $address = new Address([ + 'id' => 'test', + 'salutation' => ['id' => 'test'], + 'firstName' => 'test', + 'lastName' => 'test', + 'street' => 'test', + 'zipcode' => 'test', + 'city' => 'test', + 'company' => 'test', + 'department' => 'test', + 'title' => 'test', + 'country' => [ + 'iso3' => 'FOO', + ], + 'phoneNumber' => 'test', + 'additionalAddressLine1' => 'test', + 'additionalAddressLine2' => 'test', + 'countryState' => ['id' => 'test'], + ]); + + static::assertSame('test', $address->getId()); + static::assertSame('test', $address->getSalutation()?->getId()); + static::assertSame('test', $address->getFirstName()); + static::assertSame('test', $address->getLastName()); + static::assertSame('test', $address->getStreet()); + static::assertSame('test', $address->getZipCode()); + static::assertSame('test', $address->getCity()); + static::assertSame('test', $address->getCompany()); + static::assertSame('test', $address->getDepartment()); + static::assertSame('test', $address->getTitle()); + static::assertSame('FOO', $address->getCountry()->getIso3()); + static::assertSame('test', $address->getPhoneNumber()); + static::assertSame('test', $address->getAdditionalAddressLine1()); + static::assertSame('test', $address->getAdditionalAddressLine2()); + static::assertSame('test', $address->getCountryState()?->getId()); + } + + public function testConstructWithNullables(): void + { + $address = new Address([ + 'id' => 'test', + 'firstName' => 'test', + 'lastName' => 'test', + 'street' => 'test', + 'zipcode' => 'test', + 'city' => 'test', + ]); + + static::assertSame('test', $address->getId()); + static::assertNull($address->getSalutation()); + static::assertSame('test', $address->getFirstName()); + static::assertSame('test', $address->getLastName()); + static::assertSame('test', $address->getStreet()); + static::assertSame('test', $address->getZipCode()); + static::assertSame('test', $address->getCity()); + static::assertNull($address->getCompany()); + static::assertNull($address->getDepartment()); + static::assertNull($address->getTitle()); + static::assertNull($address->getPhoneNumber()); + static::assertNull($address->getAdditionalAddressLine1()); + static::assertNull($address->getAdditionalAddressLine2()); + static::assertNull($address->getCountryState()); + } + public function testEmptySalutation(): void { $address = new Address([]); diff --git a/tests/Context/SalesChannelContext/CountryStateTest.php b/tests/Context/SalesChannelContext/CountryStateTest.php new file mode 100644 index 0000000..2f25418 --- /dev/null +++ b/tests/Context/SalesChannelContext/CountryStateTest.php @@ -0,0 +1,28 @@ + 'test', + 'name' => 'foo', + 'shortCode' => 'FOO', + 'position' => 1, + ]); + + static::assertSame('test', $countryState->getId()); + static::assertSame('foo', $countryState->getName()); + static::assertSame('FOO', $countryState->getShortCode()); + static::assertSame(1, $countryState->getPosition()); + } +} diff --git a/tests/Context/SalesChannelContext/CountryTest.php b/tests/Context/SalesChannelContext/CountryTest.php new file mode 100644 index 0000000..0a87fe6 --- /dev/null +++ b/tests/Context/SalesChannelContext/CountryTest.php @@ -0,0 +1,30 @@ + 'test', + 'iso' => 'foo', + 'iso3' => 'FOO', + 'customerTax' => ['currencyId' => 'currency-id'], + 'companyTax' => ['currencyId' => 'currency-id'], + ]); + + static::assertSame('test', $country->getName()); + static::assertSame('foo', $country->getIso()); + static::assertSame('FOO', $country->getIso3()); + static::assertSame('currency-id', $country->getCustomerTax()->getCurrencyId()); + static::assertSame('currency-id', $country->getCompanyTax()->getCurrencyId()); + } +} diff --git a/tests/Context/SalesChannelContext/CurrencyTest.php b/tests/Context/SalesChannelContext/CurrencyTest.php index ec492ce..2c352cc 100644 --- a/tests/Context/SalesChannelContext/CurrencyTest.php +++ b/tests/Context/SalesChannelContext/CurrencyTest.php @@ -6,13 +6,36 @@ use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; -use Shopware\App\SDK\Context\ArrayStruct; use Shopware\App\SDK\Context\SalesChannelContext\Currency; #[CoversClass(Currency::class)] -#[CoversClass(ArrayStruct::class)] class CurrencyTest extends TestCase { + public function testConstruct(): void + { + $currency = new Currency([ + 'id' => 'test', + 'isoCode' => 'baz', + 'factor' => 1.0, + 'symbol' => 'bar', + 'shortName' => 'FOO', + 'name' => 'foofoo', + 'itemRounding' => ['decimals' => 2], + 'totalRounding' => ['decimals' => 2], + 'taxFreeFrom' => 100.0, + ]); + + static::assertSame('test', $currency->getId()); + static::assertSame('baz', $currency->getIsoCode()); + static::assertSame(1.0, $currency->getFactor()); + static::assertSame('bar', $currency->getSymbol()); + static::assertSame('FOO', $currency->getShortName()); + static::assertSame('foofoo', $currency->getName()); + static::assertSame(2, $currency->getItemRounding()->getDecimals()); + static::assertSame(2, $currency->getTotalRounding()->getDecimals()); + static::assertSame(100.0, $currency->getTaxFreeFrom()); + } + public function testGetTaxFreeFrom(): void { $currency = new Currency(['taxFreeFrom' => 100]); diff --git a/tests/Context/SalesChannelContext/CustomerTest.php b/tests/Context/SalesChannelContext/CustomerTest.php index c11ffe0..b964a21 100644 --- a/tests/Context/SalesChannelContext/CustomerTest.php +++ b/tests/Context/SalesChannelContext/CustomerTest.php @@ -5,29 +5,65 @@ namespace Shopware\App\SDK\Tests\Context\SalesChannelContext; use PHPUnit\Framework\Attributes\CoversClass; -use Shopware\App\SDK\Context\ArrayStruct; use Shopware\App\SDK\Context\SalesChannelContext\Customer; use PHPUnit\Framework\TestCase; #[CoversClass(Customer::class)] -#[CoversClass(ArrayStruct::class)] class CustomerTest extends TestCase { - public function testEmptySalutation(): void + public function testConstruct(): void { - $customer = new Customer(['salutation' => null]); - static::assertNull($customer->getSalutation()); - } + $customer = new Customer([ + 'id' => 'test', + 'firstName' => 'test', + 'lastName' => 'test', + 'email' => 'test@example.com', + 'company' => 'test ltd.', + 'customerNumber' => '123', + 'title' => 'Dr.', + 'active' => true, + 'guest' => false, + 'accountType' => 'customer', + 'vatIds' => ['foo', 'bar'], + 'remoteAddress' => '127.0.0.1', + 'salutation' => ['id' => 'test'], + 'defaultPaymentMethod' => ['id' => 'test'], + 'defaultBillingAddress' => ['id' => 'test'], + 'defaultShippingAddress' => ['id' => 'test'], + 'activeBillingAddress' => ['id' => 'test'], + 'activeShippingAddress' => ['id' => 'test'], + ]); - public function testGetVatIds(): void - { - $customer = new Customer(['vatIds' => ['foo', 'bar']]); + static::assertSame('test', $customer->getId()); + static::assertSame('test', $customer->getFirstName()); + static::assertSame('test', $customer->getLastName()); + static::assertSame('test@example.com', $customer->getEmail()); + static::assertSame('test ltd.', $customer->getCompany()); + static::assertSame('123', $customer->getCustomerNumber()); + static::assertSame('Dr.', $customer->getTitle()); + static::assertTrue($customer->isActive()); + static::assertFalse($customer->isGuest()); + static::assertSame('customer', $customer->getAccountType()); static::assertSame(['foo', 'bar'], $customer->getVatIds()); + static::assertSame('127.0.0.1', $customer->getRemoteAddress()); + static::assertSame('test', $customer->getSalutation()?->getId()); + static::assertSame('test', $customer->getDefaultPaymentMethod()->getId()); + static::assertSame('test', $customer->getDefaultBillingAddress()->getId()); + static::assertSame('test', $customer->getDefaultShippingAddress()->getId()); + static::assertSame('test', $customer->getActiveBillingAddress()->getId()); + static::assertSame('test', $customer->getActiveShippingAddress()->getId()); } - public function testGetEmail(): void + public function testConstructNullables(): void { - $customer = new Customer(['email' => 'foo']); - static::assertSame('foo', $customer->getEmail()); + $customer = new Customer([ + 'company' => null, + 'title' => null, + 'salutation' => null, + ]); + + static::assertNull($customer->getCompany()); + static::assertNull($customer->getTitle()); + static::assertNull($customer->getSalutation()); } } diff --git a/tests/Context/SalesChannelContext/PaymentMethodTest.php b/tests/Context/SalesChannelContext/PaymentMethodTest.php new file mode 100644 index 0000000..7c67c17 --- /dev/null +++ b/tests/Context/SalesChannelContext/PaymentMethodTest.php @@ -0,0 +1,49 @@ + 'test', + 'name' => 'foo', + 'description' => 'FOO', + 'active' => true, + 'afterOrderEnabled' => true, + 'availabilityRuleId' => 'rule-id', + 'synchronous' => true, + 'asynchronous' => true, + 'prepared' => true, + 'refundable' => true, + ]); + + static::assertSame('test', $paymentMethod->getId()); + static::assertSame('foo', $paymentMethod->getName()); + static::assertSame('FOO', $paymentMethod->getDescription()); + static::assertTrue($paymentMethod->isActive()); + static::assertSame('rule-id', $paymentMethod->getAvailabilityRuleId()); + static::assertTrue($paymentMethod->isAfterOrderEnabled()); + static::assertTrue($paymentMethod->isSynchronous()); + static::assertTrue($paymentMethod->isAsynchronous()); + static::assertTrue($paymentMethod->isPrepared()); + static::assertTrue($paymentMethod->isRefundable()); + } + + public function testConstructNullable(): void + { + $paymentMethod = new PaymentMethod([ + 'availabilityRuleId' => null, + ]); + + static::assertNull($paymentMethod->getAvailabilityRuleId()); + } +} diff --git a/tests/Context/SalesChannelContext/RoundingConfigTest.php b/tests/Context/SalesChannelContext/RoundingConfigTest.php new file mode 100644 index 0000000..9b19cfb --- /dev/null +++ b/tests/Context/SalesChannelContext/RoundingConfigTest.php @@ -0,0 +1,26 @@ + 2, + 'interval' => 0.01, + 'roundForNet' => true, + ]); + + static::assertSame(2, $roundingConfig->getDecimals()); + static::assertSame(0.01, $roundingConfig->getInterval()); + static::assertTrue($roundingConfig->isRoundForNet()); + } +} diff --git a/tests/Context/SalesChannelContext/SalesChannelContextTest.php b/tests/Context/SalesChannelContext/SalesChannelContextTest.php index 5e0541d..66f271f 100644 --- a/tests/Context/SalesChannelContext/SalesChannelContextTest.php +++ b/tests/Context/SalesChannelContext/SalesChannelContextTest.php @@ -5,37 +5,55 @@ namespace Shopware\App\SDK\Tests\Context\SalesChannelContext; use PHPUnit\Framework\Attributes\CoversClass; -use Shopware\App\SDK\Context\ArrayStruct; use PHPUnit\Framework\TestCase; -use Shopware\App\SDK\Context\SalesChannelContext\RoundingConfig; use Shopware\App\SDK\Context\SalesChannelContext\SalesChannelContext; -#[CoversClass(ArrayStruct::class)] -#[CoversClass(RoundingConfig::class)] #[CoversClass(SalesChannelContext::class)] class SalesChannelContextTest extends TestCase { - public function testCustomer(): void + public function testConstruct(): void { - $context = new SalesChannelContext(['customer' => null]); - static::assertNull($context->getCustomer()); - } + $context = new SalesChannelContext([ + 'token' => 'context-token', + 'context' => [ + 'currencyId' => 'currency-id', + 'taxState' => 'net', + 'rounding' => ['decimals' => 2], + ], + 'currency' => [ + 'id' => 'currency-id', + ], + 'shippingMethod' => [ + 'id' => 'shipping-method-id', + ], + 'paymentMethod' => [ + 'id' => 'payment-method-id', + ], + 'salesChannel' => [ + 'id' => 'sales-channel-id', + ], + 'customer' => [ + 'id' => 'customer-id', + ], + ]); - public function testGetCurrencyId(): void - { - $context = new SalesChannelContext(['context' => ['currencyId' => 'foo']]); - static::assertSame('foo', $context->getCurrencyId()); + static::assertSame('context-token', $context->getToken()); + static::assertSame('currency-id', $context->getCurrencyId()); + static::assertSame('net', $context->getTaxState()); + static::assertSame(2, $context->getRounding()->getDecimals()); + static::assertSame('currency-id', $context->getCurrency()->getId()); + static::assertSame('shipping-method-id', $context->getShippingMethod()->getId()); + static::assertSame('payment-method-id', $context->getPaymentMethod()->getId()); + static::assertSame('sales-channel-id', $context->getSalesChannel()->getId()); + static::assertSame('customer-id', $context->getCustomer()->getId()); } - public function testGetTaxState(): void + public function testConstructNullable(): void { - $context = new SalesChannelContext(['context' => ['taxState' => 'foo']]); - static::assertSame('foo', $context->getTaxState()); - } + $context = new SalesChannelContext([ + 'customer' => null, + ]); - public function testGetRounding(): void - { - $context = new SalesChannelContext(['context' => ['rounding' => ['decimals' => 2]]]); - static::assertSame(2, $context->getRounding()->getDecimals()); + static::assertNull($context->getCustomer()); } } diff --git a/tests/Context/SalesChannelContext/SalesChannelDomainTest.php b/tests/Context/SalesChannelContext/SalesChannelDomainTest.php new file mode 100644 index 0000000..dfddbdb --- /dev/null +++ b/tests/Context/SalesChannelContext/SalesChannelDomainTest.php @@ -0,0 +1,30 @@ + 'sales-channel-domain-id', + 'url' => 'https://foo.com', + 'languageId' => 'language-id', + 'currencyId' => 'currency-id', + 'snippetSetId' => 'snippet-set-id', + ]); + + static::assertSame('sales-channel-domain-id', $salesChannelDomain->getId()); + static::assertSame('https://foo.com', $salesChannelDomain->getUrl()); + static::assertSame('language-id', $salesChannelDomain->getLanguageId()); + static::assertSame('currency-id', $salesChannelDomain->getCurrencyId()); + static::assertSame('snippet-set-id', $salesChannelDomain->getSnippetSetId()); + } +} diff --git a/tests/Context/SalesChannelContext/SalesChannelTest.php b/tests/Context/SalesChannelContext/SalesChannelTest.php new file mode 100644 index 0000000..8d78a1f --- /dev/null +++ b/tests/Context/SalesChannelContext/SalesChannelTest.php @@ -0,0 +1,40 @@ + 'test', + 'name' => 'foo', + 'accessKey' => 'eyFoo', + 'taxCalculationType' => 'vertical', + 'currency' => ['id' => 'currency-id'], + 'domains' => [ + ['url' => 'https://foo.com'], + ['url' => 'https://bar.com'], + ], + ]); + + static::assertSame('test', $salesChannel->getId()); + static::assertSame('foo', $salesChannel->getName()); + static::assertSame('eyFoo', $salesChannel->getAccessKey()); + static::assertSame('vertical', $salesChannel->getTaxCalculationType()); + static::assertSame('currency-id', $salesChannel->getCurrency()->getId()); + static::assertCount(2, $salesChannel->getDomains()); + + $domains = $salesChannel->getDomains(); + + static::assertSame('https://foo.com', $domains->first()?->getUrl()); + static::assertSame('https://bar.com', $domains->last()?->getUrl()); + } +} diff --git a/tests/Context/SalesChannelContext/SalutationTest.php b/tests/Context/SalesChannelContext/SalutationTest.php new file mode 100644 index 0000000..47bd10b --- /dev/null +++ b/tests/Context/SalesChannelContext/SalutationTest.php @@ -0,0 +1,28 @@ + 'salutation-id', + 'displayName' => 'display-name', + 'letterName' => 'letter-name', + 'salutationKey' => 'salutation-key', + ]); + + static::assertSame('salutation-id', $salutation->getId()); + static::assertSame('salutation-key', $salutation->getSalutationKey()); + static::assertSame('display-name', $salutation->getDisplayName()); + static::assertSame('letter-name', $salutation->getLetterName()); + } +} diff --git a/tests/Context/SalesChannelContext/ShippingLocationTest.php b/tests/Context/SalesChannelContext/ShippingLocationTest.php index a0d96f9..a652e65 100644 --- a/tests/Context/SalesChannelContext/ShippingLocationTest.php +++ b/tests/Context/SalesChannelContext/ShippingLocationTest.php @@ -5,23 +5,31 @@ namespace Shopware\App\SDK\Tests\Context\SalesChannelContext; use PHPUnit\Framework\Attributes\CoversClass; -use Shopware\App\SDK\Context\ArrayStruct; use Shopware\App\SDK\Context\SalesChannelContext\ShippingLocation; use PHPUnit\Framework\TestCase; -/** - * @internal - * - * @covers \Shopware\App\SDK\Context\SalesChannelContext\ShippingLocation - */ #[CoversClass(ShippingLocation::class)] -#[CoversClass(ArrayStruct::class)] class ShippingLocationTest extends TestCase { - public function testFilledState(): void + public function testConstruct(): void { - $location = new ShippingLocation(['countryState' => []]); + $shippingLocation = new ShippingLocation([ + 'country' => ['iso3' => 'FOO'], + 'countryState' => ['id' => 'state-id'], + 'address' => ['id' => 'address-id'], + ]); - static::assertNotNull($location->getCountryState()); + static::assertSame('FOO', $shippingLocation->getCountry()->getIso3()); + static::assertSame('state-id', $shippingLocation->getCountryState()->getId()); + static::assertSame('address-id', $shippingLocation->getAddress()->getId()); + } + + public function testConstructNullable(): void + { + $shippingLocation = new ShippingLocation([ + 'countryState' => null, + ]); + + static::assertNull($shippingLocation->getCountryState()); } } diff --git a/tests/Context/SalesChannelContext/ShippingMethodTest.php b/tests/Context/SalesChannelContext/ShippingMethodTest.php new file mode 100644 index 0000000..48160e9 --- /dev/null +++ b/tests/Context/SalesChannelContext/ShippingMethodTest.php @@ -0,0 +1,26 @@ + 'shipping-method-id', + 'name' => 'shipping-method-name', + 'taxType' => 'net', + ]); + + static::assertSame('shipping-method-id', $shippingMethod->getId()); + static::assertSame('shipping-method-name', $shippingMethod->getName()); + static::assertSame('net', $shippingMethod->getTaxType()); + } +} diff --git a/tests/Context/SalesChannelContext/TaxInfoTest.php b/tests/Context/SalesChannelContext/TaxInfoTest.php new file mode 100644 index 0000000..f03257e --- /dev/null +++ b/tests/Context/SalesChannelContext/TaxInfoTest.php @@ -0,0 +1,26 @@ + true, + 'currencyId' => 'currency-id', + 'amount' => 100.0, + ]); + + static::assertTrue($taxInfo->isEnabled()); + static::assertSame('currency-id', $taxInfo->getCurrencyId()); + static::assertSame(100.0, $taxInfo->getAmount()); + } +} diff --git a/tests/Context/Storefront/StorefrontActionTest.php b/tests/Context/Storefront/StorefrontActionTest.php new file mode 100644 index 0000000..465914f --- /dev/null +++ b/tests/Context/Storefront/StorefrontActionTest.php @@ -0,0 +1,26 @@ + 'sales-channel-id']); + + $storefrontAction = new StorefrontAction($shop, $claims); + + static::assertSame($shop, $storefrontAction->shop); + static::assertSame($claims, $storefrontAction->claims); + } +} diff --git a/tests/Context/Storefront/StorefrontClaimsTest.php b/tests/Context/Storefront/StorefrontClaimsTest.php index f4df65b..caf60cf 100644 --- a/tests/Context/Storefront/StorefrontClaimsTest.php +++ b/tests/Context/Storefront/StorefrontClaimsTest.php @@ -7,10 +7,8 @@ use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; use Shopware\App\SDK\Context\Storefront\StorefrontClaims; -use Shopware\App\SDK\Exception\MissingClaimException; #[CoversClass(StorefrontClaims::class)] -#[CoversClass(MissingClaimException::class)] class StorefrontClaimsTest extends TestCase { public function testAllSet(): void diff --git a/tests/Context/TaxProvider/TaxProviderActionTest.php b/tests/Context/TaxProvider/TaxProviderActionTest.php new file mode 100644 index 0000000..c045dc1 --- /dev/null +++ b/tests/Context/TaxProvider/TaxProviderActionTest.php @@ -0,0 +1,32 @@ + 'sales-channel-id']); + $cart = new Cart(['token' => 'cart-token']); + + $taxProviderAction = new TaxProviderAction($shop, $source, $context, $cart); + + static::assertSame($shop, $taxProviderAction->shop); + static::assertSame($source, $taxProviderAction->source); + static::assertSame($context, $taxProviderAction->context); + static::assertSame($cart, $taxProviderAction->cart); + } +} diff --git a/tests/Context/Trait/CustomFieldsAwareTraitTest.php b/tests/Context/Trait/CustomFieldsAwareTraitTest.php index 05932ee..615a279 100644 --- a/tests/Context/Trait/CustomFieldsAwareTraitTest.php +++ b/tests/Context/Trait/CustomFieldsAwareTraitTest.php @@ -6,11 +6,9 @@ use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; -use Shopware\App\SDK\Context\ArrayStruct; use Shopware\App\SDK\Context\Trait\CustomFieldsAware; use Shopware\App\SDK\Tests\Context\_fixtures\TestCustomFieldsAware; -#[CoversClass(ArrayStruct::class)] #[CoversClass(CustomFieldsAware::class)] class CustomFieldsAwareTraitTest extends TestCase { diff --git a/tests/Event/AbstractAppLifecycleEventTest.php b/tests/Event/AbstractAppLifecycleEventTest.php new file mode 100644 index 0000000..dccc182 --- /dev/null +++ b/tests/Event/AbstractAppLifecycleEventTest.php @@ -0,0 +1,26 @@ +getRequest()); + static::assertSame($shop, $event->getShop()); + } +} diff --git a/tests/Events/BeforeRegistrationCompletedEventTest.php b/tests/Event/BeforeRegistrationCompletedEventTest.php similarity index 86% rename from tests/Events/BeforeRegistrationCompletedEventTest.php rename to tests/Event/BeforeRegistrationCompletedEventTest.php index 64d94bc..324a86f 100644 --- a/tests/Events/BeforeRegistrationCompletedEventTest.php +++ b/tests/Event/BeforeRegistrationCompletedEventTest.php @@ -2,18 +2,15 @@ declare(strict_types=1); -namespace Shopware\App\SDK\Tests\Events; +namespace Shopware\App\SDK\Tests\Event; use Nyholm\Psr7\Request; use PHPUnit\Framework\Attributes\CoversClass; -use Shopware\App\SDK\Event\AbstractAppLifecycleEvent; use Shopware\App\SDK\Event\BeforeRegistrationCompletedEvent; use PHPUnit\Framework\TestCase; use Shopware\App\SDK\Test\MockShop; #[CoversClass(BeforeRegistrationCompletedEvent::class)] -#[CoversClass(AbstractAppLifecycleEvent::class)] -#[CoversClass(MockShop::class)] class BeforeRegistrationCompletedEventTest extends TestCase { public function testEvent(): void diff --git a/tests/Events/RegistrationCompletedEventTest.php b/tests/Event/RegistrationCompletedEventTest.php similarity index 84% rename from tests/Events/RegistrationCompletedEventTest.php rename to tests/Event/RegistrationCompletedEventTest.php index a5a09c6..5d97671 100644 --- a/tests/Events/RegistrationCompletedEventTest.php +++ b/tests/Event/RegistrationCompletedEventTest.php @@ -2,18 +2,15 @@ declare(strict_types=1); -namespace Shopware\App\SDK\Tests\Events; +namespace Shopware\App\SDK\Tests\Event; use Nyholm\Psr7\Request; use PHPUnit\Framework\Attributes\CoversClass; -use Shopware\App\SDK\Event\AbstractAppLifecycleEvent; use Shopware\App\SDK\Event\RegistrationCompletedEvent; use PHPUnit\Framework\TestCase; use Shopware\App\SDK\Test\MockShop; #[CoversClass(RegistrationCompletedEvent::class)] -#[CoversClass(AbstractAppLifecycleEvent::class)] -#[CoversClass(MockShop::class)] class RegistrationCompletedEventTest extends TestCase { public function testEvent(): void diff --git a/tests/Exception/MissingClaimExceptionTest.php b/tests/Exception/MissingClaimExceptionTest.php new file mode 100644 index 0000000..fc7f3c1 --- /dev/null +++ b/tests/Exception/MissingClaimExceptionTest.php @@ -0,0 +1,20 @@ +getMessage()); + } +} diff --git a/tests/Framework/CollectionTest.php b/tests/Framework/CollectionTest.php new file mode 100644 index 0000000..9575ca0 --- /dev/null +++ b/tests/Framework/CollectionTest.php @@ -0,0 +1,176 @@ +all()); + } + + public function testAll(): void + { + $collection = new Collection(['1', 2.3, 'foo']); + + static::assertEquals(['1', 2.3, 'foo'], $collection->all()); + } + + public function testAdd(): void + { + $collection = new Collection(); + + $collection->add('foo'); + $collection->add('bar'); + $collection->add('baz'); + + static::assertEquals(['foo', 'bar', 'baz'], $collection->all()); + } + + public function testSet(): void + { + $collection = new Collection(); + + $collection->set(0, 'foo'); + $collection->set(1, 'bar'); + $collection->set(0, 'baz'); + $collection->set('foo', 'bar'); + + static::assertEquals(['baz', 'bar', 'foo' => 'bar'], $collection->all()); + } + + public function testGet(): void + { + $collection = new Collection(['foo', 'bar', 'baz' => 'qux']); + + static::assertEquals('bar', $collection->get(1)); + static::assertEquals('qux', $collection->get('baz')); + + static::assertEquals(null, $collection->get(3)); + static::assertEquals(null, $collection->get('invalid')); + } + + public function testFirst(): void + { + $collection = new Collection(['foo', 'bar', 'baz' => 'qux']); + + static::assertEquals('foo', $collection->first()); + } + + public function testLast(): void + { + $collection = new Collection(['foo', 'bar', 'baz' => 'qux']); + + static::assertEquals('qux', $collection->last()); + } + + public function testRemove(): void + { + $collection = new Collection(['foo', 'bar', 'baz' => 'qux']); + + $collection->remove(0); + $collection->remove('baz'); + + $collection->remove(3); + $collection->remove('invalid'); + + static::assertEquals([1 => 'bar'], $collection->all()); + } + + public function testHas(): void + { + $collection = new Collection(['foo', 'bar', 'baz' => 'qux']); + + static::assertTrue($collection->has(0)); + static::assertTrue($collection->has(1)); + static::assertTrue($collection->has('baz')); + + static::assertFalse($collection->has(3)); + static::assertFalse($collection->has('invalid')); + } + + public function testMap(): void + { + $collection = new Collection(['foo', 'bar', 'baz' => 'qux']); + + $new = $collection->map(function (string $value) { + return $value . '_new'; + }); + + static::assertEquals(['foo_new', 'bar_new', 'baz' => 'qux_new'], $new); + } + + public function testFilter(): void + { + $collection = new Collection(['foo', 'bar', 'baz' => 'qux']); + + $new = $collection->filter(function (string $value) { + return $value === 'bar'; + }); + + static::assertEquals([1 => 'bar'], $new->all()); + } + + public function testGetIterator(): void + { + $collection = new Collection(['foo', 'bar', 'baz' => 'qux']); + + $result = []; + foreach ($collection as $key => $value) { + $result[$key] = $value; + } + + static::assertEquals(['foo', 'bar', 'baz' => 'qux'], $result); + } + + public function testCount(): void + { + $collection = new Collection(['foo', 'bar', 'baz' => 'qux']); + + static::assertEquals(3, $collection->count()); + } + + public function testJsonSerialize(): void + { + $jsonSerialize = new class () implements \JsonSerializable { + public CalculatedTax $tax; + + public function __construct() + { + $this->tax = new CalculatedTax([ + 'taxRate' => 19, + 'tax' => 200, + 'price' => 100, + ]); + } + + /** + * @return mixed[] + */ + public function jsonSerialize(): array + { + return $this->tax->jsonSerialize(); + } + }; + + $collection = new Collection(['foo', 'bar', 'baz' => 'qux', $jsonSerialize, $jsonSerialize]); + + static::assertEquals([ + 'foo', + 'bar', + 'baz' => 'qux', + ['taxRate' => 19, 'tax' => 200, 'price' => 100], + ['taxRate' => 19, 'tax' => 200, 'price' => 100], + ], $collection->jsonSerialize()); + } +} diff --git a/tests/Gateway/Checkout/CheckoutGatewayCommandTest.php b/tests/Gateway/Checkout/CheckoutGatewayCommandTest.php new file mode 100644 index 0000000..e2a225e --- /dev/null +++ b/tests/Gateway/Checkout/CheckoutGatewayCommandTest.php @@ -0,0 +1,67 @@ +getCommand(); + $command->setPayloadValue('key', 'value'); + + static::assertEquals('value', $command->getPayloadValue('key')); + } + + public function testHasPayloadValue(): void + { + $command = $this->getCommand(); + $command->setPayloadValue('key', 'value'); + + static::assertTrue($command->hasPayloadValue('key')); + } + + public function testNotHasPayloadValue(): void + { + $command = $this->getCommand(); + $command->setPayloadValue('key', 'value'); + + static::assertFalse($command->hasPayloadValue('foo')); + } + + public function testGetPayloadValue(): void + { + $command = $this->getCommand(); + $command->setPayloadValue('key', 'value'); + + static::assertEquals('value', $command->getPayloadValue('key')); + } + + public function testGetNonExistentPayloadValue(): void + { + $command = $this->getCommand(); + $command->setPayloadValue('key', 'value'); + + static::assertNull($command->getPayloadValue('foo')); + } + + public function testJsonSerialize(): void + { + $command = $this->getCommand(); + $command->keyName = 'key'; + $command->setPayloadValue('key', 'value'); + + static::assertEquals(['command' => 'key', 'payload' => ['key' => 'value']], $command->jsonSerialize()); + } + + private function getCommand(): CheckoutGatewayCommand + { + return new class () extends CheckoutGatewayCommand {}; + } +} diff --git a/tests/Gateway/Checkout/Command/AddCartErrorCommandTest.php b/tests/Gateway/Checkout/Command/AddCartErrorCommandTest.php new file mode 100644 index 0000000..9cc0c2e --- /dev/null +++ b/tests/Gateway/Checkout/Command/AddCartErrorCommandTest.php @@ -0,0 +1,48 @@ +message); + static::assertTrue($command->blocking); + static::assertSame(Error::LEVEL_ERROR, $command->level); + static::assertSame('add-cart-error', $command->keyName); + } + + public function testConstructWithDefaults(): void + { + $command = new AddCartErrorCommand('foo'); + + static::assertSame('foo', $command->message); + static::assertFalse($command->blocking); + static::assertSame(Error::LEVEL_WARNING, $command->level); + static::assertSame('add-cart-error', $command->keyName); + } + + public function testPayloadOnConstruct(): void + { + $command = new AddCartErrorCommand('foo', true, Error::LEVEL_ERROR); + + static::assertSame('foo', $command->getPayloadValue('message')); + static::assertTrue($command->getPayloadValue('blocking')); + static::assertSame(Error::LEVEL_ERROR, $command->getPayloadValue('level')); + } + + public function testKey(): void + { + static::assertSame('add-cart-error', AddCartErrorCommand::KEY); + } +} diff --git a/tests/Gateway/Checkout/Command/AddPaymentMethodCommandTest.php b/tests/Gateway/Checkout/Command/AddPaymentMethodCommandTest.php new file mode 100644 index 0000000..5c621f3 --- /dev/null +++ b/tests/Gateway/Checkout/Command/AddPaymentMethodCommandTest.php @@ -0,0 +1,33 @@ +paymentMethodTechnicalName); + static::assertSame('add-payment-method', $command->keyName); + } + + public function testPayloadOnConstruct(): void + { + $command = new AddPaymentMethodCommand('paypal'); + + static::assertSame('paypal', $command->getPayloadValue('paymentMethodTechnicalName')); + } + + public function testKey(): void + { + static::assertSame('add-payment-method', AddPaymentMethodCommand::KEY); + } +} diff --git a/tests/Gateway/Checkout/Command/AddPaymentMethodExtensionCommandTest.php b/tests/Gateway/Checkout/Command/AddPaymentMethodExtensionCommandTest.php new file mode 100644 index 0000000..9878840 --- /dev/null +++ b/tests/Gateway/Checkout/Command/AddPaymentMethodExtensionCommandTest.php @@ -0,0 +1,37 @@ +paymentMethodTechnicalName); + static::assertSame('foo', $command->extensionKey); + static::assertSame(['bar'], $command->extensionsPayload); + static::assertSame('add-payment-method-extension', $command->keyName); + } + + public function testPayloadOnConstruct(): void + { + $command = new AddPaymentMethodExtensionCommand('paypal', 'foo', ['bar']); + + static::assertSame('paypal', $command->getPayloadValue('paymentMethodTechnicalName')); + static::assertSame('foo', $command->getPayloadValue('extensionKey')); + static::assertSame(['bar'], $command->getPayloadValue('extensionsPayload')); + } + + public function testKey(): void + { + static::assertSame('add-payment-method-extension', AddPaymentMethodExtensionCommand::KEY); + } +} diff --git a/tests/Gateway/Checkout/Command/AddShippingMethodCommandTest.php b/tests/Gateway/Checkout/Command/AddShippingMethodCommandTest.php new file mode 100644 index 0000000..28d0632 --- /dev/null +++ b/tests/Gateway/Checkout/Command/AddShippingMethodCommandTest.php @@ -0,0 +1,33 @@ +shippingMethodTechnicalName); + static::assertSame('add-shipping-method', $command->keyName); + } + + public function testPayloadOnConstruct(): void + { + $command = new AddShippingMethodCommand('dhl'); + + static::assertSame('dhl', $command->getPayloadValue('shippingMethodTechnicalName')); + } + + public function testKey(): void + { + static::assertSame('add-shipping-method', AddShippingMethodCommand::KEY); + } +} diff --git a/tests/Gateway/Checkout/Command/AddShippingMethodExtensionCommandTest.php b/tests/Gateway/Checkout/Command/AddShippingMethodExtensionCommandTest.php new file mode 100644 index 0000000..9ab312c --- /dev/null +++ b/tests/Gateway/Checkout/Command/AddShippingMethodExtensionCommandTest.php @@ -0,0 +1,37 @@ +shippingMethodTechnicalName); + static::assertSame('foo', $command->extensionKey); + static::assertSame(['bar'], $command->extensionsPayload); + static::assertSame('add-shipping-method-extension', $command->keyName); + } + + public function testPayloadOnConstruct(): void + { + $command = new AddShippingMethodExtensionCommand('dhl', 'foo', ['bar']); + + static::assertSame('dhl', $command->getPayloadValue('shippingMethodTechnicalName')); + static::assertSame('foo', $command->getPayloadValue('extensionKey')); + static::assertSame(['bar'], $command->getPayloadValue('extensionsPayload')); + } + + public function testKey(): void + { + static::assertSame('add-shipping-method-extension', AddShippingMethodExtensionCommand::KEY); + } +} diff --git a/tests/Gateway/Checkout/Command/RemovePaymentMethodCommandTest.php b/tests/Gateway/Checkout/Command/RemovePaymentMethodCommandTest.php new file mode 100644 index 0000000..ef995ca --- /dev/null +++ b/tests/Gateway/Checkout/Command/RemovePaymentMethodCommandTest.php @@ -0,0 +1,33 @@ +paymentMethodTechnicalName); + static::assertSame('remove-payment-method', $command->keyName); + } + + public function testPayloadOnConstruct(): void + { + $command = new RemovePaymentMethodCommand('paypal'); + + static::assertSame('paypal', $command->getPayloadValue('paymentMethodTechnicalName')); + } + + public function testKey(): void + { + static::assertSame('remove-payment-method', RemovePaymentMethodCommand::KEY); + } +} diff --git a/tests/Gateway/Checkout/Command/RemoveShippingMethodCommandTest.php b/tests/Gateway/Checkout/Command/RemoveShippingMethodCommandTest.php new file mode 100644 index 0000000..3f40d04 --- /dev/null +++ b/tests/Gateway/Checkout/Command/RemoveShippingMethodCommandTest.php @@ -0,0 +1,33 @@ +shippingMethodTechnicalName); + static::assertSame('remove-shipping-method', $command->keyName); + } + + public function testPayloadOnConstruct(): void + { + $command = new RemoveShippingMethodCommand('dhl'); + + static::assertSame('dhl', $command->getPayloadValue('shippingMethodTechnicalName')); + } + + public function testKey(): void + { + static::assertSame('remove-shipping-method', RemoveShippingMethodCommand::KEY); + } +} diff --git a/tests/HttpClient/AuthenticatedClientTest.php b/tests/HttpClient/AuthenticatedClientTest.php index fe41409..8e6e028 100644 --- a/tests/HttpClient/AuthenticatedClientTest.php +++ b/tests/HttpClient/AuthenticatedClientTest.php @@ -20,10 +20,6 @@ use Shopware\App\SDK\Test\MockShop; #[CoversClass(AuthenticatedClient::class)] -#[CoversClass(MockShop::class)] -#[CoversClass(NullCache::class)] -#[CoversClass(AuthenticationFailedException::class)] -#[CoversClass(MockClient::class)] class AuthenticatedClientTest extends TestCase { public function testAuthenticationFails(): void diff --git a/tests/HttpClient/ClientFactoryTest.php b/tests/HttpClient/ClientFactoryTest.php index 287bf52..b08c3fb 100644 --- a/tests/HttpClient/ClientFactoryTest.php +++ b/tests/HttpClient/ClientFactoryTest.php @@ -9,20 +9,12 @@ use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\DoesNotPerformAssertions; use Psr\Http\Client\ClientInterface; -use Shopware\App\SDK\HttpClient\AuthenticatedClient; use Shopware\App\SDK\HttpClient\ClientFactory; use PHPUnit\Framework\TestCase; -use Shopware\App\SDK\HttpClient\LoggerClient; use Shopware\App\SDK\HttpClient\NullCache; -use Shopware\App\SDK\HttpClient\SimpleHttpClient\SimpleHttpClient; use Shopware\App\SDK\Test\MockShop; #[CoversClass(ClientFactory::class)] -#[CoversClass(MockShop::class)] -#[CoversClass(AuthenticatedClient::class)] -#[CoversClass(NullCache::class)] -#[CoversClass(LoggerClient::class)] -#[CoversClass(SimpleHttpClient::class)] class ClientFactoryTest extends TestCase { /** diff --git a/tests/HttpClient/LoggerClientTest.php b/tests/HttpClient/LoggerClientTest.php index 5f473b9..e5e197b 100644 --- a/tests/HttpClient/LoggerClientTest.php +++ b/tests/HttpClient/LoggerClientTest.php @@ -15,7 +15,6 @@ use Shopware\App\SDK\Test\MockClient; #[CoversClass(LoggerClient::class)] -#[CoversClass(MockClient::class)] class LoggerClientTest extends TestCase { public function testRequestGetsLogged(): void @@ -81,7 +80,7 @@ public function testBodyRewindIsCalled(): void $body = static::createMock(StreamInterface::class); $body - ->expects(static::once()) + ->expects(static::exactly(2)) ->method('rewind'); $body @@ -91,7 +90,7 @@ public function testBodyRewindIsCalled(): void $request = $request->withBody($body); $client = new LoggerClient(new MockClient([ - new Response(200, [], '{"foo": "bar"}') + new Response(200, [], $body) ]), static::createMock(LoggerInterface::class)); $client->sendRequest($request); diff --git a/tests/HttpClient/SimpleHttpClient/SimpleHttpClientTest.php b/tests/HttpClient/SimpleHttpClient/SimpleHttpClientTest.php index 5c347b6..a03c884 100644 --- a/tests/HttpClient/SimpleHttpClient/SimpleHttpClientTest.php +++ b/tests/HttpClient/SimpleHttpClient/SimpleHttpClientTest.php @@ -9,14 +9,11 @@ use PHPUnit\Framework\Attributes\DataProvider; use Psr\Http\Client\ClientInterface; use Psr\Http\Message\RequestInterface; -use Shopware\App\SDK\HttpClient\SimpleHttpClient\SimpleHttpClientResponse; use Shopware\App\SDK\HttpClient\SimpleHttpClient\SimpleHttpClient; use PHPUnit\Framework\TestCase; use Shopware\App\SDK\Test\MockClient; #[CoversClass(SimpleHttpClient::class)] -#[CoversClass(SimpleHttpClientResponse::class)] -#[CoversClass(MockClient::class)] class SimpleHttpClientTest extends TestCase { public function testGet(): void diff --git a/tests/Registration/RegistrationServiceTest.php b/tests/Registration/RegistrationServiceTest.php index 228a7e0..03b3023 100644 --- a/tests/Registration/RegistrationServiceTest.php +++ b/tests/Registration/RegistrationServiceTest.php @@ -13,7 +13,6 @@ use Shopware\App\SDK\AppConfiguration; use Shopware\App\SDK\Authentication\RequestVerifier; use Shopware\App\SDK\Authentication\ResponseSigner; -use Shopware\App\SDK\Event\AbstractAppLifecycleEvent; use Shopware\App\SDK\Event\BeforeRegistrationCompletedEvent; use Shopware\App\SDK\Event\RegistrationCompletedEvent; use Shopware\App\SDK\Exception\MissingShopParameterException; @@ -25,15 +24,6 @@ use Shopware\App\SDK\Test\MockShopRepository; #[CoversClass(RegistrationService::class)] -#[CoversClass(AppConfiguration::class)] -#[CoversClass(ResponseSigner::class)] -#[CoversClass(MissingShopParameterException::class)] -#[CoversClass(ShopNotFoundException::class)] -#[CoversClass(AbstractAppLifecycleEvent::class)] -#[CoversClass(MockShop::class)] -#[CoversClass(MockShopRepository::class)] -#[CoversClass(BeforeRegistrationCompletedEvent::class)] -#[CoversClass(RegistrationCompletedEvent::class)] class RegistrationServiceTest extends TestCase { private RegistrationService $registerService; diff --git a/tests/Response/GatewayResponseTest.php b/tests/Response/GatewayResponseTest.php new file mode 100644 index 0000000..ce085a5 --- /dev/null +++ b/tests/Response/GatewayResponseTest.php @@ -0,0 +1,29 @@ +getStatusCode()); + static::assertSame('[{"command":"add-payment-method","payload":{"paymentMethodTechnicalName":"paypal"}},{"command":"remove-payment-method","payload":{"paymentMethodTechnicalName":"credit_card"}}]', $response->getBody()->getContents()); + } +} diff --git a/tests/Response/PaymentResponseTest.php b/tests/Response/PaymentResponseTest.php index 2f50a71..93c6d7c 100644 --- a/tests/Response/PaymentResponseTest.php +++ b/tests/Response/PaymentResponseTest.php @@ -91,6 +91,14 @@ public function testChargeback(): void static::assertSame('{"status":"chargeback"}', $response->getBody()->getContents()); } + public function testReopen(): void + { + $response = PaymentResponse::reopen(); + + static::assertSame(200, $response->getStatusCode()); + static::assertSame('{"status":"reopen"}', $response->getBody()->getContents()); + } + public function testValidateSuccess(): void { $response = PaymentResponse::validateSuccess(['foo' => 'bar']); diff --git a/tests/Shop/ShopResolverTest.php b/tests/Shop/ShopResolverTest.php index 1977d06..978de06 100644 --- a/tests/Shop/ShopResolverTest.php +++ b/tests/Shop/ShopResolverTest.php @@ -17,10 +17,6 @@ use Shopware\App\SDK\Test\MockShopRepository; #[CoversClass(ShopResolver::class)] -#[CoversClass(MissingShopParameterException::class)] -#[CoversClass(ShopNotFoundException::class)] -#[CoversClass(MockShopRepository::class)] -#[CoversClass(MockShop::class)] class ShopResolverTest extends TestCase { private MockShopRepository $shopRepository; diff --git a/tests/TaxProvider/CalculatedTaxTest.php b/tests/TaxProvider/CalculatedTaxTest.php new file mode 100644 index 0000000..8d8ee55 --- /dev/null +++ b/tests/TaxProvider/CalculatedTaxTest.php @@ -0,0 +1,29 @@ +tax); + static::assertEquals(100.0, $tax->taxRate); + static::assertEquals(19.0, $tax->price); + } + + public function testJsonSerialize(): void + { + $tax = new CalculatedTax(19.0, 100.0, 19.0); + + static::assertEquals(['tax' => 19.0, 'taxRate' => 100.0, 'price' => 19.0], $tax->jsonSerialize()); + } +} diff --git a/tests/TaxProvider/TaxProviderResponseBuilderTest.php b/tests/TaxProvider/TaxProviderResponseBuilderTest.php index 13ceeb3..e65d3aa 100644 --- a/tests/TaxProvider/TaxProviderResponseBuilderTest.php +++ b/tests/TaxProvider/TaxProviderResponseBuilderTest.php @@ -10,7 +10,6 @@ use PHPUnit\Framework\TestCase; #[CoversClass(TaxProviderResponseBuilder::class)] -#[CoversClass(CalculatedTax::class)] class TaxProviderResponseBuilderTest extends TestCase { public function testGlobalTax(): void @@ -36,7 +35,7 @@ public function testLineItemTax(): void static::assertSame(200, $response->getStatusCode()); static::assertSame( - '{"lineItemTaxes":{"lineItem1":[{"tax":19,"taxRate":100,"price":19}]},"deliveryTaxes":[],"cartPriceTaxes":[]}', + '{"lineItemTaxes":{"lineItem1":{"tax":19,"taxRate":100,"price":19}},"deliveryTaxes":[],"cartPriceTaxes":[]}', $response->getBody()->getContents() ); } @@ -50,7 +49,7 @@ public function testDeliveryTax(): void static::assertSame(200, $response->getStatusCode()); static::assertSame( - '{"lineItemTaxes":[],"deliveryTaxes":{"delivery1":[{"tax":19,"taxRate":100,"price":19}]},"cartPriceTaxes":[]}', + '{"lineItemTaxes":[],"deliveryTaxes":{"delivery1":{"tax":19,"taxRate":100,"price":19}},"cartPriceTaxes":[]}', $response->getBody()->getContents() ); } diff --git a/tests/Test/MockClientTest.php b/tests/Test/MockClientTest.php index ad5b6a1..c7c1db2 100644 --- a/tests/Test/MockClientTest.php +++ b/tests/Test/MockClientTest.php @@ -39,4 +39,20 @@ public function testUsesQueue(): void static::assertSame(200, $response->getStatusCode()); static::assertSame('{"baz": "qux"}', $response->getBody()->getContents()); } + + public function testIsEmpty(): void + { + $client = new MockClient([]); + + static::assertTrue($client->isEmpty()); + } + + public function testIsNotEmpty(): void + { + $client = new MockClient([ + new Response(200, [], '{"foo": "bar"}'), + ]); + + static::assertFalse($client->isEmpty()); + } } diff --git a/tests/Test/MockShopRepositoryTest.php b/tests/Test/MockShopRepositoryTest.php index a3b0a5f..efe06e8 100644 --- a/tests/Test/MockShopRepositoryTest.php +++ b/tests/Test/MockShopRepositoryTest.php @@ -5,12 +5,10 @@ namespace Shopware\App\SDK\Tests\Test; use PHPUnit\Framework\Attributes\CoversClass; -use Shopware\App\SDK\Test\MockShop; use Shopware\App\SDK\Test\MockShopRepository; use PHPUnit\Framework\TestCase; #[CoversClass(MockShopRepository::class)] -#[CoversClass(MockShop::class)] class MockShopRepositoryTest extends TestCase { private MockShopRepository $repository; @@ -30,6 +28,12 @@ public function testLifecycle(): void static::assertSame($shop, $this->repository->getShopFromId('1')); + $shop->setShopUrl('https://example.org'); + + $this->repository->updateShop($shop); + + static::assertSame('https://example.org', $this->repository->getShopFromId('1')?->getShopUrl()); + $this->repository->deleteShop($shop->getShopId()); static::assertNull($this->repository->getShopFromId('1')); diff --git a/tests/Test/MockShopTest.php b/tests/Test/MockShopTest.php new file mode 100644 index 0000000..f7c272e --- /dev/null +++ b/tests/Test/MockShopTest.php @@ -0,0 +1,65 @@ +getShopId()); + static::assertSame('https://example.com', $shop->getShopUrl()); + static::assertSame('shop-secret', $shop->getShopSecret()); + static::assertFalse($shop->isShopActive()); + static::assertNull($shop->getShopClientId()); + static::assertNull($shop->getShopClientSecret()); + } + + public function testConstructWithCustomValues(): void + { + $shop = new MockShop('shop-id', 'https://example.com', 'shop-secret', true, 'client-id', 'client-secret'); + + static::assertSame('shop-id', $shop->getShopId()); + static::assertSame('https://example.com', $shop->getShopUrl()); + static::assertSame('shop-secret', $shop->getShopSecret()); + static::assertTrue($shop->isShopActive()); + static::assertSame('client-id', $shop->getShopClientId()); + static::assertSame('client-secret', $shop->getShopClientSecret()); + } + + public function testSetShopApiCredentials(): void + { + $shop = new MockShop('shop-id', 'https://example.com', 'shop-secret'); + + $shop->setShopApiCredentials('client-id', 'client-secret'); + + static::assertSame('client-id', $shop->getShopClientId()); + static::assertSame('client-secret', $shop->getShopClientSecret()); + } + + public function testSetShopUrl(): void + { + $shop = new MockShop('shop-id', 'https://example.com', 'shop-secret'); + + $shop->setShopUrl('https://example.org'); + + static::assertSame('https://example.org', $shop->getShopUrl()); + } + + public function testSetShopActive(): void + { + $shop = new MockShop('shop-id', 'https://example.com', 'shop-secret'); + + $shop->setShopActive(true); + + static::assertTrue($shop->isShopActive()); + } +} diff --git a/tests/Webhook/WebhookActionTest.php b/tests/Webhook/WebhookActionTest.php new file mode 100644 index 0000000..71d758d --- /dev/null +++ b/tests/Webhook/WebhookActionTest.php @@ -0,0 +1,32 @@ + 'order-id']; + $timestamp = new \DateTimeImmutable(); + + $webhookAction = new WebhookAction($shop, $source, $eventName, $payload, $timestamp); + + static::assertSame($shop, $webhookAction->shop); + static::assertSame($source, $webhookAction->source); + static::assertSame($eventName, $webhookAction->eventName); + static::assertSame($payload, $webhookAction->payload); + static::assertSame($timestamp, $webhookAction->timestamp); + } +}