Skip to content

Commit

Permalink
[API][Payments] change endpoints and add missing specs
Browse files Browse the repository at this point in the history
  • Loading branch information
AdamKasp committed Oct 13, 2020
1 parent 62a2cb6 commit 962873c
Show file tree
Hide file tree
Showing 10 changed files with 133 additions and 95 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ Feature: Changing the method after order confirmation
Then I should see the thank you page

@api
Scenario: Changing the payment method after placed order
Scenario: Changing the payment method for placed order
Given I added product "PHP T-Shirt" to the cart
When I complete addressing step with email "john@example.com" and "United States" based billing address
And I select "Free" shipping method
And I select "Cash on delivery" payment method
And I confirm my order
And I change payment method to "Offline"
Then I should have chosen "offline" payment method for my order
Then I should have chosen "Offline" payment method for my order
6 changes: 1 addition & 5 deletions src/Sylius/Behat/Context/Api/Shop/CheckoutContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -830,11 +830,7 @@ public function iChangePaymentMethodTo(PaymentMethodInterface $paymentMethod): v
{
$this->client->request(
Request::METHOD_PATCH,
\sprintf(
'/new-api/shop/orders/%s/change-payments/%s',
$this->sharedStorage->get('cart_token'),
(string) $this->iriConverter->getItemFromIri($this->getCart()['payments'][0])->getId()
),
\sprintf('/new-api/shop/payments/%s/change-payments', $this->sharedStorage->get('cart_token')),
[],
[],
$this->getHeaders(),
Expand Down
29 changes: 3 additions & 26 deletions src/Sylius/Bundle/ApiBundle/Command/ChangePaymentMethod.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,8 @@
namespace Sylius\Bundle\ApiBundle\Command;

/** @experimental */
class ChangePaymentMethod implements OrderTokenValueAwareInterface, SubresourceIdAwareInterface
class ChangePaymentMethod
{
/** @var string|null */
public $orderTokenValue;

/**
* @psalm-immutable
*
Expand All @@ -38,28 +35,8 @@ public function __construct(string $paymentMethodCode)
$this->paymentMethodCode = $paymentMethodCode;
}

public function getOrderTokenValue(): ?string
{
return $this->orderTokenValue;
}

public function setOrderTokenValue(?string $orderTokenValue): void
{
$this->orderTokenValue = $orderTokenValue;
}

public function getSubresourceId(): ?string
{
return $this->paymentId;
}

public function setSubresourceId(?string $subresourceId): void
{
$this->paymentId = $subresourceId;
}

public function getSubresourceIdAttributeKey(): string
public function setPaymentId(string $paymentId): void
{
return 'paymentId';
$this->paymentId = $paymentId;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@

use SM\Factory\FactoryInterface;
use Sylius\Bundle\ApiBundle\Command\ChangePaymentMethod;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\Model\PaymentMethodInterface;
use Sylius\Component\Core\OrderCheckoutTransitions;
use Sylius\Component\Core\Repository\OrderRepositoryInterface;
use Sylius\Component\Core\Repository\PaymentMethodRepositoryInterface;
use Sylius\Component\Core\Repository\PaymentRepositoryInterface;
Expand All @@ -27,49 +25,39 @@
/** @experimental */
final class ChangePaymentMethodHandler
{
/** @var OrderRepositoryInterface */
private $orderRepository;

/** @var PaymentMethodRepositoryInterface */
private $paymentMethodRepository;

/** @var PaymentRepositoryInterface */
private $paymentRepository;

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

public function __construct(
OrderRepositoryInterface $orderRepository,
PaymentMethodRepositoryInterface $paymentMethodRepository,
PaymentRepositoryInterface $paymentRepository,
FactoryInterface $stateMachineFactory
PaymentRepositoryInterface $paymentRepository
) {
$this->orderRepository = $orderRepository;
$this->paymentMethodRepository = $paymentMethodRepository;
$this->paymentRepository = $paymentRepository;
$this->stateMachineFactory = $stateMachineFactory;
}

public function __invoke(ChangePaymentMethod $changePaymentMethod): OrderInterface
public function __invoke(ChangePaymentMethod $changePaymentMethod): PaymentInterface
{
/** @var OrderInterface|null $order */
$order = $this->orderRepository->findOneBy(['tokenValue' => $changePaymentMethod->orderTokenValue]);

Assert::notNull($order, 'Order has not been found.');

/** @var PaymentMethodInterface|null $paymentMethod */
$paymentMethod = $this->paymentMethodRepository->findOneBy([
'code' => $changePaymentMethod->paymentMethodCode,
]);
Assert::notNull($paymentMethod, 'Payment method has not been found');

$payment = $this->paymentRepository->findOneByOrderId($changePaymentMethod->paymentId, $order->getId());
/** @var PaymentInterface $payment */
$payment = $this->paymentRepository->find($changePaymentMethod->paymentId);
Assert::notNull($payment, 'Can not find payment with given identifier.');
if ($payment->getState() === PaymentInterface::STATE_NEW) {

Assert::same(
$payment->getState(),
PaymentInterface::STATE_NEW,
'Can not change payment method for this payment'
);
$payment->setMethod($paymentMethod);
}

return $order;
return $payment;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ private function applyUserRulesToItem(
->leftJoin('customer.user', 'user')
->andWhere('user IS NULL')
->orWhere(sprintf('%s.customer IS NULL', $rootAlias))
// ->andWhere(sprintf('%s.state = :state', $rootAlias))
// ->setParameter('state', OrderInterface::STATE_CART)
->andWhere(sprintf('%s.state = :state', $rootAlias))
->setParameter('state', OrderInterface::STATE_CART)
;

return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,40 +187,6 @@
</attribute>
</itemOperation>

<itemOperation name="shop_change_payment_method">
<attribute name="method">PATCH</attribute>
<attribute name="path">/shop/orders/{id}/change-payments/{paymentId}</attribute>
<attribute name="messenger">input</attribute>
<attribute name="input">Sylius\Bundle\ApiBundle\Command\ChangePaymentMethod</attribute>
<attribute name="denormalization_context">
<attribute name="groups">order:change_payment_method</attribute>
</attribute>
<attribute name="normalization_context">
<attribute name="groups">order:read</attribute>
</attribute>
<attribute name="openapi_context">
<attribute name="summary">Selects payment methods for particular payment</attribute>
<attribute name="parameters">
<attribute>
<attribute name="name">id</attribute>
<attribute name="in">path</attribute>
<attribute name="required">true</attribute>
<attribute name="schema">
<attribute name="type">string</attribute>
</attribute>
</attribute>
<attribute>
<attribute name="name">paymentId</attribute>
<attribute name="in">path</attribute>
<attribute name="required">true</attribute>
<attribute name="schema">
<attribute name="type">string</attribute>
</attribute>
</attribute>
</attribute>
</attribute>
</itemOperation>

<itemOperation name="shop_complete">
<attribute name="method">PATCH</attribute>
<attribute name="path">/shop/orders/{id}/complete</attribute>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,19 @@
<attribute name="summary">Completes Payment</attribute>
</attribute>
</itemOperation>

<itemOperation name="shop_change_payment_method">
<attribute name="method">PATCH</attribute>
<attribute name="path">/shop/payments/{id}/change-payments</attribute>
<attribute name="messenger">input</attribute>
<attribute name="input">Sylius\Bundle\ApiBundle\Command\ChangePaymentMethod</attribute>
<attribute name="denormalization_context">
<attribute name="groups">payment:change_payment_method</attribute>
</attribute>
<attribute name="normalization_context">
<attribute name="groups">payment:read</attribute>
</attribute>
</itemOperation>
</itemOperations>

<subresourceOperations>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
>
<class name="Sylius\Bundle\ApiBundle\Command\ChangePaymentMethod">
<attribute name="paymentMethodCode">
<group>order:change_payment_method</group>
<group>payment:change_payment_method</group>
</attribute>
</class>
</serializer>
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,8 @@
</service>

<service id="Sylius\Bundle\ApiBundle\CommandHandler\ChangePaymentMethodHandler">
<argument type="service" id="sylius.repository.order"/>
<argument type="service" id="sylius.repository.payment_method"/>
<argument type="service" id="sylius.repository.payment"/>
<argument type="service" id="sm.factory" />
<tag name="messenger.message_handler" />
</service>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<?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.
*/

declare(strict_types=1);

namespace spec\Sylius\Bundle\ApiBundle\CommandHandler;

use PhpSpec\ObjectBehavior;
use Sylius\Bundle\ApiBundle\Command\ChangePaymentMethod;
use Sylius\Component\Core\Model\PaymentInterface;
use Sylius\Component\Core\Model\PaymentMethodInterface;
use Sylius\Component\Core\Repository\PaymentMethodRepositoryInterface;
use Sylius\Component\Core\Repository\PaymentRepositoryInterface;

final class ChangePaymentMethodHandlerSpec extends ObjectBehavior
{
function let(
PaymentMethodRepositoryInterface $paymentMethodRepository,
PaymentRepositoryInterface $paymentRepository
): void {
$this->beConstructedWith($paymentMethodRepository, $paymentRepository);
}

function it_changes_payment_method_to_specified_payment(
PaymentMethodRepositoryInterface $paymentMethodRepository,
PaymentMethodInterface $paymentMethod,
PaymentRepositoryInterface $paymentRepository,
PaymentInterface $payment
): void {
$changePaymentMethod = new ChangePaymentMethod('CASH_ON_DELIVERY_METHOD');
$changePaymentMethod->setPaymentId('123');
$paymentMethodRepository->findOneBy(['code' =>'CASH_ON_DELIVERY_METHOD'])->willReturn($paymentMethod);

$paymentRepository->find('123')->willReturn($payment);

$payment->getState()->willReturn(PaymentInterface::STATE_NEW);
$payment->setMethod($paymentMethod)->shouldBeCalled();

$this($changePaymentMethod)->shouldReturn($payment);
}

function it_throws_an_exception_if_payment_method_with_given_code_has_not_been_found(
PaymentMethodRepositoryInterface $paymentMethodRepository
): void {
$changePaymentMethod = new ChangePaymentMethod('CASH_ON_DELIVERY_METHOD');
$changePaymentMethod->setPaymentId('123');
$paymentMethodRepository->findOneBy(['code' =>'CASH_ON_DELIVERY_METHOD'])->willReturn(null);

$this
->shouldThrow(\InvalidArgumentException::class)
->during('__invoke', [$changePaymentMethod])
;
}

function it_throws_an_exception_if_payment_has_not_be_found(
PaymentMethodRepositoryInterface $paymentMethodRepository,
PaymentMethodInterface $paymentMethod,
PaymentRepositoryInterface $paymentRepository
): void {
$changePaymentMethod = new ChangePaymentMethod('CASH_ON_DELIVERY_METHOD');
$changePaymentMethod->setPaymentId('123');
$paymentMethodRepository->findOneBy(['code' =>'CASH_ON_DELIVERY_METHOD'])->willReturn($paymentMethod);

$paymentRepository->find('123')->willReturn(null);

$this
->shouldThrow(\InvalidArgumentException::class)
->during('__invoke', [$changePaymentMethod])
;
}

function it_throws_an_exception_if_payment_is_in_different_state_than_new(
PaymentMethodRepositoryInterface $paymentMethodRepository,
PaymentMethodInterface $paymentMethod,
PaymentRepositoryInterface $paymentRepository,
PaymentInterface $payment
): void
{
$changePaymentMethod = new ChangePaymentMethod('CASH_ON_DELIVERY_METHOD');
$changePaymentMethod->setPaymentId('123');
$paymentMethodRepository->findOneBy(['code' => 'CASH_ON_DELIVERY_METHOD'])->willReturn($paymentMethod);

$paymentRepository->find('123')->willReturn($payment);

$payment->getState()->willReturn(PaymentInterface::STATE_CANCELLED);

$this
->shouldThrow(\InvalidArgumentException::class)
->during('__invoke', [$changePaymentMethod])
;
}
}

0 comments on commit 962873c

Please sign in to comment.