commerce_funds-8.x-1.7/tests/src/Functional/PaymentWorkflowTest.php
tests/src/Functional/PaymentWorkflowTest.php
<?php
namespace Drupal\Tests\commerce_funds\Functional;
use Drupal\Tests\commerce_funds\Traits\FundsTrait;
use Drupal\Tests\commerce_product\Functional\ProductBrowserTestBase;
/**
* Tests the payment workflow.
*
* @group commerce_funds
*/
class PaymentWorkflowTest extends ProductBrowserTestBase {
use FundsTrait;
/**
* Set default theme.
*
* @var string
*/
protected $defaultTheme = 'stark';
/**
* Modules to enable.
*
* @var array
*/
protected static $modules = [
'commerce_funds',
'commerce_exchanger',
];
/**
* The product manager.
*
* @var \Drupal\commerce_funds\ProductManagerInterface
*/
protected $productManager;
/**
* The config factory.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
protected $configFactory;
/**
* {@inheritdoc}
*/
protected function setUp() : void {
parent::setUp();
$this->adminUser = $this->drupalCreateUser($this->getAdministratorPermissions() + [
'administer commerce_order',
'administer commerce_payment',
'access commerce_order overview',
], NULL, TRUE);
$this->firstUser = $this->drupalCreateUser([
'deposit funds',
'view commerce_product',
'access checkout',
]);
$this->drupalLogin($this->firstUser);
$this->paymentGateway = $this->createEntity('commerce_payment_gateway', [
'id' => 'manual',
'label' => 'Manual',
'plugin' => 'manual',
'configuration' => [
'collect_billing_information' => FALSE,
],
'status' => 1,
]);
$this->createEntity('commerce_payment_gateway', [
'id' => 'funds',
'label' => 'Funds',
'plugin' => 'funds_balance',
'configuration' => [
'mode' => 'live',
'collect_billing_information' => FALSE,
'payment_method_types' => [
'funds_wallet',
],
],
]);
$this->createEntity('commerce_currency', [
'name' => 'Euro',
'currencyCode' => 'EUR',
'symbol' => '€',
'numericCode' => '978',
'fractionDigits' => 2,
]);
$currencies = ['USD', 'EUR'];
foreach ($currencies as $currency) {
/** @var \Drupal\commerce_product\Entity\ProductVariationInterface $variation */
$variation = $this->createEntity('commerce_product_variation', [
'uid' => 1,
'type' => 'default',
'sku' => strtolower($this->randomMachineName()),
'title' => 'Product variation ' . $currency,
'price' => [
'number' => 12.5,
'currency_code' => $currency,
],
]);
/** @var \Drupal\commerce_product\Entity\ProductInterface $product */
$this->createEntity('commerce_product', [
'uid' => 1,
'stores' => $this->stores,
'type' => 'default',
'title' => 'Product ' . $currency,
'variations' => [$variation],
]);
}
$this->transactionManager = $this->container->get('commerce_funds.transaction_manager');
$this->productManager = $this->container->get('commerce_funds.product_manager');
$this->webAssert = $this->assertSession();
}
/**
* Receive a manual payment.
*
* @param float $amount
* The amount of the order to be paid.
* @param string $currency_code
* The currency code of the order to be paid.
*/
protected function validateManualOrder($amount, $currency_code) {
$this->drupalLogin($this->adminUser);
$this->drupalGet('admin/commerce/orders/1/payments/1/operation/receive');
$this->submitForm([
'payment[amount][number]' => $amount,
], 'Receive');
}
/**
* Tests product payment using funds wallet.
*/
public function testPaymentWorkflow() {
// Payment USD.
// Go to the product page and add it to cart.
$this->drupalGet('product/1');
$this->webAssert->statusCodeEquals(200);
$this->submitForm([], 'Add to cart');
// Go to cart.
$this->drupalGet('cart');
$this->webAssert->statusCodeEquals(200);
$this->webAssert->pageTextContains('Product USD');
$this->webAssert->pageTextContains('$12.5');
$this->submitForm([], 'Checkout');
// Redirected to order information.
$this->webAssert->addressEquals('checkout/1/order_information');
$this->webAssert->pageTextContains("You do not have funds in this currency in your balance.");
// Creating USD wallet.
$this->depositFunds(12.5);
$this->drupalGet('checkout/1/order_information');
$this->webAssert->pageTextContains('Funds balance (create a new wallet)');
$this->submitForm([
'payment_information[payment_method]' => 'new--funds_wallet--funds',
], 'Continue to review');
// Redirected to order review.
$this->webAssert->addressEquals('checkout/1/review');
$this->webAssert->pageTextContains('Funds balance (USD)');
// Try to recreate a wallet with existing one.
$this->drupalGet('checkout/1/order_information');
$this->submitForm([
'payment_information[payment_method]' => 'new--funds_wallet--funds',
], 'Continue to review');
$this->webAssert->pageTextContains('You already have a virtual wallet for this currency.');
// Submit form with funds and USD wallet.
$this->submitForm([
'payment_information[payment_method]' => '1',
], 'Continue to review');
$this->submitForm([], 'Pay and complete purchase');
$this->webAssert->pageTextContains('Your order number is');
// Assert balance has been updated.
$this->assertEquals(0, $this->transactionManager->loadAccountBalance($this->firstUser)['USD']);
// Payment EUR.
// Go to the product page and add it to cart.
$this->drupalGet('product/2');
$this->webAssert->statusCodeEquals(200);
$this->submitForm([], 'Add to cart');
// Go to cart.
$this->drupalGet('cart');
$this->webAssert->statusCodeEquals(200);
$this->webAssert->pageTextContains('Product EUR');
$this->webAssert->pageTextContains('€12.5');
$this->submitForm([], 'Checkout');
// Redirected to order information.
$this->webAssert->addressEquals('checkout/2/order_information');
// Selecting USD wallet.
$this->submitForm([
'payment_information[payment_method]' => '1',
], 'Continue to review');
$this->webAssert->pageTextContains('Wallet with a different currency chosen, please select a EUR wallet.');
// Creating EUR wallet.
$this->submitForm([
'payment_information[payment_method]' => 'new--funds_wallet--funds',
], 'Continue to review');
$this->submitForm([], 'Pay and complete purchase');
$this->webAssert->pageTextContains("Not enough EUR to pay this order, please make a deposit first.");
// Selecting EUR wallet with enough funds.
$this->depositFunds(12.5, 'EUR');
$this->drupalGet('checkout/2/order_information');
$this->webAssert->pageTextContains('Funds balance (EUR)');
$this->submitForm([
'payment_information[payment_method]' => '2',
], 'Continue to review');
$this->submitForm([], 'Pay and complete purchase');
$this->webAssert->pageTextContains('Your order number is');
// Assert balance has been updated.
$this->assertEquals(0, $this->transactionManager->loadAccountBalance($this->firstUser)['EUR']);
}
/**
* Tests product payment when no funds and making a deposit.
*/
public function testPaymentDepositRedirection() {
// Go to the product page and add it to cart.
$this->drupalGet('product/1');
$this->webAssert->statusCodeEquals(200);
$this->submitForm([], 'Add to cart');
// Go to cart.
$this->drupalGet('cart');
$this->webAssert->statusCodeEquals(200);
$this->webAssert->pageTextContains('Product USD');
$this->webAssert->pageTextContains('$12.5');
$this->submitForm([], 'Checkout');
// Try submitting form without wallet.
$this->submitForm([
'payment_information[payment_method]' => 'new--funds_wallet--funds',
], 'Continue to review');
// Redirected to order review.
$this->webAssert->addressEquals('checkout/1/review');
// Try paying order with no funds.
$this->submitForm([], 'Pay and complete purchase');
// Follow make a deposit link.
$this->webAssert->pageTextContains('Not enough USD to pay this order, please make a deposit first.');
$this->clickLink('make a deposit');
// Assert form is autopopulated.
$this->webAssert->addressEquals('user/funds/deposit?amount=12.5¤cy=USD&order=1');
$this->webAssert->elementAttributeContains('css', '#edit-amount', 'value', '12.5');
$this->webAssert->elementContains('css', '#edit-currency', '<option value="USD" selected="selected">USD</option>');
// Deposit the 12.5 dollars.
$this->submitForm([], 'Next');
$this->submitForm([
'payment_information[payment_method]' => 'manual',
], 'Continue to review');
$this->submitForm([], 'Pay and complete purchase');
// Click on the go back to order button.
$this->clickLink('Go back to order');
$this->webAssert->addressEquals('checkout/1/review');
// Receive manual payment.
$this->validateManualOrder(12.5, 'USD');
// Assert balance has been updated.
$this->assertEquals(12.5, $this->transactionManager->loadAccountBalance($this->firstUser)['USD']);
// Go back to where we were.
$this->drupalLogin($this->firstUser);
$this->drupalGet('checkout/1/review');
// The funds should be available.
$this->submitForm([], 'Pay and complete purchase');
$this->webAssert->pageTextContains('Complete');
// Assert balance has been updated.
$this->assertEquals(0, $this->transactionManager->loadAccountBalance($this->firstUser)['USD']);
}
}
