diff --git a/src/Sylius/Bundle/AdminApiBundle/Resources/config/routing/checkout.yml b/src/Sylius/Bundle/AdminApiBundle/Resources/config/routing/checkout.yml index 121fa811b5c..860884c338f 100644 --- a/src/Sylius/Bundle/AdminApiBundle/Resources/config/routing/checkout.yml +++ b/src/Sylius/Bundle/AdminApiBundle/Resources/config/routing/checkout.yml @@ -75,7 +75,10 @@ sylius_admin_api_checkout_complete: _controller: sylius.controller.order:updateAction _sylius: serialization_version: $version - form: Sylius\Bundle\CoreBundle\Form\Type\Checkout\CompleteType + form: + type: Sylius\Bundle\CoreBundle\Form\Type\Checkout\CompleteType + options: + validation_groups: 'sylius_checkout_complete' repository: method: find arguments: [$orderId] diff --git a/tests/Controller/CheckoutCompleteApiTest.php b/tests/Controller/CheckoutCompleteApiTest.php index 58cfe2af03f..cd43b89bc69 100644 --- a/tests/Controller/CheckoutCompleteApiTest.php +++ b/tests/Controller/CheckoutCompleteApiTest.php @@ -11,9 +11,11 @@ namespace Sylius\Tests\Controller; -use Sylius\Component\Core\Model\OrderInterface; -use Sylius\Component\Core\Model\PaymentMethodInterface; -use Sylius\Component\Core\Model\ShippingMethodInterface; +use Doctrine\ORM\EntityManagerInterface; +use Sylius\Component\Core\Model\ProductVariant; +use Sylius\Component\Product\Model\ProductInterface; +use Sylius\Component\Product\Repository\ProductRepositoryInterface; +use Sylius\Component\Product\Repository\ProductVariantRepositoryInterface; use Symfony\Component\HttpFoundation\Response; /** @@ -64,6 +66,72 @@ public function it_does_not_allow_to_complete_order_that_is_not_addressed_and_ha $this->assertResponse($response, 'checkout/complete_invalid_order_state', Response::HTTP_INTERNAL_SERVER_ERROR); } + /** + * @test + */ + public function it_does_not_allow_to_complete_order_with_disabled_product() + { + $this->loadFixturesFromFile('authentication/api_administrator.yml'); + $this->loadFixturesFromFile('resources/checkout.yml'); + + $cartId = $this->createCart(); + $this->addItemToCart($cartId); + $this->addressOrder($cartId); + $this->selectOrderShippingMethod($cartId); + $this->selectOrderPaymentMethod($cartId); + + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = $this->client->getContainer()->get('sylius.repository.product'); + /** @var ProductInterface $product */ + $product = $productRepository->findOneBy(['code' => 'MUG']); + $this->assertNotNull($product); + $product->disable(); + + /** @var EntityManagerInterface $productManager */ + $productManager = $this->client->getContainer()->get('sylius.manager.product'); + $productManager->persist($product); + $productManager->flush(); + + $this->client->request('PUT', $this->getCheckoutCompleteUrl($cartId), [], [], static::$authorizedHeaderWithContentType); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'checkout/complete_validation_failed_disabled_product', Response::HTTP_BAD_REQUEST); + } + + /** + * @test + */ + public function it_does_not_allow_to_complete_order_with_insufficient_stock() + { + $this->loadFixturesFromFile('authentication/api_administrator.yml'); + $this->loadFixturesFromFile('resources/checkout.yml'); + + $cartId = $this->createCart(); + $this->addItemToCart($cartId); + $this->addressOrder($cartId); + $this->selectOrderShippingMethod($cartId); + $this->selectOrderPaymentMethod($cartId); + + /** @var ProductVariantRepositoryInterface $productVariantRepository */ + $productVariantRepository = $this->client->getContainer()->get('sylius.repository.product_variant'); + /** @var ProductVariant $productVariant */ + $productVariant = $productVariantRepository->findOneByCodeAndProductCode('MUG_SW', 'MUG'); + $this->assertNotNull($productVariant); + $productVariant->setTracked(true); + $productVariant->setOnHand(0); + $productVariant->setOnHold(0); + + /** @var EntityManagerInterface $productVariantManager */ + $productVariantManager = $this->client->getContainer()->get('sylius.manager.product_variant'); + $productVariantManager->persist($productVariant); + $productVariantManager->flush(); + + $this->client->request('PUT', $this->getCheckoutCompleteUrl($cartId), [], [], static::$authorizedHeaderWithContentType); + + $response = $this->client->getResponse(); + $this->assertResponse($response, 'checkout/complete_validation_failed_insufficient_stock', Response::HTTP_BAD_REQUEST); + } + /** * @test */ diff --git a/tests/Responses/Expected/checkout/complete_validation_failed_disabled_product.json b/tests/Responses/Expected/checkout/complete_validation_failed_disabled_product.json new file mode 100644 index 00000000000..58bb3f0df61 --- /dev/null +++ b/tests/Responses/Expected/checkout/complete_validation_failed_disabled_product.json @@ -0,0 +1,12 @@ +{ + "code": 400, + "message": "Validation Failed", + "errors": { + "errors": [ + "This product Mug has been disabled." + ], + "children": { + "notes": {} + } + } +} diff --git a/tests/Responses/Expected/checkout/complete_validation_failed_insufficient_stock.json b/tests/Responses/Expected/checkout/complete_validation_failed_insufficient_stock.json new file mode 100644 index 00000000000..94374c03cb7 --- /dev/null +++ b/tests/Responses/Expected/checkout/complete_validation_failed_insufficient_stock.json @@ -0,0 +1,12 @@ +{ + "code": 400, + "message": "Validation Failed", + "errors": { + "errors": [ + "Mug does not have sufficient stock." + ], + "children": { + "notes": {} + } + } +}