Add behat test

This commit is contained in:
Kamil Grygierzec 2024-10-02 14:25:59 +02:00
parent 0a584dcfd6
commit 2bb67d9ad8
No known key found for this signature in database
GPG key ID: 7F54EE42DAD4B9E9
7 changed files with 119 additions and 3 deletions

View file

@ -0,0 +1,28 @@
@paying_for_order
Feature: Cancelling payment request when payment method is changed
In order to pay with the correct payment method
As a Customer
I want my payment request with wrong payment method to be cancelled
Background:
Given the store operates on a single channel in "United States"
And the store has a product "PHP T-Shirt"
And the store ships everywhere for Free
And the store allows paying with "Cash on Delivery"
And the store also allows paying with "Bank Transfer"
And I am a logged in customer
And I placed an order "#00000001"
And I bought a single "PHP T-Shirt"
And I addressed it to "Lucifer Morningstar", "Seaside Fwy", "90802" "Los Angeles" in the "United States" with identical billing address
And I chose "Free" shipping method with "Cash on Delivery" payment
And there is a payment request action "authorize" executed for order "#00000001" with the payment method "Cash on Delivery" and state "new"
And there is also a payment request action "status" executed for order "#00000001" with the payment method "Cash on Delivery" and state "processing"
And there is also a payment request action "capture" executed for order "#00000001" with the payment method "Cash on Delivery" and state "completed"
@no-ui @api
Scenario: Cancelling only processing or new payment requests when payment method is changed
When I view the summary of my order "#00000001"
And I change payment method to "Bank Transfer" after checkout
Then my payment request with action "authorize" for payment method "Cash on Delivery" should have state "cancelled"
And my payment request with action "status" for payment method "Cash on Delivery" should have state "cancelled"
And my payment request with action "capture" for payment method "Cash on Delivery" should have state "completed"

View file

@ -110,6 +110,8 @@ final readonly class OrderContext implements Context
public function iViewTheSummaryOfMyOrder(OrderInterface $order): void
{
$this->shopClient->show(Resources::ORDERS, $order->getTokenValue());
$this->sharedStorage->set('cart_token', $order->getTokenValue());
}
/**

View file

@ -1,19 +1,29 @@
<?php
/*
* This file is part of the Sylius package.
*
* (c) Sylius Sp. z o.o.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Sylius\Behat\Context\Api\Shop;
use Behat\Behat\Context\Context;
use Sylius\Behat\Client\ApiClientInterface;
use Sylius\Behat\Client\Request;
use Sylius\Behat\Client\RequestFactoryInterface;
use Sylius\Behat\Client\ResponseCheckerInterface;
use Sylius\Behat\Context\Api\Resources;
use Sylius\Behat\Service\SharedStorageInterface;
use Sylius\Bundle\PayumBundle\Model\GatewayConfigInterface;
use Sylius\Component\Core\Model\PaymentMethodInterface;
use Sylius\Component\Core\Repository\PaymentMethodRepositoryInterface;
use Sylius\Component\Payment\Repository\PaymentRequestRepositoryInterface;
use Symfony\Component\HttpFoundation\Request as HTTPRequest;
use Webmozart\Assert\Assert;
final readonly class PaymentRequestContext implements Context
{
@ -22,6 +32,7 @@ final readonly class PaymentRequestContext implements Context
private ApiClientInterface $client,
private ResponseCheckerInterface $responseChecker,
private RequestFactoryInterface $requestFactory,
private PaymentRequestRepositoryInterface $paymentRequestRepository,
) {
}
@ -81,4 +92,33 @@ final readonly class PaymentRequestContext implements Context
$this->client->executeCustomRequest($request);
}
/**
* @Then my payment request with action :action for payment method :paymentMethod should have state :state
*/
public function myPaymentRequestShouldBeCancelled(string $action, PaymentMethodInterface $paymentMethod, string $state): void
{
if ($this->getRequestForPaymentRequestWithAction($action) === null) {
throw new \InvalidArgumentException(sprintf('Payment request with action "%s" not found', $action));
}
$request = $this->getRequestForPaymentRequestWithAction($action);
$this->client->executeCustomRequest($request);
$response = $this->client->getLastResponse();
Assert::same($this->responseChecker->getValue($response, 'action'), $action, sprintf('Payment request should have action %s', $action));
Assert::true(str_contains($this->responseChecker->getValue($response, 'method'), $paymentMethod->getCode()), sprintf('Payment request should be for %s payment method', $paymentMethod->getCode()));
Assert::same($this->responseChecker->getValue($response, 'state'), $state, sprintf('Payment request should have state %s', $state));
}
private function getRequestForPaymentRequestWithAction(string $action): ?Request
{
$orderToken = $this->sharedStorage->get('cart_token');
$order = $this->client->show(Resources::ORDERS, $orderToken);
$payments = $this->responseChecker->getValue($order, 'payments');
$paymentId = end($payments)['id'];
$paymentRequest = $this->paymentRequestRepository->findOneBy(['payment' => $paymentId, 'action' => $action]);
return $paymentRequest ? $this->requestFactory->custom('/api/v2/shop/payment-requests/' . $paymentRequest->getHash(), HttpRequest::METHOD_GET, [], $this->client->getToken()) : null;
}
}

View file

@ -14,15 +14,23 @@ declare(strict_types=1);
namespace Sylius\Behat\Context\Setup;
use Behat\Behat\Context\Context;
use Sylius\Abstraction\StateMachine\StateMachineInterface;
use Sylius\Bundle\ApiBundle\Command\Payment\AddPaymentRequest;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\Model\PaymentMethodInterface;
use Sylius\Component\Payment\Factory\PaymentRequestFactoryInterface;
use Sylius\Component\Payment\Model\PaymentRequestInterface;
use Sylius\Component\Payment\PaymentRequestTransitions;
use Sylius\Component\Payment\Repository\PaymentRequestRepositoryInterface;
use Symfony\Component\Messenger\MessageBusInterface;
final readonly class PaymentRequestContext implements Context
{
public function __construct(
private MessageBusInterface $commandBus,
private PaymentRequestRepositoryInterface $paymentRequestRepository,
private PaymentRequestFactoryInterface $paymentRequestFactory,
private StateMachineInterface $stateMachine,
) {
}
@ -32,7 +40,7 @@ final readonly class PaymentRequestContext implements Context
public function thePaymentRequestActionHasBeenExecutedForOrderWithThePaymentMethod(
string $action,
OrderInterface $order,
PaymentMethodInterface $paymentMethod
PaymentMethodInterface $paymentMethod,
): void {
$addPaymentRequest = new AddPaymentRequest(
paymentId: $order->getLastPayment()->getId(),
@ -42,4 +50,37 @@ final readonly class PaymentRequestContext implements Context
$this->commandBus->dispatch($addPaymentRequest);
}
/**
* @Given there is (also) a payment request action :action executed for order :order with the payment method :paymentMethod and state :state
*/
public function thePaymentRequestActionHasBeenExecutedForOrderWithThePaymentMethodAndState(
string $action,
OrderInterface $order,
PaymentMethodInterface $paymentMethod,
string $state,
): void {
$paymentRequest = $this->paymentRequestFactory->create($order->getLastPayment(), $paymentMethod);
if ($state !== PaymentRequestInterface::STATE_NEW) {
$this->stateMachine->apply(
$paymentRequest,
PaymentRequestTransitions::GRAPH,
$this->getTransitionForState($state),
);
}
$paymentRequest->setAction($action);
$this->paymentRequestRepository->add($paymentRequest);
}
private function getTransitionForState(string $state): string
{
return match ($state) {
'completed' => PaymentRequestTransitions::TRANSITION_COMPLETE,
'processing' => PaymentRequestTransitions::TRANSITION_PROCESS,
default => throw new \InvalidArgumentException(sprintf('Invalid state "%s" provided.', $state)),
};
}
}

View file

@ -166,6 +166,7 @@
<argument type="service" id="sylius.behat.api_platform_client.shop" />
<argument type="service" id="Sylius\Behat\Client\ResponseCheckerInterface" />
<argument type="service" id="sylius.behat.request_factory" />
<argument type="service" id="sylius.repository.payment_request" />
</service>
<service id="sylius.behat.context.api.shop.payment" class="Sylius\Behat\Context\Api\Shop\PaymentContext">

View file

@ -322,6 +322,9 @@
<service id="sylius.behat.context.setup.payment_request" class="Sylius\Behat\Context\Setup\PaymentRequestContext">
<argument type="service" id="sylius.command_bus" />
<argument type="service" id="sylius.repository.payment_request" />
<argument type="service" id="sylius.factory.payment_request" />
<argument type="service" id="sylius_abstraction.state_machine" />
</service>
</services>
</container>

View file

@ -34,6 +34,7 @@ default:
- sylius.behat.context.setup.locale
- sylius.behat.context.setup.order
- sylius.behat.context.setup.payment
- sylius.behat.context.setup.payment_request
- sylius.behat.context.setup.product
- sylius.behat.context.setup.shipping
- sylius.behat.context.setup.shop_api_security