[Api][Order] Enable Cart operations

This commit is contained in:
Wojdylak 2024-08-06 14:20:45 +02:00
parent 15d62e235f
commit 78e57b71dc
No known key found for this signature in database
GPG key ID: 7509E560A6821ABE
60 changed files with 1210 additions and 721 deletions

View file

@ -14,7 +14,7 @@ declare(strict_types=1);
namespace Sylius\Bundle\ApiBundle\Attribute;
#[\Attribute(\Attribute::TARGET_CLASS)]
final class LoggedInCustomerEmailIfNotSetAware
final class LoggedInCustomerEmailAware
{
public const DEFAULT_ARGUMENT_NAME = 'email';

View file

@ -0,0 +1,24 @@
<?php
/*
* This file is part of the Sylius package.
*
* (c) Sylius Sp. z o.o.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Sylius\Bundle\ApiBundle\Attribute;
#[\Attribute(\Attribute::TARGET_CLASS)]
final class OrderItemIdAware
{
public const DEFAULT_ARGUMENT_NAME = 'orderItemId';
public function __construct(public string $constructorArgumentName = self::DEFAULT_ARGUMENT_NAME)
{
}
}

View file

@ -15,9 +15,8 @@ namespace Sylius\Bundle\ApiBundle\Command\Account;
use Sylius\Bundle\ApiBundle\Command\IriToIdentifierConversionAwareInterface;
use Sylius\Bundle\ApiBundle\Command\OrderTokenValueAwareInterface;
use Sylius\Bundle\ApiBundle\Command\SubresourceIdAwareInterface;
class ChangePaymentMethod implements OrderTokenValueAwareInterface, SubresourceIdAwareInterface, IriToIdentifierConversionAwareInterface
class ChangePaymentMethod implements OrderTokenValueAwareInterface, IriToIdentifierConversionAwareInterface
{
/** @var string|null */
public $orderTokenValue;

View file

@ -18,29 +18,15 @@ use Sylius\Bundle\ApiBundle\Command\OrderTokenValueAwareInterface;
class AddItemToCart implements OrderTokenValueAwareInterface, IriToIdentifierConversionAwareInterface
{
/** @var string|null */
public $orderTokenValue;
public function __construct(public string $productVariantCode, public int $quantity)
{
}
public static function createFromData(string $tokenValue, string $productVariantCode, int $quantity): self
{
$command = new self($productVariantCode, $quantity);
$command->orderTokenValue = $tokenValue;
return $command;
public function __construct(
public string $productVariantCode,
public int $quantity,
public ?string $orderTokenValue = null
) {
}
public function getOrderTokenValue(): ?string
{
return $this->orderTokenValue;
}
public function setOrderTokenValue(?string $orderTokenValue): void
{
$this->orderTokenValue = $orderTokenValue;
}
}

View file

@ -13,29 +13,16 @@ declare(strict_types=1);
namespace Sylius\Bundle\ApiBundle\Command\Cart;
use Sylius\Bundle\ApiBundle\Command\OrderItemIdAwareInterface;
use Sylius\Bundle\ApiBundle\Command\OrderTokenValueAwareInterface;
use Sylius\Bundle\ApiBundle\Command\SubresourceIdAwareInterface;
class ChangeItemQuantityInCart implements OrderTokenValueAwareInterface, SubresourceIdAwareInterface
class ChangeItemQuantityInCart implements OrderTokenValueAwareInterface, OrderItemIdAwareInterface
{
/** @var string|null */
public $orderTokenValue;
/** @var string|null */
public $orderItemId;
public function __construct(public int $quantity)
{
}
public static function createFromData(string $tokenValue, string $orderItemId, int $quantity): self
{
$command = new self($quantity);
$command->orderTokenValue = $tokenValue;
$command->orderItemId = $orderItemId;
return $command;
public function __construct(
public int $quantity,
public ?int $orderItemId = null,
public ?string $orderTokenValue = null,
) {
}
public function getOrderTokenValue(): ?string
@ -43,23 +30,8 @@ class ChangeItemQuantityInCart implements OrderTokenValueAwareInterface, Subreso
return $this->orderTokenValue;
}
public function setOrderTokenValue(?string $orderTokenValue): void
{
$this->orderTokenValue = $orderTokenValue;
}
public function getSubresourceId(): ?string
public function getOrderItemId(): ?int
{
return $this->orderItemId;
}
public function setSubresourceId(?string $subresourceId): void
{
$this->orderItemId = $subresourceId;
}
public function getSubresourceIdAttributeKey(): string
{
return 'orderItemId';
}
}

View file

@ -14,22 +14,17 @@ declare(strict_types=1);
namespace Sylius\Bundle\ApiBundle\Command\Cart;
use Sylius\Bundle\ApiBundle\Command\ChannelCodeAwareInterface;
use Sylius\Bundle\ApiBundle\Command\CustomerEmailAwareInterface;
use Sylius\Bundle\ApiBundle\Command\LocaleCodeAwareInterface;
use Sylius\Bundle\ApiBundle\Command\LoggedInCustomerEmailAwareInterface;
class PickupCart implements ChannelCodeAwareInterface, CustomerEmailAwareInterface, LocaleCodeAwareInterface
class PickupCart implements ChannelCodeAwareInterface, LoggedInCustomerEmailAwareInterface, LocaleCodeAwareInterface
{
/** @var string|null */
public $localeCode;
/** @var string|null */
private $channelCode;
/** @var string|null */
public $email;
public function __construct(public ?string $tokenValue = null)
{
public function __construct(
public ?string $tokenValue = null,
public ?string $channelCode = null,
public ?string $email = null,
public ?string $localeCode = null,
) {
}
public function getChannelCode(): ?string
@ -37,28 +32,13 @@ class PickupCart implements ChannelCodeAwareInterface, CustomerEmailAwareInterfa
return $this->channelCode;
}
public function setChannelCode(?string $channelCode): void
{
$this->channelCode = $channelCode;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(?string $email): void
{
$this->email = $email;
}
public function getLocaleCode(): ?string
{
return $this->localeCode;
}
public function setLocaleCode(?string $localeCode): void
{
$this->localeCode = $localeCode;
}
}

View file

@ -14,9 +14,9 @@ declare(strict_types=1);
namespace Sylius\Bundle\ApiBundle\Command\Catalog;
use Sylius\Bundle\ApiBundle\Command\IriToIdentifierConversionAwareInterface;
use Sylius\Bundle\ApiBundle\Command\LoggedInCustomerEmailIfNotSetAwareInterface;
use Sylius\Bundle\ApiBundle\Command\LoggedInCustomerEmailAwareInterface;
readonly class AddProductReview implements IriToIdentifierConversionAwareInterface, LoggedInCustomerEmailIfNotSetAwareInterface
readonly class AddProductReview implements IriToIdentifierConversionAwareInterface, LoggedInCustomerEmailAwareInterface
{
public function __construct(
public string $title,

View file

@ -16,9 +16,8 @@ namespace Sylius\Bundle\ApiBundle\Command\Checkout;
use Sylius\Bundle\ApiBundle\Command\IriToIdentifierConversionAwareInterface;
use Sylius\Bundle\ApiBundle\Command\OrderTokenValueAwareInterface;
use Sylius\Bundle\ApiBundle\Command\PaymentMethodCodeAwareInterface;
use Sylius\Bundle\ApiBundle\Command\SubresourceIdAwareInterface;
class ChoosePaymentMethod implements OrderTokenValueAwareInterface, SubresourceIdAwareInterface, PaymentMethodCodeAwareInterface, IriToIdentifierConversionAwareInterface
class ChoosePaymentMethod implements OrderTokenValueAwareInterface, PaymentMethodCodeAwareInterface, IriToIdentifierConversionAwareInterface
{
/** @var string|null */
public $orderTokenValue;

View file

@ -15,26 +15,15 @@ namespace Sylius\Bundle\ApiBundle\Command\Checkout;
use Sylius\Bundle\ApiBundle\Command\IriToIdentifierConversionAwareInterface;
use Sylius\Bundle\ApiBundle\Command\OrderTokenValueAwareInterface;
use Sylius\Bundle\ApiBundle\Command\SubresourceIdAwareInterface;
use Sylius\Bundle\ApiBundle\Command\ShipmentIdAwareInterface;
class ChooseShippingMethod implements OrderTokenValueAwareInterface, SubresourceIdAwareInterface, IriToIdentifierConversionAwareInterface
class ChooseShippingMethod implements OrderTokenValueAwareInterface, ShipmentIdAwareInterface, IriToIdentifierConversionAwareInterface
{
/** @var string|null */
public $orderTokenValue;
/** @var string|null */
public $shipmentId;
/**
* @immutable
*
* @var string
*/
public $shippingMethodCode;
public function __construct(string $shippingMethodCode)
{
$this->shippingMethodCode = $shippingMethodCode;
public function __construct(
public string $shippingMethodCode,
public ?int $shipmentId = null,
public ?string $orderTokenValue = null,
) {
}
public function getOrderTokenValue(): ?string
@ -42,23 +31,8 @@ class ChooseShippingMethod implements OrderTokenValueAwareInterface, Subresource
return $this->orderTokenValue;
}
public function setOrderTokenValue(?string $orderTokenValue): void
{
$this->orderTokenValue = $orderTokenValue;
}
public function getSubresourceId(): ?string
public function getShipmentId(): ?int
{
return $this->shipmentId;
}
public function setSubresourceId(?string $subresourceId): void
{
$this->shipmentId = $subresourceId;
}
public function getSubresourceIdAttributeKey(): string
{
return 'shipmentId';
}
}

View file

@ -13,40 +13,21 @@ declare(strict_types=1);
namespace Sylius\Bundle\ApiBundle\Command\Checkout;
use Sylius\Bundle\ApiBundle\Command\CustomerEmailAwareInterface;
use Sylius\Bundle\ApiBundle\Command\LocaleCodeAwareInterface;
use Sylius\Bundle\ApiBundle\Command\LoggedInCustomerEmailAwareInterface;
use Sylius\Bundle\ApiBundle\Command\OrderTokenValueAwareInterface;
use Sylius\Component\Addressing\Model\AddressInterface;
class UpdateCart implements OrderTokenValueAwareInterface, CustomerEmailAwareInterface, LocaleCodeAwareInterface
class UpdateCart implements OrderTokenValueAwareInterface, LoggedInCustomerEmailAwareInterface, LocaleCodeAwareInterface
{
public ?string $orderTokenValue = null;
/** @immutable */
public ?string $email = null;
/** @immutable */
public ?AddressInterface $billingAddress = null;
/** @immutable */
public ?AddressInterface $shippingAddress = null;
public ?string $couponCode = null;
public ?string $localeCode = null;
public function __construct(
?string $email = null,
?AddressInterface $billingAddress = null,
?AddressInterface $shippingAddress = null,
?string $couponCode = null,
?string $localeCode = null,
public ?string $email = null,
public ?AddressInterface $billingAddress = null,
public ?AddressInterface $shippingAddress = null,
public ?string $couponCode = null,
public ?string $localeCode = null,
public ?string $orderTokenValue = null,
) {
$this->email = $email;
$this->billingAddress = $billingAddress;
$this->shippingAddress = $shippingAddress;
$this->couponCode = $couponCode;
$this->localeCode = $localeCode;
}
public static function createWithCouponData(?string $couponCode): self
@ -59,58 +40,28 @@ class UpdateCart implements OrderTokenValueAwareInterface, CustomerEmailAwareInt
return $this->orderTokenValue;
}
public function setOrderTokenValue(?string $orderTokenValue): void
{
$this->orderTokenValue = $orderTokenValue;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(?string $email): void
{
$this->email = $email;
}
public function getBillingAddress(): ?AddressInterface
{
return $this->billingAddress;
}
public function setBillingAddress(?AddressInterface $billingAddress): void
{
$this->billingAddress = $billingAddress;
}
public function getShippingAddress(): ?AddressInterface
{
return $this->shippingAddress;
}
public function setShippingAddress(?AddressInterface $shippingAddress): void
{
$this->shippingAddress = $shippingAddress;
}
public function getCouponCode(): ?string
{
return $this->couponCode;
}
public function setCouponCode(?string $couponCode): void
{
$this->couponCode = $couponCode;
}
public function getLocaleCode(): ?string
{
return $this->localeCode;
}
public function setLocaleCode(?string $localeCode): void
{
$this->localeCode = $localeCode;
}
}

View file

@ -13,7 +13,7 @@ declare(strict_types=1);
namespace Sylius\Bundle\ApiBundle\Command;
interface LoggedInCustomerEmailIfNotSetAwareInterface
interface LoggedInCustomerEmailAwareInterface
{
public function getEmail(): ?string;
}

View file

@ -13,9 +13,7 @@ declare(strict_types=1);
namespace Sylius\Bundle\ApiBundle\Command;
interface CustomerEmailAwareInterface extends CommandAwareDataTransformerInterface
interface OrderItemIdAwareInterface extends CommandAwareDataTransformerInterface
{
public function getEmail(): ?string;
public function setEmail(?string $email): void;
public function getOrderItemId(): ?int;
}

View file

@ -16,6 +16,4 @@ namespace Sylius\Bundle\ApiBundle\Command;
interface OrderTokenValueAwareInterface extends CommandAwareDataTransformerInterface
{
public function getOrderTokenValue(): ?string;
public function setOrderTokenValue(?string $orderTokenValue): void;
}

View file

@ -13,7 +13,7 @@ declare(strict_types=1);
namespace Sylius\Bundle\ApiBundle\Command;
class SendContactRequest implements ChannelCodeAwareInterface, LocaleCodeAwareInterface, LoggedInCustomerEmailIfNotSetAwareInterface
class SendContactRequest implements ChannelCodeAwareInterface, LocaleCodeAwareInterface, LoggedInCustomerEmailAwareInterface
{
public function __construct(
protected ?string $channelCode,

View file

@ -16,6 +16,4 @@ namespace Sylius\Bundle\ApiBundle\Command;
interface ShipmentIdAwareInterface extends CommandAwareDataTransformerInterface
{
public function getShipmentId(): ?int;
public function setShipmentId(?int $shipmentId): void;
}

View file

@ -1,23 +0,0 @@
<?php
/*
* This file is part of the Sylius package.
*
* (c) Sylius Sp. z o.o.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Sylius\Bundle\ApiBundle\Command;
interface SubresourceIdAwareInterface extends CommandAwareDataTransformerInterface
{
public function getSubresourceId(): ?string;
public function setSubresourceId(?string $subresourceId): void;
public function getSubresourceIdAttributeKey(): string;
}

View file

@ -22,7 +22,7 @@ use Sylius\Component\Order\Repository\OrderItemRepositoryInterface;
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
use Webmozart\Assert\Assert;
final class ChangeItemQuantityInCartHandler implements MessageHandlerInterface
final readonly class ChangeItemQuantityInCartHandler implements MessageHandlerInterface
{
public function __construct(
private OrderItemRepositoryInterface $orderItemRepository,

View file

@ -21,7 +21,7 @@ use Sylius\Component\Order\Repository\OrderItemRepositoryInterface;
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
use Webmozart\Assert\Assert;
final class RemoveItemFromCartHandler implements MessageHandlerInterface
final readonly class RemoveItemFromCartHandler implements MessageHandlerInterface
{
public function __construct(
private OrderItemRepositoryInterface $orderItemRepository,

View file

@ -31,7 +31,7 @@ final readonly class DeleteOrderItemAction
public function __invoke(Request $request): Response
{
$orderItemId = $request->attributes->get('itemId');
$orderItemId = $request->attributes->get('orderItemId');
$tokenValue = $request->attributes->get('tokenValue');
if (null === $orderItemId || null === $tokenValue) {
throw new OrderItemNotFoundException();

View file

@ -1,62 +0,0 @@
<?php
/*
* This file is part of the Sylius package.
*
* (c) Sylius Sp. z o.o.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Sylius\Bundle\ApiBundle\DataTransformer;
use Sylius\Bundle\ApiBundle\Command\CustomerEmailAwareInterface;
use Sylius\Bundle\ApiBundle\Context\UserContextInterface;
use Sylius\Component\Core\Model\CustomerInterface;
use Sylius\Component\Core\Model\ShopUserInterface;
use Sylius\Component\User\Model\UserInterface;
use Webmozart\Assert\Assert;
final class LoggedInCustomerEmailAwareCommandDataTransformer implements CommandDataTransformerInterface
{
public function __construct(private UserContextInterface $userContext)
{
}
public function transform($object, string $to, array $context = [])
{
/** @var CustomerInterface|null $customer */
$customer = $this->getCustomer();
/** @var CustomerEmailAwareInterface|mixed $object */
Assert::object($object, CustomerEmailAwareInterface::class);
if ($customer !== null) {
$object->setEmail($customer->getEmail());
}
return $object;
}
public function supportsTransformation($object): bool
{
return $object instanceof CustomerEmailAwareInterface;
}
private function getCustomer(): ?CustomerInterface
{
/** @var UserInterface|null $user */
$user = $this->userContext->getUser();
if ($user instanceof ShopUserInterface) {
$customer = $user->getCustomer();
Assert::nullOrIsInstanceOf($customer, CustomerInterface::class);
return $customer;
}
return null;
}
}

View file

@ -1,48 +0,0 @@
<?php
/*
* This file is part of the Sylius package.
*
* (c) Sylius Sp. z o.o.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Sylius\Bundle\ApiBundle\DataTransformer;
use Sylius\Bundle\ApiBundle\Command\ShopUserIdAwareInterface;
use Sylius\Bundle\ApiBundle\Context\UserContextInterface;
use Sylius\Component\Core\Model\ShopUserInterface;
use Sylius\Component\User\Model\UserInterface;
final class LoggedInShopUserIdAwareCommandDataTransformer implements CommandDataTransformerInterface
{
public function __construct(private UserContextInterface $userContext)
{
}
/**
* @param ShopUserIdAwareInterface $object
*/
public function transform($object, string $to, array $context = []): ShopUserIdAwareInterface
{
/** @var ShopUserInterface|UserInterface $user */
$user = $this->userContext->getUser();
if (!$user instanceof ShopUserInterface) {
return $object;
}
$object->setShopUserId($user->getId());
return $object;
}
public function supportsTransformation($object): bool
{
return $object instanceof ShopUserIdAwareInterface;
}
}

View file

@ -1,45 +0,0 @@
<?php
/*
* This file is part of the Sylius package.
*
* (c) Sylius Sp. z o.o.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Sylius\Bundle\ApiBundle\DataTransformer;
use Sylius\Bundle\ApiBundle\Command\SubresourceIdAwareInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Webmozart\Assert\Assert;
final class SubresourceIdAwareCommandDataTransformer implements CommandDataTransformerInterface
{
public function __construct(private RequestStack $requestStack)
{
}
public function transform($object, string $to, array $context = [])
{
$attributes = $this->requestStack->getCurrentRequest()->attributes;
$attributeKey = $object->getSubresourceIdAttributeKey();
Assert::true($attributes->has($attributeKey), 'Path does not have subresource id');
/** @var string $subresourceId */
$subresourceId = $attributes->get($object->getSubresourceIdAttributeKey());
$object->setSubresourceId($subresourceId);
return $object;
}
public function supportsTransformation($object): bool
{
return $object instanceof SubresourceIdAwareInterface;
}
}

View file

@ -123,6 +123,197 @@
</values>
</normalizationContext>
</operation>
<operation
class="ApiPlatform\Metadata\Post"
uriTemplate="/shop/orders"
itemUriTemplate="/shop/orders/{tokenValue}"
messenger="input"
input="Sylius\Bundle\ApiBundle\Command\Cart\PickupCart"
>
<validationContext>
<values>
<value name="groups">
<values>
<value>sylius</value>
</values>
</value>
</values>
</validationContext>
<denormalizationContext>
<values>
<value name="groups">
<values>
<value>sylius:shop:order:create</value>
</values>
</value>
</values>
</denormalizationContext>
<normalizationContext>
<values>
<value name="groups">
<values>
<value>sylius:shop:order:show</value>
<value>sylius:shop:cart:show</value>
</values>
</value>
</values>
</normalizationContext>
<openapiContext>
<values>
<value name="summary">Pickups a new cart.</value>
</values>
</openapiContext>
</operation>
<operation
class="ApiPlatform\Metadata\Post"
uriTemplate="/shop/orders/{tokenValue}/items"
itemUriTemplate="/shop/orders/{tokenValue}"
messenger="input"
input="Sylius\Bundle\ApiBundle\Command\Cart\AddItemToCart"
>
<validationContext>
<values>
<value name="groups">
<values>
<value>sylius</value>
</values>
</value>
</values>
</validationContext>
<denormalizationContext>
<values>
<value name="groups">
<values>
<value>sylius:shop:cart:add_item</value>
</values>
</value>
</values>
</denormalizationContext>
<normalizationContext>
<values>
<value name="groups">
<values>
<value>sylius:shop:cart:show</value>
</values>
</value>
</values>
</normalizationContext>
<openapiContext>
<values>
<value name="summary">Adds an item to the cart.</value>
</values>
</openapiContext>
</operation>
<operation
class="ApiPlatform\Metadata\Put"
uriTemplate="/shop/orders/{tokenValue}"
messenger="input"
input="Sylius\Bundle\ApiBundle\Command\Checkout\UpdateCart"
>
<validationContext>
<values>
<value name="groups">
<values>
<value>sylius</value>
</values>
</value>
</values>
</validationContext>
<denormalizationContext>
<values>
<value name="groups">
<values>
<value>sylius:shop:cart:update</value>
</values>
</value>
</values>
</denormalizationContext>
<normalizationContext>
<values>
<value name="groups">
<values>
<value>sylius:shop:order:show</value>
<value>sylius:shop:cart:show</value>
</values>
</value>
</values>
</normalizationContext>
<openapiContext>
<values>
<value name="summary">Addresses cart to given location, logged in Customer does not have to provide an email. Applies coupon to cart.</value>
</values>
</openapiContext>
</operation>
<operation
class="ApiPlatform\Metadata\Patch"
uriTemplate="/shop/orders/{tokenValue}/items/{orderItemId}"
messenger="input"
input="Sylius\Bundle\ApiBundle\Command\Cart\ChangeItemQuantityInCart"
>
<uriVariables>
<uriVariable parameterName="tokenValue" fromClass="Sylius\Component\Core\Model\Order"/>
<uriVariable parameterName="orderItemId" fromClass="Sylius\Component\Core\Model\OrderItem" fromProperty="order"/>
</uriVariables>
<validationContext>
<values>
<value name="groups">
<values>
<value>sylius</value>
</values>
</value>
</values>
</validationContext>
<denormalizationContext>
<values>
<value name="groups">
<values>
<value>sylius:shop:cart:change_quantity</value>
</values>
</value>
</values>
</denormalizationContext>
<normalizationContext>
<values>
<value name="groups">
<values>
<value>sylius:shop:cart:show</value>
</values>
</value>
</values>
</normalizationContext>
<openapiContext>
<values>
<value name="summary">Changes quantity of an item in the cart.</value>
</values>
</openapiContext>
</operation>
<operation
class="ApiPlatform\Metadata\Delete"
uriTemplate="/shop/orders/{tokenValue}"
>
<openapiContext>
<values>
<value name="summary">Deletes cart.</value>
</values>
</openapiContext>
</operation>
<operation
class="ApiPlatform\Metadata\Delete"
uriTemplate="/shop/orders/{tokenValue}/items/{orderItemId}"
controller="Sylius\Bundle\ApiBundle\Controller\DeleteOrderItemAction"
>
<uriVariables>
<uriVariable parameterName="tokenValue" fromClass="Sylius\Component\Core\Model\Order"/>
<uriVariable parameterName="orderItemId" fromClass="Sylius\Component\Core\Model\OrderItem" fromProperty="order"/>
</uriVariables>
</operation>
</operations>
</resource>
</resources>

View file

@ -1,24 +0,0 @@
<?xml version="1.0" ?>
<!--
This file is part of the Sylius package.
(c) Sylius Sp. z o.o.
For the full copyright and license information, please view the LICENSE
file that was distributed with this source code.
-->
<serializer xmlns="http://symfony.com/schema/dic/serializer-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/serializer-mapping https://symfony.com/schema/dic/serializer-mapping/serializer-mapping-1.0.xsd"
>
<class name="Sylius\Bundle\ApiBundle\Command\Cart\RemoveItemFromCart">
<attribute name="orderItemId">
<group>shop:cart:remove_item</group>
<group>sylius:shop:cart:remove_item</group>
</attribute>
</class>
</serializer>

View file

@ -40,9 +40,9 @@
<import resource="services/validator.xml" />
</imports>
<!-- <parameters>-->
<!-- <parameter key="sylius.model.address.interface">Sylius\Component\Addressing\Model\AddressInterface</parameter>-->
<!-- </parameters>-->
<parameters>
<parameter key="sylius.model.address.interface">Sylius\Component\Addressing\Model\AddressInterface</parameter>
</parameters>
<services>
<!-- TODO: Remove after bumping to Api Platform 3.0 -->
@ -52,21 +52,6 @@
<tag name="property_info.list_extractor" priority="-2000" />
</service>
<!-- <service id="Sylius\Bundle\ApiBundle\DataTransformer\LoggedInShopUserIdAwareCommandDataTransformer">-->
<!-- <argument type="service" id="Sylius\Bundle\ApiBundle\Context\UserContextInterface" />-->
<!-- <tag name="sylius.api.command_data_transformer" />-->
<!-- </service>-->
<!-- <service id="Sylius\Bundle\ApiBundle\DataTransformer\LoggedInCustomerEmailAwareCommandDataTransformer">-->
<!-- <argument type="service" id="Sylius\Bundle\ApiBundle\Context\UserContextInterface" />-->
<!-- <tag name="sylius.api.command_data_transformer" />-->
<!-- </service>-->
<!-- <service id="Sylius\Bundle\ApiBundle\DataTransformer\SubresourceIdAwareCommandDataTransformer">-->
<!-- <argument type="service" id="request_stack" />-->
<!-- <tag name="sylius.api.command_data_transformer" />-->
<!-- </service>-->
<service id="Sylius\Bundle\ApiBundle\Changer\PaymentMethodChangerInterface" class="Sylius\Bundle\ApiBundle\Changer\PaymentMethodChanger">
<argument type="service" id="sylius.repository.payment" />
<argument type="service" id="sylius.repository.payment_method" />

View file

@ -51,12 +51,12 @@
<tag name="messenger.message_handler" bus="sylius_default.bus" />
</service>
<!-- <service id="Sylius\Bundle\ApiBundle\CommandHandler\Cart\RemoveItemFromCartHandler">-->
<!-- <argument type="service" id="sylius.repository.order_item" />-->
<!-- <argument type="service" id="sylius.order_modifier" />-->
<!-- <tag name="messenger.message_handler" bus="sylius.command_bus" />-->
<!-- <tag name="messenger.message_handler" bus="sylius_default.bus" />-->
<!-- </service>-->
<service id="Sylius\Bundle\ApiBundle\CommandHandler\Cart\RemoveItemFromCartHandler">
<argument type="service" id="sylius.repository.order_item" />
<argument type="service" id="sylius.order_modifier" />
<tag name="messenger.message_handler" bus="sylius.command_bus" />
<tag name="messenger.message_handler" bus="sylius_default.bus" />
</service>
<!-- <service id="Sylius\Bundle\ApiBundle\CommandHandler\Cart\InformAboutCartRecalculationHandler">-->
<!-- <tag name="messenger.message_handler" bus="sylius.command_bus" />-->
@ -118,13 +118,13 @@
<!-- <tag name="messenger.message_handler" bus="sylius_default.bus" />-->
<!-- </service>-->
<!-- <service id="Sylius\Bundle\ApiBundle\CommandHandler\Cart\ChangeItemQuantityInCartHandler">-->
<!-- <argument type="service" id="sylius.repository.order_item" />-->
<!-- <argument type="service" id="sylius.order_item_quantity_modifier" />-->
<!-- <argument type="service" id="sylius.order_processing.order_processor" />-->
<!-- <tag name="messenger.message_handler" bus="sylius.command_bus" />-->
<!-- <tag name="messenger.message_handler" bus="sylius_default.bus" />-->
<!-- </service>-->
<service id="Sylius\Bundle\ApiBundle\CommandHandler\Cart\ChangeItemQuantityInCartHandler">
<argument type="service" id="sylius.repository.order_item" />
<argument type="service" id="sylius.order_item_quantity_modifier" />
<argument type="service" id="sylius.order_processing.order_processor" />
<tag name="messenger.message_handler" bus="sylius.command_bus" />
<tag name="messenger.message_handler" bus="sylius_default.bus" />
</service>
<service id="Sylius\Bundle\ApiBundle\CommandHandler\Catalog\AddProductReviewHandler">
<argument type="service" id="sylius.factory.product_review" />

View file

@ -30,13 +30,13 @@
</service>
<service
id="Sylius\Bundle\ApiBundle\SerializerContextBuilder\LoggedInCustomerEmailIfNotSetAwareContextBuilder"
id="Sylius\Bundle\ApiBundle\SerializerContextBuilder\LoggedInCustomerEmailAwareContextBuilder"
decorates="api_platform.serializer.context_builder"
decoration-priority="64"
>
<argument type="service" id=".inner" />
<argument>Sylius\Bundle\ApiBundle\Attribute\LoggedInCustomerEmailIfNotSetAware</argument>
<argument type="constant">Sylius\Bundle\ApiBundle\Attribute\LoggedInCustomerEmailIfNotSetAware::DEFAULT_ARGUMENT_NAME</argument>
<argument>Sylius\Bundle\ApiBundle\Attribute\LoggedInCustomerEmailAware</argument>
<argument type="constant">Sylius\Bundle\ApiBundle\Attribute\LoggedInCustomerEmailAware::DEFAULT_ARGUMENT_NAME</argument>
<argument type="service" id="Sylius\Bundle\ApiBundle\Context\UserContextInterface" />
</service>
@ -89,23 +89,42 @@
</service>
<service
id="Sylius\Bundle\ApiBundle\SerializerContextBuilder\ShipmentAwareContextBuilder"
id="sylius_api.serializer_context_builder.shipment_aware"
class="Sylius\Bundle\ApiBundle\SerializerContextBuilder\ObjectUriVariablesAwareContextBuilder"
decorates="api_platform.serializer.context_builder"
decoration-priority="64"
>
<argument type="service" id=".inner" />
<argument>Sylius\Bundle\ApiBundle\Attribute\ShipmentIdAware</argument>
<argument type="constant">Sylius\Bundle\ApiBundle\Attribute\ShipmentIdAware::DEFAULT_ARGUMENT_NAME</argument>
<argument>Sylius\Bundle\ApiBundle\Command\ShipmentIdAwareInterface</argument>
<argument>Sylius\Component\Core\Model\ShipmentInterface</argument>
</service>
<service
id="Sylius\Bundle\ApiBundle\SerializerContextBuilder\OrderTokenValueAwareContextBuilder"
id="sylius_api.serializer_context_builder.order_token_value_aware"
class="Sylius\Bundle\ApiBundle\SerializerContextBuilder\ObjectUriVariablesAwareContextBuilder"
decorates="api_platform.serializer.context_builder"
decoration-priority="64"
>
<argument type="service" id=".inner" />
<argument>Sylius\Bundle\ApiBundle\Attribute\OrderTokenValueAware</argument>
<argument type="constant">Sylius\Bundle\ApiBundle\Attribute\OrderTokenValueAware::DEFAULT_ARGUMENT_NAME</argument>
<argument>Sylius\Bundle\ApiBundle\Command\OrderTokenValueAwareInterface</argument>
<argument>Sylius\Component\Core\Model\OrderInterface</argument>
</service>
<service
id="sylius_api.serializer_context_builder.order_item_aware"
class="Sylius\Bundle\ApiBundle\SerializerContextBuilder\ObjectUriVariablesAwareContextBuilder"
decorates="api_platform.serializer.context_builder"
decoration-priority="64"
>
<argument type="service" id=".inner" />
<argument>Sylius\Bundle\ApiBundle\Attribute\OrderItemIdAware</argument>
<argument type="constant">Sylius\Bundle\ApiBundle\Attribute\OrderItemIdAware::DEFAULT_ARGUMENT_NAME</argument>
<argument>Sylius\Bundle\ApiBundle\Command\OrderItemIdAwareInterface</argument>
<argument>Sylius\Component\Core\Model\OrderItemInterface</argument>
</service>
</services>
</container>

View file

@ -18,12 +18,12 @@
<services>
<defaults public="true" />
<!-- <service id="Sylius\Bundle\ApiBundle\Serializer\AddressDenormalizer">-->
<!-- <argument type="service" id="serializer.normalizer.object" />-->
<!-- <argument type="string">%sylius.model.address.class%</argument>-->
<!-- <argument type="string">%sylius.model.address.interface%</argument>-->
<!-- <tag name="serializer.normalizer" priority="64" />-->
<!-- </service>-->
<service id="sylius_api.denormalizer.address" class="Sylius\Bundle\ApiBundle\Serializer\Denormalizer\AddressDenormalizer">
<argument type="service" id="serializer.normalizer.object" />
<argument type="string">%sylius.model.address.class%</argument>
<argument type="string">%sylius.model.address.interface%</argument>
<tag name="serializer.normalizer" priority="64" />
</service>
<service id="sylius_api.denormalizer.command_arguments" class="Sylius\Bundle\ApiBundle\Serializer\Denormalizer\CommandArgumentsDenormalizer">
<argument type="service" id="sylius_api.denormalizer.command" />

View file

@ -22,10 +22,11 @@
<tag name="validator.constraint_validator" alias="sylius_validator_unique_shop_user_email" />
</service>
<!-- <service id="Sylius\Bundle\ApiBundle\Validator\Constraints\OrderNotEmptyValidator" class="Sylius\Bundle\ApiBundle\Validator\Constraints\OrderNotEmptyValidator">-->
<!-- <argument type="service" id="sylius.repository.order" />-->
<!-- <tag name="validator.constraint_validator" alias="sylius_api_validator_order_not_empty" />-->
<!-- </service>-->
<service id="sylius_api.validator.order_not_empty"
class="Sylius\Bundle\ApiBundle\Validator\Constraints\OrderNotEmptyValidator">
<argument type="service" id="sylius.repository.order" />
<tag name="validator.constraint_validator" alias="sylius_api_validator_order_not_empty" />
</service>
<!-- <service id="Sylius\Bundle\ApiBundle\Validator\Constraints\OrderProductEligibilityValidator">-->
<!-- <argument type="service" id="sylius.repository.order" />-->
@ -63,24 +64,27 @@
<!-- <tag name="validator.constraint_validator" alias="sylius_api_validator_chosen_shipping_method_eligibility" />-->
<!-- </service>-->
<!-- <service id="Sylius\Bundle\ApiBundle\Validator\Constraints\AddingEligibleProductVariantToCartValidator">-->
<!-- <argument type="service" id="sylius.repository.product_variant" />-->
<!-- <argument type="service" id="sylius.repository.order" />-->
<!-- <argument type="service" id="sylius.availability_checker" />-->
<!-- <tag name="validator.constraint_validator" alias="sylius_api_validator_adding_eligible_product_variant_to_cart" />-->
<!-- </service>-->
<service id="sylius_api.validator.adding_eligible_product_variant_to_cart"
class="Sylius\Bundle\ApiBundle\Validator\Constraints\AddingEligibleProductVariantToCartValidator">
<argument type="service" id="sylius.repository.product_variant" />
<argument type="service" id="sylius.repository.order" />
<argument type="service" id="sylius.availability_checker" />
<tag name="validator.constraint_validator" alias="sylius_api_validator_adding_eligible_product_variant_to_cart" />
</service>
<!-- <service id="Sylius\Bundle\ApiBundle\Validator\Constraints\ChangedItemQuantityInCartValidator">-->
<!-- <argument type="service" id="sylius.repository.order_item" />-->
<!-- <argument type="service" id="sylius.repository.order" />-->
<!-- <argument type="service" id="sylius.availability_checker" />-->
<!-- <tag name="validator.constraint_validator" alias="sylius_api_validator_changed_item_quantity_in_cart" />-->
<!-- </service>-->
<service id="sylius_api.validator.changed_item_quantity_in_cart"
class="Sylius\Bundle\ApiBundle\Validator\Constraints\ChangedItemQuantityInCartValidator">
<argument type="service" id="sylius.repository.order_item" />
<argument type="service" id="sylius.repository.order" />
<argument type="service" id="sylius.availability_checker" />
<tag name="validator.constraint_validator" alias="sylius_api_validator_changed_item_quantity_in_cart" />
</service>
<!-- <service id="Sylius\Bundle\ApiBundle\Validator\Constraints\CorrectOrderAddressValidator">-->
<!-- <argument type="service" id="sylius.repository.country" />-->
<!-- <tag name="validator.constraint_validator" alias="sylius_api_validator_correct_order_address" />-->
<!-- </service>-->
<service id="sylius_api.validator.correct_order_address"
class="Sylius\Bundle\ApiBundle\Validator\Constraints\CorrectOrderAddressValidator">
<argument type="service" id="sylius.repository.country" />
<tag name="validator.constraint_validator" alias="sylius_api_validator_correct_order_address" />
</service>
<!-- <service id="Sylius\Bundle\ApiBundle\Validator\Constraints\OrderPaymentMethodEligibilityValidator">-->
<!-- <argument type="service" id="sylius.repository.order" />-->
@ -107,12 +111,13 @@
<tag name="validator.constraint_validator" alias="sylius_api_confirm_reset_password" />
</service>
<!-- <service id="Sylius\Bundle\ApiBundle\Validator\Constraints\PromotionCouponEligibilityValidator">-->
<!-- <argument type="service" id="sylius.repository.promotion_coupon" />-->
<!-- <argument type="service" id="sylius.repository.order" />-->
<!-- <argument type="service" id="Sylius\Bundle\ApiBundle\Checker\AppliedCouponEligibilityCheckerInterface" />-->
<!-- <tag name="validator.constraint_validator" alias="sylius_api_promotion_coupon_eligibility" />-->
<!-- </service>-->
<service id="sylius_api.validator.promotion_coupon_eligibility"
class="Sylius\Bundle\ApiBundle\Validator\Constraints\PromotionCouponEligibilityValidator">
<argument type="service" id="sylius.repository.promotion_coupon" />
<argument type="service" id="sylius.repository.order" />
<argument type="service" id="Sylius\Bundle\ApiBundle\Checker\AppliedCouponEligibilityCheckerInterface" />
<tag name="validator.constraint_validator" alias="sylius_api_promotion_coupon_eligibility" />
</service>
<service id="sylius_api.validator.shipment_already_shipped" class="Sylius\Bundle\ApiBundle\Validator\Constraints\ShipmentAlreadyShippedValidator">
<argument type="service" id="sylius.repository.shipment" />

View file

@ -11,12 +11,11 @@
declare(strict_types=1);
namespace Sylius\Bundle\ApiBundle\Serializer;
namespace Sylius\Bundle\ApiBundle\Serializer\Denormalizer;
use Symfony\Component\Serializer\Normalizer\ContextAwareDenormalizerInterface;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
final class AddressDenormalizer implements ContextAwareDenormalizerInterface
final readonly class AddressDenormalizer implements DenormalizerInterface
{
public function __construct(
private DenormalizerInterface $objectNormalizer,

View file

@ -14,7 +14,7 @@ declare(strict_types=1);
namespace Sylius\Bundle\ApiBundle\SerializerContextBuilder;
use ApiPlatform\Serializer\SerializerContextBuilderInterface;
use Sylius\Bundle\ApiBundle\Command\LoggedInCustomerEmailIfNotSetAwareInterface;
use Sylius\Bundle\ApiBundle\Command\LoggedInCustomerEmailAwareInterface;
use Sylius\Bundle\ApiBundle\Context\UserContextInterface;
use Sylius\Component\Core\Model\CustomerInterface;
use Sylius\Component\Core\Model\ShopUserInterface;
@ -22,7 +22,7 @@ use Sylius\Component\User\Model\UserInterface;
use Symfony\Component\HttpFoundation\Request;
use Webmozart\Assert\Assert;
final class LoggedInCustomerEmailIfNotSetAwareContextBuilder extends AbstractInputContextBuilder
final class LoggedInCustomerEmailAwareContextBuilder extends AbstractInputContextBuilder
{
public function __construct(
SerializerContextBuilderInterface $decoratedContextBuilder,
@ -35,12 +35,12 @@ final class LoggedInCustomerEmailIfNotSetAwareContextBuilder extends AbstractInp
protected function supportsClass(string $class): bool
{
return is_a($class, LoggedInCustomerEmailIfNotSetAwareInterface::class, true);
return is_a($class, LoggedInCustomerEmailAwareInterface::class, true);
}
protected function supports(Request $request, array $context, ?array $extractedAttributes): bool
{
return !array_key_exists('email', $request->toArray()) &&
return !isset($request->toArray()['email']) &&
$this->getCustomer() !== null;
}

View file

@ -14,28 +14,37 @@ declare(strict_types=1);
namespace Sylius\Bundle\ApiBundle\SerializerContextBuilder;
use ApiPlatform\Metadata\HttpOperation;
use Sylius\Bundle\ApiBundle\Command\ShipmentIdAwareInterface;
use Sylius\Component\Core\Model\ShipmentInterface;
use ApiPlatform\Serializer\SerializerContextBuilderInterface;
use Symfony\Component\HttpFoundation\Request;
final class ShipmentAwareContextBuilder extends AbstractInputContextBuilder
final class ObjectUriVariablesAwareContextBuilder extends AbstractInputContextBuilder
{
public function __construct(
SerializerContextBuilderInterface $decoratedContextBuilder,
string $attributeClass,
string $defaultConstructorArgumentName,
private readonly string $commandInterface,
private readonly string $objectInterface,
) {
parent::__construct($decoratedContextBuilder, $attributeClass, $defaultConstructorArgumentName);
}
protected function supportsClass(string $class): bool
{
return is_a($class, ShipmentIdAwareInterface::class, true);
return is_a($class, $this->commandInterface, true);
}
protected function supports(Request $request, array $context, ?array $extractedAttributes): bool
{
return null !== $this->resolveShipmentIdFromUriVariables($context, $extractedAttributes);
return null !== $this->resolveValueFromUriVariables($context, $extractedAttributes);
}
protected function resolveValue(array $context, ?array $extractedAttributes): mixed
{
return $this->resolveShipmentIdFromUriVariables($context, $extractedAttributes);
return $this->resolveValueFromUriVariables($context, $extractedAttributes);
}
private function resolveShipmentIdFromUriVariables(array $context, ?array $attributes): ?string
private function resolveValueFromUriVariables(array $context, ?array $attributes): ?string
{
if (
null !== $attributes &&
@ -44,11 +53,11 @@ final class ShipmentAwareContextBuilder extends AbstractInputContextBuilder
) {
$operation = $attributes['operation'];
foreach ($operation->getUriVariables() as $uriVariable) {
if (false === is_a($uriVariable->getFromClass(), ShipmentInterface::class, true)) {
if (false === is_a($uriVariable->getFromClass(), $this->objectInterface, true)) {
continue;
}
$identifier = $uriVariable->getFromProperty() ?? $uriVariable->getParameterName() ?? 'id';
$identifier = $uriVariable->getParameterName() ?? $this->defaultConstructorArgumentName;
return $context['uri_variables'][$identifier] ?? null;
}

View file

@ -1,59 +0,0 @@
<?php
/*
* This file is part of the Sylius package.
*
* (c) Sylius Sp. z o.o.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Sylius\Bundle\ApiBundle\SerializerContextBuilder;
use ApiPlatform\Metadata\HttpOperation;
use Sylius\Bundle\ApiBundle\Command\OrderTokenValueAwareInterface;
use Sylius\Component\Core\Model\OrderInterface;
use Symfony\Component\HttpFoundation\Request;
final class OrderTokenValueAwareContextBuilder extends AbstractInputContextBuilder
{
protected function supportsClass(string $class): bool
{
return is_a($class, OrderTokenValueAwareInterface::class, true);
}
protected function supports(Request $request, array $context, ?array $extractedAttributes): bool
{
return null !== $this->resolveOrderTokenValueFromUriVariables($context, $extractedAttributes);
}
protected function resolveValue(array $context, ?array $extractedAttributes): mixed
{
return $this->resolveOrderTokenValueFromUriVariables($context, $extractedAttributes);
}
private function resolveOrderTokenValueFromUriVariables(array $context, ?array $attributes): ?string
{
if (
null !== $attributes &&
isset($attributes['operation']) &&
$attributes['operation'] instanceof HttpOperation
) {
$operation = $attributes['operation'];
foreach ($operation->getUriVariables() as $uriVariable) {
if (false === is_a($uriVariable->getFromClass(), OrderInterface::class, true)) {
continue;
}
$identifier = $uriVariable->getFromProperty() ?? $uriVariable->getParameterName() ?? 'id';
return $context['uri_variables'][$identifier] ?? null;
}
}
return null;
}
}

View file

@ -27,9 +27,9 @@ use Webmozart\Assert\Assert;
final class AddingEligibleProductVariantToCartValidator extends ConstraintValidator
{
public function __construct(
private ProductVariantRepositoryInterface $productVariantRepository,
private OrderRepositoryInterface $orderRepository,
private AvailabilityCheckerInterface $availabilityChecker,
private readonly ProductVariantRepositoryInterface $productVariantRepository,
private readonly OrderRepositoryInterface $orderRepository,
private readonly AvailabilityCheckerInterface $availabilityChecker,
) {
}

View file

@ -27,13 +27,11 @@ use Webmozart\Assert\Assert;
final class ChangedItemQuantityInCartValidator extends ConstraintValidator
{
/**
* @param OrderItemRepositoryInterface<OrderItemInterface> $orderItemRepository
*/
/** @param OrderItemRepositoryInterface<OrderItemInterface> $orderItemRepository */
public function __construct(
private OrderItemRepositoryInterface $orderItemRepository,
private OrderRepositoryInterface $orderRepository,
private AvailabilityCheckerInterface $availabilityChecker,
private readonly OrderItemRepositoryInterface $orderItemRepository,
private readonly OrderRepositoryInterface $orderRepository,
private readonly AvailabilityCheckerInterface $availabilityChecker,
) {
}

View file

@ -23,7 +23,7 @@ use Webmozart\Assert\Assert;
final class CorrectOrderAddressValidator extends ConstraintValidator
{
public function __construct(private RepositoryInterface $countryRepository)
public function __construct(private readonly RepositoryInterface $countryRepository)
{
}

View file

@ -13,7 +13,7 @@ declare(strict_types=1);
namespace Sylius\Bundle\ApiBundle\Validator\Constraints;
use Sylius\Bundle\ApiBundle\Command\CustomerEmailAwareInterface;
use Sylius\Bundle\ApiBundle\Command\LoggedInCustomerEmailAwareInterface;
use Sylius\Bundle\ApiBundle\Command\OrderTokenValueAwareInterface;
use Sylius\Bundle\ApiBundle\Context\UserContextInterface;
use Sylius\Component\Core\Model\OrderInterface;
@ -33,7 +33,7 @@ final class UpdateCartEmailNotAllowedValidator extends ConstraintValidator
public function validate(mixed $value, Constraint $constraint): void
{
Assert::isInstanceOf($value, OrderTokenValueAwareInterface::class);
Assert::isInstanceOf($value, CustomerEmailAwareInterface::class);
Assert::isInstanceOf($value, LoggedInCustomerEmailAwareInterface::class);
/** @var UpdateCartEmailNotAllowed $constraint */
Assert::isInstanceOf($constraint, UpdateCartEmailNotAllowed::class);

View file

@ -1,68 +0,0 @@
<?php
/*
* This file is part of the Sylius package.
*
* (c) Sylius Sp. z o.o.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace spec\Sylius\Bundle\ApiBundle\DataTransformer;
use PhpSpec\ObjectBehavior;
use Sylius\Bundle\ApiBundle\Command\CustomerEmailAwareInterface;
use Sylius\Bundle\ApiBundle\Context\UserContextInterface;
use Sylius\Component\Core\Model\CustomerInterface;
use Sylius\Component\Core\Model\ShopUserInterface;
final class LoggedInCustomerEmailAwareCommandDataTransformerSpec extends ObjectBehavior
{
function let(UserContextInterface $userContext)
{
$this->beConstructedWith($userContext);
}
function it_adds_email_to_customer_email_aware_commands_from_logged_in_customer(
UserContextInterface $userContext,
CustomerEmailAwareInterface $command,
ShopUserInterface $shopUser,
CustomerInterface $customer,
): void {
$userContext->getUser()->willReturn($shopUser);
$shopUser->getCustomer()->willReturn($customer);
$customer->getEmail()->willReturn('sample@email.com');
$command->setEmail('sample@email.com')->shouldBeCalled();
$this->transform(
$command,
'Sylius\Component\Core\Model\ProductReview',
[],
);
}
function it_does_not_add_email_to_customer_email_aware_for_visitor(
UserContextInterface $userContext,
CustomerEmailAwareInterface $command,
): void {
$userContext->getUser()->willReturn(null);
$command->setEmail('sample@email.com')->shouldNotBeCalled();
$this->transform(
$command,
'Sylius\Component\Core\Model\ProductReview',
[],
);
}
function it_supports_command_with_customer_email_aware_interface(CustomerEmailAwareInterface $command): void
{
$this->supportsTransformation($command)->shouldReturn(true);
}
}

View file

@ -58,9 +58,7 @@ final class ChooseShippingMethodHandlerSpec extends ObjectBehavior
ShipmentInterface $shipment,
WinzouStateMachineInterface $stateMachine,
): void {
$chooseShippingMethod = new ChooseShippingMethod('DHL_SHIPPING_METHOD');
$chooseShippingMethod->setOrderTokenValue('ORDERTOKEN');
$chooseShippingMethod->setSubresourceId('123');
$chooseShippingMethod = new ChooseShippingMethod('DHL_SHIPPING_METHOD', 123, 'ORDERTOKEN');
$orderRepository->findOneBy(['tokenValue' => 'ORDERTOKEN'])->willReturn($cart);
@ -101,9 +99,7 @@ final class ChooseShippingMethodHandlerSpec extends ObjectBehavior
$stateMachine,
);
$chooseShippingMethod = new ChooseShippingMethod('DHL_SHIPPING_METHOD');
$chooseShippingMethod->setOrderTokenValue('ORDERTOKEN');
$chooseShippingMethod->setSubresourceId('123');
$chooseShippingMethod = new ChooseShippingMethod('DHL_SHIPPING_METHOD', 123, 'ORDERTOKEN');
$orderRepository->findOneBy(['tokenValue' => 'ORDERTOKEN'])->willReturn($cart);
@ -136,9 +132,7 @@ final class ChooseShippingMethodHandlerSpec extends ObjectBehavior
ShipmentInterface $shipment,
WinzouStateMachineInterface $stateMachine,
): void {
$chooseShippingMethod = new ChooseShippingMethod('DHL_SHIPPING_METHOD');
$chooseShippingMethod->setOrderTokenValue('ORDERTOKEN');
$chooseShippingMethod->setSubresourceId('123');
$chooseShippingMethod = new ChooseShippingMethod('DHL_SHIPPING_METHOD', 123, 'ORDERTOKEN');
$orderRepository->findOneBy(['tokenValue' => 'ORDERTOKEN'])->willReturn($cart);
@ -168,8 +162,7 @@ final class ChooseShippingMethodHandlerSpec extends ObjectBehavior
OrderRepositoryInterface $orderRepository,
ShipmentInterface $shipment,
): void {
$chooseShippingMethod = new ChooseShippingMethod('DHL_SHIPPING_METHOD');
$chooseShippingMethod->setOrderTokenValue('ORDERTOKEN');
$chooseShippingMethod = new ChooseShippingMethod('DHL_SHIPPING_METHOD', null, 'ORDERTOKEN');
$orderRepository->findOneBy(['tokenValue' => 'ORDERTOKEN'])->willReturn(null);
@ -189,8 +182,7 @@ final class ChooseShippingMethodHandlerSpec extends ObjectBehavior
WinzouStateMachineInterface $stateMachine,
ShipmentInterface $shipment,
): void {
$chooseShippingMethod = new ChooseShippingMethod('DHL_SHIPPING_METHOD');
$chooseShippingMethod->setOrderTokenValue('ORDERTOKEN');
$chooseShippingMethod = new ChooseShippingMethod('DHL_SHIPPING_METHOD', null, 'ORDERTOKEN');
$orderRepository->findOneBy(['tokenValue' => 'ORDERTOKEN'])->willReturn($cart);
$shippingMethodRepository->findOneBy(['code' => 'DHL_SHIPPING_METHOD'])->willReturn(null);
@ -215,9 +207,7 @@ final class ChooseShippingMethodHandlerSpec extends ObjectBehavior
WinzouStateMachineInterface $stateMachine,
ShipmentInterface $shipment,
): void {
$chooseShippingMethod = new ChooseShippingMethod('DHL_SHIPPING_METHOD');
$chooseShippingMethod->setOrderTokenValue('ORDERTOKEN');
$chooseShippingMethod->setSubresourceId('123');
$chooseShippingMethod = new ChooseShippingMethod('DHL_SHIPPING_METHOD', 123, 'ORDERTOKEN');
$orderRepository->findOneBy(['tokenValue' => 'ORDERTOKEN'])->willReturn($cart);
@ -244,9 +234,7 @@ final class ChooseShippingMethodHandlerSpec extends ObjectBehavior
ShippingMethodInterface $shippingMethod,
WinzouStateMachineInterface $stateMachine,
): void {
$chooseShippingMethod = new ChooseShippingMethod('DHL_SHIPPING_METHOD');
$chooseShippingMethod->setOrderTokenValue('ORDERTOKEN');
$chooseShippingMethod->setSubresourceId('123');
$chooseShippingMethod = new ChooseShippingMethod('DHL_SHIPPING_METHOD', 123, 'ORDERTOKEN');
$orderRepository->findOneBy(['tokenValue' => 'ORDERTOKEN'])->willReturn($cart);

View file

@ -62,8 +62,13 @@ final class UpdateCartHandlerSpec extends ObjectBehavior
$orderPromotionCodeAssigner->assign($order, 'coupon')->shouldNotBeCalled();
$updateCart = new UpdateCart('john.doe@email.com', $billingAddress->getWrappedObject(), $shippingAddress->getWrappedObject(), 'coupon');
$updateCart->setOrderTokenValue('cart');
$updateCart = new UpdateCart(
email: 'john.doe@email.com',
billingAddress: $billingAddress->getWrappedObject(),
shippingAddress: $shippingAddress->getWrappedObject(),
couponCode: 'coupon',
orderTokenValue: 'cart',
);
$this->shouldThrow(\InvalidArgumentException::class)
->during('__invoke', [$updateCart])
@ -77,8 +82,10 @@ final class UpdateCartHandlerSpec extends ObjectBehavior
OrderInterface $order,
AddressInterface $billingAddress,
): void {
$updateCart = new UpdateCart(null, $billingAddress->getWrappedObject());
$updateCart->setOrderTokenValue('cart');
$updateCart = new UpdateCart(
billingAddress: $billingAddress->getWrappedObject(),
orderTokenValue: 'cart',
);
$orderRepository->findOneBy(['tokenValue' => 'cart'])->willReturn($order);
@ -105,9 +112,10 @@ final class UpdateCartHandlerSpec extends ObjectBehavior
OrderInterface $order,
AddressInterface $shippingAddress,
): void {
$updateCart = new UpdateCart(null, null, $shippingAddress->getWrappedObject(), null);
$updateCart->setOrderTokenValue('cart');
$updateCart = new UpdateCart(
shippingAddress: $shippingAddress->getWrappedObject(),
orderTokenValue: 'cart',
);
$orderRepository->findOneBy(['tokenValue' => 'cart'])->willReturn($order->getWrappedObject());
@ -137,8 +145,10 @@ final class UpdateCartHandlerSpec extends ObjectBehavior
OrderPromotionCodeAssignerInterface $orderPromotionCodeAssigner,
OrderInterface $order,
): void {
$updateCart = new UpdateCart(null, null, null, 'couponCode');
$updateCart->setOrderTokenValue('cart');
$updateCart = new UpdateCart(
couponCode: 'couponCode',
orderTokenValue: 'cart',
);
$orderRepository->findOneBy(['tokenValue' => 'cart'])->willReturn($order->getWrappedObject());
@ -166,14 +176,13 @@ final class UpdateCartHandlerSpec extends ObjectBehavior
CustomerResolverInterface $customerResolver,
): void {
$updateCart = new UpdateCart(
'john.doe@email.com',
$billingAddress->getWrappedObject(),
$shippingAddress->getWrappedObject(),
'couponCode',
email: 'john.doe@email.com',
billingAddress: $billingAddress->getWrappedObject(),
shippingAddress: $shippingAddress->getWrappedObject(),
couponCode: 'couponCode',
orderTokenValue: 'cart',
);
$updateCart->setOrderTokenValue('cart');
$orderRepository->findOneBy(['tokenValue' => 'cart'])->willReturn($order->getWrappedObject());
$customerResolver->resolve('john.doe@email.com')->shouldBeCalled()->willReturn($customer);
@ -208,14 +217,13 @@ final class UpdateCartHandlerSpec extends ObjectBehavior
CustomerInterface $customer,
): void {
$updateCart = new UpdateCart(
'john.doe@email.com',
$billingAddress->getWrappedObject(),
$shippingAddress->getWrappedObject(),
'couponCode',
email: 'john.doe@email.com',
billingAddress: $billingAddress->getWrappedObject(),
shippingAddress: $shippingAddress->getWrappedObject(),
couponCode: 'couponCode',
orderTokenValue: 'cart',
);
$updateCart->setOrderTokenValue('cart');
$orderRepository->findOneBy(['tokenValue' => 'cart'])->willReturn($order->getWrappedObject());
$customerResolver->resolve('john.doe@email.com')->shouldBeCalled()->willReturn($customer);

View file

@ -15,7 +15,7 @@ namespace spec\Sylius\Bundle\ApiBundle\SerializerContextBuilder;
use ApiPlatform\Serializer\SerializerContextBuilderInterface;
use PhpSpec\ObjectBehavior;
use Sylius\Bundle\ApiBundle\Attribute\LoggedInCustomerEmailIfNotSetAware;
use Sylius\Bundle\ApiBundle\Attribute\LoggedInCustomerEmailAware;
use Sylius\Bundle\ApiBundle\Command\SendContactRequest;
use Sylius\Bundle\ApiBundle\Context\UserContextInterface;
use Sylius\Component\Core\Model\AdminUserInterface;
@ -24,7 +24,7 @@ use Sylius\Component\Core\Model\ShopUserInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
final class LoggedInCustomerEmailIfNotSetAwareContextBuilderSpec extends ObjectBehavior
final class LoggedInCustomerEmailAwareContextBuilderSpec extends ObjectBehavior
{
function let(
SerializerContextBuilderInterface $decoratedContextBuilder,
@ -32,7 +32,7 @@ final class LoggedInCustomerEmailIfNotSetAwareContextBuilderSpec extends ObjectB
): void {
$this->beConstructedWith(
$decoratedContextBuilder,
LoggedInCustomerEmailIfNotSetAware::class,
LoggedInCustomerEmailAware::class,
'email',
$userContext,
);

View file

@ -0,0 +1,124 @@
<?php
/*
* This file is part of the Sylius package.
*
* (c) Sylius Sp. z o.o.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace spec\Sylius\Bundle\ApiBundle\SerializerContextBuilder;
use ApiPlatform\Metadata\HttpOperation;
use ApiPlatform\Metadata\Link;
use ApiPlatform\Serializer\SerializerContextBuilderInterface;
use PhpSpec\ObjectBehavior;
use Sylius\Bundle\ApiBundle\Attribute\ShipmentIdAware;
use Sylius\Bundle\ApiBundle\Command\ShipmentIdAwareInterface;
use Sylius\Component\Core\Model\ShipmentInterface;
use Symfony\Component\HttpFoundation\Request;
final class ObjectUriVariablesAwareContextBuilderSpec extends ObjectBehavior
{
function let(
SerializerContextBuilderInterface $decoratedContextBuilder,
): void {
$this->beConstructedWith(
$decoratedContextBuilder,
ShipmentIdAware::class,
'shipmentId',
ShipmentIdAwareInterface::class,
ShipmentInterface::class,
);
}
function it_does_nothing_if_there_is_no_input_class(
SerializerContextBuilderInterface $decoratedContextBuilder,
Request $request,
): void {
$decoratedContextBuilder
->createFromRequest($request, true, [])
->willReturn([])
;
$this->createFromRequest($request, true, [])->shouldReturn([]);
}
function it_does_nothing_if_input_class_is_no_supported_attribute(
SerializerContextBuilderInterface $decoratedContextBuilder,
Request $request,
): void {
$decoratedContextBuilder
->createFromRequest($request, true, [])
->willReturn(['input' => ['class' => \stdClass::class]])
;
$this
->createFromRequest($request, true, [])
->shouldReturn(['input' => ['class' => \stdClass::class]])
;
}
function it_does_nothing_if_there_is_no_uri_variable(
SerializerContextBuilderInterface $decoratedContextBuilder,
Request $request,
HttpOperation $operation,
): void {
$decoratedContextBuilder
->createFromRequest($request, true, ['operation' => $operation])
->willReturn(['input' => ['class' => ShipmentIdAwareInterface::class]])
;
$operation->getUriVariables()->willReturn([]);
$this
->createFromRequest($request, true, ['operation' => $operation])
->shouldReturn(['input' => ['class' => ShipmentIdAwareInterface::class]])
;
}
function it_does_nothing_if_there_is_different_uri_variable(
SerializerContextBuilderInterface $decoratedContextBuilder,
Request $request,
HttpOperation $operation,
): void {
$decoratedContextBuilder
->createFromRequest($request, true, ['operation' => $operation])
->willReturn(['input' => ['class' => ShipmentIdAwareInterface::class]])
;
$uriVariable = new Link(fromClass: 'stdClass');
$operation->getUriVariables()->willReturn([$uriVariable]);
$this
->createFromRequest($request, true, ['operation' => $operation])
->shouldReturn(['input' => ['class' => ShipmentIdAwareInterface::class]])
;
}
function it_set_shipment_id_as_a_constructor_argument(
SerializerContextBuilderInterface $decoratedContextBuilder,
Request $request,
HttpOperation $operation,
): void {
$decoratedContextBuilder
->createFromRequest($request, true, ['operation' => $operation])
->willReturn(['input' => ['class' => ShipmentIdAwareInterface::class], 'uri_variables' => ['shipmentId' => '123']])
;
$uriVariable = new Link(fromClass: ShipmentInterface::class, parameterName: 'shipmentId');
$operation->getUriVariables()->willReturn([$uriVariable]);
$this
->createFromRequest($request, true, ['operation' => $operation])
->shouldReturn([
'input' => ['class' => ShipmentIdAwareInterface::class],
'uri_variables' => ['shipmentId' => '123'],
'default_constructor_arguments' => [
ShipmentIdAwareInterface::class => ['shipmentId' => '123'],
],
])
;
}
}

View file

@ -149,8 +149,7 @@ final class AddingEligibleProductVariantToCartValidatorSpec extends ObjectBehavi
): void {
$this->initialize($executionContext);
$command = new AddItemToCart('productVariantCode', 1);
$command->setOrderTokenValue('TOKEN');
$command = new AddItemToCart('productVariantCode', 1, 'TOKEN');
$productVariantRepository->findOneBy(['code' => 'productVariantCode'])->willReturn($productVariant);
$productVariant->getCode()->willReturn('productVariantCode');
@ -198,8 +197,7 @@ final class AddingEligibleProductVariantToCartValidatorSpec extends ObjectBehavi
): void {
$this->initialize($executionContext);
$command = new AddItemToCart('productVariantCode', 1);
$command->setOrderTokenValue('TOKEN');
$command = new AddItemToCart('productVariantCode', 1, 'TOKEN');
$productVariantRepository->findOneBy(['code' => 'productVariantCode'])->willReturn($productVariant);
$productVariant->getCode()->willReturn('productVariantCode');
@ -248,8 +246,7 @@ final class AddingEligibleProductVariantToCartValidatorSpec extends ObjectBehavi
): void {
$this->initialize($executionContext);
$command = new AddItemToCart('productVariantCode', 1);
$command->setOrderTokenValue('TOKEN');
$command = new AddItemToCart('productVariantCode', 1, 'TOKEN');
$productVariantRepository->findOneBy(['code' => 'productVariantCode'])->willReturn($productVariant);
$productVariant->getCode()->willReturn('productVariantCode');
@ -299,8 +296,7 @@ final class AddingEligibleProductVariantToCartValidatorSpec extends ObjectBehavi
): void {
$this->initialize($executionContext);
$command = new AddItemToCart('productVariantCode', 1);
$command->setOrderTokenValue('TOKEN');
$command = new AddItemToCart('productVariantCode', 1, 'TOKEN');
$productVariantRepository->findOneBy(['code' => 'productVariantCode'])->willReturn($productVariant);
$productVariant->getCode()->willReturn('productVariantCode');

View file

@ -77,7 +77,7 @@ final class ChangedItemQuantityInCartValidatorSpec extends ObjectBehavior
$this
->shouldThrow(OrderItemNotFoundException::class)
->during('validate', [
ChangeItemQuantityInCart::createFromData('token', '11', 2),
new ChangeItemQuantityInCart(2, 11, 'token'),
new ChangedItemQuantityInCart(),
])
;
@ -100,7 +100,7 @@ final class ChangedItemQuantityInCartValidatorSpec extends ObjectBehavior
;
$this->validate(
ChangeItemQuantityInCart::createFromData('token', '11', 2),
new ChangeItemQuantityInCart(2, 11, 'token'),
new ChangedItemQuantityInCart(),
);
}
@ -130,7 +130,7 @@ final class ChangedItemQuantityInCartValidatorSpec extends ObjectBehavior
;
$this->validate(
ChangeItemQuantityInCart::createFromData('token', '11', 2),
new ChangeItemQuantityInCart(2, 11, 'token'),
new ChangedItemQuantityInCart(),
);
}
@ -162,7 +162,7 @@ final class ChangedItemQuantityInCartValidatorSpec extends ObjectBehavior
;
$this->validate(
ChangeItemQuantityInCart::createFromData('token', '11', 2),
new ChangeItemQuantityInCart(2, 11, 'token'),
new ChangedItemQuantityInCart(),
);
}
@ -197,7 +197,7 @@ final class ChangedItemQuantityInCartValidatorSpec extends ObjectBehavior
;
$this->validate(
ChangeItemQuantityInCart::createFromData('token', '11', 2),
new ChangeItemQuantityInCart(2, 11, 'token'),
new ChangedItemQuantityInCart(),
);
}
@ -242,7 +242,7 @@ final class ChangedItemQuantityInCartValidatorSpec extends ObjectBehavior
;
$this->validate(
ChangeItemQuantityInCart::createFromData('token', '11', 2),
new ChangeItemQuantityInCart(2, 11, 'token'),
new ChangedItemQuantityInCart(),
);
}
@ -295,7 +295,7 @@ final class ChangedItemQuantityInCartValidatorSpec extends ObjectBehavior
;
$this->validate(
ChangeItemQuantityInCart::createFromData('token', '11', 2),
new ChangeItemQuantityInCart(2, 11, 'token'),
new ChangedItemQuantityInCart(),
);
}

View file

@ -75,9 +75,7 @@ final class ChosenShippingMethodEligibilityValidatorSpec extends ObjectBehavior
OrderInterface $order,
AddressInterface $shippingAddress,
): void {
$command = new ChooseShippingMethod('SHIPPING_METHOD_CODE');
$command->setOrderTokenValue('ORDER_TOKEN');
$command->setSubresourceId('123');
$command = new ChooseShippingMethod('SHIPPING_METHOD_CODE', 123, 'ORDER_TOKEN');
$shippingMethodRepository->findOneBy(['code' => 'SHIPPING_METHOD_CODE'])->willReturn($shippingMethod);
$shippingMethod->getName()->willReturn('DHL');
@ -108,9 +106,7 @@ final class ChosenShippingMethodEligibilityValidatorSpec extends ObjectBehavior
OrderInterface $order,
AddressInterface $shippingAddress,
): void {
$command = new ChooseShippingMethod('SHIPPING_METHOD_CODE');
$command->setOrderTokenValue('ORDER_TOKEN');
$command->setSubresourceId('123');
$command = new ChooseShippingMethod('SHIPPING_METHOD_CODE', 123, 'ORDER_TOKEN');
$shippingMethodRepository->findOneBy(['code' => 'SHIPPING_METHOD_CODE'])->willReturn($shippingMethod);
@ -135,9 +131,7 @@ final class ChosenShippingMethodEligibilityValidatorSpec extends ObjectBehavior
ShippingMethodRepositoryInterface $shippingMethodRepository,
ExecutionContextInterface $executionContext,
): void {
$command = new ChooseShippingMethod('SHIPPING_METHOD_CODE');
$command->setOrderTokenValue('ORDER_TOKEN');
$command->setSubresourceId('123');
$command = new ChooseShippingMethod('SHIPPING_METHOD_CODE', 123, 'ORDER_TOKEN');
$shippingMethodRepository->findOneBy(['code' => 'SHIPPING_METHOD_CODE'])->willReturn(null);
@ -164,9 +158,7 @@ final class ChosenShippingMethodEligibilityValidatorSpec extends ObjectBehavior
OrderInterface $order,
AddressInterface $shippingAddress,
): void {
$command = new ChooseShippingMethod('SHIPPING_METHOD_CODE');
$command->setOrderTokenValue('ORDER_TOKEN');
$command->setSubresourceId('123');
$command = new ChooseShippingMethod('SHIPPING_METHOD_CODE', 123, 'ORDER_TOKEN');
$shippingMethodRepository->findOneBy(['code' => 'SHIPPING_METHOD_CODE'])->willReturn($shippingMethod);
@ -192,9 +184,7 @@ final class ChosenShippingMethodEligibilityValidatorSpec extends ObjectBehavior
ExecutionContextInterface $executionContext,
ShippingMethodInterface $shippingMethod,
): void {
$command = new ChooseShippingMethod('SHIPPING_METHOD_CODE');
$command->setOrderTokenValue('ORDER_TOKEN');
$command->setSubresourceId('123');
$command = new ChooseShippingMethod('SHIPPING_METHOD_CODE', 123, 'ORDER_TOKEN');
$shippingMethodRepository->findOneBy(['code' => 'SHIPPING_METHOD_CODE'])->willReturn($shippingMethod);

View file

@ -74,8 +74,7 @@ final class OrderAddressRequirementValidatorSpec extends ObjectBehavior
): void {
$orderRepository->findCartByTokenValue('TOKEN')->willReturn(null);
$updateCart = new UpdateCart(billingAddress: $billingAddress->getWrappedObject());
$updateCart->setOrderTokenValue('TOKEN');
$updateCart = new UpdateCart(billingAddress: $billingAddress->getWrappedObject(), orderTokenValue: 'TOKEN');
$this
->shouldThrow(ChannelNotFoundException::class)
@ -91,8 +90,7 @@ final class OrderAddressRequirementValidatorSpec extends ObjectBehavior
$orderRepository->findCartByTokenValue('TOKEN')->willReturn($order);
$order->getChannel()->willReturn(null);
$updateCart = new UpdateCart(billingAddress: $billingAddress->getWrappedObject());
$updateCart->setOrderTokenValue('TOKEN');
$updateCart = new UpdateCart(billingAddress: $billingAddress->getWrappedObject(), orderTokenValue: 'TOKEN');
$this
->shouldThrow(ChannelNotFoundException::class)
@ -111,8 +109,7 @@ final class OrderAddressRequirementValidatorSpec extends ObjectBehavior
$order->getChannel()->willReturn($channel);
$channel->isShippingAddressInCheckoutRequired()->willReturn(true);
$updateCart = new UpdateCart(shippingAddress: $shippingAddress->getWrappedObject());
$updateCart->setOrderTokenValue('TOKEN');
$updateCart = new UpdateCart(shippingAddress: $shippingAddress->getWrappedObject(), orderTokenValue: 'TOKEN');
$this->validate($updateCart, new OrderAddressRequirement());
@ -130,8 +127,7 @@ final class OrderAddressRequirementValidatorSpec extends ObjectBehavior
$order->getChannel()->willReturn($channel);
$channel->isShippingAddressInCheckoutRequired()->willReturn(false);
$updateCart = new UpdateCart(billingAddress: $billingAddress->getWrappedObject());
$updateCart->setOrderTokenValue('TOKEN');
$updateCart = new UpdateCart(billingAddress: $billingAddress->getWrappedObject(), orderTokenValue: 'TOKEN');
$this->validate($updateCart, new OrderAddressRequirement());
@ -149,8 +145,7 @@ final class OrderAddressRequirementValidatorSpec extends ObjectBehavior
$order->getChannel()->willReturn($channel);
$channel->isShippingAddressInCheckoutRequired()->willReturn(true);
$updateCart = new UpdateCart(billingAddress: $billingAddress->getWrappedObject());
$updateCart->setOrderTokenValue('TOKEN');
$updateCart = new UpdateCart(billingAddress: $billingAddress->getWrappedObject(), orderTokenValue: 'TOKEN');
$this->validate($updateCart, new OrderAddressRequirement());
@ -168,8 +163,7 @@ final class OrderAddressRequirementValidatorSpec extends ObjectBehavior
$order->getChannel()->willReturn($channel);
$channel->isShippingAddressInCheckoutRequired()->willReturn(false);
$updateCart = new UpdateCart(shippingAddress: $shippingAddress->getWrappedObject());
$updateCart->setOrderTokenValue('TOKEN');
$updateCart = new UpdateCart(shippingAddress: $shippingAddress->getWrappedObject(), orderTokenValue: 'TOKEN');
$this->validate($updateCart, new OrderAddressRequirement());

View file

@ -65,8 +65,7 @@ final class PromotionCouponEligibilityValidatorSpec extends ObjectBehavior
$this->initialize($executionContext);
$constraint = new PromotionCouponEligibility();
$value = UpdateCart::createWithCouponData('couponCode');
$value->setOrderTokenValue('token');
$value = new UpdateCart(couponCode: 'couponCode', orderTokenValue: 'token');
$promotionCouponRepository->findOneBy(['code' => 'couponCode'])->willReturn($promotionCoupon);
$orderRepository->findCartByTokenValue('token')->willReturn($cart);
@ -93,8 +92,7 @@ final class PromotionCouponEligibilityValidatorSpec extends ObjectBehavior
$constraint = new PromotionCouponEligibility();
$constraint->message = 'message';
$value = UpdateCart::createWithCouponData('couponCode');
$value->setOrderTokenValue('token');
$value = new UpdateCart(couponCode: 'couponCode', orderTokenValue: 'token');
$promotionCouponRepository->findOneBy(['code' => 'couponCode'])->willReturn($promotionCoupon);
$orderRepository->findCartByTokenValue('token')->willReturn($cart);
@ -120,8 +118,7 @@ final class PromotionCouponEligibilityValidatorSpec extends ObjectBehavior
$constraint = new PromotionCouponEligibility();
$constraint->message = 'message';
$value = UpdateCart::createWithCouponData('couponCode');
$value->setOrderTokenValue('token');
$value = new UpdateCart(couponCode: 'couponCode', orderTokenValue: 'token');
$promotionCouponRepository->findOneBy(['code' => 'couponCode'])->willReturn(null);

View file

@ -87,8 +87,7 @@ final class UpdateCartEmailNotAllowedValidatorSpec extends ObjectBehavior
): void {
$this->initialize($executionContext);
$value = new UpdateCart('sylius@example.com');
$value->setOrderTokenValue('token');
$value = new UpdateCart(email: 'sylius@example.com', orderTokenValue: 'token');
$orderRepository->findOneBy(['tokenValue' => 'token'])->willReturn($order);
$userContext->getUser()->shouldBeCalled()->willReturn($user);
@ -106,8 +105,7 @@ final class UpdateCartEmailNotAllowedValidatorSpec extends ObjectBehavior
): void {
$this->initialize($executionContext);
$value = new UpdateCart('sylius@example.com');
$value->setOrderTokenValue('token');
$value = new UpdateCart(email: 'sylius@example.com', orderTokenValue: 'token');
$orderRepository->findOneBy(['tokenValue' => 'token'])->willReturn($order);
$userContext->getUser()->shouldBeCalled()->willReturn(null);

View file

@ -0,0 +1,18 @@
Sylius\Component\Core\Model\Order:
existing_cart:
channel: "@channel_web"
currencyCode: "USD"
localeCode: "en_US"
state: "cart"
paymentState: "cart"
shippingState: "cart"
checkoutState: "cart"
tokenValue: "existingCartToken"
__calls:
- setCustomerWithAuthorization: ["@customer_dave"]
Sylius\Component\Core\Model\OrderItem:
existing_cart_order_item:
variant: "@product_variant_mug_blue"
order: "@existing_cart"

View file

@ -28,9 +28,9 @@ Sylius\Component\Core\Model\Order:
currencyCode: "USD"
localeCode: "en_US"
state: "cart"
paymentState: "paid"
shippingState: "ready"
checkoutState: "completed"
paymentState: "cart"
shippingState: "cart"
checkoutState: "cart"
tokenValue: "cartToken"
customer: "@customer_dave"

View file

@ -2,6 +2,8 @@
"@context": "\/api\/v2\/contexts\/Order",
"@id": "\/api\/v2\/shop\/orders\/nAWw2jewpA",
"@type": "Order",
"shippingAddress": null,
"billingAddress": null,
"payments": [
{
"@id": "\/api\/v2\/shop\/payments\/@integer@",
@ -25,6 +27,7 @@
"shippingState": "cart",
"tokenValue": "nAWw2jewpA",
"id": "@integer@",
"number": null,
"items": [
{
"@id": "\/api\/v2\/shop\/order-items\/@integer@",

View file

@ -3,6 +3,8 @@
"@id": "\/api\/v2\/shop\/orders\/@string@",
"@type": "Order",
"channel": "\/api\/v2\/shop\/channels\/WEB",
"shippingAddress": null,
"billingAddress": null,
"payments": [],
"shipments": [],
"currencyCode": "USD",
@ -12,6 +14,7 @@
"shippingState": "cart",
"tokenValue": "@string@",
"id": "@integer@",
"number": null,
"items": [],
"itemsTotal": 0,
"total": 0,

View file

@ -3,6 +3,8 @@
"@id": "\/api\/v2\/shop\/orders\/@string@",
"@type": "Order",
"channel": "\/api\/v2\/shop\/channels\/WEB",
"shippingAddress": null,
"billingAddress": null,
"payments": [],
"shipments": [],
"currencyCode": "USD",
@ -12,6 +14,7 @@
"shippingState": "cart",
"tokenValue": "@string@",
"id": "@integer@",
"number": null,
"items": [],
"itemsTotal": 0,
"total": 0,

View file

@ -2,6 +2,8 @@
"@context": "\/api\/v2\/contexts\/Order",
"@id": "\/api\/v2\/shop\/orders\/nAWw2jewpA",
"@type": "Order",
"shippingAddress": null,
"billingAddress": null,
"payments": [
{
"@id": "\/api\/v2\/shop\/payments\/@integer@",
@ -25,6 +27,7 @@
"shippingState": "cart",
"tokenValue": "nAWw2jewpA",
"id": "@integer@",
"number": null,
"items": [
{
"@id": "\/api\/v2\/shop\/order-items\/@integer@",

View file

@ -2,6 +2,8 @@
"@context": "\/api\/v2\/contexts\/Order",
"@id": "\/api\/v2\/shop\/orders\/nAWw2jewpA",
"@type": "Order",
"shippingAddress": null,
"billingAddress": null,
"payments": [],
"shipments": [],
"currencyCode": "USD",
@ -11,6 +13,7 @@
"shippingState": "cart",
"tokenValue": "nAWw2jewpA",
"id": "@integer@",
"number": null,
"items": [],
"itemsTotal": 0,
"total": 0,

View file

@ -0,0 +1,44 @@
{
"@context": "\/api\/v2\/contexts\/Order",
"@id": "\/api\/v2\/shop\/orders\/existingCartToken",
"@type": "Order",
"channel": "\/api\/v2\/shop\/channels\/WEB",
"shippingAddress": null,
"billingAddress": null,
"payments": [],
"shipments": [],
"currencyCode": "USD",
"localeCode": "en_US",
"checkoutState": "cart",
"paymentState": "cart",
"shippingState": "cart",
"tokenValue": "existingCartToken",
"id": "@integer@",
"number": null,
"items": [
{
"@id": "\/api\/v2\/shop\/order-items\/@integer@",
"@type": "OrderItem",
"variant": "\/api\/v2\/shop\/product-variants\/MUG_BLUE",
"productName": "Mug",
"id": "@integer@",
"quantity": 0,
"unitPrice": 0,
"originalUnitPrice": 0,
"total": 0,
"discountedUnitPrice": 0,
"subtotal": 0
}
],
"itemsTotal": 0,
"total": 0,
"state": "cart",
"itemsSubtotal": 0,
"taxTotal": 0,
"shippingTaxTotal": 0,
"taxExcludedTotal": 0,
"taxIncludedTotal": 0,
"shippingTotal": 0,
"orderPromotionTotal": 0,
"shippingPromotionTotal": 0
}

View file

@ -9,8 +9,10 @@
"firstName": "Updated: Jane",
"lastName": "Updated: Doe",
"phoneNumber": "123456789",
"company": null,
"countryCode": "US",
"provinceCode": "US-MI",
"provinceName": null,
"street": "Updated: Top secret",
"city": "Updated: Nebraska",
"postcode": "121212"
@ -21,8 +23,10 @@
"firstName": "Updated: Jane",
"lastName": "Updated: Doe",
"phoneNumber": "123456789",
"company": null,
"countryCode": "US",
"provinceCode": "US-MI",
"provinceName": null,
"street": "Updated: Top secret",
"city": "Updated: Nebraska",
"postcode": "10001"
@ -50,6 +54,7 @@
"shippingState": "cart",
"tokenValue": "nAWw2jewpA",
"id": "@integer@",
"number": null,
"items": [
{
"@id": "\/api\/v2\/shop\/order-items\/@integer@",

View file

@ -2,6 +2,8 @@
"@context": "\/api\/v2\/contexts\/Order",
"@id": "\/api\/v2\/shop\/orders\/nAWw2jewpA",
"@type": "Order",
"shippingAddress": null,
"billingAddress": null,
"payments": [
{
"@id": "\/api\/v2\/shop\/payments\/@integer@",
@ -25,6 +27,7 @@
"shippingState": "cart",
"tokenValue": "nAWw2jewpA",
"id": "@integer@",
"number": null,
"items": [
{
"@id": "\/api\/v2\/shop\/order-items\/@integer@",

View file

@ -0,0 +1,548 @@
<?php
/*
* This file is part of the Sylius package.
*
* (c) Sylius Sp. z o.o.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Sylius\Tests\Api\Shop\Checkout;
use Sylius\Tests\Api\JsonApiTestCase;
use Sylius\Tests\Api\Utils\OrderPlacerTrait;
use Symfony\Component\HttpFoundation\Response;
final class CartTest extends JsonApiTestCase
{
use OrderPlacerTrait;
protected function setUp(): void
{
$this->setUpOrderPlacer();
parent::setUp();
}
/** @test */
public function it_creates_empty_cart(): void
{
$this->loadFixturesFromFiles(['channel.yaml', 'cart.yaml']);
$this->client->request(
method: 'POST',
uri: '/api/v2/shop/orders',
server: array_merge([], self::CONTENT_TYPE_HEADER),
content: '{}',
);
$this->assertResponse(
$this->client->getResponse(),
'shop/checkout/cart/create_cart',
Response::HTTP_CREATED,
);
}
/** @test */
public function it_creates_empty_cart_with_provided_locale(): void
{
$this->loadFixturesFromFiles(['channel.yaml', 'cart.yaml']);
$this->client->request(
method: 'POST',
uri: '/api/v2/shop/orders',
server: array_merge(['HTTP_ACCEPT_LANGUAGE' => 'pl_PL'], self::CONTENT_TYPE_HEADER),
content: '{}',
);
$this->assertResponse(
$this->client->getResponse(),
'shop/checkout/cart/create_cart_with_locale',
Response::HTTP_CREATED,
);
}
/** @test */
public function it_gets_existing_cart_if_customer_has_cart(): void
{
$this->loadFixturesFromFiles([
'authentication/shop_user.yaml',
'channel.yaml',
'cart.yaml',
'cart/existing_cart.yaml',
]);
$this->client->request(
method: 'POST',
uri: '/api/v2/shop/orders',
server: $this->headerBuilder()->withJsonLdAccept()->withJsonLdContentType()->withShopUserAuthorization('dave@doe.com')->build(),
content: '{}',
);
$this->assertResponse(
$this->client->getResponse(),
'shop/checkout/cart/get_existing_cart_if_customer_has_cart',
Response::HTTP_CREATED,
);
}
/** @test */
public function it_gets_empty_cart(): void
{
$this->setUpDefaultGetHeaders();
$this->loadFixturesFromFiles(['channel.yaml', 'cart.yaml']);
$tokenValue = $this->pickUpCart();
$this->requestGet(sprintf('/api/v2/shop/orders/%s', $tokenValue));
$this->assertResponseSuccessful('shop/checkout/cart/get_empty_cart');
}
/** @test */
public function it_gets_a_cart(): void
{
$this->setUpDefaultGetHeaders();
$this->loadFixturesFromFiles([
'channel.yaml',
'cart.yaml',
'country.yaml',
'shipping_method.yaml',
'payment_method.yaml',
]);
$tokenValue = $this->pickUpCart();
$this->addItemToCart('MUG_BLUE', 3, $tokenValue);
$this->requestGet(sprintf('/api/v2/shop/orders/%s', $tokenValue));
$this->assertResponseSuccessful('shop/checkout/cart/get_cart');
}
/** @test */
public function it_adds_item_to_order(): void
{
$this->loadFixturesFromFiles([
'channel.yaml',
'cart.yaml',
'country.yaml',
'shipping_method.yaml',
'payment_method.yaml',
]);
$tokenValue = $this->pickUpCart();
$this->client->request(
method: 'POST',
uri: sprintf('/api/v2/shop/orders/%s/items', $tokenValue),
server: self::CONTENT_TYPE_HEADER,
content: json_encode([
'productVariant' => '/api/v2/shop/product-variants/MUG_BLUE',
'quantity' => 4,
], \JSON_THROW_ON_ERROR),
);
$this->assertResponse(
$this->client->getResponse(),
'shop/checkout/cart/add_item',
Response::HTTP_CREATED,
);
}
/** @test */
public function it_does_not_allow_to_add_item_to_order_with_missing_fields(): void
{
$this->loadFixturesFromFiles([
'channel.yaml',
'cart.yaml',
'country.yaml',
'shipping_method.yaml',
'payment_method.yaml',
]);
$tokenValue = $this->pickUpCart();
$this->client->request(
method: 'POST',
uri: sprintf('/api/v2/shop/orders/%s/items', $tokenValue),
server: self::CONTENT_TYPE_HEADER,
content: '{}',
);
$this->assertResponse(
$this->client->getResponse(),
'shop/checkout/cart/add_item_with_missing_fields',
Response::HTTP_BAD_REQUEST,
);
}
/** @test */
public function it_removes_item_from_the_cart(): void
{
$this->setUpDefaultGetHeaders();
$this->loadFixturesFromFiles([
'channel.yaml',
'cart.yaml',
'country.yaml',
'shipping_method.yaml',
'payment_method.yaml',
]);
$tokenValue = $this->pickUpCart();
$this->addItemToCart('MUG_BLUE', 3, $tokenValue);
$this->requestGet(sprintf('/api/v2/shop/orders/%s', $tokenValue));
$itemId = json_decode($this->client->getResponse()->getContent(), true)['items'][0]['id'];
$this->requestDelete(sprintf('/api/v2/shop/orders/%s/items/%s', $tokenValue, $itemId));
$this->assertResponseCode($this->client->getResponse(), Response::HTTP_NO_CONTENT);
}
/** @test */
public function it_does_not_allow_to_remove_item_from_the_cart_if_invalid_id_item(): void
{
$this->setUpDefaultDeleteHeaders();
$this->loadFixturesFromFiles([
'channel.yaml',
'cart.yaml',
'country.yaml',
'shipping_method.yaml',
'payment_method.yaml',
]);
$tokenValue = $this->pickUpCart();
$this->addItemToCart('MUG_BLUE', 3, $tokenValue);
$this->requestDelete(sprintf('/api/v2/shop/orders/%s/items/STRING-INSTEAD-OF-ID', $tokenValue));
$this->assertResponseCode($this->client->getResponse(), Response::HTTP_NOT_FOUND);
}
/** @test */
public function it_does_not_allow_to_remove_item_from_the_cart_if_invalid_order_token(): void
{
$this->setUpDefaultDeleteHeaders();
$this->loadFixturesFromFiles([
'channel.yaml',
'cart.yaml',
'country.yaml',
'shipping_method.yaml',
'payment_method.yaml',
]);
$tokenValue = $this->pickUpCart();
$this->addItemToCart('MUG_BLUE', 3, $tokenValue);
$this->requestDelete('/api/v2/shop/orders/INVALID/items/STRING-INSTEAD-OF-ID');
$this->assertResponseCode($this->client->getResponse(), Response::HTTP_NOT_FOUND);
}
/** @test */
public function it_updates_item_quantity_in_cart(): void
{
$this->loadFixturesFromFiles([
'channel.yaml',
'cart.yaml',
'country.yaml',
'shipping_method.yaml',
'payment_method.yaml',
]);
$tokenValue = $this->pickUpCart();
$this->addItemToCart('MUG_BLUE', 3, $tokenValue);
$this->requestGet(sprintf('/api/v2/shop/orders/%s', $tokenValue));
$itemId = json_decode($this->client->getResponse()->getContent(), true)['items'][0]['id'];
$this->client->request(
method: 'PATCH',
uri: sprintf('/api/v2/shop/orders/%s/items/%s', $tokenValue, $itemId),
server: $this->headerBuilder()->withMergePatchJsonContentType()->withJsonLdAccept()->build(),
content: json_encode([
'quantity' => 5,
], \JSON_THROW_ON_ERROR),
);
$this->assertResponse(
$this->client->getResponse(),
'shop/checkout/cart/update_item_quantity',
);
}
/** @test */
public function it_does_not_allow_to_update_item_quantity_in_cart_with_missing_fields(): void
{
$this->loadFixturesFromFiles([
'channel.yaml',
'cart.yaml',
'country.yaml',
'shipping_method.yaml',
'payment_method.yaml',
]);
$tokenValue = $this->pickUpCart();
$this->addItemToCart('MUG_BLUE', 3, $tokenValue);
$this->requestGet(sprintf('/api/v2/shop/orders/%s', $tokenValue));
$itemId = json_decode($this->client->getResponse()->getContent(), true)['items'][0]['id'];
$this->client->request(
method: 'PATCH',
uri: sprintf('/api/v2/shop/orders/%s/items/%s', $tokenValue, $itemId),
server: $this->headerBuilder()->withMergePatchJsonContentType()->withJsonLdAccept()->build(),
content: '{}',
);
$this->assertResponse(
$this->client->getResponse(),
'shop/checkout/cart/update_item_quantity_with_missing_fields',
Response::HTTP_BAD_REQUEST,
);
}
/** @test */
public function it_does_not_allow_to_update_item_quantity_if_invalid_id_item(): void
{
$this->loadFixturesFromFiles([
'channel.yaml',
'cart.yaml',
'country.yaml',
'shipping_method.yaml',
'payment_method.yaml',
]);
$tokenValue = $this->pickUpCart();
$this->client->request(
method: 'PATCH',
uri: sprintf('/api/v2/shop/orders/%s/items/%s', $tokenValue, 'invalid-item-id'),
server: $this->headerBuilder()->withMergePatchJsonContentType()->withJsonLdAccept()->build(),
content: json_encode(['quantity' => 5]),
);
$this->assertResponseCode($this->client->getResponse(), Response::HTTP_NOT_FOUND);
}
/** @test */
public function it_updates_cart(): void
{
$this->loadFixturesFromFiles([
'channel.yaml',
'cart.yaml',
'country.yaml',
'shipping_method.yaml',
'payment_method.yaml',
]);
$tokenValue = $this->pickUpCart();
$this->addItemToCart('MUG_BLUE', 3, $tokenValue);
$this->client->request(
method: 'PUT',
uri: sprintf('/api/v2/shop/orders/%s', $tokenValue),
server: self::CONTENT_TYPE_HEADER,
content: json_encode([
'email' => 'oliver@doe.com',
'billingAddress' => [
'firstName' => 'Updated: Jane',
'lastName' => 'Updated: Doe',
'phoneNumber' => '123456789',
'countryCode' => 'US',
'provinceCode' => 'US-MI',
'city' => 'Updated: Nebraska',
'street' => 'Updated: Top secret',
'postcode' => '10001',
],
'shippingAddress' => [
'firstName' => 'Updated: Jane',
'lastName' => 'Updated: Doe',
'phoneNumber' => '123456789',
'countryCode' => 'US',
'provinceCode' => 'US-MI',
'city' => 'Updated: Nebraska',
'street' => 'Updated: Top secret',
'postcode' => '121212',
],
], \JSON_THROW_ON_ERROR),
);
$this->assertResponse(
$this->client->getResponse(),
'shop/checkout/cart/update_cart',
);
}
/** @test */
public function it_does_not_allow_update_without_items(): void
{
$this->loadFixturesFromFiles(['channel.yaml', 'cart.yaml']);
$tokenValue = $this->pickUpCart();
$this->client->request(
method: 'PUT',
uri: sprintf('/api/v2/shop/orders/%s', $tokenValue),
server: self::CONTENT_TYPE_HEADER,
content: json_encode([
'email' => 'oliver@doe.com',
], \JSON_THROW_ON_ERROR),
);
$this->assertResponseViolations(
$this->client->getResponse(),
[
['propertyPath' => '', 'message' => 'An empty order cannot be processed.'],
],
);
}
/** @test */
public function it_does_not_allow_update_without_required_billing_address(): void
{
$this->loadFixturesFromFiles([
'channel.yaml',
'cart.yaml',
'country.yaml',
]);
$tokenValue = $this->pickUpCart();
$this->addItemToCart('MUG_BLUE', 3, $tokenValue);
$this->client->request(
method: 'PUT',
uri: sprintf('/api/v2/shop/orders/%s', $tokenValue),
server: self::CONTENT_TYPE_HEADER,
content: json_encode([
'email' => 'oliver@doe.com',
'shippingAddress' => [
'firstName' => 'Oliver',
'lastName' => 'Doe',
'phoneNumber' => '123456789',
'countryCode' => 'US',
'provinceCode' => 'US-MI',
'city' => 'New York',
'street' => 'Broadway',
'postcode' => '10001',
],
], \JSON_THROW_ON_ERROR),
);
$this->assertResponseViolations(
$this->client->getResponse(),
[
['propertyPath' => '', 'message' => 'Please provide a billing address.'],
],
);
}
/** @test */
public function it_does_not_allow_update_without_required_shipping_address(): void
{
$this->loadFixturesFromFiles([
'channel.yaml',
'cart.yaml',
'country.yaml',
]);
$tokenValue = $this->pickUpCart(channelCode: 'MOBILE');
$this->addItemToCart('MUG_BLUE', 3, $tokenValue);
$this->client->request(
method: 'PUT',
uri: sprintf('/api/v2/shop/orders/%s', $tokenValue),
server: self::CONTENT_TYPE_HEADER,
content: json_encode([
'email' => 'oliver@doe.com',
'billingAddress' => [
'firstName' => 'Oliver',
'lastName' => 'Doe',
'phoneNumber' => '123456789',
'countryCode' => 'US',
'provinceCode' => 'US-MI',
'city' => 'New York',
'street' => 'Broadway',
'postcode' => '10001',
],
], \JSON_THROW_ON_ERROR),
);
$this->assertResponseViolations(
$this->client->getResponse(),
[
['propertyPath' => '', 'message' => 'Please provide a shipping address.'],
],
);
}
/** @test */
public function it_does_not_allow_update_with_invalid_data(): void
{
$this->loadFixturesFromFiles([
'channel.yaml',
'cart.yaml',
'country.yaml',
]);
$tokenValue = $this->pickUpCart(channelCode: 'MOBILE');
$this->addItemToCart('MUG_BLUE', 3, $tokenValue);
$this->client->request(
method: 'PUT',
uri: sprintf('/api/v2/shop/orders/%s', $tokenValue),
server: self::CONTENT_TYPE_HEADER,
content: json_encode([
'billingAddress' => [
'countryCode' => 'invalid-code',
],
'shippingAddress' => [],
'couponCode' => 'invalid',
], \JSON_THROW_ON_ERROR),
);
$this->assertResponseViolations(
$this->client->getResponse(),
[
['propertyPath' => '', 'message' => 'The country invalid-code does not exist.'],
['propertyPath' => '', 'message' => 'The address without country cannot exist'],
['propertyPath' => 'couponCode', 'message' => 'Coupon code is invalid.'],
['propertyPath' => 'billingAddress.firstName', 'message' => 'Please enter first name.'],
['propertyPath' => 'billingAddress.lastName', 'message' => 'Please enter last name.'],
['propertyPath' => 'billingAddress.countryCode', 'message' => 'This value is not a valid country.'],
['propertyPath' => 'billingAddress.street', 'message' => 'Please enter street.'],
['propertyPath' => 'billingAddress.city', 'message' => 'Please enter city.'],
['propertyPath' => 'billingAddress.postcode', 'message' => 'Please enter postcode.'],
['propertyPath' => 'shippingAddress.firstName', 'message' => 'Please enter first name.'],
['propertyPath' => 'shippingAddress.lastName', 'message' => 'Please enter last name.'],
['propertyPath' => 'shippingAddress.countryCode', 'message' => 'Please select country.'],
['propertyPath' => 'shippingAddress.street', 'message' => 'Please enter street.'],
['propertyPath' => 'shippingAddress.city', 'message' => 'Please enter city.'],
['propertyPath' => 'shippingAddress.postcode', 'message' => 'Please enter postcode.'],
],
);
}
/** @test */
public function it_deletes_cart(): void
{
$this->setUpDefaultGetHeaders();
$this->loadFixturesFromFiles([
'channel.yaml',
'cart.yaml',
'country.yaml',
'shipping_method.yaml',
'payment_method.yaml',
]);
$tokenValue = $this->pickUpCart();
$this->requestDelete(sprintf('/api/v2/shop/orders/%s', $tokenValue));
$this->assertResponseCode($this->client->getResponse(), Response::HTTP_NO_CONTENT);
}
}

View file

@ -190,8 +190,10 @@ trait OrderPlacerTrait
protected function pickUpCart(string $tokenValue = 'nAWw2jewpA', string $channelCode = 'WEB'): string
{
$pickupCartCommand = new PickupCart($tokenValue);
$pickupCartCommand->setChannelCode($channelCode);
$pickupCartCommand = new PickupCart(
tokenValue: $tokenValue,
channelCode: $channelCode,
);
$this->commandBus->dispatch($pickupCartCommand);
@ -200,8 +202,11 @@ trait OrderPlacerTrait
protected function addItemToCart(string $productVariantCode, int $quantity, string $tokenValue): string
{
$addItemToCartCommand = new AddItemToCart($productVariantCode, $quantity);
$addItemToCartCommand->setOrderTokenValue($tokenValue);
$addItemToCartCommand = new AddItemToCart(
productVariantCode: $productVariantCode,
quantity: $quantity,
orderTokenValue: $tokenValue,
);
$this->commandBus->dispatch($addItemToCartCommand);