diff --git a/UPGRADE-API-1.13.md b/UPGRADE-API-1.13.md
index 7c93e1a2acf..cf1335afbf3 100644
--- a/UPGRADE-API-1.13.md
+++ b/UPGRADE-API-1.13.md
@@ -1,5 +1,41 @@
# UPGRADE FROM `v1.12.x` TO `v1.13.0`
+1. The signature of constructor of 'Sylius\Bundle\ApiBundle\Command\Cart\ChangeItemQuantityInCart' command changed:
+
+````diff
+ public function __construct(
+- public int $quantity,
++ public ?int $quantity,
+ ) {
+ }
+````
+
+1. The constructor signature of 'Sylius\Bundle\ApiBundle\Command\Cart\AddItemToCart' changed:
+
+````diff
+ public function __construct(
+- public string $productCode,
++ public ?string $productCode,
+- public int $quantity,
++ public ?int $quantity,
+ ) {
+ }
+````
+
+1. The constructor signature of `Sylius\Bundle\ApiBundle\Command\Catalog\AddProductReview` changed:
+
+````diff
+ public function __construct(
+ public ?string $title,
+ public ?int $rating,
+ public ?string $comment,
+- public string $productCode,
++ public ?string $productCode,
+ public ?string $email = null,
+ ) {
+ }
+````
+
1. The item operation paths for ProductVariantTranslation resource changed:
- `GET /admin/product-variant-translation/{id}` -> `GET /admin/product-variant-translations/{id}`
diff --git a/src/Sylius/Behat/Context/Api/Shop/CheckoutContext.php b/src/Sylius/Behat/Context/Api/Shop/CheckoutContext.php
index 2eef494cf77..65b0e211bc9 100644
--- a/src/Sylius/Behat/Context/Api/Shop/CheckoutContext.php
+++ b/src/Sylius/Behat/Context/Api/Shop/CheckoutContext.php
@@ -1052,7 +1052,7 @@ public function iShouldBeInformedThatProductVariantDoesNotExist(ProductVariantIn
{
Assert::true($this->isViolationWithMessageInResponse(
$this->client->getLastResponse(),
- sprintf('The product variant with %s does not exist.', $productVariant->getCode()),
+ sprintf('The product variant %s does not exist.', $productVariant->getCode()),
));
}
@@ -1063,7 +1063,7 @@ public function iShouldBeInformedThatProductVariantWithCodeDoesNotExist(string $
{
Assert::true($this->isViolationWithMessageInResponse(
$this->client->getLastResponse(),
- sprintf('The product variant with %s does not exist.', $code),
+ sprintf('The product variant %s does not exist.', $code),
));
}
diff --git a/src/Sylius/Bundle/ApiBundle/Command/Account/ChangePaymentMethod.php b/src/Sylius/Bundle/ApiBundle/Command/Account/ChangePaymentMethod.php
index 610120cc2ef..8b3b7b3fd46 100644
--- a/src/Sylius/Bundle/ApiBundle/Command/Account/ChangePaymentMethod.php
+++ b/src/Sylius/Bundle/ApiBundle/Command/Account/ChangePaymentMethod.php
@@ -30,16 +30,8 @@ class ChangePaymentMethod implements OrderTokenValueAwareInterface, SubresourceI
*/
public $paymentId;
- /**
- * @psalm-immutable
- *
- * @var string
- */
- public $paymentMethodCode;
-
- public function __construct(string $paymentMethodCode)
+ public function __construct(public string $paymentMethodCode)
{
- $this->paymentMethodCode = $paymentMethodCode;
}
public function getOrderTokenValue(): ?string
diff --git a/src/Sylius/Bundle/ApiBundle/Command/Account/ChangeShopUserPassword.php b/src/Sylius/Bundle/ApiBundle/Command/Account/ChangeShopUserPassword.php
index 4758fbda690..76a9b42ff99 100644
--- a/src/Sylius/Bundle/ApiBundle/Command/Account/ChangeShopUserPassword.php
+++ b/src/Sylius/Bundle/ApiBundle/Command/Account/ChangeShopUserPassword.php
@@ -21,32 +21,8 @@ class ChangeShopUserPassword implements ShopUserIdAwareInterface
/** @var mixed|null */
public $shopUserId;
- /**
- * @psalm-immutable
- *
- * @var string|null
- */
- public $newPassword;
-
- /**
- * @psalm-immutable
- *
- * @var string|null
- */
- public $confirmNewPassword;
-
- /**
- * @psalm-immutable
- *
- * @var string|null
- */
- public $currentPassword;
-
- public function __construct(?string $newPassword, ?string $confirmNewPassword, ?string $currentPassword)
+ public function __construct(public ?string $newPassword, public ?string $confirmNewPassword, public ?string $currentPassword)
{
- $this->newPassword = $newPassword;
- $this->confirmNewPassword = $confirmNewPassword;
- $this->currentPassword = $currentPassword;
}
public function getShopUserId()
diff --git a/src/Sylius/Bundle/ApiBundle/Command/Cart/AddItemToCart.php b/src/Sylius/Bundle/ApiBundle/Command/Cart/AddItemToCart.php
index 71670241f91..52954b9ca5c 100644
--- a/src/Sylius/Bundle/ApiBundle/Command/Cart/AddItemToCart.php
+++ b/src/Sylius/Bundle/ApiBundle/Command/Cart/AddItemToCart.php
@@ -22,24 +22,8 @@ class AddItemToCart implements OrderTokenValueAwareInterface, IriToIdentifierCon
/** @var string|null */
public $orderTokenValue;
- /**
- * @psalm-immutable
- *
- * @var string
- */
- public $productVariantCode;
-
- /**
- * @psalm-immutable
- *
- * @var int
- */
- public $quantity;
-
- public function __construct(string $productVariantCode, int $quantity)
+ public function __construct(public ?string $productVariantCode, public ?int $quantity)
{
- $this->productVariantCode = $productVariantCode;
- $this->quantity = $quantity;
}
public static function createFromData(string $tokenValue, string $productVariantCode, int $quantity): self
diff --git a/src/Sylius/Bundle/ApiBundle/Command/Cart/BlameCart.php b/src/Sylius/Bundle/ApiBundle/Command/Cart/BlameCart.php
index bd4cea3b59b..1b1e52f6ea3 100644
--- a/src/Sylius/Bundle/ApiBundle/Command/Cart/BlameCart.php
+++ b/src/Sylius/Bundle/ApiBundle/Command/Cart/BlameCart.php
@@ -16,23 +16,7 @@
/** @experimental */
class BlameCart
{
- /**
- * @psalm-immutable
- *
- * @var string
- */
- public $shopUserEmail;
-
- /**
- * @psalm-immutable
- *
- * @var string
- */
- public $orderTokenValue;
-
- public function __construct(string $shopUserEmail, string $orderTokenValue)
+ public function __construct(public string $shopUserEmail, public string $orderTokenValue)
{
- $this->shopUserEmail = $shopUserEmail;
- $this->orderTokenValue = $orderTokenValue;
}
}
diff --git a/src/Sylius/Bundle/ApiBundle/Command/Cart/ChangeItemQuantityInCart.php b/src/Sylius/Bundle/ApiBundle/Command/Cart/ChangeItemQuantityInCart.php
index 3ee1a338e50..0ac9ba88898 100644
--- a/src/Sylius/Bundle/ApiBundle/Command/Cart/ChangeItemQuantityInCart.php
+++ b/src/Sylius/Bundle/ApiBundle/Command/Cart/ChangeItemQuantityInCart.php
@@ -25,16 +25,8 @@ class ChangeItemQuantityInCart implements OrderTokenValueAwareInterface, Subreso
/** @var string|null */
public $orderItemId;
- /**
- * @psalm-immutable
- *
- * @var int
- */
- public $quantity;
-
- public function __construct(int $quantity)
+ public function __construct(public ?int $quantity)
{
- $this->quantity = $quantity;
}
public static function createFromData(string $tokenValue, string $orderItemId, int $quantity): self
diff --git a/src/Sylius/Bundle/ApiBundle/Command/Cart/PickupCart.php b/src/Sylius/Bundle/ApiBundle/Command/Cart/PickupCart.php
index 1a08b89695a..f4618b0afc8 100644
--- a/src/Sylius/Bundle/ApiBundle/Command/Cart/PickupCart.php
+++ b/src/Sylius/Bundle/ApiBundle/Command/Cart/PickupCart.php
@@ -20,13 +20,6 @@
/** @experimental */
class PickupCart implements ChannelCodeAwareInterface, CustomerEmailAwareInterface, LocaleCodeAwareInterface
{
- /**
- * @psalm-immutable
- *
- * @var string|null
- */
- public $tokenValue;
-
/** @var string|null */
public $localeCode;
@@ -36,9 +29,8 @@ class PickupCart implements ChannelCodeAwareInterface, CustomerEmailAwareInterfa
/** @var string|null */
public $email;
- public function __construct(?string $tokenValue = null)
+ public function __construct(public ?string $tokenValue = null)
{
- $this->tokenValue = $tokenValue;
}
public function getChannelCode(): ?string
diff --git a/src/Sylius/Bundle/ApiBundle/Command/Cart/RemoveItemFromCart.php b/src/Sylius/Bundle/ApiBundle/Command/Cart/RemoveItemFromCart.php
index c359baf5ab7..c7004a62345 100644
--- a/src/Sylius/Bundle/ApiBundle/Command/Cart/RemoveItemFromCart.php
+++ b/src/Sylius/Bundle/ApiBundle/Command/Cart/RemoveItemFromCart.php
@@ -18,20 +18,8 @@
/** @experimental */
class RemoveItemFromCart implements OrderTokenValueAwareInterface
{
- /** @var string|null */
- public $orderTokenValue;
-
- /**
- * @psalm-immutable
- *
- * @var string
- */
- public $itemId;
-
- public function __construct(?string $orderTokenValue, string $itemId)
+ public function __construct(public ?string $orderTokenValue, public string $itemId)
{
- $this->orderTokenValue = $orderTokenValue;
- $this->itemId = $itemId;
}
public static function removeFromData(string $tokenValue, string $orderItemId): self
diff --git a/src/Sylius/Bundle/ApiBundle/Command/Catalog/AddProductReview.php b/src/Sylius/Bundle/ApiBundle/Command/Catalog/AddProductReview.php
index 52af00ce339..387f8fb75ef 100644
--- a/src/Sylius/Bundle/ApiBundle/Command/Catalog/AddProductReview.php
+++ b/src/Sylius/Bundle/ApiBundle/Command/Catalog/AddProductReview.php
@@ -19,53 +19,13 @@
/** @experimental */
class AddProductReview implements IriToIdentifierConversionAwareInterface, CustomerEmailAwareInterface
{
- /**
- * @psalm-immutable
- *
- * @var string|null
- */
- public $title;
-
- /**
- * @psalm-immutable
- *
- * @var int|null
- */
- public $rating;
-
- /**
- * @psalm-immutable
- *
- * @var string|null
- */
- public $comment;
-
- /**
- * @psalm-immutable
- *
- * @var string
- */
- public $productCode;
-
- /**
- * @psalm-immutable
- *
- * @var string|null
- */
- public $email;
-
public function __construct(
- ?string $title,
- ?int $rating,
- ?string $comment,
- string $productCode,
- ?string $email = null,
+ public ?string $title,
+ public ?int $rating,
+ public ?string $comment,
+ public ?string $productCode,
+ public ?string $email = null,
) {
- $this->title = $title;
- $this->rating = $rating;
- $this->comment = $comment;
- $this->productCode = $productCode;
- $this->email = $email;
}
public function getEmail(): ?string
diff --git a/src/Sylius/Bundle/ApiBundle/CommandHandler/Catalog/AddProductReviewHandler.php b/src/Sylius/Bundle/ApiBundle/CommandHandler/Catalog/AddProductReviewHandler.php
index 67f588b9030..6bd6ab893fd 100644
--- a/src/Sylius/Bundle/ApiBundle/CommandHandler/Catalog/AddProductReviewHandler.php
+++ b/src/Sylius/Bundle/ApiBundle/CommandHandler/Catalog/AddProductReviewHandler.php
@@ -14,6 +14,7 @@
namespace Sylius\Bundle\ApiBundle\CommandHandler\Catalog;
use Sylius\Bundle\ApiBundle\Command\Catalog\AddProductReview;
+use Sylius\Bundle\ApiBundle\Exception\ProductNotFoundException;
use Sylius\Bundle\CoreBundle\Resolver\CustomerResolverInterface;
use Sylius\Component\Core\Model\CustomerInterface;
use Sylius\Component\Core\Model\ProductInterface;
@@ -21,6 +22,7 @@
use Sylius\Component\Resource\Factory\FactoryInterface;
use Sylius\Component\Resource\Repository\RepositoryInterface;
use Sylius\Component\Review\Model\ReviewInterface;
+use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
/** @experimental */
@@ -36,9 +38,13 @@ public function __construct(
public function __invoke(AddProductReview $addProductReview): ReviewInterface
{
- /** @var ProductInterface $product */
+ /** @var ProductInterface|null $product */
$product = $this->productRepository->findOneByCode($addProductReview->productCode);
+ if ($product === null) {
+ throw new ProductNotFoundException(Response::HTTP_UNPROCESSABLE_ENTITY);
+ }
+
/** @var string|null $email */
$email = $addProductReview->getEmail();
diff --git a/src/Sylius/Bundle/ApiBundle/Exception/ProductNotFoundException.php b/src/Sylius/Bundle/ApiBundle/Exception/ProductNotFoundException.php
new file mode 100644
index 00000000000..6d25db789bb
--- /dev/null
+++ b/src/Sylius/Bundle/ApiBundle/Exception/ProductNotFoundException.php
@@ -0,0 +1,26 @@
+sylius
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Sylius/Bundle/ApiBundle/Resources/config/validation/AddProductReview.xml b/src/Sylius/Bundle/ApiBundle/Resources/config/validation/AddProductReview.xml
index 528ca0871c6..92285bd629c 100644
--- a/src/Sylius/Bundle/ApiBundle/Resources/config/validation/AddProductReview.xml
+++ b/src/Sylius/Bundle/ApiBundle/Resources/config/validation/AddProductReview.xml
@@ -52,6 +52,14 @@
+
+
+
+
+
+
diff --git a/src/Sylius/Bundle/ApiBundle/Resources/config/validation/ChangeItemQuantityInCart.xml b/src/Sylius/Bundle/ApiBundle/Resources/config/validation/ChangeItemQuantityInCart.xml
index 5eaaab51fb6..e3b4dacc803 100644
--- a/src/Sylius/Bundle/ApiBundle/Resources/config/validation/ChangeItemQuantityInCart.xml
+++ b/src/Sylius/Bundle/ApiBundle/Resources/config/validation/ChangeItemQuantityInCart.xml
@@ -24,6 +24,10 @@
+
+
+
+
diff --git a/src/Sylius/Bundle/ApiBundle/Resources/translations/validators.en.yaml b/src/Sylius/Bundle/ApiBundle/Resources/translations/validators.en.yaml
index a20959fa6e7..53e8897d5b2 100644
--- a/src/Sylius/Bundle/ApiBundle/Resources/translations/validators.en.yaml
+++ b/src/Sylius/Bundle/ApiBundle/Resources/translations/validators.en.yaml
@@ -19,7 +19,7 @@ sylius:
product:
not_exist: 'The product %productName% does not exist.'
product_variant:
- not_exist: 'The product variant with %productVariantCode% does not exist.'
+ not_exist: 'The product variant %productVariantCode% does not exist.'
not_longer_available: 'The product variant with name %productVariantName% does not exist.'
not_sufficient: 'The product variant with %productVariantCode% code does not have sufficient stock.'
product_variant_with_name_not_sufficient: 'The product variant with %productVariantName% name does not have sufficient stock.'
diff --git a/src/Sylius/Bundle/ApiBundle/Validator/Constraints/AddingEligibleProductVariantToCartValidator.php b/src/Sylius/Bundle/ApiBundle/Validator/Constraints/AddingEligibleProductVariantToCartValidator.php
index c4edeade03b..9d43e13cbe1 100644
--- a/src/Sylius/Bundle/ApiBundle/Validator/Constraints/AddingEligibleProductVariantToCartValidator.php
+++ b/src/Sylius/Bundle/ApiBundle/Validator/Constraints/AddingEligibleProductVariantToCartValidator.php
@@ -41,6 +41,10 @@ public function validate($value, Constraint $constraint)
/** @var AddingEligibleProductVariantToCart $constraint */
Assert::isInstanceOf($constraint, AddingEligibleProductVariantToCart::class);
+ if ($value->productVariantCode === null) {
+ return;
+ }
+
/** @var ProductVariantInterface|null $productVariant */
$productVariant = $this->productVariantRepository->findOneBy(['code' => $value->productVariantCode]);
diff --git a/src/Sylius/Bundle/ApiBundle/Validator/Constraints/ChangedItemQuantityInCartValidator.php b/src/Sylius/Bundle/ApiBundle/Validator/Constraints/ChangedItemQuantityInCartValidator.php
index 980384e4495..0f5655279d9 100644
--- a/src/Sylius/Bundle/ApiBundle/Validator/Constraints/ChangedItemQuantityInCartValidator.php
+++ b/src/Sylius/Bundle/ApiBundle/Validator/Constraints/ChangedItemQuantityInCartValidator.php
@@ -40,6 +40,10 @@ public function validate($value, Constraint $constraint)
/** @var ChangedItemQuantityInCart $constraint */
Assert::isInstanceOf($constraint, ChangedItemQuantityInCart::class);
+ if ($value->quantity === null) {
+ return;
+ }
+
/** @var OrderItemInterface|null $orderItem */
$orderItem = $this->orderItemRepository->findOneBy(['id' => $value->orderItemId]);
Assert::notNull($orderItem);
diff --git a/src/Sylius/Bundle/ApiBundle/spec/CommandHandler/Catalog/AddProductReviewHandlerSpec.php b/src/Sylius/Bundle/ApiBundle/spec/CommandHandler/Catalog/AddProductReviewHandlerSpec.php
index 02da3964c91..61be96ac045 100644
--- a/src/Sylius/Bundle/ApiBundle/spec/CommandHandler/Catalog/AddProductReviewHandlerSpec.php
+++ b/src/Sylius/Bundle/ApiBundle/spec/CommandHandler/Catalog/AddProductReviewHandlerSpec.php
@@ -15,6 +15,7 @@
use PhpSpec\ObjectBehavior;
use Sylius\Bundle\ApiBundle\Command\Catalog\AddProductReview;
+use Sylius\Bundle\ApiBundle\Exception\ProductNotFoundException;
use Sylius\Bundle\CoreBundle\Resolver\CustomerResolverInterface;
use Sylius\Component\Core\Model\CustomerInterface;
use Sylius\Component\Core\Model\ProductInterface;
@@ -91,4 +92,21 @@ function it_throws_an_exception_if_email_has_not_been_found(
])
;
}
+
+ function it_throws_an_exception_if_product_has_not_been_found(ProductRepositoryInterface $productRepository): void
+ {
+ $productRepository->findOneByCode('winter_cap')->willReturn(null);
+
+ $this
+ ->shouldThrow(ProductNotFoundException::class)
+ ->during('__invoke', [
+ new AddProductReview(
+ 'Good stuff',
+ 5,
+ 'Really good stuff',
+ 'winter_cap',
+ ),
+ ])
+ ;
+ }
}
diff --git a/src/Sylius/Bundle/ApiBundle/spec/Validator/Constraints/AddingEligibleProductVariantToCartValidatorSpec.php b/src/Sylius/Bundle/ApiBundle/spec/Validator/Constraints/AddingEligibleProductVariantToCartValidatorSpec.php
index 41068710b2b..4dd3e2e92a4 100644
--- a/src/Sylius/Bundle/ApiBundle/spec/Validator/Constraints/AddingEligibleProductVariantToCartValidatorSpec.php
+++ b/src/Sylius/Bundle/ApiBundle/spec/Validator/Constraints/AddingEligibleProductVariantToCartValidatorSpec.php
@@ -15,6 +15,7 @@
use Doctrine\Common\Collections\Collection;
use PhpSpec\ObjectBehavior;
+use Prophecy\Argument;
use Sylius\Bundle\ApiBundle\Command\Cart\AddItemToCart;
use Sylius\Bundle\ApiBundle\Command\Checkout\CompleteOrder;
use Sylius\Bundle\ApiBundle\Validator\Constraints\AddingEligibleProductVariantToCart;
@@ -135,6 +136,37 @@ function it_adds_violation_if_product_variant_is_disabled(
);
}
+ function it_does_nothing_if_product_variant_is_not_provided(
+ ProductVariantRepositoryInterface $productVariantRepository,
+ OrderRepositoryInterface $orderRepository,
+ AvailabilityCheckerInterface $availabilityChecker,
+ AddItemToCart $addItemToCart,
+ ExecutionContextInterface $executionContext,
+ ProductInterface $product,
+ ProductVariantInterface $productVariant,
+ ): void {
+ $this->initialize($executionContext);
+
+ $productVariantRepository->findOneBy(['code' => null])->shouldNotBeCalled();
+ $productVariant->getProduct()->shouldNotBeCalled();
+ $product->isEnabled()->shouldNotBeCalled();
+
+ $addItemToCart->getOrderTokenValue()->willReturn('TOKEN');
+ $orderRepository->findCartByTokenValue('TOKEN')->shouldNotBeCalled();
+
+ $availabilityChecker->isStockSufficient($productVariant, 1)->shouldNotBeCalled();
+
+ $executionContext
+ ->addViolation(Argument::any())
+ ->shouldNotBeCalled()
+ ;
+
+ $this->validate(
+ new AddItemToCart(null, 1),
+ new AddingEligibleProductVariantToCart(),
+ );
+ }
+
function it_adds_violation_if_product_variant_stock_is_not_sufficient_and_cart_has_same_units(
ProductVariantRepositoryInterface $productVariantRepository,
OrderRepositoryInterface $orderRepository,
diff --git a/src/Sylius/Bundle/ApiBundle/spec/Validator/Constraints/ChangedItemQuantityInCartValidatorSpec.php b/src/Sylius/Bundle/ApiBundle/spec/Validator/Constraints/ChangedItemQuantityInCartValidatorSpec.php
index dae9de3a778..a83976bb55f 100644
--- a/src/Sylius/Bundle/ApiBundle/spec/Validator/Constraints/ChangedItemQuantityInCartValidatorSpec.php
+++ b/src/Sylius/Bundle/ApiBundle/spec/Validator/Constraints/ChangedItemQuantityInCartValidatorSpec.php
@@ -14,6 +14,7 @@
namespace spec\Sylius\Bundle\ApiBundle\Validator\Constraints;
use PhpSpec\ObjectBehavior;
+use Prophecy\Argument;
use Sylius\Bundle\ApiBundle\Command\Cart\ChangeItemQuantityInCart;
use Sylius\Bundle\ApiBundle\Command\Checkout\CompleteOrder;
use Sylius\Bundle\ApiBundle\Validator\Constraints\AddingEligibleProductVariantToCart;
diff --git a/src/Sylius/Bundle/CoreBundle/Resources/translations/validators.en.yml b/src/Sylius/Bundle/CoreBundle/Resources/translations/validators.en.yml
index 35b7f78cd89..1da5419edd1 100644
--- a/src/Sylius/Bundle/CoreBundle/Resources/translations/validators.en.yml
+++ b/src/Sylius/Bundle/CoreBundle/Resources/translations/validators.en.yml
@@ -125,6 +125,8 @@ sylius:
review:
author:
not_blank: Please enter your email.
+ product:
+ not_blank: Please enter a product.
rating:
range: Review rating must be an integer in the range 1-5.
not_in_range: Review rating must be between {{ min }} and {{ max }}.
diff --git a/src/Sylius/Bundle/OrderBundle/Resources/translations/validators.en.yml b/src/Sylius/Bundle/OrderBundle/Resources/translations/validators.en.yml
index b984f947d6b..c7ee1e52bb3 100644
--- a/src/Sylius/Bundle/OrderBundle/Resources/translations/validators.en.yml
+++ b/src/Sylius/Bundle/OrderBundle/Resources/translations/validators.en.yml
@@ -1,4 +1,10 @@
+# This file is part of the Sylius package.
+# (c) Sylius Sp. z o.o.
+
sylius:
order_item:
+ product_variant:
+ not_blank: The product variant has not been provided.
quantity:
min: Quantity of an order item cannot be lower than 1.
+ not_blank: The quantity has not been provided.
diff --git a/tests/Api/Shop/OrdersTest.php b/tests/Api/Shop/OrdersTest.php
index d440f7434f2..5f2cb8fc67f 100644
--- a/tests/Api/Shop/OrdersTest.php
+++ b/tests/Api/Shop/OrdersTest.php
@@ -477,4 +477,83 @@ public function it_returns_unprocessable_entity_status_if_tries_to_remove_an_ite
$this->assertResponseCode($this->client->getResponse(), Response::HTTP_UNPROCESSABLE_ENTITY);
}
+
+ /** @test */
+ public function it_prevents_from_adding_an_item_to_the_cart_if_product_variant_is_missing(): void
+ {
+ $this->loadFixturesFromFiles(['channel.yaml', 'cart.yaml']);
+
+ $tokenValue = 'nAWw2jewpA';
+
+ /** @var MessageBusInterface $commandBus */
+ $commandBus = self::getContainer()->get('sylius.command_bus');
+
+ $pickupCartCommand = new PickupCart($tokenValue);
+ $pickupCartCommand->setChannelCode('WEB');
+ $commandBus->dispatch($pickupCartCommand);
+
+ $this->client->request(
+ method: 'POST',
+ uri: sprintf('/api/v2/shop/orders/%s/items', $tokenValue),
+ server: self::CONTENT_TYPE_HEADER,
+ content: json_encode([
+ 'quantity' => 3,
+ ], JSON_THROW_ON_ERROR),
+ );
+ $response = $this->client->getResponse();
+
+ $this->assertResponseCode($response, Response::HTTP_UNPROCESSABLE_ENTITY);
+ }
+
+ /** @test */
+ public function it_prevents_from_adding_an_item_to_the_cart_if_quantity_is_missing(): void
+ {
+ $this->loadFixturesFromFiles(['channel.yaml', 'cart.yaml']);
+
+ $tokenValue = 'nAWw2jewpA';
+
+ /** @var MessageBusInterface $commandBus */
+ $commandBus = self::getContainer()->get('sylius.command_bus');
+
+ $pickupCartCommand = new PickupCart($tokenValue);
+ $pickupCartCommand->setChannelCode('WEB');
+ $commandBus->dispatch($pickupCartCommand);
+
+ $this->client->request(
+ method: 'POST',
+ uri: sprintf('/api/v2/shop/orders/%s/items', $tokenValue),
+ server: self::CONTENT_TYPE_HEADER,
+ content: json_encode([
+ 'productVariant' => 'MUG_BLUE',
+ ], JSON_THROW_ON_ERROR),
+ );
+ $response = $this->client->getResponse();
+
+ $this->assertResponseCode($response, Response::HTTP_UNPROCESSABLE_ENTITY);
+ }
+
+ /** @test */
+ public function it_prevents_from_changing_an_item_quantity_if_quantity_is_missing(): void
+ {
+ $this->loadFixturesFromFiles(['channel.yaml', 'cart.yaml']);
+
+ $tokenValue = 'nAWw2jewpA';
+
+ /** @var MessageBusInterface $commandBus */
+ $commandBus = self::getContainer()->get('sylius.command_bus');
+
+ $pickupCartCommand = new PickupCart($tokenValue);
+ $pickupCartCommand->setChannelCode('WEB');
+ $commandBus->dispatch($pickupCartCommand);
+
+ $this->client->request(
+ method: 'PATCH',
+ uri: sprintf('/api/v2/shop/orders/%s/items/%s', $tokenValue, 1),
+ server: self::PATCH_CONTENT_TYPE_HEADER,
+ content: json_encode([]),
+ );
+ $response = $this->client->getResponse();
+
+ $this->assertResponseCode($response, Response::HTTP_UNPROCESSABLE_ENTITY);
+ }
}
diff --git a/tests/Api/Shop/ProductReviewsTest.php b/tests/Api/Shop/ProductReviewsTest.php
index 342a96fbced..afac1a7eff1 100644
--- a/tests/Api/Shop/ProductReviewsTest.php
+++ b/tests/Api/Shop/ProductReviewsTest.php
@@ -80,4 +80,45 @@ public function it_creates_a_product_review(): void
Response::HTTP_CREATED,
);
}
+
+ /** @test */
+ public function it_prevents_from_creating_a_product_review_with_non_existing_product(): void
+ {
+ $this->loadFixturesFromFiles(['product/product_variant.yaml']);
+
+ $this->client->request(
+ method: 'POST',
+ uri: '/api/v2/shop/product-reviews',
+ server: self::CONTENT_TYPE_HEADER,
+ content: json_encode([
+ 'title' => 'Greatest product!',
+ 'rating' => 3,
+ 'comment' => 'I\'ve never bought anything better.',
+ 'email' => 'test@test.com',
+ 'product' => '/api/v2/shop/products/NON-EXISTING-PRODUCT',
+ ], JSON_THROW_ON_ERROR),
+ );
+
+ $this->assertResponseCode($this->client->getResponse(), Response::HTTP_UNPROCESSABLE_ENTITY);
+ }
+
+ /** @test */
+ public function it_prevents_from_creating_a_product_review_if_no_product_provided(): void
+ {
+ $this->loadFixturesFromFiles(['product/product_variant.yaml']);
+
+ $this->client->request(
+ method: 'POST',
+ uri: '/api/v2/shop/product-reviews',
+ server: self::CONTENT_TYPE_HEADER,
+ content: json_encode([
+ 'title' => 'Greatest product!',
+ 'rating' => 3,
+ 'comment' => 'I\'ve never bought anything better.',
+ 'email' => 'test@test.com',
+ ], JSON_THROW_ON_ERROR),
+ );
+
+ $this->assertResponseCode($this->client->getResponse(), Response::HTTP_UNPROCESSABLE_ENTITY);
+ }
}