commerce_api-8.x-1.x-dev/tests/src/Kernel/Field/PaymentInstrumentFieldTest.php
tests/src/Kernel/Field/PaymentInstrumentFieldTest.php
<?php
declare(strict_types=1);
namespace Drupal\Tests\commerce_api\Kernel\Field;
use Drupal\commerce_order\Entity\Order;
use Drupal\commerce_order\Entity\OrderInterface;
use Drupal\commerce_payment\Entity\PaymentGateway;
use Drupal\commerce_payment\Entity\PaymentMethod;
use Drupal\commerce_payment\Entity\PaymentMethodInterface;
use Drupal\profile\Entity\Profile;
use Drupal\profile\Entity\ProfileInterface;
use Drupal\Tests\commerce_api\Kernel\KernelTestBase;
use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;
/**
* Test the payment instrument field.
*
* @group commerce_api
*/
final class PaymentInstrumentFieldTest extends KernelTestBase {
protected const TEST_PAYMENT_METHOD_UUID = '99edaa72-85b0-4160-bdb5-56d846f3ba22';
protected const TEST_OFFSITE_PAYMENT_METHOD_UUID = '672d1161-fb32-4f5e-972f-0caaa1e7a93e';
/**
* {@inheritdoc}
*/
protected static $modules = [
'commerce_payment_example',
];
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
$this->installEntitySchema('commerce_payment_method');
PaymentGateway::create([
'id' => 'cod',
'label' => 'Manual',
'plugin' => 'manual',
])->save();
PaymentGateway::create([
'id' => 'onsite',
'plugin' => 'example_onsite',
])->save();
PaymentGateway::create([
'id' => 'example_offsite',
'plugin' => 'example_offsite_redirect',
])->save();
PaymentGateway::create([
'id' => 'stored_offsite',
'plugin' => 'example_stored_offsite_redirect',
])->save();
PaymentMethod::create([
'uuid' => self::TEST_PAYMENT_METHOD_UUID,
'uid' => 0,
'type' => 'credit_card',
'payment_gateway' => 'onsite',
'card_type' => 'visa',
'card_number' => '1111',
'reusable' => TRUE,
'expires' => strtotime('2028/03/24'),
'billing_profile' => Profile::create([
'type' => 'customer',
'uid' => 0,
]),
])->save();
PaymentMethod::create([
'uuid' => self::TEST_OFFSITE_PAYMENT_METHOD_UUID,
'uid' => 0,
'type' => 'credit_card',
'payment_gateway' => 'stored_offsite',
'card_type' => 'visa',
'card_number' => '4444',
'reusable' => TRUE,
'expires' => strtotime('2028/03/24'),
'billing_profile' => Profile::create([
'type' => 'customer',
'uid' => 0,
]),
])->save();
}
/**
* Tests the billing order profile through the order profile field.
*
* @dataProvider dataPaymentInstruments
*/
public function testPaymentInstrument(
?string $payment_gateway_id,
?string $payment_method_id,
string $payment_method_type,
array $payment_details,
bool $expects_payment_method,
?string $expected_error,
) {
$order = $this->createOrder();
$this->assertTrue($order->hasField('payment_instrument'));
$profile = Profile::create([
'type' => 'customer',
'uid' => 0,
'address' => [
'country_code' => 'US',
'postal_code' => '53177',
'locality' => 'Milwaukee',
'address_line1' => 'Pabst Blue Ribbon Dr',
'administrative_area' => 'WI',
'given_name' => 'Frederick',
'family_name' => 'Pabst',
],
]);
assert($profile instanceof ProfileInterface);
$profile->save();
$profile = $this->reloadEntity($profile);
$order->setBillingProfile($profile);
if ($expected_error) {
$this->expectException(UnprocessableEntityHttpException::class);
$this->expectExceptionMessage($expected_error);
}
$order->set('payment_instrument', [
'payment_gateway_id' => $payment_gateway_id,
'payment_method_type' => $payment_method_type,
'payment_method_id' => $payment_method_id,
'payment_details' => $payment_details,
]);
if ($expects_payment_method) {
/** @var \Drupal\commerce_payment\Entity\PaymentMethodInterface $payment_method */
$payment_method = $order->get('payment_method')->entity;
$this->assertInstanceOf(PaymentMethodInterface::class, $payment_method);
$this->assertEquals($payment_method->getBillingProfile(), $order->getBillingProfile());
$this->assertEquals($payment_method_type, $payment_method->bundle());
$this->assertEquals($payment_gateway_id, $payment_method->getPaymentGatewayId());
}
}
/**
* Data for payment instrument testing.
*
* @return \Generator
* The test data.
*/
public static function dataPaymentInstruments(): \Generator {
yield [
NULL,
NULL,
'',
[],
FALSE,
'You must specify a `payment_gateway_id`',
];
yield [
'onsite',
NULL,
'credit_card',
[
'type' => 'visa',
'number' => '4111111111111111',
'expiration' => [
'month' => '05',
'year' => '2026',
],
],
TRUE,
NULL,
];
yield [
'onsite',
NULL,
'credit_card',
[
'type' => 'visa',
'number' => '4111111111111111',
],
TRUE,
'We encountered an unexpected error processing your payment method. Please try again later.',
];
yield [
'example_offsite',
NULL,
'credit_card',
[],
FALSE,
NULL,
];
yield [
'onsite',
self::TEST_PAYMENT_METHOD_UUID,
'credit_card',
[],
TRUE,
NULL,
];
yield [
'stored_offsite',
self::TEST_OFFSITE_PAYMENT_METHOD_UUID,
'credit_card',
[],
TRUE,
NULL,
];
yield [
'stored_offsite',
NULL,
'credit_card',
[
'foo' => 'bar',
],
TRUE,
'The referenced payment gateway does not support creating payment methods.',
];
yield [
'stored_offsite',
self::TEST_PAYMENT_METHOD_UUID,
'credit_card',
[],
TRUE,
'Provided payment method does not belong to the payment gateway.',
];
yield [
'onsite',
'38ca7cbb-25ce-4fa1-9872-a9db41ede2d6',
'credit_card',
[],
TRUE,
'Provided payment method does not exist',
];
}
/**
* Creates a test order.
*
* @return \Drupal\commerce_order\Entity\OrderInterface
* The order.
*/
private function createOrder(): OrderInterface {
$order = Order::create([
'type' => 'default',
'state' => 'draft',
'store_id' => $this->store,
]);
assert($order instanceof OrderInterface);
return $order;
}
}
