Skip to content

Commit

Permalink
bug #401 Double cart fix (mamazu)
Browse files Browse the repository at this point in the history
This PR was merged into the 1.0-dev branch.

Discussion
----------

This fixes #393 

In this pull request I introduced a new Request and Command object for picking up a cart of a customer that is logged in. This way I registered a new handler. The `PickupLoggedInCart` Command and Request object inherit from the "non logged in"-version.

Commits
-------

433ec63 Fix for the duplicate cart
ab94312 Codestyle
42ae068 Refactored it
164b3d2 Reverted to simpler fix
  • Loading branch information
lchrusciel authored Mar 7, 2019
2 parents 3e5d831 + 164b3d2 commit a4b2f62
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 13 deletions.
21 changes: 17 additions & 4 deletions spec/Handler/Cart/PickupCartHandlerSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,28 @@
use Sylius\Component\Locale\Model\LocaleInterface;
use Sylius\Component\Resource\Factory\FactoryInterface;
use Sylius\ShopApiPlugin\Command\PickupCart;
use Sylius\ShopApiPlugin\Handler\Cart\PickupCartHandler;

final class PickupCartHandlerSpec extends ObjectBehavior
{
function let(FactoryInterface $cartFactory, OrderRepositoryInterface $cartRepository, ChannelRepositoryInterface $channelRepository): void
function let(
FactoryInterface $cartFactory,
OrderRepositoryInterface $cartRepository,
ChannelRepositoryInterface $channelRepository
): void {
$this->beConstructedWith(
$cartFactory,
$cartRepository,
$channelRepository
);
}

function it_is_initializable(): void
{
$this->beConstructedWith($cartFactory, $cartRepository, $channelRepository);
$this->shouldHaveType(PickupCartHandler::class);
}

function it_handles_cart_pickup(
function it_handles_cart_pickup_for_not_logged_in_user(
ChannelInterface $channel,
CurrencyInterface $currency,
ChannelRepositoryInterface $channelRepository,
Expand All @@ -43,7 +56,7 @@ function it_handles_cart_pickup(
$cart->setCurrencyCode('EUR')->shouldBeCalled();
$cart->setLocaleCode('de_DE')->shouldBeCalled();

$cartRepository->add($cart)->shouldBeCalled();
$cartRepository->add($cart)->shouldBeCalledOnce();

$this->handle(new PickupCart('ORDERTOKEN', 'CHANNEL_CODE'));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Validator\Validator\ValidatorInterface;

final class PickupAction
final class PickupCartAction
{
/** @var ViewHandlerInterface */
private $viewHandler;
Expand Down Expand Up @@ -66,6 +66,8 @@ public function __invoke(Request $request): Response
}
}

return $this->viewHandler->handle(View::create($this->validationErrorViewFactory->create($validationResults), Response::HTTP_BAD_REQUEST));
return $this->viewHandler->handle(
View::create($this->validationErrorViewFactory->create($validationResults), Response::HTTP_BAD_REQUEST)
);
}
}
10 changes: 6 additions & 4 deletions src/Handler/Cart/PickupCartHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,19 @@ final class PickupCartHandler
/** @var ChannelRepositoryInterface */
private $channelRepository;

public function __construct(FactoryInterface $cartFactory, OrderRepositoryInterface $cartRepository, ChannelRepositoryInterface $channelRepository)
{
public function __construct(
FactoryInterface $cartFactory,
OrderRepositoryInterface $cartRepository,
ChannelRepositoryInterface $channelRepository
) {
$this->cartFactory = $cartFactory;
$this->cartRepository = $cartRepository;
$this->channelRepository = $channelRepository;
}

/** @param PickupCart $pickupCart */
public function handle(PickupCart $pickupCart)
{
/** @var ChannelInterface $channel */
/** @var ChannelInterface|null $channel */
$channel = $this->channelRepository->findOneByCode($pickupCart->channelCode());

Assert::notNull($channel, sprintf('Channel with %s code has not been found.', $pickupCart->channelCode()));
Expand Down
5 changes: 5 additions & 0 deletions src/Resources/config/services.xml
Original file line number Diff line number Diff line change
Expand Up @@ -63,5 +63,10 @@
<argument type="service" id="validator" />
<argument type="service" id="tactician.commandbus" />
</service>

<!-- Removing the create cart context from composite context (see: https://github.com/Sylius/Sylius/issues/10192) -->
<service id="sylius.context.cart.new" class="Sylius\Component\Order\Context\CartContext">
<argument type="service" id="sylius.factory.order" />
</service>
</services>
</container>
2 changes: 1 addition & 1 deletion src/Resources/config/services/actions/cart.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
</service>

<service id="sylius.shop_api_plugin.controller.cart.pickup_action"
class="Sylius\ShopApiPlugin\Controller\Cart\PickupAction"
class="Sylius\ShopApiPlugin\Controller\Cart\PickupCartAction"
>
<argument type="service" id="fos_rest.view_handler" />
<argument type="service" id="tactician.commandbus" />
Expand Down
39 changes: 37 additions & 2 deletions tests/Controller/Cart/CartPickupApiTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@
namespace Tests\Sylius\ShopApiPlugin\Controller\Cart;

use League\Tactician\CommandBus;
use Sylius\Component\Core\Repository\OrderRepositoryInterface;
use Sylius\ShopApiPlugin\Command\PickupCart;
use Symfony\Component\HttpFoundation\Response;
use Tests\Sylius\ShopApiPlugin\Controller\JsonApiTestCase;
use Tests\Sylius\ShopApiPlugin\Controller\Utils\ShopUserLoginTrait;

final class CartPickupApiTest extends JsonApiTestCase
{
use ShopUserLoginTrait;

/**
* @test
*/
Expand All @@ -23,23 +27,52 @@ public function it_creates_a_new_cart(): void
$response = $this->client->getResponse();

$this->assertResponse($response, 'cart/empty_response', Response::HTTP_CREATED);

$orderRepository = $this->get('sylius.repository.order');
$count = $orderRepository->count([]);

$this->assertSame(1, $count, 'Only one cart should be created');
}

/**
* @test
*/
public function it_only_creates_one_cart_if_user_is_logged_in(): void
{
$this->loadFixturesFromFiles(['shop.yml', 'customer.yml']);

$this->logInUser('oliver@queen.com', '123password');

$this->client->request('POST', '/shop-api/WEB_GB/carts', [], [], static::CONTENT_TYPE_HEADER);
$response = $this->client->getResponse();
$this->assertResponseCode($response, Response::HTTP_CREATED);

/** @var OrderRepositoryInterface $orderRepository */
$orderRepository = $this->get('sylius.repository.order');
$orders = $orderRepository->findAll();

$this->assertCount(1, $orders, 'Only one cart should be created');
}

/**
* @deprecated
* @test
*/
public function it_creates_a_new_cart_using_deprecated_api(): void
{
$this->loadFixturesFromFiles(['shop.yml']);

$this->client->request('POST', '/shop-api/WEB_GB/carts/SDAOSLEFNWU35H3QLI5325', [], [], self::CONTENT_TYPE_HEADER);
$this->client->request(
'POST', '/shop-api/WEB_GB/carts/SDAOSLEFNWU35H3QLI5325', [], [], self::CONTENT_TYPE_HEADER
);

$response = $this->client->getResponse();

$this->assertResponse($response, 'cart/deprecated_empty_response', Response::HTTP_CREATED);
}

/**
* @deprecated
* @test
*/
public function it_does_not_allow_to_create_a_new_cart_if_token_is_already_used(): void
Expand All @@ -66,7 +99,9 @@ public function it_does_not_allow_to_create_a_new_cart_in_non_existent_channel()
{
$this->loadFixturesFromFiles(['shop.yml']);

$this->client->request('POST', '/shop-api/SPACE_KLINGON/carts/SDAOSLEFNWU35H3QLI5325', [], [], self::CONTENT_TYPE_HEADER);
$this->client->request(
'POST', '/shop-api/SPACE_KLINGON/carts/SDAOSLEFNWU35H3QLI5325', [], [], self::CONTENT_TYPE_HEADER
);

$response = $this->client->getResponse();

Expand Down

0 comments on commit a4b2f62

Please sign in to comment.