Merge pull request #137 from woocommerce/PCP-75-validate-form-before-sending-paypal-request

Validate checkout form before sending request to PayPal
This commit is contained in:
Emili Castells 2021-04-06 11:20:46 +02:00 committed by GitHub
commit 5d1979b2fe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 148 additions and 110 deletions

View file

@ -9,7 +9,6 @@ declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\ApiClient\Repository; namespace WooCommerce\PayPalCommerce\ApiClient\Repository;
use WooCommerce\PayPalCommerce\ApiClient\Entity\Item;
use WooCommerce\PayPalCommerce\ApiClient\Entity\PurchaseUnit; use WooCommerce\PayPalCommerce\ApiClient\Entity\PurchaseUnit;
use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory; use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory;

View file

@ -13,12 +13,15 @@ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
use WooCommerce\PayPalCommerce\ApiClient\Entity\Order; use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
use WooCommerce\PayPalCommerce\ApiClient\Entity\Payer; use WooCommerce\PayPalCommerce\ApiClient\Entity\Payer;
use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentMethod; use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentMethod;
use WooCommerce\PayPalCommerce\ApiClient\Entity\PurchaseUnit;
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException; use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
use WooCommerce\PayPalCommerce\ApiClient\Factory\PayerFactory; use WooCommerce\PayPalCommerce\ApiClient\Factory\PayerFactory;
use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory; use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory;
use WooCommerce\PayPalCommerce\ApiClient\Repository\CartRepository; use WooCommerce\PayPalCommerce\ApiClient\Repository\CartRepository;
use WooCommerce\PayPalCommerce\Button\Helper\EarlyOrderHandler; use WooCommerce\PayPalCommerce\Button\Helper\EarlyOrderHandler;
use WooCommerce\PayPalCommerce\Session\SessionHandler; use WooCommerce\PayPalCommerce\Session\SessionHandler;
use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException;
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings; use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
/** /**
@ -86,11 +89,18 @@ class CreateOrderEndpoint implements EndpointInterface {
private $early_order_handler; private $early_order_handler;
/** /**
* The current PayPal order in a process. * Data from the request.
* *
* @var Order|null * @var array
*/ */
private $order; private $parsed_request_data;
/**
* The array of purchase units for order.
*
* @var PurchaseUnit[]
*/
private $purchase_units;
/** /**
* CreateOrderEndpoint constructor. * CreateOrderEndpoint constructor.
@ -138,12 +148,12 @@ class CreateOrderEndpoint implements EndpointInterface {
* Handles the request. * Handles the request.
* *
* @return bool * @return bool
* @throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException In case a setting was not found.
*/ */
public function handle_request(): bool { public function handle_request(): bool {
try { try {
$data = $this->request_data->read_request( $this->nonce() ); $data = $this->request_data->read_request( $this->nonce() );
$wc_order = null; $this->parsed_request_data = $data;
$wc_order = null;
if ( 'pay-now' === $data['context'] ) { if ( 'pay-now' === $data['context'] ) {
$wc_order = wc_get_order( (int) $data['order_id'] ); $wc_order = wc_get_order( (int) $data['order_id'] );
if ( ! is_a( $wc_order, \WC_Order::class ) ) { if ( ! is_a( $wc_order, \WC_Order::class ) ) {
@ -156,28 +166,23 @@ class CreateOrderEndpoint implements EndpointInterface {
) )
); );
} }
$purchase_units = array( $this->purchase_unit_factory->from_wc_order( $wc_order ) ); $this->purchase_units = array( $this->purchase_unit_factory->from_wc_order( $wc_order ) );
} else { } else {
$purchase_units = $this->cart_repository->all(); $this->purchase_units = $this->cart_repository->all();
} }
$this->set_bn_code( $data ); $this->set_bn_code( $data );
$needs_shipping = WC()->cart && WC()->cart->needs_shipping();
$shipping_address_is_fix = $needs_shipping && 'checkout' === $data['context'];
$order = $this->api_endpoint->create(
$purchase_units,
$this->payer( $data, $wc_order ),
null,
$this->payment_method(),
'',
$shipping_address_is_fix
);
if ( 'checkout' === $data['context'] ) { if ( 'checkout' === $data['context'] ) {
$this->process_checkout_form( $data['form'], $order ); $this->process_checkout_form( $data['form'] );
} }
if ( 'pay-now' === $data['context'] && get_option( 'woocommerce_terms_page_id', '' ) !== '' ) { if ( 'pay-now' === $data['context'] && get_option( 'woocommerce_terms_page_id', '' ) !== '' ) {
$this->validate_paynow_form( $data['form'] ); $this->validate_paynow_form( $data['form'] );
} }
// if we are here so the context is not 'checkout' as it exits before. Therefore, a PayPal order is not created yet.
// It would be a good idea to refactor the checkout process in the future.
$order = $this->create_paypal_order( $wc_order );
wp_send_json_success( $order->to_array() ); wp_send_json_success( $order->to_array() );
return true; return true;
} catch ( \RuntimeException $error ) { } catch ( \RuntimeException $error ) {
@ -189,15 +194,41 @@ class CreateOrderEndpoint implements EndpointInterface {
'details' => is_a( $error, PayPalApiException::class ) ? $error->details() : array(), 'details' => is_a( $error, PayPalApiException::class ) ? $error->details() : array(),
) )
); );
return false; } catch ( \Exception $exception ) {
wc_add_notice( $exception->getMessage(), 'error' );
} }
return false;
}
/**
* Creates the order in the PayPal, uses data from WC order if provided.
*
* @param \WC_Order|null $wc_order WC order to get data from.
*
* @return Order Created PayPal order.
*
* @throws RuntimeException If create order request fails.
*/
private function create_paypal_order( \WC_Order $wc_order = null ): Order {
$needs_shipping = WC()->cart && WC()->cart->needs_shipping();
$shipping_address_is_fix = $needs_shipping && 'checkout' === $this->parsed_request_data['context'];
return $this->api_endpoint->create(
$this->purchase_units,
$this->payer( $this->parsed_request_data, $wc_order ),
null,
$this->payment_method(),
'',
$shipping_address_is_fix
);
} }
/** /**
* Returns the Payer entity based on the request data. * Returns the Payer entity based on the request data.
* *
* @param array $data The request data. * @param array $data The request data.
* @param \WC_Order $wc_order The order. * @param \WC_Order|null $wc_order The order.
* *
* @return Payer|null * @return Payer|null
*/ */
@ -245,13 +276,17 @@ class CreateOrderEndpoint implements EndpointInterface {
* Returns the PaymentMethod object for the order. * Returns the PaymentMethod object for the order.
* *
* @return PaymentMethod * @return PaymentMethod
* @throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException In case a setting would not be found.
*/ */
private function payment_method() : PaymentMethod { private function payment_method() : PaymentMethod {
$payee_preferred = $this->settings->has( 'payee_preferred' ) && $this->settings->get( 'payee_preferred' ) ? try {
PaymentMethod::PAYEE_PREFERRED_IMMEDIATE_PAYMENT_REQUIRED $payee_preferred = $this->settings->has( 'payee_preferred' ) && $this->settings->get( 'payee_preferred' ) ?
: PaymentMethod::PAYEE_PREFERRED_UNRESTRICTED; PaymentMethod::PAYEE_PREFERRED_IMMEDIATE_PAYMENT_REQUIRED
$payment_method = new PaymentMethod( $payee_preferred ); : PaymentMethod::PAYEE_PREFERRED_UNRESTRICTED;
} catch ( NotFoundException $exception ) {
$payee_preferred = PaymentMethod::PAYEE_PREFERRED_UNRESTRICTED;
}
$payment_method = new PaymentMethod( $payee_preferred );
return $payment_method; return $payment_method;
} }
@ -259,12 +294,10 @@ class CreateOrderEndpoint implements EndpointInterface {
* Prepare the Request parameter and process the checkout form and validate it. * Prepare the Request parameter and process the checkout form and validate it.
* *
* @param string $form_values The values of the form. * @param string $form_values The values of the form.
* @param Order $order The Order.
* *
* @throws \Exception On Error. * @throws \Exception On Error.
*/ */
private function process_checkout_form( string $form_values, Order $order ) { private function process_checkout_form( string $form_values ) {
$this->order = $order;
$form_values = explode( '&', $form_values ); $form_values = explode( '&', $form_values );
$parsed_values = array(); $parsed_values = array();
@ -316,10 +349,10 @@ class CreateOrderEndpoint implements EndpointInterface {
* @return array * @return array
*/ */
public function after_checkout_validation( array $data, \WP_Error $errors ): array { public function after_checkout_validation( array $data, \WP_Error $errors ): array {
$order = $this->order;
if ( ! $errors->errors ) { if ( ! $errors->errors ) {
$order = $this->create_paypal_order();
/** /**
* In case we are onboarded and everything is fine with the \WC_Order * In case we are onboarded and everything is fine with the \WC_Order
* we want this order to be created. We will intercept it and leave it * we want this order to be created. We will intercept it and leave it

View file

@ -130,9 +130,7 @@ return array(
'wcgateway.order-processor' => static function ( $container ): OrderProcessor { 'wcgateway.order-processor' => static function ( $container ): OrderProcessor {
$session_handler = $container->get( 'session.handler' ); $session_handler = $container->get( 'session.handler' );
$cart_repository = $container->get( 'api.repository.cart' );
$order_endpoint = $container->get( 'api.endpoint.order' ); $order_endpoint = $container->get( 'api.endpoint.order' );
$payments_endpoint = $container->get( 'api.endpoint.payments' );
$order_factory = $container->get( 'api.factory.order' ); $order_factory = $container->get( 'api.factory.order' );
$threed_secure = $container->get( 'button.helper.three-d-secure' ); $threed_secure = $container->get( 'button.helper.three-d-secure' );
$authorized_payments_processor = $container->get( 'wcgateway.processor.authorized-payments' ); $authorized_payments_processor = $container->get( 'wcgateway.processor.authorized-payments' );
@ -142,9 +140,7 @@ return array(
return new OrderProcessor( return new OrderProcessor(
$session_handler, $session_handler,
$cart_repository,
$order_endpoint, $order_endpoint,
$payments_endpoint,
$order_factory, $order_factory,
$threed_secure, $threed_secure,
$authorized_payments_processor, $authorized_payments_processor,

View file

@ -21,13 +21,23 @@ trait ProcessPaymentTrait {
* *
* @param int $order_id The WooCommerce order id. * @param int $order_id The WooCommerce order id.
* *
* @return array|null * @return array
*/ */
public function process_payment( $order_id ) { public function process_payment( $order_id ) {
global $woocommerce;
$failure_data = array(
'result' => 'failure',
'redirect' => wc_get_checkout_url(),
);
$wc_order = wc_get_order( $order_id ); $wc_order = wc_get_order( $order_id );
if ( ! is_a( $wc_order, \WC_Order::class ) ) { if ( ! is_a( $wc_order, \WC_Order::class ) ) {
return null; wc_add_notice(
__( 'Couldn\'t find order to process', 'woocommerce-paypal-payments' ),
'error'
);
return $failure_data;
} }
/** /**
@ -44,7 +54,7 @@ trait ProcessPaymentTrait {
//phpcs:enable WordPress.Security.NonceVerification.Recommended //phpcs:enable WordPress.Security.NonceVerification.Recommended
try { try {
if ( $this->order_processor->process( $wc_order, $woocommerce ) ) { if ( $this->order_processor->process( $wc_order ) ) {
$this->session_handler->destroy_session_data(); $this->session_handler->destroy_session_data();
return array( return array(
'result' => 'success', 'result' => 'success',
@ -63,7 +73,7 @@ trait ProcessPaymentTrait {
__( 'Please use a different payment method.', 'woocommerce-paypal-payments' ), __( 'Please use a different payment method.', 'woocommerce-paypal-payments' ),
'error' 'error'
); );
return null; return $failure_data;
} }
return array( return array(
'result' => 'success', 'result' => 'success',
@ -75,7 +85,7 @@ trait ProcessPaymentTrait {
} catch ( RuntimeException $error ) { } catch ( RuntimeException $error ) {
$this->session_handler->destroy_session_data(); $this->session_handler->destroy_session_data();
wc_add_notice( $error->getMessage(), 'error' ); wc_add_notice( $error->getMessage(), 'error' );
return null; return $failure_data;
} }
wc_add_notice( wc_add_notice(
@ -83,6 +93,6 @@ trait ProcessPaymentTrait {
'error' 'error'
); );
return null; return $failure_data;
} }
} }

View file

@ -11,11 +11,9 @@ namespace WooCommerce\PayPalCommerce\WcGateway\Processor;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint; use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentsEndpoint;
use WooCommerce\PayPalCommerce\ApiClient\Entity\Order; use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus; use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus;
use WooCommerce\PayPalCommerce\ApiClient\Factory\OrderFactory; use WooCommerce\PayPalCommerce\ApiClient\Factory\OrderFactory;
use WooCommerce\PayPalCommerce\ApiClient\Repository\CartRepository;
use WooCommerce\PayPalCommerce\Button\Helper\ThreeDSecure; use WooCommerce\PayPalCommerce\Button\Helper\ThreeDSecure;
use WooCommerce\PayPalCommerce\Session\SessionHandler; use WooCommerce\PayPalCommerce\Session\SessionHandler;
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway; use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
@ -40,13 +38,6 @@ class OrderProcessor {
*/ */
private $session_handler; private $session_handler;
/**
* The Cart Repository.
*
* @var CartRepository
*/
private $cart_repository;
/** /**
* The Order Endpoint. * The Order Endpoint.
* *
@ -54,13 +45,6 @@ class OrderProcessor {
*/ */
private $order_endpoint; private $order_endpoint;
/**
* The Payments Endpoint.
*
* @var PaymentsEndpoint
*/
private $payments_endpoint;
/** /**
* The Order Factory. * The Order Factory.
* *
@ -107,9 +91,7 @@ class OrderProcessor {
* OrderProcessor constructor. * OrderProcessor constructor.
* *
* @param SessionHandler $session_handler The Session Handler. * @param SessionHandler $session_handler The Session Handler.
* @param CartRepository $cart_repository The Cart Repository.
* @param OrderEndpoint $order_endpoint The Order Endpoint. * @param OrderEndpoint $order_endpoint The Order Endpoint.
* @param PaymentsEndpoint $payments_endpoint The Payments Endpoint.
* @param OrderFactory $order_factory The Order Factory. * @param OrderFactory $order_factory The Order Factory.
* @param ThreeDSecure $three_d_secure The ThreeDSecure Helper. * @param ThreeDSecure $three_d_secure The ThreeDSecure Helper.
* @param AuthorizedPaymentsProcessor $authorized_payments_processor The Authorized Payments Processor. * @param AuthorizedPaymentsProcessor $authorized_payments_processor The Authorized Payments Processor.
@ -119,9 +101,7 @@ class OrderProcessor {
*/ */
public function __construct( public function __construct(
SessionHandler $session_handler, SessionHandler $session_handler,
CartRepository $cart_repository,
OrderEndpoint $order_endpoint, OrderEndpoint $order_endpoint,
PaymentsEndpoint $payments_endpoint,
OrderFactory $order_factory, OrderFactory $order_factory,
ThreeDSecure $three_d_secure, ThreeDSecure $three_d_secure,
AuthorizedPaymentsProcessor $authorized_payments_processor, AuthorizedPaymentsProcessor $authorized_payments_processor,
@ -131,9 +111,7 @@ class OrderProcessor {
) { ) {
$this->session_handler = $session_handler; $this->session_handler = $session_handler;
$this->cart_repository = $cart_repository;
$this->order_endpoint = $order_endpoint; $this->order_endpoint = $order_endpoint;
$this->payments_endpoint = $payments_endpoint;
$this->order_factory = $order_factory; $this->order_factory = $order_factory;
$this->threed_secure = $three_d_secure; $this->threed_secure = $three_d_secure;
$this->authorized_payments_processor = $authorized_payments_processor; $this->authorized_payments_processor = $authorized_payments_processor;
@ -145,12 +123,11 @@ class OrderProcessor {
/** /**
* Processes a given WooCommerce order and captured/authorizes the connected PayPal orders. * Processes a given WooCommerce order and captured/authorizes the connected PayPal orders.
* *
* @param \WC_Order $wc_order The WooCommerce order. * @param \WC_Order $wc_order The WooCommerce order.
* @param \WooCommerce $woocommerce The WooCommerce object.
* *
* @return bool * @return bool
*/ */
public function process( \WC_Order $wc_order, \WooCommerce $woocommerce ): bool { public function process( \WC_Order $wc_order ): bool {
$order = $this->session_handler->order(); $order = $this->session_handler->order();
if ( ! $order ) { if ( ! $order ) {
return false; return false;
@ -212,7 +189,7 @@ class OrderProcessor {
$wc_order->update_meta_data( PayPalGateway::CAPTURED_META_KEY, 'true' ); $wc_order->update_meta_data( PayPalGateway::CAPTURED_META_KEY, 'true' );
$wc_order->update_status( 'processing' ); $wc_order->update_status( 'processing' );
} }
$woocommerce->cart->empty_cart(); WC()->cart->empty_cart();
$this->session_handler->destroy_session_data(); $this->session_handler->destroy_session_data();
$this->last_error = ''; $this->last_error = '';
return true; return true;

View file

@ -12,10 +12,10 @@ use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderProcessor; use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderProcessor;
use WooCommerce\PayPalCommerce\WcGateway\Processor\RefundProcessor; use WooCommerce\PayPalCommerce\WcGateway\Processor\RefundProcessor;
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings; use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsFields;
use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsRenderer; use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsRenderer;
use Mockery; use Mockery;
use function Brain\Monkey\Functions\expect; use function Brain\Monkey\Functions\expect;
use function Brain\Monkey\Functions\when;
class WcGatewayTest extends TestCase class WcGatewayTest extends TestCase
{ {
@ -31,7 +31,7 @@ class WcGatewayTest extends TestCase
$orderProcessor $orderProcessor
->expects('process') ->expects('process')
->andReturnUsing( ->andReturnUsing(
function(\WC_Order $order, $woocommerce) use ($wcOrder) : bool { function(\WC_Order $order) use ($wcOrder) : bool {
return $order === $wcOrder; return $order === $wcOrder;
} }
); );
@ -64,11 +64,14 @@ class WcGatewayTest extends TestCase
->with($orderId) ->with($orderId)
->andReturn($wcOrder); ->andReturn($wcOrder);
global $woocommerce;
$woocommerce = Mockery::mock(\WooCommerce::class); when('wc_get_checkout_url')
->justReturn('test');
$result = $testee->process_payment($orderId); $result = $testee->process_payment($orderId);
unset($woocommerce);
$this->assertIsArray($result); $this->assertIsArray($result);
$this->assertEquals('success', $result['result']); $this->assertEquals('success', $result['result']);
$this->assertEquals($result['redirect'], $wcOrder); $this->assertEquals($result['redirect'], $wcOrder);
} }
@ -106,10 +109,21 @@ class WcGatewayTest extends TestCase
->with($orderId) ->with($orderId)
->andReturn(false); ->andReturn(false);
global $woocommerce; $redirectUrl = 'http://example.com/checkout';
$woocommerce = Mockery::mock(\WooCommerce::class);
$this->assertNull($testee->process_payment($orderId)); when('wc_get_checkout_url')
unset($woocommerce); ->justReturn($redirectUrl);
expect('wc_add_notice')
->with('Couldn\'t find order to process','error');
$this->assertEquals(
[
'result' => 'failure',
'redirect' => $redirectUrl
],
$testee->process_payment($orderId)
);
} }
@ -156,11 +170,19 @@ class WcGatewayTest extends TestCase
expect('wc_add_notice') expect('wc_add_notice')
->with($lastError, 'error'); ->with($lastError, 'error');
global $woocommerce; $redirectUrl = 'http://example.com/checkout';
$woocommerce = Mockery::mock(\WooCommerce::class);
when('wc_get_checkout_url')
->justReturn($redirectUrl);
$result = $testee->process_payment($orderId); $result = $testee->process_payment($orderId);
unset($woocommerce); $this->assertEquals(
$this->assertNull($result); [
'result' => 'failure',
'redirect' => $redirectUrl
],
$result
);
} }
public function testCaptureAuthorizedPayment() { public function testCaptureAuthorizedPayment() {

View file

@ -6,20 +6,19 @@ namespace WooCommerce\PayPalCommerce\WcGateway\Processor;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint; use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentsEndpoint;
use Woocommerce\PayPalCommerce\ApiClient\Entity\Capture; use Woocommerce\PayPalCommerce\ApiClient\Entity\Capture;
use WooCommerce\PayPalCommerce\ApiClient\Entity\Order; use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus; use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus;
use WooCommerce\PayPalCommerce\ApiClient\Entity\Payments; use WooCommerce\PayPalCommerce\ApiClient\Entity\Payments;
use WooCommerce\PayPalCommerce\ApiClient\Entity\PurchaseUnit; use WooCommerce\PayPalCommerce\ApiClient\Entity\PurchaseUnit;
use WooCommerce\PayPalCommerce\ApiClient\Factory\OrderFactory; use WooCommerce\PayPalCommerce\ApiClient\Factory\OrderFactory;
use WooCommerce\PayPalCommerce\ApiClient\Repository\CartRepository;
use WooCommerce\PayPalCommerce\Button\Helper\ThreeDSecure; use WooCommerce\PayPalCommerce\Button\Helper\ThreeDSecure;
use WooCommerce\PayPalCommerce\Session\SessionHandler; use WooCommerce\PayPalCommerce\Session\SessionHandler;
use WooCommerce\PayPalCommerce\TestCase; use WooCommerce\PayPalCommerce\TestCase;
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway; use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings; use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
use Mockery; use Mockery;
use function Brain\Monkey\Functions\when;
class OrderProcessorTest extends TestCase class OrderProcessorTest extends TestCase
{ {
@ -78,8 +77,6 @@ class OrderProcessorTest extends TestCase
$sessionHandler $sessionHandler
->expects('destroy_session_data'); ->expects('destroy_session_data');
$cartRepository = Mockery::mock(CartRepository::class);
$orderEndpoint = Mockery::mock(OrderEndpoint::class); $orderEndpoint = Mockery::mock(OrderEndpoint::class);
$orderEndpoint $orderEndpoint
->expects('patch_order_with') ->expects('patch_order_with')
@ -90,8 +87,6 @@ class OrderProcessorTest extends TestCase
->with($currentOrder) ->with($currentOrder)
->andReturn($currentOrder); ->andReturn($currentOrder);
$paymentsEndpoint = Mockery::mock(PaymentsEndpoint::class);
$orderFactory = Mockery::mock(OrderFactory::class); $orderFactory = Mockery::mock(OrderFactory::class);
$orderFactory $orderFactory
->expects('from_wc_order') ->expects('from_wc_order')
@ -111,9 +106,7 @@ class OrderProcessorTest extends TestCase
$testee = new OrderProcessor( $testee = new OrderProcessor(
$sessionHandler, $sessionHandler,
$cartRepository,
$orderEndpoint, $orderEndpoint,
$paymentsEndpoint,
$orderFactory, $orderFactory,
$threeDSecure, $threeDSecure,
$authorizedPaymentProcessor, $authorizedPaymentProcessor,
@ -126,6 +119,9 @@ class OrderProcessorTest extends TestCase
$cart $cart
->expects('empty_cart'); ->expects('empty_cart');
$woocommerce = Mockery::mock(\WooCommerce::class); $woocommerce = Mockery::mock(\WooCommerce::class);
when('WC')
->justReturn($woocommerce);
$woocommerce->cart = $cart; $woocommerce->cart = $cart;
$wcOrder $wcOrder
@ -149,7 +145,9 @@ class OrderProcessorTest extends TestCase
$wcOrder $wcOrder
->expects('update_status') ->expects('update_status')
->with('on-hold', 'Awaiting payment.'); ->with('on-hold', 'Awaiting payment.');
$this->assertTrue($testee->process($wcOrder, $woocommerce));
$this->assertTrue($testee->process($wcOrder));
} }
public function testCapture() { public function testCapture() {
@ -198,7 +196,6 @@ class OrderProcessorTest extends TestCase
->andReturn($currentOrder); ->andReturn($currentOrder);
$sessionHandler $sessionHandler
->expects('destroy_session_data'); ->expects('destroy_session_data');
$cartRepository = Mockery::mock(CartRepository::class);
$orderEndpoint = Mockery::mock(OrderEndpoint::class); $orderEndpoint = Mockery::mock(OrderEndpoint::class);
$orderEndpoint $orderEndpoint
->expects('patch_order_with') ->expects('patch_order_with')
@ -208,7 +205,6 @@ class OrderProcessorTest extends TestCase
->expects('capture') ->expects('capture')
->with($currentOrder) ->with($currentOrder)
->andReturn($currentOrder); ->andReturn($currentOrder);
$paymentsEndpoint = Mockery::mock(PaymentsEndpoint::class);
$orderFactory = Mockery::mock(OrderFactory::class); $orderFactory = Mockery::mock(OrderFactory::class);
$orderFactory $orderFactory
->expects('from_wc_order') ->expects('from_wc_order')
@ -221,14 +217,24 @@ class OrderProcessorTest extends TestCase
->shouldReceive('has') ->shouldReceive('has')
->andReturnFalse(); ->andReturnFalse();
$cart = Mockery::mock(\WC_Cart::class);
$cart
->shouldReceive('empty_cart');
$woocommerce = Mockery::Mock(\Woocommerce::class);
$woocommerce
->shouldReceive('__get')
->with('cart')
->set('cart', $cart);
when('WC')
->justReturn($woocommerce);
$logger = Mockery::mock(LoggerInterface::class); $logger = Mockery::mock(LoggerInterface::class);
$testee = new OrderProcessor( $testee = new OrderProcessor(
$sessionHandler, $sessionHandler,
$cartRepository,
$orderEndpoint, $orderEndpoint,
$paymentsEndpoint,
$orderFactory, $orderFactory,
$threeDSecure, $threeDSecure,
$authorizedPaymentProcessor, $authorizedPaymentProcessor,
@ -243,6 +249,9 @@ class OrderProcessorTest extends TestCase
$woocommerce = Mockery::mock(\WooCommerce::class); $woocommerce = Mockery::mock(\WooCommerce::class);
$woocommerce->cart = $cart; $woocommerce->cart = $cart;
when('WC')
->justReturn($woocommerce);
$wcOrder $wcOrder
->expects('update_meta_data') ->expects('update_meta_data')
->with( ->with(
@ -265,7 +274,7 @@ class OrderProcessorTest extends TestCase
$wcOrder $wcOrder
->expects('update_status') ->expects('update_status')
->with('processing', 'Payment received.'); ->with('processing', 'Payment received.');
$this->assertTrue($testee->process($wcOrder, $woocommerce)); $this->assertTrue($testee->process($wcOrder));
} }
public function testError() { public function testError() {
@ -316,9 +325,7 @@ class OrderProcessorTest extends TestCase
$sessionHandler $sessionHandler
->expects('order') ->expects('order')
->andReturn($currentOrder); ->andReturn($currentOrder);
$cartRepository = Mockery::mock(CartRepository::class);
$orderEndpoint = Mockery::mock(OrderEndpoint::class); $orderEndpoint = Mockery::mock(OrderEndpoint::class);
$paymentsEndpoint = Mockery::mock(PaymentsEndpoint::class);
$orderFactory = Mockery::mock(OrderFactory::class); $orderFactory = Mockery::mock(OrderFactory::class);
$threeDSecure = Mockery::mock(ThreeDSecure::class); $threeDSecure = Mockery::mock(ThreeDSecure::class);
$authorizedPaymentProcessor = Mockery::mock(AuthorizedPaymentsProcessor::class); $authorizedPaymentProcessor = Mockery::mock(AuthorizedPaymentsProcessor::class);
@ -328,9 +335,7 @@ class OrderProcessorTest extends TestCase
$testee = new OrderProcessor( $testee = new OrderProcessor(
$sessionHandler, $sessionHandler,
$cartRepository,
$orderEndpoint, $orderEndpoint,
$paymentsEndpoint,
$orderFactory, $orderFactory,
$threeDSecure, $threeDSecure,
$authorizedPaymentProcessor, $authorizedPaymentProcessor,
@ -339,10 +344,6 @@ class OrderProcessorTest extends TestCase
false false
); );
$cart = Mockery::mock(\WC_Cart::class);
$woocommerce = Mockery::mock(\WooCommerce::class);
$woocommerce->cart = $cart;
$wcOrder $wcOrder
->expects('update_meta_data') ->expects('update_meta_data')
->with( ->with(
@ -355,7 +356,8 @@ class OrderProcessorTest extends TestCase
PayPalGateway::INTENT_META_KEY, PayPalGateway::INTENT_META_KEY,
$orderIntent $orderIntent
); );
$this->assertFalse($testee->process($wcOrder, $woocommerce));
$this->assertFalse($testee->process($wcOrder));
$this->assertNotEmpty($testee->last_error()); $this->assertNotEmpty($testee->last_error());
} }

View file

@ -2,10 +2,11 @@
declare(strict_types=1); declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\ApiClient\Repository; namespace WooCommerce\PayPalCommerce\WcGateway\Repository;
use Hamcrest\Matchers; use Hamcrest\Matchers;
use WooCommerce\PayPalCommerce\ApiClient\Entity\ApplicationContext; use WooCommerce\PayPalCommerce\ApiClient\Entity\ApplicationContext;
use WooCommerce\PayPalCommerce\ApiClient\Repository\ApplicationContextRepository;
use WooCommerce\PayPalCommerce\TestCase; use WooCommerce\PayPalCommerce\TestCase;
use Mockery\MockInterface; use Mockery\MockInterface;
use Psr\Container\ContainerInterface; use Psr\Container\ContainerInterface;
@ -25,8 +26,6 @@ class ApplicationContextRepositoryTest extends TestCase
array $expected array $expected
): void ): void
{ {
$brandName = 'Acme Corp.';
// Config // Config
foreach ($container as $key => $value) { foreach ($container as $key => $value) {
$this->buildTestee()[0]->shouldReceive('has') $this->buildTestee()[0]->shouldReceive('has')

View file

@ -2,7 +2,7 @@
declare(strict_types=1); declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\ApiClient\Repository; namespace WooCommerce\PayPalCommerce\WcGateway\Repository;
use Mockery\Adapter\Phpunit\MockeryTestCase; use Mockery\Adapter\Phpunit\MockeryTestCase;