mirror of
https://github.com/Sylius/Sylius.git
synced 2026-07-14 17:10:53 +00:00
[Shop][Checkout] Prevent starting checkout with empty cart
This commit is contained in:
parent
a63e26058c
commit
5210baf7d5
6 changed files with 97 additions and 10 deletions
|
|
@ -0,0 +1,17 @@
|
|||
@checkout
|
||||
Feature: Prevent starting checkout with empty cart
|
||||
In order to get back to shop after starting checkout with empty cart
|
||||
As a Customer
|
||||
I want to be able to add something to cart before entering checkout
|
||||
|
||||
Background:
|
||||
Given the store operates on a single channel in "United States"
|
||||
And the store has a product "PHP T-Shirt" priced at "$19.99"
|
||||
And the store ships everywhere for free
|
||||
And the store allows paying offline
|
||||
And I am a logged in customer
|
||||
|
||||
@ui
|
||||
Scenario: Being on shop home page after starting checkout with empty cart
|
||||
Given I have tried to open checkout addressing page
|
||||
Then I should be redirected to the homepage
|
||||
|
|
@ -169,6 +169,14 @@ final class CheckoutContext implements Context
|
|||
$this->addressPage->open();
|
||||
}
|
||||
|
||||
/**
|
||||
* @Given I have tried to open checkout addressing page
|
||||
*/
|
||||
public function iHaveTriedToOpenCheckoutAddressingPage()
|
||||
{
|
||||
$this->addressPage->tryToOpen();
|
||||
}
|
||||
|
||||
/**
|
||||
* @Given /^(this user) bought this product$/
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -83,6 +83,11 @@ final class CheckoutResolver implements EventSubscriberInterface
|
|||
|
||||
/** @var OrderInterface $order */
|
||||
$order = $this->cartContext->getCart();
|
||||
|
||||
if ($order->isEmpty()) {
|
||||
$event->setResponse(new RedirectResponse($this->urlGenerator->generate('sylius_shop_homepage')));
|
||||
}
|
||||
|
||||
$stateMachine = $this->stateMachineFactory->get($order, OrderCheckoutTransitions::GRAPH);
|
||||
|
||||
if ($stateMachine->can($this->getRequestedTransition($request))) {
|
||||
|
|
@ -95,7 +100,7 @@ final class CheckoutResolver implements EventSubscriberInterface
|
|||
return;
|
||||
}
|
||||
|
||||
$event->setResponse(new RedirectResponse($this->urlGenerator->generate($order->getCheckoutState())));
|
||||
$event->setResponse(new RedirectResponse($this->urlGenerator->generateForOrderCheckoutState($order)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -11,15 +11,15 @@
|
|||
|
||||
namespace Sylius\Bundle\CoreBundle\Checkout;
|
||||
|
||||
use Sylius\Component\Core\Model\OrderInterface;
|
||||
use Symfony\Component\Routing\Exception\RouteNotFoundException;
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
use Symfony\Component\Routing\RequestContext;
|
||||
use Symfony\Component\Routing\RouterInterface;
|
||||
|
||||
/**
|
||||
* @author Arkadiusz Krakowiak <arkadiusz.krakowiak@lakion.com>
|
||||
*/
|
||||
final class CheckoutStateUrlGenerator implements UrlGeneratorInterface
|
||||
final class CheckoutStateUrlGenerator implements CheckoutStateUrlGeneratorInterface
|
||||
{
|
||||
/**
|
||||
* @var RouterInterface
|
||||
|
|
@ -44,13 +44,21 @@ final class CheckoutStateUrlGenerator implements UrlGeneratorInterface
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH)
|
||||
public function generate($name, $parameters = [], $referenceType = self::ABSOLUTE_PATH)
|
||||
{
|
||||
if (!isset($this->routeCollection[$name]['route'])) {
|
||||
return $this->router->generate($name, $parameters, $referenceType);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function generateForOrderCheckoutState(OrderInterface $order, $parameters = [], $referenceType = self::ABSOLUTE_PATH)
|
||||
{
|
||||
if (!isset($this->routeCollection[$order->getCheckoutState()]['route'])) {
|
||||
throw new RouteNotFoundException();
|
||||
}
|
||||
|
||||
return $this->router->generate($this->routeCollection[$name]['route'], $parameters, $referenceType);
|
||||
return $this->router->generate($this->routeCollection[$order->getCheckoutState()]['route'], $parameters, $referenceType);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Paweł Jędrzejewski
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Sylius\Bundle\CoreBundle\Checkout;
|
||||
|
||||
use Sylius\Component\Core\Model\OrderInterface;
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
|
||||
/**
|
||||
* @author Arkadiusz Krakowiak <arkadiusz.krakowiak@lakion.com>
|
||||
*/
|
||||
interface CheckoutStateUrlGeneratorInterface extends UrlGeneratorInterface
|
||||
{
|
||||
/**
|
||||
* @param OrderInterface $order
|
||||
* @param array $parameters
|
||||
* @param int $referenceType
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function generateForOrderCheckoutState(OrderInterface $order, $parameters = [], $referenceType = self::ABSOLUTE_PATH);
|
||||
}
|
||||
|
|
@ -14,6 +14,8 @@ namespace spec\Sylius\Bundle\CoreBundle\Checkout;
|
|||
use PhpSpec\ObjectBehavior;
|
||||
use Prophecy\Argument;
|
||||
use Sylius\Bundle\CoreBundle\Checkout\CheckoutStateUrlGenerator;
|
||||
use Sylius\Bundle\CoreBundle\Checkout\CheckoutStateUrlGeneratorInterface;
|
||||
use Sylius\Component\Core\Model\OrderInterface;
|
||||
use Symfony\Component\Routing\Exception\RouteNotFoundException;
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
use Symfony\Component\Routing\RouterInterface;
|
||||
|
|
@ -46,19 +48,36 @@ final class CheckoutStateUrlGeneratorSpec extends ObjectBehavior
|
|||
$this->shouldImplement(UrlGeneratorInterface::class);
|
||||
}
|
||||
|
||||
function it_generates_state_url(RouterInterface $router)
|
||||
function it_is_a_checkout_state_url_generator()
|
||||
{
|
||||
$this->shouldImplement(CheckoutStateUrlGeneratorInterface::class);
|
||||
}
|
||||
|
||||
function it_generates_state_url(RouterInterface $router, OrderInterface $order)
|
||||
{
|
||||
$order->getCheckoutState()->willReturn('addressed');
|
||||
|
||||
$router->generate('sylius_shop_checkout_select_shipping', [], UrlGeneratorInterface::ABSOLUTE_PATH)
|
||||
->willReturn('/checkout/address')
|
||||
;
|
||||
|
||||
$this->generate('addressed')->shouldReturn('/checkout/address');
|
||||
$this->generateForOrderCheckoutState($order)->shouldReturn('/checkout/address');
|
||||
}
|
||||
|
||||
function it_throws_route_not_found_exception_if_there_is_no_route_for_given_state(RouterInterface $router)
|
||||
function it_is_a_regular_url_generator(RouterInterface $router)
|
||||
{
|
||||
$router->generate('route_name', [], UrlGeneratorInterface::ABSOLUTE_PATH)->willReturn('/some-route');
|
||||
|
||||
$this->generate('route_name')->shouldReturn('/some-route');
|
||||
}
|
||||
|
||||
function it_throws_route_not_found_exception_if_there_is_no_route_for_given_state(
|
||||
RouterInterface $router,
|
||||
OrderInterface $order
|
||||
) {
|
||||
$order->getCheckoutState()->willReturn('shipping_selected');
|
||||
$router->generate(Argument::any())->shouldNotBeCalled();
|
||||
|
||||
$this->shouldThrow(RouteNotFoundException::class)->during('generate', ['shipping_selected']);
|
||||
$this->shouldThrow(RouteNotFoundException::class)->during('generateForOrderCheckoutState', [$order]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue