diff --git a/changelog.txt b/changelog.txt index 7ea3394574..f1f9fa2768 100644 --- a/changelog.txt +++ b/changelog.txt @@ -53,6 +53,7 @@ * Update - Back button on the settings pages. * Update - Use individual product tax status instead of storewide tax setup when determining express checkout availability. * Add - Use Stripe Configuration API to manage payment methods enabled/disabled states. +* Dev - Add track events when enabling/disabling payment methods. = 9.3.1 - 2025-03-14 = * Fix - Temporarily disables the subscriptions detached notice feature due to long loading times on stores with many subscriptions. diff --git a/includes/admin/class-wc-rest-stripe-account-keys-controller.php b/includes/admin/class-wc-rest-stripe-account-keys-controller.php index 7d23468cef..2a1be1bbea 100644 --- a/includes/admin/class-wc-rest-stripe-account-keys-controller.php +++ b/includes/admin/class-wc-rest-stripe-account-keys-controller.php @@ -299,7 +299,7 @@ public function set_account_keys( WP_REST_Request $request ) { } } else { $upe_gateway = new WC_Stripe_UPE_Payment_Gateway(); - $upe_gateway->update_option( 'upe_checkout_experience_accepted_payments', [ WC_Stripe_Payment_Methods::CARD, WC_Stripe_Payment_Methods::LINK ] ); + $upe_gateway->update_enabled_payment_methods( [ WC_Stripe_Payment_Methods::CARD, WC_Stripe_Payment_Methods::LINK ] ); // Handle Multibanco separately as it is a non UPE method but it is part of the same settings page. $multibanco = WC_Stripe_Helper::get_legacy_payment_method( 'stripe_multibanco' ); diff --git a/includes/admin/class-wc-rest-stripe-settings-controller.php b/includes/admin/class-wc-rest-stripe-settings-controller.php index 20f74a470a..77a0d02a72 100644 --- a/includes/admin/class-wc-rest-stripe-settings-controller.php +++ b/includes/admin/class-wc-rest-stripe-settings-controller.php @@ -241,7 +241,7 @@ public function get_settings() { $is_upe_enabled = WC_Stripe_Feature_Flags::is_upe_checkout_enabled(); $available_payment_method_ids = $is_upe_enabled ? $this->gateway->get_upe_available_payment_methods() : WC_Stripe_Helper::get_legacy_available_payment_method_ids(); $ordered_payment_method_ids = $is_upe_enabled ? WC_Stripe_Helper::get_upe_ordered_payment_method_ids( $this->gateway ) : $available_payment_method_ids; - $enabled_payment_method_ids = $is_upe_enabled ? WC_Stripe_Helper::get_upe_settings_enabled_payment_method_ids( $this->gateway ) : WC_Stripe_Helper::get_legacy_enabled_payment_method_ids(); + $enabled_payment_method_ids = $is_upe_enabled ? $this->gateway->get_upe_enabled_payment_method_ids() : WC_Stripe_Helper::get_legacy_enabled_payment_method_ids(); return new WP_REST_Response( [ @@ -604,6 +604,10 @@ private function update_enabled_payment_methods( WP_REST_Request $request ) { return; } + if ( null === $payment_method_ids_to_enable ) { + return; + } + if ( ! $is_upe_enabled ) { $currently_enabled_payment_method_ids = WC_Stripe_Helper::get_legacy_enabled_payment_method_ids(); $payment_gateways = WC_Stripe_Helper::get_legacy_payment_methods(); @@ -620,26 +624,8 @@ private function update_enabled_payment_methods( WP_REST_Request $request ) { return; } - if ( null === $payment_method_ids_to_enable ) { - return; - } - - $currently_enabled_payment_method_ids = (array) $this->gateway->get_option( 'upe_checkout_experience_accepted_payments' ); - $upe_checkout_experience_accepted_payments = []; - - foreach ( WC_Stripe_UPE_Payment_Gateway::UPE_AVAILABLE_METHODS as $gateway ) { - if ( in_array( $gateway::STRIPE_ID, $payment_method_ids_to_enable, true ) ) { - $upe_checkout_experience_accepted_payments[] = $gateway::STRIPE_ID; - } - } - - $this->gateway->update_option( 'upe_checkout_experience_accepted_payments', $upe_checkout_experience_accepted_payments ); - - // After updating payment methods record tracks events. - $newly_enabled_methods = array_diff( $upe_checkout_experience_accepted_payments, $currently_enabled_payment_method_ids ); - $newly_disabled_methods = array_diff( $currently_enabled_payment_method_ids, $payment_method_ids_to_enable ); - - $this->record_payment_method_settings_event( $newly_enabled_methods, $newly_disabled_methods ); + $upe_gateway = new WC_Stripe_UPE_Payment_Gateway(); + $upe_gateway->update_enabled_payment_methods( $payment_method_ids_to_enable ); } /** diff --git a/includes/admin/class-wc-stripe-payment-gateways-controller.php b/includes/admin/class-wc-stripe-payment-gateways-controller.php index 6114587947..3ef6dc58ff 100644 --- a/includes/admin/class-wc-stripe-payment-gateways-controller.php +++ b/includes/admin/class-wc-stripe-payment-gateways-controller.php @@ -18,7 +18,8 @@ class WC_Stripe_Payment_Gateways_Controller { public function __construct() { // If UPE is enabled and there are enabled payment methods, we need to load the disable Stripe confirmation modal. $stripe_settings = WC_Stripe_Helper::get_stripe_settings(); - $enabled_upe_payment_methods = isset( $stripe_settings['upe_checkout_experience_accepted_payments'] ) ? $stripe_settings['upe_checkout_experience_accepted_payments'] : []; + $upe_gateway = new WC_Stripe_UPE_Payment_Gateway(); + $enabled_upe_payment_methods = $upe_gateway->get_upe_enabled_payment_method_ids(); $upe_payment_requests_enabled = 'yes' === $stripe_settings['payment_request']; if ( ( is_array( $enabled_upe_payment_methods ) && count( $enabled_upe_payment_methods ) > 0 ) || $upe_payment_requests_enabled ) { diff --git a/includes/admin/stripe-settings.php b/includes/admin/stripe-settings.php index bd2a5e72f3..53062c0bcc 100644 --- a/includes/admin/stripe-settings.php +++ b/includes/admin/stripe-settings.php @@ -307,14 +307,6 @@ 'desc_tip' => true, ], ]; - if ( WC_Stripe_Feature_Flags::is_upe_checkout_enabled() ) { - // This adds the payment method section - $upe_settings['upe_checkout_experience_accepted_payments'] = [ - 'title' => __( 'Payments accepted on checkout (Early access)', 'woocommerce-gateway-stripe' ), - 'type' => 'upe_checkout_experience_accepted_payments', - 'default' => [ WC_Stripe_Payment_Methods::CARD, WC_Stripe_Payment_Methods::LINK ], - ]; - } // Insert UPE options below the 'logging' setting. $stripe_settings = array_merge( $stripe_settings, $upe_settings ); } diff --git a/includes/class-wc-stripe-api.php b/includes/class-wc-stripe-api.php index 743e75f04c..0ce455bb3d 100644 --- a/includes/class-wc-stripe-api.php +++ b/includes/class-wc-stripe-api.php @@ -23,6 +23,34 @@ class WC_Stripe_API { */ private static $secret_key = ''; + /** + * Instance of WC_Stripe_API. + * + * @var WC_Stripe_API + */ + private static $instance; + + /** + * Get instance of WC_Stripe_API. + * + * @return WC_Stripe_API + */ + public static function get_instance() { + if ( ! isset( self::$instance ) ) { + self::$instance = new self(); + } + return self::$instance; + } + + /** + * Set instance of WC_Stripe_API. + * + * @param WC_Stripe_API $instance + */ + public static function set_instance( $instance ) { + self::$instance = $instance; + } + /** * Set secret API Key. * @@ -441,7 +469,20 @@ public static function should_detach_payment_method_from_customer() { * * @return array The response from the API request. */ - public static function get_payment_method_configurations() { + public function get_payment_method_configurations() { return self::retrieve( 'payment_method_configurations' ); } + + /** + * Update the payment method configuration. + * + * @param array $payment_method_configurations The payment method configurations to update. + */ + public function update_payment_method_configurations( $id, $payment_method_configurations ) { + $response = self::request( + $payment_method_configurations, + 'payment_method_configurations/' . $id + ); + return $response; + } } diff --git a/includes/class-wc-stripe-payment-method-configurations.php b/includes/class-wc-stripe-payment-method-configurations.php new file mode 100644 index 0000000000..94027f6b32 --- /dev/null +++ b/includes/class-wc-stripe-payment-method-configurations.php @@ -0,0 +1,174 @@ +get_payment_method_configurations(); + $payment_method_configurations = $result->data ?? null; + + if ( ! $payment_method_configurations ) { + return null; + } + + foreach ( $payment_method_configurations as $payment_method_configuration ) { + if ( ! $payment_method_configuration->livemode && $payment_method_configuration->parent && self::TEST_MODE_CONFIGURATION_PARENT_ID === $payment_method_configuration->parent ) { + self::$primary_configuration = $payment_method_configuration; + return $payment_method_configuration; + } + + if ( $payment_method_configuration->livemode && $payment_method_configuration->parent && self::LIVE_MODE_CONFIGURATION_PARENT_ID === $payment_method_configuration->parent ) { + self::$primary_configuration = $payment_method_configuration; + return $payment_method_configuration; + } + } + return null; + } + + /** + * Get the UPE enabled payment method IDs. + * + * @return array + */ + public static function get_upe_enabled_payment_method_ids() { + $enabled_payment_method_ids = []; + $merchant_payment_method_configuration = self::get_primary_configuration(); + + if ( $merchant_payment_method_configuration ) { + foreach ( $merchant_payment_method_configuration as $payment_method_id => $payment_method ) { + if ( isset( $payment_method->display_preference->value ) && 'on' === $payment_method->display_preference->value ) { + $enabled_payment_method_ids[] = $payment_method_id; + } + } + } + + return $enabled_payment_method_ids; + } + + /** + * Update the payment method configuration. + * + * @param array $enabled_payment_method_ids + * @param array $available_payment_method_ids + */ + public static function update_payment_method_configuration( $enabled_payment_method_ids, $available_payment_method_ids ) { + $payment_method_configuration = self::get_primary_configuration(); + $updated_payment_method_configuration = []; + $newly_enabled_methods = []; + $newly_disabled_methods = []; + + foreach ( $available_payment_method_ids as $stripe_id ) { + $will_enable = in_array( $stripe_id, $enabled_payment_method_ids, true ); + + if ( 'on' === ( $payment_method_configuration->$stripe_id->display_preference->value ?? null ) && ! $will_enable ) { + $newly_disabled_methods[] = $stripe_id; + } + + if ( 'off' === ( $payment_method_configuration->$stripe_id->display_preference->value ?? null ) && $will_enable ) { + $newly_enabled_methods[] = $stripe_id; + } + + $updated_payment_method_configuration[ $stripe_id ] = [ + 'display_preference' => [ + 'preference' => in_array( $stripe_id, $enabled_payment_method_ids, true ) ? 'on' : 'off', + ], + ]; + } + + if ( ! $payment_method_configuration ) { + WC_Stripe_Logger::log( 'No primary payment method configuration found while updating payment method configuration' ); + return; + } + + WC_Stripe_API::get_instance()->update_payment_method_configurations( + $payment_method_configuration->id, + $updated_payment_method_configuration + ); + + self::record_payment_method_settings_event( $newly_enabled_methods, $newly_disabled_methods ); + } + + /** + * Record tracks events for each payment method that was enabled or disabled. + * + * @param array $enabled_methods An array of payment method ids that were enabled. + * @param array $disabled_methods An array of payment method ids that were disabled. + * + * @return void + */ + private static function record_payment_method_settings_event( $enabled_methods, $disabled_methods ) { + if ( ! function_exists( 'wc_admin_record_tracks_event' ) ) { + return; + } + + $is_test_mode = WC_Stripe_Mode::is_test(); + + // Track the events for both arrays. + array_map( + function ( $id ) use ( $is_test_mode ) { + wc_admin_record_tracks_event( + 'wcstripe_payment_method_settings_enabled', + [ + 'is_test_mode' => $is_test_mode, + 'payment_method' => $id, + ] + ); + }, + $enabled_methods + ); + array_map( + function ( $id ) use ( $is_test_mode ) { + wc_admin_record_tracks_event( + 'wcstripe_payment_method_settings_disabled', + [ + 'is_test_mode' => $is_test_mode, + 'payment_method' => $id, + ] + ); + }, + $disabled_methods + ); + } +} diff --git a/includes/connect/class-wc-stripe-connect.php b/includes/connect/class-wc-stripe-connect.php index 43ad8b8da6..48353bed1f 100644 --- a/includes/connect/class-wc-stripe-connect.php +++ b/includes/connect/class-wc-stripe-connect.php @@ -240,8 +240,9 @@ private function get_default_stripe_config() { } } - $result['upe_checkout_experience_enabled'] = 'yes'; - $result['upe_checkout_experience_accepted_payments'][] = WC_Stripe_Payment_Methods::LINK; + $result['upe_checkout_experience_enabled'] = 'yes'; + $upe_gateway = new WC_Stripe_UPE_Payment_Gateway(); + $upe_gateway->update_enabled_payment_methods( [ WC_Stripe_Payment_Methods::LINK ] ); return $result; } diff --git a/includes/payment-methods/class-wc-stripe-upe-payment-gateway.php b/includes/payment-methods/class-wc-stripe-upe-payment-gateway.php index 6fbba581f7..738a062185 100644 --- a/includes/payment-methods/class-wc-stripe-upe-payment-gateway.php +++ b/includes/payment-methods/class-wc-stripe-upe-payment-gateway.php @@ -607,12 +607,12 @@ private function get_enabled_payment_method_config() { } /** - * Returns the list of enabled payment method types for UPE. + * Returns UPE enabled payment method IDs. * * @return string[] */ public function get_upe_enabled_payment_method_ids() { - return $this->get_option( 'upe_checkout_experience_accepted_payments', [ WC_Stripe_Payment_Methods::CARD ] ); + return WC_Stripe_Payment_Method_Configurations::get_upe_enabled_payment_method_ids(); } /** @@ -664,6 +664,40 @@ public function get_upe_available_payment_methods() { return $available_payment_methods; } + /** + * Updates the enabled payment methods. + * + * @param string[] $payment_method_ids_to_enable + */ + public function update_enabled_payment_methods( $payment_method_ids_to_enable ) { + WC_Stripe_Payment_Method_Configurations::update_payment_method_configuration( $payment_method_ids_to_enable, $this->get_stripe_supported_payment_methods() ); + } + + /** + * Returns the list of supported payment method types for Stripe. + * + * @return string[] + */ + private function get_stripe_supported_payment_methods() { + $supported_stripe_ids = []; + $available_payment_method_ids = $this->get_upe_available_payment_methods(); + + foreach ( self::UPE_AVAILABLE_METHODS as $gateway_class ) { + $gateway = new $gateway_class(); + + if ( + ! in_array( $gateway->get_id(), $available_payment_method_ids, true ) || + ( $gateway->get_supported_currencies() && ! in_array( get_woocommerce_currency(), $gateway->get_supported_currencies(), true ) ) + ) { + continue; + } + + $supported_stripe_ids[] = $gateway::STRIPE_ID; + } + + return $supported_stripe_ids; + } + /** * Renders the UPE input fields needed to get the user's payment information on the checkout page */ diff --git a/includes/payment-methods/class-wc-stripe-upe-payment-method-amazon-pay.php b/includes/payment-methods/class-wc-stripe-upe-payment-method-amazon-pay.php index 7376a627fd..8d124d771d 100644 --- a/includes/payment-methods/class-wc-stripe-upe-payment-method-amazon-pay.php +++ b/includes/payment-methods/class-wc-stripe-upe-payment-method-amazon-pay.php @@ -73,7 +73,8 @@ public static function is_amazon_pay_enabled() { return false; } - $upe_enabled_method_ids = WC_Stripe_Helper::get_settings( null, 'upe_checkout_experience_accepted_payments' ); + $wc_stripe_upe_payment_method_amazon_pay = new self(); + $upe_enabled_method_ids = $wc_stripe_upe_payment_method_amazon_pay->get_upe_enabled_payment_method_ids(); return is_array( $upe_enabled_method_ids ) && in_array( self::STRIPE_ID, $upe_enabled_method_ids, true ); } diff --git a/includes/payment-methods/class-wc-stripe-upe-payment-method-link.php b/includes/payment-methods/class-wc-stripe-upe-payment-method-link.php index a733a0efb5..ec1092ebfb 100644 --- a/includes/payment-methods/class-wc-stripe-upe-payment-method-link.php +++ b/includes/payment-methods/class-wc-stripe-upe-payment-method-link.php @@ -39,7 +39,8 @@ public static function is_link_enabled() { return false; } - $upe_enabled_method_ids = WC_Stripe_Helper::get_settings( null, 'upe_checkout_experience_accepted_payments' ); + $upe_gateway = new WC_Stripe_UPE_Payment_Gateway(); + $upe_enabled_method_ids = $upe_gateway->get_upe_enabled_payment_method_ids(); return is_array( $upe_enabled_method_ids ) && in_array( self::STRIPE_ID, $upe_enabled_method_ids, true ); } diff --git a/includes/payment-methods/class-wc-stripe-upe-payment-method.php b/includes/payment-methods/class-wc-stripe-upe-payment-method.php index 86963b0ff2..054703ed43 100644 --- a/includes/payment-methods/class-wc-stripe-upe-payment-method.php +++ b/includes/payment-methods/class-wc-stripe-upe-payment-method.php @@ -126,7 +126,7 @@ public function __construct() { $main_settings = WC_Stripe_Helper::get_stripe_settings(); $is_stripe_enabled = ! empty( $main_settings['enabled'] ) && 'yes' === $main_settings['enabled']; - $this->enabled = $is_stripe_enabled && in_array( static::STRIPE_ID, $this->get_option( 'upe_checkout_experience_accepted_payments', [ WC_Stripe_Payment_Methods::CARD ] ), true ) ? 'yes' : 'no'; // @phpstan-ignore-line (STRIPE_ID is defined in classes using this class) + $this->enabled = $is_stripe_enabled && in_array( static::STRIPE_ID, $this->get_upe_enabled_payment_method_ids(), true ) ? 'yes' : 'no'; // @phpstan-ignore-line (STRIPE_ID is defined in classes using this class) $this->id = WC_Gateway_Stripe::ID . '_' . static::STRIPE_ID; // @phpstan-ignore-line (STRIPE_ID is defined in classes using this class) $this->has_fields = true; $this->testmode = WC_Stripe_Mode::is_test(); @@ -758,4 +758,13 @@ public function get_transaction_url( $order ) { public function supports_deferred_intent() { return $this->supports_deferred_intent; } + + /** + * Returns UPE enabled payment method IDs. + * + * @return string[] + */ + public function get_upe_enabled_payment_method_ids() { + return WC_Stripe_Payment_Method_Configurations::get_upe_enabled_payment_method_ids(); + } } diff --git a/package-lock.json b/package-lock.json index 8a3c55ec6b..b3780cca32 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,7 +6,7 @@ "packages": { "": { "name": "woocommerce-gateway-stripe", - "version": "9.2.0", + "version": "9.3.1", "hasInstallScript": true, "license": "GPL-3.0", "dependencies": { diff --git a/readme.txt b/readme.txt index cdc7612c0f..7db3ed0901 100644 --- a/readme.txt +++ b/readme.txt @@ -163,5 +163,6 @@ If you get stuck, you can ask for help in the [Plugin Forum](https://wordpress.o * Update - Back button on the settings pages. * Update - Use individual product tax status instead of storewide tax setup when determining express checkout availability. * Add - Use Stripe Configuration API to manage payment methods enabled/disabled states. +* Dev - Add track events when enabling/disabling payment methods. [See changelog for all versions](https://raw.githubusercontent.com/woocommerce/woocommerce-gateway-stripe/trunk/changelog.txt). diff --git a/tests/phpunit/admin/test-class-wc-rest-stripe-settings-controller-gb.php b/tests/phpunit/admin/test-class-wc-rest-stripe-settings-controller-gb.php index ab027021ad..b9b15ed89a 100644 --- a/tests/phpunit/admin/test-class-wc-rest-stripe-settings-controller-gb.php +++ b/tests/phpunit/admin/test-class-wc-rest-stripe-settings-controller-gb.php @@ -9,7 +9,7 @@ /** * WC_REST_Stripe_Settings_Controller_Test_GB unit tests. */ -class WC_REST_Stripe_Settings_Controller_Test_GB extends WP_UnitTestCase { +class WC_REST_Stripe_Settings_Controller_Test_GB extends WC_Mock_Stripe_API_Unit_Test_Case { /** * Tested REST route. @@ -23,6 +23,13 @@ class WC_REST_Stripe_Settings_Controller_Test_GB extends WP_UnitTestCase { */ private static $gateway; + /** + * Controller instance + * + * @var WC_REST_Stripe_Settings_Controller + */ + private $controller; + /** * Enable UPE and store gateway instance. * @@ -82,6 +89,9 @@ public function set_up() { $upe_helper = new UPE_Test_Helper(); $upe_helper->enable_upe(); $upe_helper->reload_payment_gateways(); + $this->mock_payment_method_configurations( [ 'card' ], [] ); + + $this->controller = new WC_REST_Stripe_Settings_Controller( new WC_Stripe_UPE_Payment_Gateway() ); self::$gateway = WC()->payment_gateways()->payment_gateways()[ WC_Gateway_Stripe::ID ]; } @@ -154,7 +164,7 @@ public function test_get_settings_returns_ordered_payment_method_ids_for_gb() { private function rest_get_settings() { $request = new WP_REST_Request( 'GET', self::SETTINGS_ROUTE ); - return rest_do_request( $request ); + return $this->controller->get_settings( $request ); } /** diff --git a/tests/phpunit/admin/test-class-wc-rest-stripe-settings-controller.php b/tests/phpunit/admin/test-class-wc-rest-stripe-settings-controller.php index 76f8c7d698..dd1471c342 100644 --- a/tests/phpunit/admin/test-class-wc-rest-stripe-settings-controller.php +++ b/tests/phpunit/admin/test-class-wc-rest-stripe-settings-controller.php @@ -9,13 +9,21 @@ /** * WC_REST_Stripe_Settings_Controller_Test unit tests. */ -class WC_REST_Stripe_Settings_Controller_Test extends WP_UnitTestCase { +class WC_REST_Stripe_Settings_Controller_Test extends WC_Mock_Stripe_API_Unit_Test_Case { /** * Tested REST route. */ const SETTINGS_ROUTE = '/wc/v3/wc_stripe/settings'; + /** + * Controller instance + * + * @var WC_REST_Stripe_Settings_Controller + */ + private $controller; + + /** * Gateway instance that the controller uses. * @@ -66,6 +74,9 @@ public function set_up() { $this->markTestSkipped( 'The controller is not compatible with older WC versions, due to the missing `update_option` method on the gateway.' ); } + $this->upe_helper = new UPE_Test_Helper(); + $this->controller = new WC_REST_Stripe_Settings_Controller( $this->get_gateway() ); + add_action( 'rest_api_init', [ $this, 'deregister_wc_blocks_rest_api' ], 5 ); // Set the user so that we can pass the authentication. @@ -80,6 +91,37 @@ public function tear_down() { delete_option( WC_Stripe_Feature_Flags::AMAZON_PAY_FEATURE_FLAG_NAME ); } + /** + * @dataProvider stripe_payment_method_configurations_provider + */ + public function test_get_stripe_payment_method_configurations_settings( $enabled_payment_method_ids, $disabled_payment_method_ids ) { + $this->mock_payment_method_configurations( $enabled_payment_method_ids, $disabled_payment_method_ids ); + + $response = $this->controller->get_settings(); + $this->assertEquals( 200, $response->get_status() ); + foreach ( $enabled_payment_method_ids as $payment_method ) { + $this->assertContains( $payment_method, $response->get_data()['enabled_payment_method_ids'] ); + } + foreach ( $disabled_payment_method_ids as $payment_method ) { + $this->assertNotContains( $payment_method, $response->get_data()['enabled_payment_method_ids'] ); + } + } + + /** + * Test that the update_settings method updates the payment method configurations settings. + */ + public function test_update_stripe_payment_method_configurations_settings() { + $this->mock_payment_method_configurations( [ 'card' ], [] ); + $this->expect_payment_method_configurations_update( [ 'amazon_pay', 'card' ] ); + + $request = new WP_REST_Request( 'POST', self::SETTINGS_ROUTE ); + $request->set_param( 'enabled_payment_method_ids', [ 'amazon_pay', 'card' ] ); + $request->set_param( 'is_upe_enabled', true ); + + $response = $this->controller->update_settings( $request ); + $this->assertEquals( 200, $response->get_status() ); + } + /** * @dataProvider boolean_field_provider */ @@ -322,13 +364,15 @@ public function test_get_settings_returns_ordered_payment_method_ids() { public function test_get_settings_fails_if_user_cannot_manage_woocommerce() { $cb = $this->create_can_manage_woocommerce_cap_override( false ); add_filter( 'user_has_cap', $cb ); - $response = $this->rest_get_settings(); + $request = new WP_REST_Request( 'GET', self::SETTINGS_ROUTE ); + $response = rest_do_request( $request ); $this->assertEquals( 403, $response->get_status() ); remove_filter( 'user_has_cap', $cb ); $cb = $this->create_can_manage_woocommerce_cap_override( true ); add_filter( 'user_has_cap', $cb ); - $response = $this->rest_get_settings(); + $request = new WP_REST_Request( 'GET', self::SETTINGS_ROUTE ); + $response = rest_do_request( $request ); $this->assertEquals( 200, $response->get_status() ); remove_filter( 'user_has_cap', $cb ); } @@ -375,16 +419,17 @@ public function boolean_field_provider() { ]; } + public function stripe_payment_method_configurations_provider() { + return [ + 'amazon_pay' => [ [ 'amazon_pay' ], [] ], + 'amazon_pay' => [ [], [ 'amazon_pay' ] ], + 'card' => [ [ 'card', 'link' ], [] ], + 'card' => [ [], [ 'card', 'link' ] ], + ]; + } + public function enum_field_provider() { return [ - 'enabled_payment_method_ids' => [ - 'enabled_payment_method_ids', - 'upe_checkout_experience_accepted_payments', - [ WC_Stripe_Payment_Methods::CARD ], - [ WC_Stripe_Payment_Methods::CARD, WC_Stripe_Payment_Methods::ALIPAY ], - [ 'foo' ], - true, - ], 'payment_request_button_theme' => [ 'payment_request_button_theme', 'payment_request_button_theme', @@ -454,7 +499,7 @@ public function deregister_wc_blocks_rest_api() { private function rest_get_settings() { $request = new WP_REST_Request( 'GET', self::SETTINGS_ROUTE ); - return rest_do_request( $request ); + return $this->controller->get_settings( $request ); } /** diff --git a/tests/phpunit/admin/test-wc-stripe-admin-notices.php b/tests/phpunit/admin/test-wc-stripe-admin-notices.php index 759e3391c6..133bb36f05 100644 --- a/tests/phpunit/admin/test-wc-stripe-admin-notices.php +++ b/tests/phpunit/admin/test-wc-stripe-admin-notices.php @@ -1,6 +1,6 @@ mock_payment_method_configurations( [ - 'upe_checkout_experience_accepted_payments' => [ - WC_Stripe_Payment_Methods::GIROPAY, - WC_Stripe_Payment_Methods::BANCONTACT, - WC_Stripe_Payment_Methods::EPS, - ], + WC_Stripe_Payment_Methods::GIROPAY, + WC_Stripe_Payment_Methods::BANCONTACT, + WC_Stripe_Payment_Methods::EPS, ] ); - WC_Stripe_Helper::update_main_stripe_settings( $stripe_settings ); update_option( 'wc_stripe_show_style_notice', 'no' ); update_option( 'home', 'https://...' ); diff --git a/tests/phpunit/bootstrap.php b/tests/phpunit/bootstrap.php index 0fc6adf3c2..e6fd231361 100644 --- a/tests/phpunit/bootstrap.php +++ b/tests/phpunit/bootstrap.php @@ -51,6 +51,9 @@ function _manually_load_plugin() { require $_tests_dir . '/includes/bootstrap.php'; +# Load the WC Mock Stripe API Unit Test Case +require_once __DIR__ . '/wc-mock-stripe-api-unit-test-case.php'; + # Load WooCommerce Helpers (https://github.com/woocommerce/woocommerce/tree/master/tests/legacy/framework/helpers) # To keep the plugin self-contained, copy any needed helper to the `helpers/` sub-folder. require_once __DIR__ . '/helpers/class-upe-test-helper.php'; diff --git a/tests/phpunit/helpers/class-upe-test-helper.php b/tests/phpunit/helpers/class-upe-test-helper.php index 0d39ee74f8..1aa6d75c62 100644 --- a/tests/phpunit/helpers/class-upe-test-helper.php +++ b/tests/phpunit/helpers/class-upe-test-helper.php @@ -4,6 +4,16 @@ * Provides methods useful when testing UPE-related logic. */ class UPE_Test_Helper { + /** + * Creates a mock object for the specified class + * + * @param string $class_name Name of the class to mock + * @return PHPUnit\Framework\MockObject\MockObject + */ + private function create_mock( $class_name ) { + $mock_builder = new PHPUnit\Framework\MockObject\Generator(); + return $mock_builder->getMock( $class_name ); + } public function enable_upe_feature_flag() { // Force the UPE feature flag on. diff --git a/tests/phpunit/helpers/class-wc-helper-stripe-api.php b/tests/phpunit/helpers/class-wc-helper-stripe-api.php index 5cf9c14e02..689e6dac2f 100644 --- a/tests/phpunit/helpers/class-wc-helper-stripe-api.php +++ b/tests/phpunit/helpers/class-wc-helper-stripe-api.php @@ -11,7 +11,7 @@ * This helper class should ONLY be used for unit tests!. * This helper class is used to mock static functions of WC_Stripe_API */ -class WC_Helper_Stripe_Api { +class WC_Helper_Stripe_Api extends WC_Stripe_API { /** * Retrieve response. diff --git a/tests/phpunit/payment-methods/test-class-wc-stripe-upe-payment-gateway-gb.php b/tests/phpunit/payment-methods/test-class-wc-stripe-upe-payment-gateway-gb.php index 64749c7abd..a69a37c7d0 100644 --- a/tests/phpunit/payment-methods/test-class-wc-stripe-upe-payment-gateway-gb.php +++ b/tests/phpunit/payment-methods/test-class-wc-stripe-upe-payment-gateway-gb.php @@ -2,7 +2,7 @@ /** * Unit tests for the UPE payment gateway */ -class WC_Stripe_UPE_Payment_Gateway_Test_GB extends WP_UnitTestCase { +class WC_Stripe_UPE_Payment_Gateway_Test_GB extends WC_Mock_Stripe_API_Unit_Test_Case { /** * Initial setup. */ @@ -89,17 +89,4 @@ public function get_upe_available_payment_methods_provider() { ], ]; } - - /** - * @param array $account_data - * - * @return void - */ - private function set_stripe_account_data( $account_data ) { - WC_Stripe::get_instance()->account = $this->getMockBuilder( 'WC_Stripe_Account' ) - ->disableOriginalConstructor() - ->setMethods( [ 'get_cached_account_data' ] ) - ->getMock(); - WC_Stripe::get_instance()->account->method( 'get_cached_account_data' )->willReturn( $account_data ); - } } diff --git a/tests/phpunit/payment-methods/test-class-wc-stripe-upe-payment-gateway.php b/tests/phpunit/payment-methods/test-class-wc-stripe-upe-payment-gateway.php index aadbaba01d..d02efd1e12 100644 --- a/tests/phpunit/payment-methods/test-class-wc-stripe-upe-payment-gateway.php +++ b/tests/phpunit/payment-methods/test-class-wc-stripe-upe-payment-gateway.php @@ -5,7 +5,7 @@ /** * Unit tests for the UPE payment gateway */ -class WC_Stripe_UPE_Payment_Gateway_Test extends WP_UnitTestCase { +class WC_Stripe_UPE_Payment_Gateway_Test extends WC_Mock_Stripe_API_Unit_Test_Case { /** * Mock UPE Gateway * @@ -21,11 +21,11 @@ class WC_Stripe_UPE_Payment_Gateway_Test extends WP_UnitTestCase { private $mock_stripe_customer; /** - * Array mapping Stripe IDs to mock WC_Stripe_UPE_Payment_Methods. + * Array of available payment methods. * * @var array */ - private $mock_payment_methods; + private $available_payment_methods; /** * Mocked value of return_url. @@ -262,13 +262,7 @@ public function test_get_upe_enabled_at_checkout_payment_method_ids() { WC_Stripe_UPE_Payment_Method_CC::STRIPE_ID, WC_Stripe_UPE_Payment_Method_Link::STRIPE_ID, ]; - $this->mock_gateway->update_option( - 'upe_checkout_experience_accepted_payments', - [ - WC_Stripe_Payment_Methods::CARD, - WC_Stripe_Payment_Methods::LINK, - ] - ); + $this->mock_payment_method_configurations( $available_payment_methods ); $this->assertSame( $available_payment_methods, $this->mock_gateway->get_upe_enabled_at_checkout_payment_method_ids() ); } @@ -2276,6 +2270,8 @@ public function test_process_payment_deferred_intent_with_existing_intent() { $currency = $order->get_currency(); $order_id = $order->get_id(); + list( $amount ) = $this->get_order_details( $order ); + $mock_intent = (object) wp_parse_args( [ 'payment_method' => 'pm_mock', @@ -2290,6 +2286,7 @@ public function test_process_payment_deferred_intent_with_existing_intent() { ], ], 'status' => WC_Stripe_Intent_Status::REQUIRES_ACTION, + 'amount' => $amount, ], self::MOCK_CARD_PAYMENT_INTENT_TEMPLATE ); @@ -2425,6 +2422,7 @@ public function test_process_payment_creates_new_intent_when_existing_intent_fai $order_id = $order->get_id(); $mock_payment_method = (object) self::MOCK_CARD_PAYMENT_METHOD_TEMPLATE; + list( $amount ) = $this->get_order_details( $order ); // Create a mock failed payment intent that would be attached to the order $mock_failed_intent = (object) wp_parse_args( @@ -2436,6 +2434,7 @@ public function test_process_payment_creates_new_intent_when_existing_intent_fai 'charges' => (object) [ 'data' => [], ], + 'amount' => $amount, ], self::MOCK_CARD_PAYMENT_INTENT_TEMPLATE ); @@ -2653,19 +2652,6 @@ public function provide_test_filter_saved_payment_methods_list() { ]; } - /** - * @param array $account_data - * - * @return void - */ - private function set_stripe_account_data( $account_data ) { - WC_Stripe::get_instance()->account = $this->getMockBuilder( 'WC_Stripe_Account' ) - ->disableOriginalConstructor() - ->setMethods( [ 'get_cached_account_data' ] ) - ->getMock(); - WC_Stripe::get_instance()->account->method( 'get_cached_account_data' )->willReturn( $account_data ); - } - /** * Test test_set_payment_method_title_for_order. * diff --git a/tests/phpunit/payment-methods/test-class-wc-stripe-upe-payment-method.php b/tests/phpunit/payment-methods/test-class-wc-stripe-upe-payment-method.php index 66cf6d2064..6a652e7484 100644 --- a/tests/phpunit/payment-methods/test-class-wc-stripe-upe-payment-method.php +++ b/tests/phpunit/payment-methods/test-class-wc-stripe-upe-payment-method.php @@ -2,7 +2,7 @@ /** * Unit tests for UPE payment methods */ -class WC_Stripe_UPE_Payment_Method_Test extends WP_UnitTestCase { +class WC_Stripe_UPE_Payment_Method_Test extends WC_Mock_Stripe_API_Unit_Test_Case { /** * Array of mocked UPE payment methods. * @@ -936,46 +936,30 @@ public function test_update_payment_token() { } /** - * Tests that UPE methods are only enabled if Stripe is enabled and the individual methods is enabled in the settings. + * Tests that UPE methods are only enabled if Stripe is enabled. */ public function test_upe_method_enabled() { - // Enable Stripe and reset the accepted payment methods. $stripe_settings = WC_Stripe_Helper::get_stripe_settings(); $stripe_settings['enabled'] = 'yes'; - $stripe_settings['upe_checkout_experience_accepted_payments'] = []; WC_Stripe_Helper::update_main_stripe_settings( $stripe_settings ); - // For each method we'll test the following combinations: - $stripe_enabled_settings = [ 'yes', 'no', '' ]; - $upe_method_enabled_options = [ true, false ]; + $this->mock_payment_method_configurations( [ WC_Stripe_Payment_Methods::LINK ], [] ); - foreach ( WC_Stripe_UPE_Payment_Gateway::UPE_AVAILABLE_METHODS as $payment_method ) { - foreach ( $stripe_enabled_settings as $stripe_enabled ) { - foreach ( $upe_method_enabled_options as $upe_method_enabled_option ) { - // Update the settings. - $stripe_settings['enabled'] = $stripe_enabled; - - $payment_method_index = array_search( $payment_method::STRIPE_ID, $stripe_settings['upe_checkout_experience_accepted_payments'] ); - - if ( $upe_method_enabled_option && false === $payment_method_index ) { - $stripe_settings['upe_checkout_experience_accepted_payments'][] = $payment_method::STRIPE_ID; - } elseif ( ! $upe_method_enabled_option && false !== $payment_method_index ) { - unset( $stripe_settings['upe_checkout_experience_accepted_payments'][ $payment_method_index ] ); - } + $link_upe_method = new WC_Stripe_UPE_Payment_Method_Link(); + $this->assertTrue( $link_upe_method->is_enabled() ); + } - WC_Stripe_Helper::update_main_stripe_settings( $stripe_settings ); + /** + * Tests that UPE methods are not enabled if Stripe is disabled. + */ + public function test_upe_method_disabled() { + $stripe_settings = WC_Stripe_Helper::get_stripe_settings(); + $stripe_settings['enabled'] = 'no'; + WC_Stripe_Helper::update_main_stripe_settings( $stripe_settings ); - // Verify that the payment method is enabled/disabled. - $payment_method_instance = new $payment_method(); + $this->mock_payment_method_configurations( [ WC_Stripe_Payment_Methods::LINK ], [] ); - // The UPE method is only enabled if Stripe is enabled and the method is enabled in the settings. - if ( 'yes' === $stripe_enabled && $upe_method_enabled_option ) { - $this->assertTrue( $payment_method_instance->is_enabled() ); - } else { - $this->assertFalse( $payment_method_instance->is_enabled() ); - } - } - } - } + $link_upe_method = new WC_Stripe_UPE_Payment_Method_Link(); + $this->assertFalse( $link_upe_method->is_enabled() ); } } diff --git a/tests/phpunit/payment-methods/test-wc-stripe-payment-request.php b/tests/phpunit/payment-methods/test-wc-stripe-payment-request.php index 0f5fdf1297..914ccd4854 100644 --- a/tests/phpunit/payment-methods/test-wc-stripe-payment-request.php +++ b/tests/phpunit/payment-methods/test-wc-stripe-payment-request.php @@ -8,7 +8,7 @@ /** * WC_Stripe_Payment_Request_Test class. */ -class WC_Stripe_Payment_Request_Test extends WP_UnitTestCase { +class WC_Stripe_Payment_Request_Test extends WC_Mock_Stripe_API_Unit_Test_Case { const SHIPPING_ADDRESS = [ 'country' => 'US', 'state' => 'CA', @@ -193,15 +193,7 @@ public function test_is_at_least_one_payment_request_button_enabled_link_enabled $this->pr->stripe_settings = [ 'payment_request' => false ]; $this->upe_helper->enable_upe(); - - WC_Stripe_Helper::update_main_stripe_settings( - array_merge( - WC_Stripe_Helper::get_stripe_settings(), - [ - 'upe_checkout_experience_accepted_payments' => [ 'link' ], - ] - ) - ); + $this->mock_payment_method_configurations( [ WC_Stripe_Payment_Methods::LINK ], [] ); $this->assertTrue( $this->pr->is_at_least_one_payment_request_button_enabled() ); } @@ -216,15 +208,7 @@ public function test_is_at_least_one_payment_request_button_enabled_none_enabled // Disable Apple Pay/Google Pay $this->pr->stripe_settings = [ 'payment_request' => false ]; - // Disable Link by Stripe - WC_Stripe_Helper::update_main_stripe_settings( - array_merge( - WC_Stripe_Helper::get_stripe_settings(), - [ - 'upe_checkout_experience_accepted_payments' => [ WC_Stripe_Payment_Methods::CARD ], - ] - ) - ); + $this->mock_payment_method_configurations( [ WC_Stripe_Payment_Methods::CARD ], [] ); $this->assertFalse( $this->pr->is_at_least_one_payment_request_button_enabled() ); } diff --git a/tests/phpunit/test-class-wc-stripe-notes.php b/tests/phpunit/test-class-wc-stripe-notes.php index cfbcfd33b1..75286dbcde 100644 --- a/tests/phpunit/test-class-wc-stripe-notes.php +++ b/tests/phpunit/test-class-wc-stripe-notes.php @@ -8,9 +8,7 @@ /** * Class WC_Stripe_Inbox_Notes_Note tests. */ -class WC_Stripe_Inbox_Notes_Test extends WP_UnitTestCase { - // public static $global_woocommerce_gateway_stripe; - +class WC_Stripe_Inbox_Notes_Test extends WC_Mock_Stripe_API_Unit_Test_Case { public $stripe_connect_mock; public $stripe_connect_original; @@ -24,6 +22,9 @@ public function set_up() { $this->stripe_connect_original = woocommerce_gateway_stripe()->connect; woocommerce_gateway_stripe()->connect = $this->stripe_connect_mock; + $this->stripe_api = $this->createMock( WC_Stripe_API::class ); + WC_Stripe_API::set_instance( $this->stripe_api ); + if ( version_compare( WC_VERSION, '4.4.0', '<' ) ) { $this->markTestSkipped( 'The used WC components are not backward compatible' ); return; @@ -47,28 +48,25 @@ public function tear_down() { } public function test_create_upe_availability_note() { - + WC_Stripe_Helper::update_main_stripe_settings( [ 'enabled' => 'yes' ] ); WC_Stripe_Inbox_Notes::create_upe_notes(); $admin_note_store = WC_Data_Store::load( 'admin-note' ); $this->assertSame( 1, count( $admin_note_store->get_notes_with_name( WC_Stripe_UPE_Availability_Note::NOTE_NAME ) ) ); } public function test_create_upe_stripelink_note() { + $upe_helper = new UPE_Test_Helper(); + $upe_helper->enable_upe(); + $upe_helper->reload_payment_gateways(); + WC_Stripe_Helper::update_main_stripe_settings( [ 'enabled' => 'yes', 'upe_checkout_experience_enabled' => 'yes', ] ); - WC_Stripe::get_instance()->account = $this->getMockBuilder( 'WC_Stripe_Account' ) - ->disableOriginalConstructor() - ->setMethods( - [ - 'get_cached_account_data', - ] - ) - ->getMock(); - WC_Stripe::get_instance()->account->method( 'get_cached_account_data' )->willReturn( [ 'country' => 'US' ] ); + $this->mock_payment_method_configurations( [ WC_Stripe_Payment_Methods::LINK, WC_Stripe_Payment_Methods::CARD ] ); + $this->set_stripe_account_data( [ 'country' => 'US' ] ); WC_Stripe_Inbox_Notes::create_upe_notes(); $admin_note_store = WC_Data_Store::load( 'admin-note' ); $this->assertSame( 1, count( $admin_note_store->get_notes_with_name( WC_Stripe_UPE_StripeLink_Note::NOTE_NAME ) ) ); @@ -84,21 +82,19 @@ public function test_create_upe_notes_does_not_create_note_when_upe_preview_is_d } public function test_create_upe_notes_does_not_create_availability_note_when_upe_is_enbled() { + $upe_helper = new UPE_Test_Helper(); + $upe_helper->enable_upe(); + $upe_helper->reload_payment_gateways(); + WC_Stripe_Helper::update_main_stripe_settings( [ 'enabled' => 'yes', 'upe_checkout_experience_enabled' => 'yes', ] ); - WC_Stripe::get_instance()->account = $this->getMockBuilder( 'WC_Stripe_Account' ) - ->disableOriginalConstructor() - ->setMethods( - [ - 'get_cached_account_data', - ] - ) - ->getMock(); - WC_Stripe::get_instance()->account->method( 'get_cached_account_data' )->willReturn( [ 'country' => 'US' ] ); + + $this->set_stripe_account_data( [ 'country' => 'US' ] ); + $this->mock_payment_method_configurations( [ WC_Stripe_Payment_Methods::LINK, WC_Stripe_Payment_Methods::CARD ] ); WC_Stripe_Inbox_Notes::create_upe_notes(); $admin_note_store = WC_Data_Store::load( 'admin-note' ); @@ -144,7 +140,7 @@ public function test_create_stripelink_note_unavailable_if_cc_not_enabled() { ] ); - $this->set_enabled_payment_methods( [ 'test' ] ); + $this->mock_payment_method_configurations( [ 'test' ] ); WC_Stripe_Inbox_Notes::create_upe_notes(); $admin_note_store = WC_Data_Store::load( 'admin-note' ); @@ -160,30 +156,11 @@ public function test_create_stripelink_note_unavailable_link_enabled() { ] ); - $this->set_enabled_payment_methods( [ WC_Stripe_Payment_Methods::CARD, WC_Stripe_Payment_Methods::LINK ] ); + $this->mock_payment_method_configurations( [ WC_Stripe_Payment_Methods::CARD, WC_Stripe_Payment_Methods::LINK ] ); - WC_Stripe_Helper::update_main_stripe_settings( - array_merge( - WC_Stripe_Helper::get_stripe_settings(), - [ - 'upe_checkout_experience_accepted_payments' => [ WC_Stripe_Payment_Methods::CARD, WC_Stripe_Payment_Methods::LINK ], - ] - ) - ); WC_Stripe_Inbox_Notes::create_upe_notes(); $admin_note_store = WC_Data_Store::load( 'admin-note' ); $this->assertSame( 0, count( $admin_note_store->get_notes_with_name( WC_Stripe_UPE_StripeLink_Note::NOTE_NAME ) ) ); } - - private function set_enabled_payment_methods( $payment_methods ) { - WC_Stripe_Helper::update_main_stripe_settings( - array_merge( - WC_Stripe_Helper::get_stripe_settings(), - [ - 'upe_checkout_experience_accepted_payments' => $payment_methods, - ] - ) - ); - } } diff --git a/tests/phpunit/test-wc-rest-stripe-account-keys-controller.php b/tests/phpunit/test-wc-rest-stripe-account-keys-controller.php index a3aa4b42f2..9c72f0f33d 100644 --- a/tests/phpunit/test-wc-rest-stripe-account-keys-controller.php +++ b/tests/phpunit/test-wc-rest-stripe-account-keys-controller.php @@ -8,7 +8,7 @@ /** * WC_REST_Stripe_Account_Keys_Controller unit tests. */ -class WC_REST_Stripe_Account_Keys_Controller_Test extends WP_UnitTestCase { +class WC_REST_Stripe_Account_Keys_Controller_Test extends WC_Mock_Stripe_API_Unit_Test_Case { /** * Tested REST route. */ @@ -162,16 +162,11 @@ public function test_changing_keys_resets_payment_methods() { $request->set_param( 'publishable_key', '' ); // Set initial payment methods - $upe_gateway = new WC_Stripe_UPE_Payment_Gateway(); - $upe_gateway->update_option( 'upe_checkout_experience_accepted_payments', [ WC_Stripe_Payment_Methods::CARD, WC_Stripe_Payment_Methods::LINK, WC_Stripe_Payment_Methods::SEPA, WC_Stripe_Payment_Methods::IDEAL ] ); + $this->set_stripe_account_data( [ 'country' => 'US' ] ); + $this->mock_payment_method_configurations( [ WC_Stripe_Payment_Methods::CARD, WC_Stripe_Payment_Methods::LINK, WC_Stripe_Payment_Methods::SEPA, WC_Stripe_Payment_Methods::IDEAL ], [] ); + $this->expect_payment_method_configurations_update( [ WC_Stripe_Payment_Methods::CARD, WC_Stripe_Payment_Methods::LINK ] ); $this->controller->set_account_keys( $request ); - - // Retrieve the current enabled payment methods - $upe_gateway = new WC_Stripe_UPE_Payment_Gateway(); - $enabled_methods = count( $upe_gateway->get_option( 'upe_checkout_experience_accepted_payments' ) ); - - $this->assertEquals( 2, $enabled_methods ); // card and link are default payments } /** diff --git a/tests/phpunit/test-wc-stripe.php b/tests/phpunit/test-wc-stripe.php index ee588df624..8cb0449dab 100644 --- a/tests/phpunit/test-wc-stripe.php +++ b/tests/phpunit/test-wc-stripe.php @@ -1,6 +1,6 @@ upe_helper = new UPE_Test_Helper(); + $this->set_stripe_account_data( [ 'country' => 'US' ] ); } public function test_constants_defined() { @@ -142,6 +143,8 @@ public function test_turning_on_upe_with_no_stripe_legacy_payment_methods_enable $stripe_settings = WC_Stripe_Helper::get_stripe_settings(); $this->assertEquals( 'no', $stripe_settings['enabled'] ); $this->assertEquals( 'no', $stripe_settings['upe_checkout_experience_enabled'] ); + $this->mock_payment_method_configurations( [], [] ); + $this->expect_payment_method_configurations_update( [ WC_Stripe_Payment_Methods::CARD, WC_Stripe_Payment_Methods::LINK ], [] ); $stripe_settings['upe_checkout_experience_enabled'] = 'yes'; WC_Stripe_Helper::update_main_stripe_settings( $stripe_settings ); @@ -150,17 +153,19 @@ public function test_turning_on_upe_with_no_stripe_legacy_payment_methods_enable // Because no Stripe LPM's were enabled when UPE was enabled, the Stripe gateway is not enabled yet. $this->assertEquals( 'no', $stripe_settings['enabled'] ); $this->assertEquals( 'yes', $stripe_settings['upe_checkout_experience_enabled'] ); - $this->assertContains( WC_Stripe_Payment_Methods::CARD, $stripe_settings['upe_checkout_experience_accepted_payments'] ); - $this->assertContains( WC_Stripe_Payment_Methods::LINK, $stripe_settings['upe_checkout_experience_accepted_payments'] ); - $this->assertCount( 2, $stripe_settings['upe_checkout_experience_accepted_payments'] ); } - public function test_turning_on_upe_enables_the_correct_upe_methods_based_on_which_legacy_payment_methods_were_enabled_and_vice_versa() { + public function test_turning_on_upe_enables_the_correct_upe_methods_based_on_which_legacy_payment_methods_were_enabled() { + update_option( 'woocommerce_currency', 'EUR' ); $this->upe_helper->enable_upe_feature_flag(); - // Enable Alipay and iDEAL LPM gateways. - update_option( 'woocommerce_stripe_alipay_settings', [ 'enabled' => 'yes' ] ); + // Enable the EPS UPE method. Now when UPE is disabled, the EPS LPM should be enabled. + $this->mock_payment_method_configurations( [ WC_Stripe_Payment_Methods::EPS, WC_Stripe_Payment_Methods::SEPA_DEBIT, WC_Stripe_Payment_Methods::IDEAL ] ); + + // Enable sepa and iDEAL LPM gateways. + update_option( 'woocommerce_stripe_sepa_settings', [ 'enabled' => 'yes' ] ); update_option( 'woocommerce_stripe_ideal_settings', [ 'enabled' => 'yes' ] ); + $this->expect_payment_method_configurations_update( [ WC_Stripe_Payment_Methods::SEPA_DEBIT, WC_Stripe_Payment_Methods::IDEAL ], [ WC_Stripe_Payment_Methods::CARD ] ); $this->upe_helper->reload_payment_gateways(); // Initialize default stripe settings, turn on UPE. @@ -169,20 +174,28 @@ public function test_turning_on_upe_enables_the_correct_upe_methods_based_on_whi $stripe_settings = WC_Stripe_Helper::get_stripe_settings(); $this->assertEquals( 'yes', $stripe_settings['enabled'] ); $this->assertEquals( 'yes', $stripe_settings['upe_checkout_experience_enabled'] ); - $this->assertNotContains( WC_Stripe_Payment_Methods::CARD, $stripe_settings['upe_checkout_experience_accepted_payments'] ); - $this->assertContains( WC_Stripe_Payment_Methods::ALIPAY, $stripe_settings['upe_checkout_experience_accepted_payments'] ); - $this->assertContains( WC_Stripe_Payment_Methods::IDEAL, $stripe_settings['upe_checkout_experience_accepted_payments'] ); - // Make sure the Alipay and iDEAL LPMs were disabled. - $alipay_settings = get_option( 'woocommerce_stripe_alipay_settings' ); - $this->assertEquals( 'no', $alipay_settings['enabled'] ); + // Make sure the SEPA and iDEAL LPMs were disabled. + $sepa_settings = get_option( 'woocommerce_stripe_sepa_settings' ); + $this->assertEquals( 'no', $sepa_settings['enabled'] ); $ideal_settings = get_option( 'woocommerce_stripe_ideal_settings' ); $this->assertEquals( 'no', $ideal_settings['enabled'] ); + } - // Enable the EPS UPE method. Now when UPE is disabled, the EPS LPM should be enabled. - $stripe_settings['upe_checkout_experience_accepted_payments'][] = WC_Stripe_Payment_Methods::EPS; + public function test_turning_off_upe_enables_the_correct_legacy_payment_methods_based_on_which_upe_payment_methods_were_enabled() { + update_option( 'woocommerce_currency', 'EUR' ); + $this->upe_helper->enable_upe_feature_flag(); + + // Disable sepa and iDEAL LPM gateways. + update_option( 'woocommerce_stripe_sepa_settings', [ 'enabled' => 'no' ] ); + update_option( 'woocommerce_stripe_ideal_settings', [ 'enabled' => 'no' ] ); + + // Turn UPE on first. + $stripe_settings['upe_checkout_experience_enabled'] = 'yes'; WC_Stripe_Helper::update_main_stripe_settings( $stripe_settings ); + $this->mock_payment_method_configurations( [ WC_Stripe_Payment_Methods::SEPA_DEBIT, WC_Stripe_Payment_Methods::IDEAL ] ); + // Turn UPE off. $stripe_settings['upe_checkout_experience_enabled'] = 'no'; WC_Stripe_Helper::update_main_stripe_settings( $stripe_settings ); @@ -191,11 +204,9 @@ public function test_turning_on_upe_enables_the_correct_upe_methods_based_on_whi $stripe_settings = WC_Stripe_Helper::get_stripe_settings(); $this->assertEquals( 'no', $stripe_settings['enabled'] ); // Check that the correct LPMs were re-enabled. - $alipay_settings = get_option( 'woocommerce_stripe_alipay_settings' ); - $this->assertEquals( 'yes', $alipay_settings['enabled'] ); + $sepa_settings = get_option( 'woocommerce_stripe_sepa_settings' ); + $this->assertEquals( 'yes', $sepa_settings['enabled'] ); $ideal_settings = get_option( 'woocommerce_stripe_ideal_settings' ); $this->assertEquals( 'yes', $ideal_settings['enabled'] ); - $eps_settings = get_option( 'woocommerce_stripe_eps_settings' ); - $this->assertEquals( 'yes', $eps_settings['enabled'] ); } } diff --git a/tests/phpunit/wc-mock-stripe-api-unit-test-case.php b/tests/phpunit/wc-mock-stripe-api-unit-test-case.php new file mode 100644 index 0000000000..94fa57ef6c --- /dev/null +++ b/tests/phpunit/wc-mock-stripe-api-unit-test-case.php @@ -0,0 +1,110 @@ +stripe_api = $this->createMock( WC_Stripe_API::class ); + WC_Stripe_API::set_instance( $this->stripe_api ); + } + + /** + * Tear down. + */ + public function tear_down() { + parent::tear_down(); + WC_Stripe_Payment_Method_Configurations::reset_primary_configuration(); + } + + /** + * Expect payment method configuration to be updated with enabled payment method IDs and disabled payment method IDs. + * + * @param array $enabled_payment_method_ids + * @param array $disabled_payment_method_ids + */ + protected function expect_payment_method_configurations_update( $enabled_payment_method_ids = [], $disabled_payment_method_ids = [] ) { + $this->stripe_api->expects( $this->once() )->method( 'update_payment_method_configurations' )->with( + $this->equalTo( 'pmc_abcdef' ), + $this->callback( + function( $actual ) use ( $enabled_payment_method_ids, $disabled_payment_method_ids ) { + foreach ( $enabled_payment_method_ids as $payment_method ) { + if ( ! isset( $actual[ $payment_method ] ) || 'on' !== $actual[ $payment_method ]['display_preference']['preference'] ) { + return false; + } + } + foreach ( $disabled_payment_method_ids as $payment_method ) { + if ( ! isset( $actual[ $payment_method ] ) || 'off' !== $actual[ $payment_method ]['display_preference']['preference'] ) { + return false; + } + } + return true; + } + ) + ); + } + + /** + * Mock the payment method configurations. + * + * @param array $enabled_payment_method_ids + * @param array $disabled_payment_method_ids + */ + protected function mock_payment_method_configurations( $enabled_payment_method_ids = [], $disabled_payment_method_ids = [] ) { + $payment_method_configuration = [ + 'id' => 'pmc_abcdef', + 'object' => 'payment_method_configuration', + 'active' => true, + 'parent' => WC_Stripe_Payment_Method_Configurations::TEST_MODE_CONFIGURATION_PARENT_ID, + 'livemode' => false, + ]; + + foreach ( $enabled_payment_method_ids as $payment_method ) { + $payment_method_configuration[ $payment_method ] = (object) [ + 'display_preference' => (object) [ 'value' => 'on' ], + ]; + } + + foreach ( $disabled_payment_method_ids as $payment_method ) { + $payment_method_configuration[ $payment_method ] = (object) [ + 'display_preference' => (object) [ 'value' => 'off' ], + ]; + } + + $this->stripe_api->method( 'get_payment_method_configurations' )->willReturn( + (object) [ + 'data' => [ + (object) $payment_method_configuration, + ], + ], + ); + } + + /** + * @param array $account_data + * + * @return void + */ + protected function set_stripe_account_data( $account_data ) { + WC_Stripe::get_instance()->account = $this->getMockBuilder( 'WC_Stripe_Account' ) + ->disableOriginalConstructor() + ->setMethods( [ 'get_cached_account_data' ] ) + ->getMock(); + WC_Stripe::get_instance()->account->method( 'get_cached_account_data' )->willReturn( $account_data ); + } +} diff --git a/woocommerce-gateway-stripe.php b/woocommerce-gateway-stripe.php index 23ae15ca23..fbf3f6de48 100644 --- a/woocommerce-gateway-stripe.php +++ b/woocommerce-gateway-stripe.php @@ -198,6 +198,7 @@ public function init() { require_once __DIR__ . '/includes/class-wc-stripe-exception.php'; require_once __DIR__ . '/includes/class-wc-stripe-logger.php'; require_once __DIR__ . '/includes/class-wc-stripe-helper.php'; + require_once __DIR__ . '/includes/class-wc-stripe-payment-method-configurations.php'; include_once __DIR__ . '/includes/class-wc-stripe-api.php'; include_once __DIR__ . '/includes/class-wc-stripe-mode.php'; require_once __DIR__ . '/includes/compat/class-wc-stripe-subscriptions-helper.php'; @@ -620,7 +621,7 @@ protected function toggle_upe( $settings, $old_settings ) { } protected function enable_upe( $settings ) { - $settings['upe_checkout_experience_accepted_payments'] = []; + $payment_methods_to_enable = []; $payment_gateways = WC_Stripe_Helper::get_legacy_payment_methods(); foreach ( WC_Stripe_UPE_Payment_Gateway::UPE_AVAILABLE_METHODS as $method_class ) { @@ -646,21 +647,24 @@ protected function enable_upe( $settings ) { 'yes' ); // ENABLE UPE METHOD - $settings['upe_checkout_experience_accepted_payments'][] = $method_class::STRIPE_ID; + $payment_methods_to_enable[] = $method_class::STRIPE_ID; } if ( 'stripe' === $lpm_gateway_id && isset( $this->stripe_gateway ) && $this->stripe_gateway->is_enabled() ) { - $settings['upe_checkout_experience_accepted_payments'][] = 'card'; - $settings['upe_checkout_experience_accepted_payments'][] = 'link'; + $payment_methods_to_enable[] = 'card'; + $payment_methods_to_enable[] = 'link'; } } - if ( empty( $settings['upe_checkout_experience_accepted_payments'] ) ) { - $settings['upe_checkout_experience_accepted_payments'] = [ 'card', 'link' ]; + if ( empty( $payment_methods_to_enable ) ) { + $payment_methods_to_enable = [ 'card', 'link' ]; } else { // The 'stripe' gateway must be enabled for UPE if any LPMs were enabled. $settings['enabled'] = 'yes'; } + $upe_gateway = new WC_Stripe_UPE_Payment_Gateway(); + $upe_gateway->update_enabled_payment_methods( $payment_methods_to_enable ); + return $settings; } @@ -689,9 +693,7 @@ protected function disable_upe( $settings ) { $settings['enabled'] = 'no'; } // DISABLE ALL UPE METHODS - if ( ! isset( $settings['upe_checkout_experience_accepted_payments'] ) ) { - $settings['upe_checkout_experience_accepted_payments'] = []; - } + $upe_gateway->update_enabled_payment_methods( [] ); return $settings; }