commerce-8.x-2.8/modules/payment/tests/src/Kernel/PaymentOptionsBuilderTest.php
modules/payment/tests/src/Kernel/PaymentOptionsBuilderTest.php
<?php namespace Drupal\Tests\commerce_payment\Kernel; use Drupal\commerce_order\Entity\Order; use Drupal\commerce_order\Entity\OrderItem; use Drupal\commerce_order\Entity\OrderItemType; use Drupal\commerce_payment\Entity\PaymentGateway; use Drupal\commerce_payment\Entity\PaymentMethod; use Drupal\commerce_price\Price; use Drupal\profile\Entity\Profile; use Drupal\Tests\commerce\Kernel\CommerceKernelTestBase; /** * Tests the payment options builder. * * @coversDefaultClass \Drupal\commerce_payment\PaymentOptionsBuilder * * @group commerce */ class PaymentOptionsBuilderTest extends CommerceKernelTestBase { /** * The payment options builder. * * @var \Drupal\commerce_payment\PaymentOptionsBuilderInterface */ protected $paymentOptionsBuilder; /** * The sample order. * * @var \Drupal\commerce_order\Entity\OrderInterface */ protected $order; /** * Modules to enable. * * @var array */ public static $modules = [ 'address', 'entity_reference_revisions', 'profile', 'state_machine', 'commerce_product', 'commerce_order', 'commerce_payment', 'commerce_payment_example', 'commerce_payment_test', ]; /** * {@inheritdoc} */ protected function setUp() { parent::setUp(); $this->installEntitySchema('profile'); $this->installEntitySchema('commerce_order'); $this->installEntitySchema('commerce_order_item'); $this->installEntitySchema('commerce_payment'); $this->installEntitySchema('commerce_payment_method'); $this->installConfig('commerce_order'); $this->installConfig('commerce_payment'); $this->paymentOptionsBuilder = $this->container->get('commerce_payment.options_builder'); $user = $this->createUser(); $another_user = $this->createUser(); // An order item type that doesn't need a purchasable entity, for simplicity. OrderItemType::create([ 'id' => 'test', 'label' => 'Test', 'orderType' => 'default', ])->save(); $payment_gateway = PaymentGateway::create([ 'id' => 'onsite', 'label' => 'On-site', 'plugin' => 'example_onsite', ]); $payment_gateway->save(); $payment_gateway = PaymentGateway::create([ 'id' => 'offsite', 'label' => 'Off-site', 'plugin' => 'example_offsite_redirect', 'configuration' => [ 'redirect_method' => 'post', 'payment_method_types' => ['credit_card'], ], ]); $payment_gateway->save(); $payment_gateway = PaymentGateway::create([ 'id' => 'cash_on_delivery', 'label' => 'Manual', 'plugin' => 'manual', 'configuration' => [ 'display_label' => 'Cash on delivery', 'instructions' => [ 'value' => 'Sample payment instructions.', 'format' => 'plain_text', ], ], 'weight' => 10, ]); $payment_gateway->save(); // A manual gateway with a condition that won't be satisfied, to ensure // that it's not offered to the user. $payment_gateway = PaymentGateway::create([ 'id' => 'card_on_delivery', 'label' => 'Manual', 'plugin' => 'manual', 'configuration' => [ 'display_label' => 'Card on delivery', 'instructions' => [ 'value' => 'Sample payment instructions.', 'format' => 'plain_text', ], ], 'conditions' => [ [ 'plugin' => 'order_total_price', 'configuration' => [ 'operator' => '>', 'amount' => [ 'number' => '99.00', 'currency_code' => 'USD', ], ], ], ], 'weight' => 10, ]); $payment_gateway->save(); $profile = Profile::create([ 'type' => 'customer', 'address' => [ 'country_code' => 'US', 'postal_code' => '53177', 'locality' => 'Milwaukee', 'address_line1' => 'Pabst Blue Ribbon Dr', 'administrative_area' => 'WI', 'given_name' => 'Frederick', 'family_name' => 'Pabst', ], 'uid' => $user->id(), ]); $profile->save(); $payment_method = PaymentMethod::create([ 'uid' => $user->id(), 'type' => 'credit_card', 'payment_gateway' => 'onsite', 'card_type' => 'visa', 'card_number' => '1111', 'billing_profile' => $profile, 'reusable' => TRUE, 'expires' => strtotime('2028/03/24'), ]); $payment_method->setBillingProfile($profile); $payment_method->save(); // Create a payment method for $another_user as well, to confirm that it's // not offered to the first user. $payment_method = PaymentMethod::create([ 'uid' => $another_user->id(), 'type' => 'credit_card', 'payment_gateway' => 'onsite', 'card_type' => 'visa', 'card_number' => '1112', 'billing_profile' => $profile, 'reusable' => TRUE, 'expires' => strtotime('2028/03/24'), ]); $payment_method->setBillingProfile($profile); $payment_method->save(); $order_payment_method = PaymentMethod::create([ 'type' => 'credit_card', 'payment_gateway' => 'onsite', 'card_type' => 'visa', 'card_number' => '9999', 'reusable' => FALSE, ]); $order_payment_method->save(); $order_item = OrderItem::create([ 'type' => 'test', 'quantity' => 1, 'unit_price' => new Price('10', 'USD'), ]); $order_item->save(); $this->order = Order::create([ 'uid' => $user->id(), 'type' => 'default', 'state' => 'draft', 'order_items' => [$order_item], 'payment_gateway' => 'onsite', 'payment_method' => $order_payment_method, 'store_id' => $this->store, ]); $this->order->save(); } /** * Tests building options for all available gateways. * * @covers ::buildOptions */ public function testBuildOptions() { $options = $this->paymentOptionsBuilder->buildOptions($this->order); /** @var \Drupal\commerce_payment\PaymentOption[] $options */ $options = array_values($options); $this->assertCount(5, $options); // Stored payment methods. $this->assertEquals('1', $options[0]->getId()); $this->assertEquals('Visa ending in 1111', $options[0]->getLabel()); $this->assertEquals('onsite', $options[0]->getPaymentGatewayId()); $this->assertEquals('1', $options[0]->getPaymentMethodId()); $this->assertNull($options[0]->getPaymentMethodTypeId()); // Order payment method. $this->assertEquals('3', $options[1]->getId()); $this->assertEquals('Visa ending in 9999', $options[1]->getLabel()); $this->assertEquals('onsite', $options[1]->getPaymentGatewayId()); $this->assertEquals('3', $options[1]->getPaymentMethodId()); $this->assertNull($options[1]->getPaymentMethodTypeId()); // Add new payment method. $this->assertEquals('new--credit_card--onsite', $options[2]->getId()); $this->assertEquals('Credit card', $options[2]->getLabel()); $this->assertEquals('onsite', $options[2]->getPaymentGatewayId()); $this->assertNull($options[2]->getPaymentMethodId()); $this->assertEquals('credit_card', $options[2]->getPaymentMethodTypeId()); // Offsite gateways. $this->assertEquals('offsite', $options[3]->getId()); $this->assertEquals('Example', $options[3]->getLabel()); $this->assertEquals('offsite', $options[3]->getPaymentGatewayId()); $this->assertNull($options[3]->getPaymentMethodId()); $this->assertNull($options[3]->getPaymentMethodTypeId()); // Manual gateways. $this->assertEquals('cash_on_delivery', $options[4]->getId()); $this->assertEquals('Cash on delivery', $options[4]->getLabel()); $this->assertEquals('cash_on_delivery', $options[4]->getPaymentGatewayId()); $this->assertNull($options[4]->getPaymentMethodId()); $this->assertNull($options[4]->getPaymentMethodTypeId()); } /** * Tests building options for two different on-site gateways. * * Confirms that the payment gateway list can be restricted, and that * multiple on-site gateways get unique "add" option labels. * * @covers ::buildOptions */ public function testBuildOptionsWithTwoOnsiteGateways() { $first_payment_gateway = PaymentGateway::create([ 'id' => 'first_onsite', 'label' => 'First (On-site)', 'plugin' => 'example_onsite', ]); $second_payment_gateway = PaymentGateway::create([ 'id' => 'second_onsite', 'label' => 'Second (On-site)', 'plugin' => 'test_onsite', ]); $second_payment_gateway->save(); $payment_gateways = [$first_payment_gateway, $second_payment_gateway]; $options = $this->paymentOptionsBuilder->buildOptions($this->order, $payment_gateways); /** @var \Drupal\commerce_payment\PaymentOption[] $options */ $options = array_values($options); $this->assertCount(2, $options); $this->assertEquals('new--credit_card--first_onsite', $options[0]->getId()); $this->assertEquals('Credit card (Example)', $options[0]->getLabel()); $this->assertEquals('first_onsite', $options[0]->getPaymentGatewayId()); $this->assertNull($options[0]->getPaymentMethodId()); $this->assertEquals('credit_card', $options[0]->getPaymentMethodTypeId()); $this->assertEquals('new--credit_card--second_onsite', $options[1]->getId()); $this->assertEquals('Credit card (Test)', $options[1]->getLabel()); $this->assertEquals('second_onsite', $options[1]->getPaymentGatewayId()); $this->assertNull($options[1]->getPaymentMethodId()); $this->assertEquals('credit_card', $options[1]->getPaymentMethodTypeId()); } /** * Tests selecting the default option. * * @covers ::selectDefaultOption */ public function testSelectDefaultOption() { $options = $this->paymentOptionsBuilder->buildOptions($this->order); // The order payment method is selected first. $default_option = $this->paymentOptionsBuilder->selectDefaultOption($this->order, $options); $this->assertEquals($options[3], $default_option); // The order payment gateway is selected second. $this->order->set('payment_method', NULL); $this->order->set('payment_gateway', 'cash_on_delivery'); $default_option = $this->paymentOptionsBuilder->selectDefaultOption($this->order, $options); $this->assertEquals($options['cash_on_delivery'], $default_option); // Finally, the method falls back to the first option. $this->order->set('payment_gateway', NULL); $default_option = $this->paymentOptionsBuilder->selectDefaultOption($this->order, $options); $this->assertEquals(reset($options), $default_option); // Non-available order payment method is ignored. $this->order->set('payment_method', '2'); $this->order->set('payment_gateway', 'onsite'); $default_option = $this->paymentOptionsBuilder->selectDefaultOption($this->order, $options); $this->assertEquals(reset($options), $default_option); // Non-available order payment gateway is ignored. $this->order->set('payment_method', NULL); $this->order->set('payment_gateway', 'card_on_delivery'); $default_option = $this->paymentOptionsBuilder->selectDefaultOption($this->order, $options); $this->assertEquals(reset($options), $default_option); } }