New context to handle Payment request notify urls

This commit is contained in:
Francis Hilaire 2024-10-09 16:20:25 +02:00
parent 0a2ce39795
commit eedc381c12
No known key found for this signature in database
GPG key ID: 3392F830BF33D421
13 changed files with 377 additions and 0 deletions

View file

@ -0,0 +1,26 @@
@payment_request_notify
Feature: Calling notify for a payment method
In order to process a payment request action related to a payment method
As an external payment provider
I want to be able to send HTTP request data to trigger a new payment request action
Background:
Given the store operates on a single channel in "United States"
And the store has a "PHP T-Shirt" product
And the store ships everywhere for Free
And the store has a payment method "Offline" with a code "offline"
And there is a customer "john@example.com" that placed order with "PHP T-Shirt" product to "United States" based billing address with "Free" shipping method and "Offline" payment method
@ui
Scenario: I want to send HTTP request to the payment method notify and succeeded
When I call the payment method notify page with the code "offline"
Then a payment request with "notify" action and state "completed" should exists
And the response status code should be 204
And the response content should be empty
@ui
Scenario: I want to send HTTP request to the payment method notify and failed
When I call the payment method notify page with the code "not_existing"
Then no payment request with "notify" action should exists
And the response status code should be 404

View file

@ -0,0 +1,29 @@
@payment_request_notify
Feature: Calling notify for a payment method
In order to process a payment request action related to a payment method
As an external payment provider
I want to be able to send HTTP request data to trigger a new payment request action
Background:
Given the store operates on a single channel in "United States"
And the store has a "PHP T-Shirt" product
And the store ships everywhere for Free
And the store has a payment method "Offline" with a code "offline"
And there is a customer "john@example.com" that placed order with "PHP T-Shirt" product to "United States" based billing address with "Free" shipping method and "Offline" payment method
@ui
Scenario: I want to send HTTP request to the payment request notify and succeeded
Given there is a "new" "notify" payment request for order "#000001" using the "Offline" payment method
When I call the payment request notify page for this payment request
Then a payment request with "notify" action and state "completed" should exists
And the response status code should be 204
And the response content should be empty
@ui
Scenario: I want to send HTTP request to the payment method notify and failed
Given there is a "completed" "notify" payment request for order "#000001" using the "Offline" payment method
When I call the payment request notify page for this payment request
Then a payment request with "notify" action and state "completed" should exists
And the response status code should be 404

View file

@ -0,0 +1,119 @@
<?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\Ui\Shop;
use Behat\Behat\Context\Context;
use Doctrine\Persistence\ObjectManager;
use Sylius\Behat\Page\Shop\PaymentRequest\PaymentMethodNotifyPageInterface;
use Sylius\Behat\Page\Shop\PaymentRequest\PaymentRequestNotifyPage;
use Sylius\Component\Payment\Model\PaymentRequestInterface;
use Sylius\Component\Payment\Repository\PaymentRequestRepositoryInterface;
use Webmozart\Assert\Assert;
final readonly class PaymentRequestContext implements Context
{
public function __construct(
private PaymentRequestRepositoryInterface $paymentRequestRepository,
private PaymentMethodNotifyPageInterface $paymentMethodNotifyPage,
private PaymentRequestNotifyPage $paymentRequestNotifyPage,
private ObjectManager $objectManager,
) {
}
/**
* @When I call the payment method notify page with the code :paymentMethod
*/
public function iCallThePaymentMethodNotifyPageWithTheCode(string $paymentMethodCode): void
{
$this->paymentMethodNotifyPage->openWithClient(
'GET',
[ 'code' => $paymentMethodCode ],
);
}
/**
* @When /^I call the payment request notify page for this payment request$/
*/
public function iCallThePaymentRequestNotifyPageForThisPaymentRequest(): void
{
/** @var PaymentRequestInterface[] $paymentRequests */
$paymentRequests = $this->paymentRequestRepository->findBy(
['action' => PaymentRequestInterface::ACTION_NOTIFY],
['createdAt' => 'ASC'],
1
);
$paymentRequest = $paymentRequests[0];
$this->paymentRequestNotifyPage->openWithClient(
'GET',
[ 'hash' => $paymentRequest->getHash() ],
);
}
/**
* @Then /^a payment request with "([^"]*)" action and state "([^"]*)" should exists$/
*/
public function aPaymentRequestWithActionAndStateCompletedShouldExists(string $action, string $state): void
{
$this->objectManager->clear(); // avoiding doctrine cache
/** @var PaymentRequestInterface[] $paymentRequests */
$paymentRequests = $this->paymentRequestRepository->findBy(
['action' => $action],
['createdAt' => 'ASC'],
1
);
Assert::count($paymentRequests, 1);
$paymentRequest = $paymentRequests[0];
Assert::notNull($paymentRequest);
Assert::eq($paymentRequest->getState(), $state);
}
/**
* @Then /^no payment request with "([^"]*)" action should exists$/
*/
public function noPaymentRequestWithActionShouldExists(string $action, ?string $state = null): void
{
/** @var PaymentRequestInterface[] $paymentRequests */
$paymentRequests = $this->paymentRequestRepository->findBy(
['action' => $action],
['createdAt' => 'ASC'],
1
);
Assert::isEmpty($paymentRequests);
}
/**
* @Given /^the response content should be empty$/
*/
public function theResponseContentShouldBeEmpty(): void
{
$response = $this->paymentMethodNotifyPage->getClient()->getInternalResponse();
Assert::isEmpty($response->getContent());
}
/**
* @Given /^the response status code should be (\d+)$/
*/
public function theResponseStatusCodeShouldBe(int $statusCode): void
{
$response = $this->paymentMethodNotifyPage->getClient()->getInternalResponse();
Assert::eq($response->getStatusCode(), $statusCode);
}
}

View file

@ -0,0 +1,22 @@
<?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\Page\Shop\PaymentRequest;
class PaymentMethodNotifyPage extends PaymentRequestNotifyPage implements PaymentMethodNotifyPageInterface
{
public function getRouteName(): string
{
return 'sylius_payment_method_notify';
}
}

View file

@ -0,0 +1,18 @@
<?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\Page\Shop\PaymentRequest;
interface PaymentMethodNotifyPageInterface extends PaymentRequestNotifyPageInterface
{
}

View file

@ -0,0 +1,53 @@
<?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\Page\Shop\PaymentRequest;
use Behat\Mink\Driver\BrowserKitDriver;
use FriendsOfBehat\PageObjectExtension\Page\SymfonyPage;
use Symfony\Component\BrowserKit\AbstractBrowser;
class PaymentRequestNotifyPage extends SymfonyPage implements PaymentRequestNotifyPageInterface
{
public function getRouteName(): string
{
return 'sylius_payment_request_notify';
}
public function openWithClient(
string $method,
array $urlParameters = [],
array $files = [],
array $server = [],
?string $content = null,
): void {
$client = $this->getClient();
$client->request(
method: $method,
uri: $this->getUrl($urlParameters),
files: $files,
server: $server,
content: $content,
);
}
public function getClient(): AbstractBrowser
{
$driver = $this->getDriver();
if ($driver instanceof BrowserKitDriver) {
return $driver->getClient();
}
throw new \LogicException(sprintf('This page require a "%s" driver.', BrowserKitDriver::class));
}
}

View file

@ -0,0 +1,39 @@
<?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\Page\Shop\PaymentRequest;
use FriendsOfBehat\PageObjectExtension\Page\PageInterface as BasePageInterface;
use Symfony\Component\BrowserKit\AbstractBrowser;
interface PaymentRequestNotifyPageInterface extends BasePageInterface
{
/**
* Calls a URI.
*
* @param string $method The request method
* @param array $urlParameters The url parameters
* @param array $files The files
* @param array $server The server parameters (HTTP headers are referenced with an HTTP_ prefix as PHP does)
* @param string|null $content The raw body data
*/
public function openWithClient(
string $method,
array $urlParameters = [],
array $files = [],
array $server = [],
?string $content = null,
): void;
public function getClient(): AbstractBrowser;
}

View file

@ -167,6 +167,8 @@
<argument type="service" id="Sylius\Behat\Client\ResponseCheckerInterface" />
<argument type="service" id="sylius.behat.request_factory" />
<argument type="service" id="sylius.repository.payment_request" />
<argument type="service" id="sylius.behat.page.shop.payment_request.payment_method_notify" />
<argument type="service" id="test.client" />
</service>
<service id="sylius.behat.context.api.shop.payment" class="Sylius\Behat\Context\Api\Shop\PaymentContext">

View file

@ -578,6 +578,13 @@
<argument type="service" id="sylius.repository.customer" />
</service>
<service id="sylius.behat.context.ui.shop.payment_request" class="Sylius\Behat\Context\Ui\Shop\PaymentRequestContext">
<argument type="service" id="sylius.repository.payment_request" />
<argument type="service" id="sylius.behat.page.shop.payment_request.payment_method_notify" />
<argument type="service" id="sylius.behat.page.shop.payment_request.payment_request_notify" />
<argument type="service" id="doctrine.orm.entity_manager" />
</service>
<service id="sylius.behat.context.ui.email" class="Sylius\Behat\Context\Ui\EmailContext">
<argument type="service" id="sylius.behat.shared_storage" />
<argument type="service" id="sylius.behat.email_checker" />

View file

@ -17,6 +17,7 @@
<import resource="shop/checkout.xml" />
<import resource="shop/contact.xml" />
<import resource="shop/order.xml" />
<import resource="shop/payment_request.xml" />
<import resource="shop/product.xml" />
</imports>

View file

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<parameters>
<parameter key="sylius.behat.page.shop.payment_request.payment_method_notify.class">Sylius\Behat\Page\Shop\PaymentRequest\PaymentMethodNotifyPage</parameter>
<parameter key="sylius.behat.page.shop.payment_request.payment_request_notify.class">Sylius\Behat\Page\Shop\PaymentRequest\PaymentRequestNotifyPage</parameter>
</parameters>
<services>
<service id="sylius.behat.page.shop.payment_request.payment_method_notify"
class="%sylius.behat.page.shop.payment_request.payment_method_notify.class%"
parent="sylius.behat.symfony_page"
/>
<service id="sylius.behat.page.shop.payment_request.payment_request_notify"
class="%sylius.behat.page.shop.payment_request.payment_request_notify.class%"
parent="sylius.behat.symfony_page"
/>
</services>
</container>

View file

@ -42,6 +42,7 @@ imports:
- ui/payment/managing_payment_methods.yml
- ui/payment/managing_payments.yml
- ui/product/navigating_between_product_show_and_edit_pages.yaml
- ui/payment_request/payment_request_notify.yml
- ui/product/accessing_price_history.yml
- ui/product/adding_product_review.yml
- ui/product/managing_product_association_types.yml

View file

@ -0,0 +1,28 @@
# This file is part of the Sylius package.
# (c) Sylius Sp. z o.o.
default:
suites:
ui_payment_request_notify:
contexts:
- sylius.behat.context.hook.doctrine_orm
- sylius.behat.context.transform.address
- sylius.behat.context.transform.payment
- sylius.behat.context.transform.customer
- sylius.behat.context.transform.order
- sylius.behat.context.transform.product
- sylius.behat.context.transform.shared_storage
- sylius.behat.context.transform.shipping_method
- sylius.behat.context.setup.channel
- 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.ui.shop.payment_request
filters:
tags: "@payment_request_notify&&@ui"