Skip to content

Commit

Permalink
Adding tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mamazu committed Jun 5, 2020
1 parent a36aa36 commit b94f121
Show file tree
Hide file tree
Showing 15 changed files with 386 additions and 32 deletions.
94 changes: 94 additions & 0 deletions spec/Validator/Cart/PaymentMethodAvailableValidatorSpec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?php

declare(strict_types=1);

namespace spec\Sylius\ShopApiPlugin\Validator\Cart;

use Doctrine\Common\Collections\ArrayCollection;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\Model\PaymentInterface;
use Sylius\Component\Core\Model\PaymentMethodInterface;
use Sylius\Component\Core\Repository\OrderRepositoryInterface;
use Sylius\Component\Payment\Resolver\PaymentMethodsResolverInterface;
use Sylius\ShopApiPlugin\Request\Checkout\ChoosePaymentMethodRequest;
use Sylius\ShopApiPlugin\Validator\Constraints\PaymentMethodAvailable;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Symfony\Component\Validator\Violation\ConstraintViolationBuilderInterface;

final class PaymentMethodAvailableValidatorSpec extends ObjectBehavior
{
function let(
ChoosePaymentMethodRequest $request,
OrderRepositoryInterface $orderRepository,
PaymentMethodsResolverInterface $paymentMethodsResolver,
ExecutionContextInterface $context
): void {
$this->beConstructedWith($orderRepository, $paymentMethodsResolver);
$this->initialize($context);

$request->getOrderToken()->willReturn('NON_EXISTING');
$request->getPaymentId()->willReturn(0);
$request->getMethod()->willReturn('COD');
}

function it_does_not_validate_carts_if_the_order_does_not_exist(
OrderRepositoryInterface $orderRepository,
PaymentMethodsResolverInterface $paymentMethodsResolver,
ExecutionContextInterface $context,
ChoosePaymentMethodRequest $request
): void {
$orderRepository->findOneBy(['tokenValue' => 'NON_EXISTING', 'state' => 'cart'])->willReturn(null);
$paymentMethodsResolver->getSupportedMethods(Argument::any())->shouldNotBeCalled();
$context->buildViolation(Argument::any())->shouldNotBeCalled();

$this->validate($request, new PaymentMethodAvailable());
}

function it_adds_a_violation_if_payment_method_is_not_available(
OrderRepositoryInterface $orderRepository,
OrderInterface $cart,
PaymentInterface $payment,
ConstraintViolationBuilderInterface $violationBuilder,
PaymentMethodsResolverInterface $paymentMethodsResolver,
PaymentMethodInterface $paymentMethod,
ExecutionContextInterface $context,
ChoosePaymentMethodRequest $request
): void {
$orderRepository->findOneBy(['tokenValue' => 'NON_EXISTING', 'state' => 'cart'])->willReturn($cart);
$cart->getPayments()->willReturn(new ArrayCollection([$payment->getWrappedObject()]));

$paymentMethodsResolver->getSupportedMethods($payment)->shouldBeCalled()->willReturn([$paymentMethod]);
$paymentMethod->getCode()->willReturn('paypal');

$context->buildViolation('sylius.shop_api.checkout.payment_method_not_available')->willReturn(
$violationBuilder
)
;
$violationBuilder->atPath('method')->willReturn($violationBuilder);
$violationBuilder->addViolation()->shouldBeCalled();

$this->validate($request, new PaymentMethodAvailable());
}

function it_adds_no_violation_if_payment_method_is_available(
OrderRepositoryInterface $orderRepository,
OrderInterface $cart,
PaymentInterface $payment,
PaymentMethodsResolverInterface $paymentMethodsResolver,
PaymentMethodInterface $paymentMethod,
ExecutionContextInterface $context,
ChoosePaymentMethodRequest $request
): void {
$orderRepository->findOneBy(['tokenValue' => 'NON_EXISTING', 'state' => 'cart'])->willReturn($cart);
$cart->getPayments()->willReturn(new ArrayCollection([$payment->getWrappedObject()]));

$paymentMethodsResolver->getSupportedMethods($payment)->shouldBeCalled()->willReturn([$paymentMethod]);
$paymentMethod->getCode()->willReturn('COD');

$context->buildViolation(Argument::any())->shouldNotBeCalled();

$this->validate($request, new PaymentMethodAvailable());
}
}
56 changes: 56 additions & 0 deletions spec/Validator/Cart/PaymentMethodExistsValidatorSpec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

declare(strict_types=1);

namespace spec\Sylius\ShopApiPlugin\Validator\Cart;

use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\Repository\PaymentMethodRepositoryInterface;
use Sylius\ShopApiPlugin\Validator\Constraints\CartExists;
use Sylius\ShopApiPlugin\Validator\Constraints\PaymentMethodExists;
use Symfony\Component\Validator\Context\ExecutionContextInterface;

final class PaymentMethodExistsValidatorSpec extends ObjectBehavior
{
function let(
ExecutionContextInterface $executionContext,
PaymentMethodRepositoryInterface $paymentMethodRepository
): void {
$this->beConstructedWith($paymentMethodRepository);

$this->initialize($executionContext);
}

function it_does_not_add_constraint_if_payment_method_exists(
OrderInterface $order,
PaymentMethodRepositoryInterface $paymentMethodRepository,
ExecutionContextInterface $executionContext
): void {
$paymentMethodRepository->findOneBy(['code' => 'paypal'])->willReturn($order);

$executionContext->addViolation(Argument::any(), Argument::any())->shouldNotBeCalled();

$this->validate('paypal', new PaymentMethodExists());
}

function it_adds_constraint_if_payment_method_does_not_exists(
PaymentMethodRepositoryInterface $paymentMethodRepository,
ExecutionContextInterface $executionContext
): void {
$paymentMethodRepository->findOneBy(['code' => 'paypal'])->willReturn(null);

$executionContext->addViolation('sylius.shop_api.checkout.payment_method_does_not_exist')->shouldBeCalled();

$this->validate('paypal', new PaymentMethodExists());
}

function it_throws_an_exception_if_constraint_is_not_payment_exists(): void
{
$this
->shouldThrow(\InvalidArgumentException::class)
->during('validate', ['paypal', new CartExists()])
;
}
}
16 changes: 15 additions & 1 deletion src/Controller/Checkout/ChoosePaymentMethodAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use FOS\RestBundle\View\View;
use FOS\RestBundle\View\ViewHandlerInterface;
use Sylius\ShopApiPlugin\CommandProvider\CommandProviderInterface;
use Sylius\ShopApiPlugin\Factory\ValidationErrorViewFactoryInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Messenger\MessageBusInterface;
Expand All @@ -22,18 +23,31 @@ final class ChoosePaymentMethodAction
/** @var CommandProviderInterface */
private $choosePaymentMethodCommandProvider;

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

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

public function __invoke(Request $request): Response
{
$validationResults = $this->choosePaymentMethodCommandProvider->validate($request);
if (0 !== count($validationResults)) {
return $this->viewHandler->handle(View::create(
$this->validationErrorViewFactory->create($validationResults),
Response::HTTP_BAD_REQUEST
));
}

$this->bus->dispatch($this->choosePaymentMethodCommandProvider->getCommand($request));

return $this->viewHandler->handle(View::create(null, Response::HTTP_NO_CONTENT));
Expand Down
1 change: 1 addition & 0 deletions src/Resources/config/services/actions/checkout.xml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
<argument type="service" id="fos_rest.view_handler" />
<argument type="service" id="sylius_shop_api_plugin.command_bus" />
<argument type="service" id="sylius.shop_api_plugin.command_provider.choose_payment_method" />
<argument type="service" id="sylius.shop_api_plugin.factory.validation_error_view_factory" />
</service>

<service
Expand Down
9 changes: 8 additions & 1 deletion src/Resources/config/services/validators/cart.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,20 @@
</service>

<service id="sylius.shop_api_plugin.validator.cart.correct_payment_method_validator"
class="Sylius\ShopApiPlugin\Validator\Cart\CorrectPaymentMethodValidator">
class="Sylius\ShopApiPlugin\Validator\Cart\PaymentMethodAvailableValidator">
<argument type="service" id="sylius.repository.order" />
<argument type="service" id="sylius.payment_methods_resolver" />

<tag name="validator.constraint_validator" alias="sylius_shop_api_cart_correct_payment_method_selected" />
</service>

<service id="sylius.shop_api_plugin.validator.cart.payment_method_exists_validator"
class="Sylius\ShopApiPlugin\Validator\Cart\PaymentMethodExistsValidator">
<argument type="service" id="sylius.repository.payment_method" />

<tag name="validator.constraint_validator" alias="sylius_shop_api_cart_payment_method_exists" />
</service>

<service id="sylius.shop_api_plugin.validator.valid_promotion_coupon_code_validator"
class="Sylius\ShopApiPlugin\Validator\Cart\ValidPromotionCouponCodeValidator">
<argument type="service" id="sylius.repository.order" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,17 @@
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\ChoosePaymentMethodRequest">
<constraint name="Sylius\ShopApiPlugin\Validator\Constraints\CorrectPaymentMethod" />
<constraint name="Sylius\ShopApiPlugin\Validator\Constraints\PaymentMethodAvailable"/>

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

<property name="method">
<constraint name="Sylius\ShopApiPlugin\Validator\Constraints\PaymentMethodExists"/>
</property>
</class>
</constraint-mapping>
2 changes: 2 additions & 0 deletions src/Resources/translations/validators.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ sylius:
address_required: Please provide the cart with a shipping and billing address
shipping_required: Please select a shipping method
payment_required: Please select a payment method
payment_method_does_not_exist: The selected payment method does not exist.
payment_method_not_available: The selected payment method is not available for this cart.
cart_item:
not_exists: Cart item does not exist.
email:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@

use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\Model\PaymentMethodInterface;
use Sylius\Component\Core\OrderCheckoutStates;
use Sylius\Component\Core\Repository\OrderRepositoryInterface;
use Sylius\Component\Payment\Resolver\PaymentMethodsResolverInterface;
use Sylius\ShopApiPlugin\Request\Checkout\ChoosePaymentMethodRequest;
use Sylius\ShopApiPlugin\Validator\Constraints\CorrectPaymentMethod;
use Sylius\ShopApiPlugin\Validator\Constraints\PaymentMethodAvailable;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

final class CorrectPaymentMethodValidator extends ConstraintValidator
final class PaymentMethodAvailableValidator extends ConstraintValidator
{
/** @var OrderRepositoryInterface */
private $orderRepository;
Expand All @@ -34,7 +35,9 @@ public function validate($value, Constraint $constraint): void
/** @var ChoosePaymentMethodRequest $value */

/** @var OrderInterface|null $order */
$order = $this->orderRepository->findOneByTokenValue($value->getOrderToken());
$order = $this->orderRepository->findOneBy(
['tokenValue' => $value->getOrderToken(), 'state' => OrderCheckoutStates::STATE_CART]
);
if ($order === null) {
return;
}
Expand All @@ -48,9 +51,12 @@ static function (PaymentMethodInterface $paymentMethod) {
$this->paymentMethodsResolver->getSupportedMethods($payment)
);

if (!in_array($value->getMethod(), $paymentMethodCodes)) {
/** @var CorrectPaymentMethod $constraint */
$this->context->addViolation($constraint->message);
if (!in_array($value->getMethod(), $paymentMethodCodes, true)) {
/** @var PaymentMethodAvailable $constraint */
$this->context
->buildViolation($constraint->message)
->atPath('method')
->addViolation();
}
}
}
33 changes: 33 additions & 0 deletions src/Validator/Cart/PaymentMethodExistsValidator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace Sylius\ShopApiPlugin\Validator\Cart;

use Sylius\Component\Core\Repository\PaymentMethodRepositoryInterface;
use Sylius\ShopApiPlugin\Validator\Constraints\PaymentMethodExists;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Webmozart\Assert\Assert;

final class PaymentMethodExistsValidator extends ConstraintValidator
{
/** @var PaymentMethodRepositoryInterface */
private $paymentMethodRepository;

public function __construct(PaymentMethodRepositoryInterface $paymentMethodRepository)
{
$this->paymentMethodRepository = $paymentMethodRepository;
}

/** {@inheritdoc} */
public function validate($value, Constraint $constraint): void
{
Assert::isInstanceOf($constraint, PaymentMethodExists::class);

if ($this->paymentMethodRepository->findOneBy(['code' => $value]) === null) {
/** @var PaymentMethodExists $constraint */
$this->context->addViolation($constraint->message);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@

use Symfony\Component\Validator\Constraint;

final class CorrectPaymentMethod extends Constraint
final class PaymentMethodAvailable extends Constraint
{
/** @var string */
public $message = 'sylius.shop_api.cart.payment_method.valid';
public $message = 'sylius.shop_api.checkout.payment_method_not_available';

/** {@inheritdoc} */
public function getTargets(): string
Expand Down
19 changes: 19 additions & 0 deletions src/Validator/Constraints/PaymentMethodExists.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types=1);

namespace Sylius\ShopApiPlugin\Validator\Constraints;

use Sylius\ShopApiPlugin\Validator\Cart\PaymentMethodExistsValidator;
use Symfony\Component\Validator\Constraint;

final class PaymentMethodExists extends Constraint
{
/** @var string */
public $message = 'sylius.shop_api.checkout.payment_method_does_not_exist';

public function validatedBy(): string
{
return PaymentMethodExistsValidator::class;
}
}
Loading

0 comments on commit b94f121

Please sign in to comment.