Skip to content

Commit

Permalink
refactor #423 [Maintenance] Enable some tests (GSadee)
Browse files Browse the repository at this point in the history
This PR was merged into the 1.0-dev branch.

Discussion
----------



Commits
-------

527de3d [Tests] Enable test for addressing order with a wrong token
2128106 [Tests] Enable tests for showing available payment and shipping methods in wrong state of checkout
  • Loading branch information
lchrusciel authored Apr 10, 2019
2 parents 2c2c473 + 2128106 commit a74ff98
Show file tree
Hide file tree
Showing 13 changed files with 190 additions and 20 deletions.
9 changes: 9 additions & 0 deletions spec/Validator/Cart/CartExistsValidatorSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\Repository\OrderRepositoryInterface;
use Sylius\ShopApiPlugin\Validator\Constraints\CartExists;
use Sylius\ShopApiPlugin\Validator\Constraints\CartItemExists;
use Symfony\Component\Validator\Context\ExecutionContextInterface;

final class CartExistsValidatorSpec extends ObjectBehavior
Expand Down Expand Up @@ -42,4 +43,12 @@ function it_adds_constraint_if_order_does_not_exits_exists(

$this->validate('ORDERTOKEN', new CartExists());
}

function it_throws_an_exception_if_constraint_is_not_cart_exists(): void
{
$this
->shouldThrow(\InvalidArgumentException::class)
->during('validate', ['ORDERTOKEN', new CartItemExists()])
;
}
}
39 changes: 29 additions & 10 deletions src/Controller/Checkout/AddressAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@

use FOS\RestBundle\View\View;
use FOS\RestBundle\View\ViewHandlerInterface;
use Sylius\ShopApiPlugin\Command\Cart\AddressOrder;
use Sylius\ShopApiPlugin\Model\Address;
use Sylius\ShopApiPlugin\Factory\ValidationErrorViewFactoryInterface;
use Sylius\ShopApiPlugin\Request\Checkout\AddressOrderRequest;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface;

final class AddressAction
{
Expand All @@ -20,20 +21,38 @@ final class AddressAction
/** @var MessageBusInterface */
private $bus;

public function __construct(ViewHandlerInterface $viewHandler, MessageBusInterface $bus)
{
/** @var ValidatorInterface */
private $validator;

/** @var ValidationErrorViewFactoryInterface */
private $validationErrorViewFactory;

public function __construct(
ViewHandlerInterface $viewHandler,
MessageBusInterface $bus,
ValidatorInterface $validator,
ValidationErrorViewFactoryInterface $validationErrorViewFactory
) {
$this->viewHandler = $viewHandler;
$this->bus = $bus;
$this->validator = $validator;
$this->validationErrorViewFactory = $validationErrorViewFactory;
}

public function __invoke(Request $request): Response
{
$this->bus->dispatch(new AddressOrder(
$request->attributes->get('token'),
Address::createFromArray($request->request->get('shippingAddress')),
Address::createFromArray($request->request->get('billingAddress') ?: $request->request->get('shippingAddress'))
));
$addressOrderRequest = new AddressOrderRequest($request);

return $this->viewHandler->handle(View::create(null, Response::HTTP_NO_CONTENT));
$validationResults = $this->validator->validate($addressOrderRequest);
if (0 === count($validationResults)) {
$this->bus->dispatch($addressOrderRequest->getCommand());

return $this->viewHandler->handle(View::create(null, Response::HTTP_NO_CONTENT));
}

return $this->viewHandler->handle(View::create(
$this->validationErrorViewFactory->create($validationResults),
Response::HTTP_BAD_REQUEST
));
}
}
20 changes: 18 additions & 2 deletions src/Controller/Checkout/ShowAvailablePaymentMethodsAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@

use FOS\RestBundle\View\View;
use FOS\RestBundle\View\ViewHandlerInterface;
use SM\Factory\FactoryInterface;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\Model\PaymentInterface;
use Sylius\Component\Core\Model\PaymentMethodInterface;
use Sylius\Component\Core\OrderCheckoutTransitions;
use Sylius\Component\Core\Repository\OrderRepositoryInterface;
use Sylius\Component\Payment\Resolver\PaymentMethodsResolverInterface;
use Sylius\ShopApiPlugin\Factory\Checkout\PaymentMethodViewFactoryInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;

final class ShowAvailablePaymentMethodsAction
{
Expand All @@ -29,25 +32,33 @@ final class ShowAvailablePaymentMethodsAction
/** @var PaymentMethodViewFactoryInterface */
private $paymentMethodViewFactory;

/** @var FactoryInterface */
private $stateMachineFactory;

public function __construct(
OrderRepositoryInterface $cartRepository,
ViewHandlerInterface $viewHandler,
PaymentMethodsResolverInterface $paymentMethodResolver,
PaymentMethodViewFactoryInterface $paymentMethodViewFactory
PaymentMethodViewFactoryInterface $paymentMethodViewFactory,
FactoryInterface $stateMachineFactory
) {
$this->cartRepository = $cartRepository;
$this->viewHandler = $viewHandler;
$this->paymentMethodsResolver = $paymentMethodResolver;
$this->paymentMethodViewFactory = $paymentMethodViewFactory;
$this->stateMachineFactory = $stateMachineFactory;
}

public function __invoke(Request $request): Response
{
/** @var OrderInterface $cart */
$cart = $this->cartRepository->findOneBy(['tokenValue' => $request->attributes->get('token')]);

$payments = [];
if (!$this->isCheckoutTransitionPossible($cart, OrderCheckoutTransitions::TRANSITION_SELECT_PAYMENT)) {
throw new BadRequestHttpException('The payment methods cannot be resolved in the current state of cart!');
}

$payments = [];
foreach ($cart->getPayments() as $payment) {
$payments['payments'][] = $this->getPaymentMethods($payment, $cart->getLocaleCode());
}
Expand All @@ -66,4 +77,9 @@ private function getPaymentMethods(PaymentInterface $payment, string $locale): a

return $rawPaymentMethods;
}

private function isCheckoutTransitionPossible(OrderInterface $cart, string $transition): bool
{
return $this->stateMachineFactory->get($cart, OrderCheckoutTransitions::GRAPH)->can($transition);
}
}
20 changes: 18 additions & 2 deletions src/Controller/Checkout/ShowAvailableShippingMethodsAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@

use FOS\RestBundle\View\View;
use FOS\RestBundle\View\ViewHandlerInterface;
use SM\Factory\FactoryInterface;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\Model\ShipmentInterface;
use Sylius\Component\Core\Model\ShippingMethodInterface;
use Sylius\Component\Core\OrderCheckoutTransitions;
use Sylius\Component\Core\Repository\OrderRepositoryInterface;
use Sylius\Component\Shipping\Resolver\ShippingMethodsResolverInterface;
use Sylius\ShopApiPlugin\Factory\Checkout\ShippingMethodViewFactoryInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;

final class ShowAvailableShippingMethodsAction
{
Expand All @@ -29,25 +32,33 @@ final class ShowAvailableShippingMethodsAction
/** @var ShippingMethodViewFactoryInterface */
private $shippingMethodViewFactory;

/** @var FactoryInterface */
private $stateMachineFactory;

public function __construct(
OrderRepositoryInterface $cartRepository,
ViewHandlerInterface $viewHandler,
ShippingMethodsResolverInterface $shippingMethodsResolver,
ShippingMethodViewFactoryInterface $shippingMethodViewFactory
ShippingMethodViewFactoryInterface $shippingMethodViewFactory,
FactoryInterface $stateMachineFactory
) {
$this->cartRepository = $cartRepository;
$this->viewHandler = $viewHandler;
$this->shippingMethodsResolver = $shippingMethodsResolver;
$this->shippingMethodViewFactory = $shippingMethodViewFactory;
$this->stateMachineFactory = $stateMachineFactory;
}

public function __invoke(Request $request): Response
{
/** @var OrderInterface $cart */
$cart = $this->cartRepository->findOneBy(['tokenValue' => $request->attributes->get('token')]);

$shipments = [];
if (!$this->isCheckoutTransitionPossible($cart, OrderCheckoutTransitions::TRANSITION_SELECT_SHIPPING)) {
throw new BadRequestHttpException('The shipment methods cannot be resolved in the current state of cart!');
}

$shipments = [];
foreach ($cart->getShipments() as $shipment) {
$shipments['shipments'][] = $this->getCalculatedShippingMethods($shipment, $cart->getLocaleCode());
}
Expand All @@ -74,4 +85,9 @@ private function getCalculatedShippingMethods(ShipmentInterface $shipment, strin

return $rawShippingMethods;
}

private function isCheckoutTransitionPossible(OrderInterface $cart, string $transition): bool
{
return $this->stateMachineFactory->get($cart, OrderCheckoutTransitions::GRAPH)->can($transition);
}
}
52 changes: 52 additions & 0 deletions src/Request/Checkout/AddressOrderRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

declare(strict_types=1);

namespace Sylius\ShopApiPlugin\Request\Checkout;

use Sylius\ShopApiPlugin\Command\Cart\AddressOrder;
use Sylius\ShopApiPlugin\Model\Address;
use Symfony\Component\HttpFoundation\Request;

class AddressOrderRequest
{
/** @var string|null */
protected $token;

/** @var array|null */
protected $shippingAddress;

/** @var array|null */
protected $billingAddress;

public function __construct(Request $request)
{
$this->token = $request->attributes->get('token');
$this->shippingAddress = $request->request->get('shippingAddress');
$this->billingAddress = $request->request->get('billingAddress') ?: $request->request->get('shippingAddress');
}

public function getCommand(): AddressOrder
{
return new AddressOrder(
$this->token,
Address::createFromArray($this->shippingAddress),
Address::createFromArray($this->billingAddress)
);
}

public function getToken(): ?string
{
return $this->token;
}

public function getShippingAddress(): ?array
{
return $this->shippingAddress;
}

public function getBillingAddress(): ?array
{
return $this->billingAddress;
}
}
4 changes: 4 additions & 0 deletions src/Resources/config/services/actions/checkout.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
>
<argument type="service" id="fos_rest.view_handler" />
<argument type="service" id="sylius_shop_api_plugin.command_bus" />
<argument type="service" id="validator" />
<argument type="service" id="sylius.shop_api_plugin.factory.validation_error_view_factory" />
</service>

<service id="sylius.shop_api_plugin.controller.checkout.show_available_shipping_methods_action"
Expand All @@ -18,6 +20,7 @@
<argument type="service" id="fos_rest.view_handler" />
<argument type="service" id="sylius.shipping_methods_resolver" />
<argument type="service" id="sylius.shop_api_plugin.factory.shipping_method_view_factory" />
<argument type="service" id="sm.factory" />
</service>

<service id="sylius.shop_api_plugin.controller.checkout.choose_shipping_method_action"
Expand All @@ -34,6 +37,7 @@
<argument type="service" id="fos_rest.view_handler" />
<argument type="service" id="sylius.payment_methods_resolver" />
<argument type="service" id="sylius.shop_api_plugin.factory.payment_method_view_factory" />
<argument type="service" id="sm.factory" />
</service>

<service id="sylius.shop_api_plugin.controller.checkout.choose_payment_method_action"
Expand Down
26 changes: 26 additions & 0 deletions src/Resources/config/validation/checkout/AddressOrderRequest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>

<!--
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.
-->

<constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping http://symfony.com/schema/dic/services/constraint-mapping-1.0.xsd"
>
<class name="Sylius\ShopApiPlugin\Request\Checkout\AddressOrderRequest">
<property name="token">
<constraint name="NotNull">
<option name="message">sylius.shop_api.token.not_null</option>
</constraint>
<constraint name="Sylius\ShopApiPlugin\Validator\Constraints\CartExists" />
</property>
</class>
</constraint-mapping>
4 changes: 4 additions & 0 deletions src/Validator/Cart/CartExistsValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@

use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\Repository\OrderRepositoryInterface;
use Sylius\ShopApiPlugin\Validator\Constraints\CartExists;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Webmozart\Assert\Assert;

final class CartExistsValidator extends ConstraintValidator
{
Expand All @@ -22,6 +24,8 @@ public function __construct(OrderRepositoryInterface $orderRepository)
/** {@inheritdoc} */
public function validate($token, Constraint $constraint)
{
Assert::isInstanceOf($constraint, CartExists::class);

if (null === $this->orderRepository->findOneBy(['tokenValue' => $token, 'state' => OrderInterface::STATE_CART])) {
$this->context->addViolation($constraint->message);
}
Expand Down
22 changes: 19 additions & 3 deletions tests/Controller/Checkout/CheckoutAddressApiTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,30 @@
final class CheckoutAddressApiTest extends JsonApiTestCase
{
/**
* TODO check is it possible (test annotation make it fail)
* @test
*/
public function it_does_not_allow_to_address_non_existing_order(): void
{
$this->client->request('PUT', '/shop-api/WEB_GB/checkout/SDAOSLEFNWU35H3QLI5325/address', [], [], self::CONTENT_TYPE_HEADER);
$this->loadFixturesFromFiles(['shop.yml']);

$data =
<<<EOT
{
"shippingAddress": {
"firstName": "Sherlock",
"lastName": "Holmes",
"countryCode": "GB",
"street": "Baker Street 221b",
"city": "London",
"postcode": "NW1",
"provinceName": "Greater London"
}
}
EOT;
$this->client->request('PUT', '/shop-api/WEB_GB/checkout/WRONGTOKEN/address', [], [], self::CONTENT_TYPE_HEADER, $data);

$response = $this->client->getResponse();
$this->assertResponse($response, 'cart/cart_has_not_been_found_response', Response::HTTP_NOT_FOUND);
$this->assertResponse($response, 'cart/validation_cart_not_exists_response', Response::HTTP_BAD_REQUEST);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public function it_does_not_provide_details_about_available_payment_method_for_n
}

/**
* TODO check is it possible (test annotation make it fail)
* @test
*/
public function it_does_not_provide_details_about_available_payment_method_before_addressing(): void
{
Expand All @@ -47,7 +47,7 @@ public function it_does_not_provide_details_about_available_payment_method_befor
}

/**
* TODO check is it possible (test annotation make it fail)
* @test
*/
public function it_does_not_provide_details_about_available_payment_method_before_choosing_shipping_method(): void
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public function it_provides_details_about_available_shipping_method(): void
}

/**
* TODO check is it possible (test annotation make it fail)
* @test
*/
public function it_does_not_provide_details_about_available_shipping_method_before_addressing(): void
{
Expand Down
Loading

0 comments on commit a74ff98

Please sign in to comment.