View source
<?php
namespace Drupal\Tests\commerce_mollie\Functional;
use Drupal\commerce_order\Entity\OrderType;
use Drupal\commerce_payment\Entity\PaymentGateway;
use Drupal\commerce_price\Price;
use Drupal\Core\Entity\Entity\EntityFormDisplay;
use Drupal\Tests\commerce\Functional\CommerceBrowserTestBase;
use Mollie\Api\Types\PaymentStatus as MolliePaymentStatus;
class MolliePaymentOffsiteFormTest extends CommerceBrowserTestBase {
protected $paymentGateway;
protected $orderStorage;
protected $paymentStorage;
public static $modules = [
'commerce_product',
'commerce_order',
'commerce_cart',
'commerce_checkout',
'commerce_payment',
'commerce_mollie',
'commerce_mollie_tests',
];
protected function setUp() {
parent::setUp();
$this->orderStorage = \Drupal::entityTypeManager()
->getStorage('commerce_order');
$this->paymentStorage = \Drupal::entityTypeManager()
->getStorage('commerce_payment');
$variation = $this
->createEntity('commerce_product_variation', [
'type' => 'default',
'sku' => strtolower($this
->randomMachineName()),
'price' => [
'number' => '29.99',
'currency_code' => 'USD',
],
]);
$this->product = $this
->createEntity('commerce_product', [
'type' => 'default',
'title' => 'My product',
'variations' => [
$variation,
],
'stores' => [
$this->store,
],
]);
$order_type = OrderType::load('default');
$order_type
->setWorkflowId('order_default_validation');
$order_type
->save();
$gateway = PaymentGateway::create([
'id' => 'mollie_test_gateway',
'label' => 'Mollie',
'plugin' => 'mollie',
]);
$gateway
->getPlugin()
->setConfiguration([
'mode' => 'test',
'api_key_test' => 'test_Dfm3kc8CNcFb34xHnxwNNEyAJTteez',
'api_key_live' => 'live_key',
'callback_domain' => 'https://molliedevelopment.localtunnel.me',
]);
$gateway
->save();
$customer_form_display = EntityFormDisplay::load('profile.customer.default');
$address_component = $customer_form_display
->getComponent('address');
$address_component['settings']['default_country'] = 'US';
$customer_form_display
->setComponent('address', $address_component);
$customer_form_display
->save();
}
public function testMolliePaymentStatusPaid() {
$this
->drupalGet($this->product
->toUrl()
->toString());
$this
->submitForm([], 'Add to cart');
$this
->helperGotoCheckoutAndProceedPayment();
$this
->helperValidateStatus([
'commerce_order_status' => 'draft',
'commerce_order_isPaid' => FALSE,
'commerce_order_totalPaid' => new Price(0, 'USD'),
'commerce_payment_status' => 'new',
'commerce_payment_remoteStatus' => MolliePaymentStatus::STATUS_PAID,
]);
$this
->helperCallOnNotifyWebhook();
$this
->drupalGet('mollie_return/1');
$this
->assertSession()
->addressEquals('checkout/1/complete');
$this
->assertSession()
->pageTextContains('Your order number is 1. You can view your order on your account page when logged in.');
$this
->assertSession()
->pageTextContains('Thank you for your payment with Mollie. We will inform you when your payment is processed. This is usually done within 24 hours.');
$this
->helperValidateStatus([
'commerce_order_status' => 'validation',
'commerce_order_isPaid' => TRUE,
'commerce_order_totalPaid' => new Price(29.99, 'USD'),
'commerce_payment_status' => 'completed',
'commerce_payment_remoteStatus' => MolliePaymentStatus::STATUS_PAID,
]);
}
public function testMolliePaymentStatusCanceled() {
$this
->drupalGet($this->product
->toUrl()
->toString());
$this
->submitForm([], 'Add to cart');
$this
->drupalGet($this->product
->toUrl()
->toString());
$this
->submitForm([], 'Add to cart');
$this
->helperGotoCheckoutAndProceedPayment();
$this
->helperValidateStatus([
'commerce_order_status' => 'draft',
'commerce_order_isPaid' => FALSE,
'commerce_order_totalPaid' => new Price(0, 'USD'),
'commerce_payment_status' => 'new',
'commerce_payment_remoteStatus' => MolliePaymentStatus::STATUS_CANCELED,
]);
$this
->helperCallOnNotifyWebhook();
$this
->drupalGet('mollie_return/1');
$this
->assertSession()
->addressEquals('checkout/1/review');
$this
->assertSession()
->pageTextContains('You have canceled checkout at Mollie but may resume the checkout process here when you are ready.');
$this
->helperValidateStatus([
'commerce_order_status' => 'draft',
'commerce_order_isPaid' => FALSE,
'commerce_order_totalPaid' => new Price(0, 'USD'),
'commerce_payment_status' => 'authorization_voided',
'commerce_payment_remoteStatus' => MolliePaymentStatus::STATUS_CANCELED,
]);
}
public function testMolliePaymentStatusOpen() {
$this
->drupalGet($this->product
->toUrl()
->toString());
$this
->submitForm([], 'Add to cart');
$this
->drupalGet($this->product
->toUrl()
->toString());
$this
->submitForm([], 'Add to cart');
$this
->drupalGet($this->product
->toUrl()
->toString());
$this
->submitForm([], 'Add to cart');
$this
->helperGotoCheckoutAndProceedPayment();
$this
->helperValidateStatus([
'commerce_order_status' => 'draft',
'commerce_order_isPaid' => FALSE,
'commerce_order_totalPaid' => new Price(0, 'USD'),
'commerce_payment_status' => 'new',
'commerce_payment_remoteStatus' => MolliePaymentStatus::STATUS_OPEN,
]);
$this
->helperCallOnNotifyWebhook();
$this
->drupalGet('mollie_return/1');
$this
->assertSession()
->addressEquals('mollie_return/1');
$this
->assertSession()
->pageTextContains('We have not yet received the payment status from Mollie. Please reload this page.');
$this
->helperValidateStatus([
'commerce_order_status' => 'draft',
'commerce_order_isPaid' => FALSE,
'commerce_order_totalPaid' => new Price(0, 'USD'),
'commerce_payment_status' => 'authorization',
'commerce_payment_remoteStatus' => MolliePaymentStatus::STATUS_OPEN,
]);
}
public function testMolliePaymentStatusFailed() {
$this
->drupalGet($this->product
->toUrl()
->toString());
$this
->submitForm([], 'Add to cart');
$this
->drupalGet($this->product
->toUrl()
->toString());
$this
->submitForm([], 'Add to cart');
$this
->drupalGet($this->product
->toUrl()
->toString());
$this
->submitForm([], 'Add to cart');
$this
->drupalGet($this->product
->toUrl()
->toString());
$this
->submitForm([], 'Add to cart');
$this
->helperGotoCheckoutAndProceedPayment();
$this
->helperValidateStatus([
'commerce_order_status' => 'draft',
'commerce_order_isPaid' => FALSE,
'commerce_order_totalPaid' => new Price(0, 'USD'),
'commerce_payment_status' => 'new',
'commerce_payment_remoteStatus' => MolliePaymentStatus::STATUS_FAILED,
]);
$this
->helperCallOnNotifyWebhook();
$this
->drupalGet('mollie_return/1');
$this
->assertSession()
->addressEquals('checkout/1/review');
$this
->assertSession()
->pageTextContains('Your payment at Mollie has failed. You may resume the checkout process here when you are ready.');
$this
->assertSession()
->pageTextContains('You have canceled checkout at Mollie but may resume the checkout process here when you are ready.');
$this
->helperValidateStatus([
'commerce_order_status' => 'draft',
'commerce_order_isPaid' => FALSE,
'commerce_order_totalPaid' => new Price(0, 'USD'),
'commerce_payment_status' => 'authorization_voided',
'commerce_payment_remoteStatus' => MolliePaymentStatus::STATUS_FAILED,
]);
}
public function testMolliePaymentStatusExpired() {
$this
->drupalGet($this->product
->toUrl()
->toString());
$this
->submitForm([], 'Add to cart');
$this
->drupalGet($this->product
->toUrl()
->toString());
$this
->submitForm([], 'Add to cart');
$this
->drupalGet($this->product
->toUrl()
->toString());
$this
->submitForm([], 'Add to cart');
$this
->drupalGet($this->product
->toUrl()
->toString());
$this
->submitForm([], 'Add to cart');
$this
->drupalGet($this->product
->toUrl()
->toString());
$this
->submitForm([], 'Add to cart');
$this
->helperGotoCheckoutAndProceedPayment();
$this
->helperValidateStatus([
'commerce_order_status' => 'draft',
'commerce_order_isPaid' => FALSE,
'commerce_order_totalPaid' => new Price(0, 'USD'),
'commerce_payment_status' => 'new',
'commerce_payment_remoteStatus' => MolliePaymentStatus::STATUS_EXPIRED,
]);
$this
->helperCallOnNotifyWebhook();
$this
->drupalGet('mollie_return/1');
$this
->assertSession()
->addressEquals('checkout/1/review');
$this
->assertSession()
->pageTextContains('Your payment at Mollie has expired. You may resume the checkout process here when you are ready.');
$this
->assertSession()
->pageTextContains('You have canceled checkout at Mollie but may resume the checkout process here when you are ready.');
$this
->helperValidateStatus([
'commerce_order_status' => 'draft',
'commerce_order_isPaid' => FALSE,
'commerce_order_totalPaid' => new Price(0, 'USD'),
'commerce_payment_status' => 'authorization_expired',
'commerce_payment_remoteStatus' => MolliePaymentStatus::STATUS_EXPIRED,
]);
}
protected function helperGotoCheckoutAndProceedPayment() {
$cart_link = $this
->getSession()
->getPage()
->findLink('your cart');
$cart_link
->click();
$this
->submitForm([], 'Checkout');
$this
->assertSession()
->pageTextContains('Order Summary');
$this
->submitForm([
'payment_information[billing_information][address][0][address][given_name]' => 'Johnny',
'payment_information[billing_information][address][0][address][family_name]' => 'Appleseed',
'payment_information[billing_information][address][0][address][address_line1]' => '123 New York Drive',
'payment_information[billing_information][address][0][address][locality]' => 'New York City',
'payment_information[billing_information][address][0][address][administrative_area]' => 'NY',
'payment_information[billing_information][address][0][address][postal_code]' => '10001',
], 'Continue to review');
$this
->assertSession()
->pageTextContains('Contact information');
$this
->assertSession()
->pageTextContains($this->loggedInUser
->getEmail());
$this
->assertSession()
->pageTextContains('Payment information');
$this
->assertSession()
->pageTextContains('Order Summary');
$this
->submitForm([], 'Pay and complete purchase');
}
protected function helperCallOnNotifyWebhook() {
$notify_url = $this
->getAbsoluteUrl('/payment/notify/mollie_test_gateway');
$post_data = [
'id' => 'test_id',
];
$session = $this
->getSession();
$session
->setCookie('SIMPLETEST_USER_AGENT', drupal_generate_test_ua($this->databasePrefix));
$session
->getDriver()
->getClient()
->request('POST', $notify_url, $post_data);
}
protected function helperValidateStatus($validations = []) {
$this->orderStorage
->resetCache([
1,
]);
$order = $this->orderStorage
->load(1);
$this->paymentStorage
->resetCache([
1,
]);
$payment = $this->paymentStorage
->load(1);
if (array_key_exists('commerce_order_status', $validations)) {
$this
->assertEquals($validations['commerce_order_status'], $order
->getState()->value);
}
if (array_key_exists('commerce_order_isPaid', $validations)) {
$this
->assertEquals($validations['commerce_order_isPaid'], $order
->isPaid());
}
if (array_key_exists('commerce_order_totalPaid', $validations)) {
$this
->assertEquals($validations['commerce_order_totalPaid'], $order
->getTotalPaid());
}
if (array_key_exists('commerce_payment_status', $validations)) {
$this
->assertEquals($validations['commerce_payment_status'], $payment
->getState()->value);
}
if (array_key_exists('commerce_payment_remoteStatus', $validations)) {
$this
->assertEquals($validations['commerce_payment_remoteStatus'], $payment
->getRemoteState());
}
}
}