Commit 27eb08ac34 for woocommerce
commit 27eb08ac344a9e1dae5294a69640d47977bd956f
Author: Leonardo Lopes de Albuquerque <leonardo.albuquerque@automattic.com>
Date: Mon Jan 12 17:54:50 2026 -0300
[Fraud Protection] Removed jetpack connection button (#62753)
* Removed jetpack connection button
* Added check to prevent accessing an empty variable
* Fixed error message and phstan error
* php lint fixes
* lint fixes
* Removed unecessary variable
* Fixed translators comment
* Fixed the way we try to connect to jetpack
* Added comment to maybe_register_jetpack_connection
* Added since and internal to method
* added log when the automatic jetpack connection fails
diff --git a/plugins/woocommerce/includes/class-woocommerce.php b/plugins/woocommerce/includes/class-woocommerce.php
index c6b1796248..34cdd14483 100644
--- a/plugins/woocommerce/includes/class-woocommerce.php
+++ b/plugins/woocommerce/includes/class-woocommerce.php
@@ -375,7 +375,6 @@ final class WooCommerce {
$container->get( Automattic\WooCommerce\Internal\Orders\OrderAttributionBlocksController::class )->register();
$container->get( Automattic\WooCommerce\Internal\CostOfGoodsSold\CostOfGoodsSoldController::class )->register();
$container->get( Automattic\WooCommerce\Internal\FraudProtection\FraudProtectionController::class )->register();
- $container->get( Automattic\WooCommerce\Internal\FraudProtection\AdminSettingsHandler::class )->register();
$container->get( Automattic\WooCommerce\Internal\Admin\Settings\PaymentsController::class )->register();
$container->get( Automattic\WooCommerce\Internal\Admin\Settings\PaymentsProviders\WooPayments\WooPaymentsController::class )->register();
$container->get( Automattic\WooCommerce\Internal\Utilities\LegacyRestApiStub::class )->register();
diff --git a/plugins/woocommerce/src/Internal/FraudProtection/AdminSettingsHandler.php b/plugins/woocommerce/src/Internal/FraudProtection/AdminSettingsHandler.php
deleted file mode 100644
index d89c2d22ef..0000000000
--- a/plugins/woocommerce/src/Internal/FraudProtection/AdminSettingsHandler.php
+++ /dev/null
@@ -1,158 +0,0 @@
-<?php
-/**
- * AdminSettingsHandler class file.
- */
-
-declare( strict_types=1 );
-
-namespace Automattic\WooCommerce\Internal\FraudProtection;
-
-defined( 'ABSPATH' ) || exit;
-
-/**
- * Handles admin settings for fraud protection.
- *
- * @since 10.5.0
- */
-class AdminSettingsHandler {
-
- /**
- * Jetpack connection manager instance.
- *
- * @var JetpackConnectionManager
- */
- private $connection_manager;
-
- /**
- * Register hooks.
- */
- public function register(): void {
- add_filter( 'woocommerce_get_settings_advanced', array( $this, 'add_jetpack_connection_field' ), 100, 2 );
- add_action( 'woocommerce_admin_field_jetpack_connection', array( $this, 'handle_output_jetpack_connection_field' ), 10, 1 );
- }
-
-
- /**
- * Initialize the class with dependencies.
- *
- * @internal
- *
- * @param JetpackConnectionManager $connection_manager Jetpack connection manager instance.
- * @return void
- */
- final public function init( JetpackConnectionManager $connection_manager ): void {
- $this->connection_manager = $connection_manager;
- }
-
- /**
- * Add Jetpack connection field to fraud protection settings.
- *
- * @internal
- *
- * @param array $settings Existing settings.
- * @param string $current_section Current section name.
- * @return array Modified settings.
- */
- public function add_jetpack_connection_field( $settings, $current_section ): array {
- // Only add on the features section.
- if ( 'features' !== $current_section ) {
- return $settings;
- }
-
- // Check if field already exists to prevent duplicates.
- foreach ( $settings as $setting ) {
- if ( isset( $setting['id'] ) && 'woocommerce_fraud_protection_jetpack_connection' === $setting['id'] ) {
- return $settings;
- }
- }
-
- // Find the fraud_protection field and add Jetpack connection field after it.
- $new_settings = array();
- foreach ( $settings as $setting ) {
- $new_settings[] = $setting;
-
- // Add Jetpack connection field after fraud_protection checkbox.
- if ( isset( $setting['id'] ) && 'woocommerce_feature_fraud_protection_enabled' === $setting['id'] ) {
- $new_settings[] = array(
- 'id' => 'woocommerce_fraud_protection_jetpack_connection',
- 'type' => 'jetpack_connection',
- 'title' => __( 'Jetpack Connection', 'woocommerce' ),
- 'desc' => __( 'Connect your site to Jetpack to enable fraud protection features.', 'woocommerce' ),
- );
- }
- }
-
- return $new_settings;
- }
-
- /**
- * Output the Jetpack connection field.
- *
- * @internal
- *
- * @param array $value Field configuration.
- * @return void
- */
- public function handle_output_jetpack_connection_field( $value ): void { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found
- // Only show Jetpack connection when fraud protection is enabled.
- if ( 'yes' !== get_option( 'woocommerce_feature_fraud_protection_enabled', 'no' ) ) {
- return;
- }
-
- $this->output_jetpack_connection_status();
- }
-
- /**
- * Output the Jetpack connection status and button.
- *
- * @internal
- *
- * @return void
- */
- private function output_jetpack_connection_status(): void {
- // Get connection status from connection manager.
- $connection_status = $this->connection_manager->get_connection_status();
- ?>
- <tr valign="top">
- <th scope="row" class="titledesc">
- <label><?php esc_html_e( 'Jetpack Connection', 'woocommerce' ); ?></label>
- </th>
- <td class="forminp forminp-button">
- <?php if ( ! $connection_status['connected'] ) : ?>
- <?php
- // Get authorization URL for connecting.
- $redirect_url = admin_url( 'admin.php?page=wc-settings&tab=advanced§ion=features' );
- $connection_url = $this->connection_manager->get_authorization_url( $redirect_url );
-
- // If we couldn't get authorization URL, show error message.
- if ( ! $connection_url ) :
- ?>
- <p class="description" style="color: #dc3232;">
- <?php echo esc_html( $connection_status['error'] ); ?>
- </p>
- <?php else : ?>
- <a href="<?php echo esc_url( $connection_url ); ?>" class="button button-secondary jetpack_connection_button">
- <?php esc_html_e( 'Connect to Jetpack', 'woocommerce' ); ?>
- </a>
- <p class="description">
- <?php esc_html_e( 'Connect your site to Jetpack to enable fraud protection features.', 'woocommerce' ); ?>
- </p>
- <?php endif; ?>
- <?php else : ?>
- <span class="dashicons dashicons-yes-alt" style="color: #46b450;"></span>
- <span><?php esc_html_e( 'Connected to Jetpack', 'woocommerce' ); ?></span>
- <p class="description">
- <?php
- printf(
- /* translators: %d: Blog ID */
- esc_html__( 'Site ID: %d', 'woocommerce' ),
- (int) $connection_status['blog_id']
- );
- ?>
- </p>
- <?php endif; ?>
- </td>
- </tr>
- <?php
- }
-}
diff --git a/plugins/woocommerce/src/Internal/FraudProtection/FraudProtectionController.php b/plugins/woocommerce/src/Internal/FraudProtection/FraudProtectionController.php
index 17634d4dad..1039e68e46 100644
--- a/plugins/woocommerce/src/Internal/FraudProtection/FraudProtectionController.php
+++ b/plugins/woocommerce/src/Internal/FraudProtection/FraudProtectionController.php
@@ -8,6 +8,7 @@ declare( strict_types=1 );
namespace Automattic\WooCommerce\Internal\FraudProtection;
use Automattic\WooCommerce\Internal\Features\FeaturesController;
+use Automattic\WooCommerce\Internal\Jetpack\JetpackConnection;
use Automattic\WooCommerce\Internal\RegisterHooksInterface;
defined( 'ABSPATH' ) || exit;
@@ -30,13 +31,6 @@ class FraudProtectionController implements RegisterHooksInterface {
*/
private FeaturesController $features_controller;
- /**
- * Jetpack connection manager instance.
- *
- * @var JetpackConnectionManager
- */
- private JetpackConnectionManager $connection_manager;
-
/**
* Blocked session notice instance.
*
@@ -50,6 +44,7 @@ class FraudProtectionController implements RegisterHooksInterface {
public function register(): void {
add_action( 'init', array( $this, 'on_init' ) );
add_action( 'admin_notices', array( $this, 'on_admin_notices' ) );
+ add_action( FeaturesController::FEATURE_ENABLED_CHANGED_ACTION, array( $this, 'maybe_register_jetpack_connection' ), 10, 2 );
}
/**
@@ -57,17 +52,14 @@ class FraudProtectionController implements RegisterHooksInterface {
*
* @internal
*
- * @param FeaturesController $features_controller The instance of FeaturesController to use.
- * @param JetpackConnectionManager $connection_manager The instance of JetpackConnectionManager to use.
- * @param BlockedSessionNotice $blocked_session_notice The instance of BlockedSessionNotice to use.
+ * @param FeaturesController $features_controller The instance of FeaturesController to use.
+ * @param BlockedSessionNotice $blocked_session_notice The instance of BlockedSessionNotice to use.
*/
final public function init(
FeaturesController $features_controller,
- JetpackConnectionManager $connection_manager,
BlockedSessionNotice $blocked_session_notice
): void {
$this->features_controller = $features_controller;
- $this->connection_manager = $connection_manager;
$this->blocked_session_notice = $blocked_session_notice;
}
@@ -92,35 +84,25 @@ class FraudProtectionController implements RegisterHooksInterface {
*/
public function on_admin_notices(): void {
// Only show if feature is enabled.
- if ( ! $this->feature_is_enabled() ) {
+ if ( ! $this->feature_is_enabled() || JetpackConnection::get_manager()->is_connected() ) {
return;
}
// Only show on WooCommerce settings page.
$screen = get_current_screen();
- if ( ! $screen || 'woocommerce_page_wc-settings' !== $screen->id ) {
- return;
- }
- $connection_status = $this->connection_manager->get_connection_status();
- if ( $connection_status['connected'] ) {
+ if ( ! $screen || 'woocommerce_page_wc-settings' !== $screen->id ) {
return;
}
- $settings_url = admin_url( 'admin.php?page=wc-settings&tab=advanced§ion=features' );
-
?>
<div class="notice notice-warning is-dismissible">
- <p>
- <strong><?php esc_html_e( 'Fraud protection warning:', 'woocommerce' ); ?></strong>
- <?php echo esc_html( $connection_status['error'] ); ?>
- </p>
<p>
<?php
printf(
- /* translators: %s: Settings page URL */
- wp_kses_post( __( 'Fraud protection will fail open and allow all sessions until connected. <a href="%s">Connect to Jetpack</a>', 'woocommerce' ) ),
- esc_url( $settings_url )
+ /* translators: %s: Getting Started with Jetpack documentation URL */
+ wp_kses_post( __( 'Your site failed to connect to Jetpack automatically. Fraud protection will fail open and allow all sessions until your site is connected to Jetpack. <a href="%s">How to connect to Jetpack</a>', 'woocommerce' ) ),
+ esc_url( 'https://jetpack.com/support/getting-started-with-jetpack/' )
);
?>
</p>
@@ -128,6 +110,40 @@ class FraudProtectionController implements RegisterHooksInterface {
<?php
}
+ /**
+ * Maybe register Jetpack connection when fraud protection is enabled.
+ *
+ * Attempts to automatically register the site with Jetpack when the fraud protection
+ * feature is enabled and the site is not already connected.
+ *
+ * @since 10.5.0
+ *
+ * @internal
+ *
+ * @param string $feature_id The feature ID being toggled.
+ * @param bool $is_enabled Whether the feature is being enabled or disabled.
+ */
+ public function maybe_register_jetpack_connection( string $feature_id, bool $is_enabled ): void {
+ if ( 'fraud_protection' !== $feature_id || ! $is_enabled ) {
+ return;
+ }
+
+ $manager = JetpackConnection::get_manager();
+
+ if ( $manager->is_connected() ) {
+ return;
+ }
+
+ $result = $manager->try_registration();
+
+ if ( is_wp_error( $result ) ) {
+ $this->log( 'error', 'Failed to register Jetpack connection: ' . $result->get_error_message() );
+ return;
+ }
+
+ $this->log( 'info', 'Jetpack connection registered successfully' );
+ }
+
/**
* Check if fraud protection feature is enabled.
*
diff --git a/plugins/woocommerce/src/Internal/FraudProtection/JetpackConnectionManager.php b/plugins/woocommerce/src/Internal/FraudProtection/JetpackConnectionManager.php
deleted file mode 100644
index e3e904bd5a..0000000000
--- a/plugins/woocommerce/src/Internal/FraudProtection/JetpackConnectionManager.php
+++ /dev/null
@@ -1,105 +0,0 @@
-<?php
-/**
- * JetpackConnectionManager class file.
- */
-
-declare( strict_types=1 );
-
-namespace Automattic\WooCommerce\Internal\FraudProtection;
-
-use Automattic\WooCommerce\Internal\Jetpack\JetpackConnection;
-
-defined( 'ABSPATH' ) || exit;
-
-/**
- * Manages Jetpack connection status and validation for fraud protection.
- *
- * Provides centralized methods to check connection status, validate requirements,
- * and handle connection-related errors gracefully.
- *
- * @since 10.5.0
- */
-class JetpackConnectionManager {
-
- /**
- * Get the Jetpack blog ID.
- *
- * @return int|null Blog ID if available, null otherwise.
- */
- public function get_blog_id(): ?int {
- // Get blog ID from Jetpack options.
- $blog_id = \Jetpack_Options::get_option( 'id' );
-
- return $blog_id ? (int) $blog_id : null;
- }
-
- /**
- * Get connection status with detailed error information.
- *
- * Returns an array with connection status and any error details.
- *
- * @return array {
- * Connection status information.
- *
- * @type bool $connected Whether the site is connected.
- * @type string $error Error message if not connected.
- * @type string $error_code Error code if not connected.
- * @type int $blog_id Blog ID if available.
- * }
- */
- public function get_connection_status(): array {
- $status = array(
- 'connected' => false,
- 'error' => '',
- 'error_code' => '',
- 'blog_id' => null,
- );
-
- // Check if connected.
- if ( ! JetpackConnection::get_manager()->is_connected() ) {
- $status['error'] = __( 'Site is not connected to WordPress.com. Please connect your site to enable fraud protection.', 'woocommerce' );
- $status['error_code'] = 'not_connected';
- return $status;
- }
-
- // Get blog ID.
- $blog_id = $this->get_blog_id();
- if ( ! $blog_id ) {
- $status['error'] = __( 'Jetpack blog ID not found. Please reconnect your site to WordPress.com.', 'woocommerce' );
- $status['error_code'] = 'no_blog_id';
- return $status;
- }
-
- // All checks passed.
- $status['connected'] = true;
- $status['blog_id'] = $blog_id;
-
- return $status;
- }
-
- /**
- * Get the Jetpack authorization URL for connecting the site.
- *
- * @param string $redirect_url URL to redirect to after authorization.
- * @return string|null Authorization URL or null on error.
- */
- public function get_authorization_url( string $redirect_url = '' ): ?string {
- // If no redirect URL provided, use current admin URL.
- if ( empty( $redirect_url ) ) {
- $redirect_url = admin_url( 'admin.php?page=wc-settings&tab=advanced§ion=features' );
- }
-
- $authorization_data = JetpackConnection::get_authorization_url( $redirect_url, 'woocommerce-fraud-protection' );
-
- if ( ! $authorization_data['success'] ) {
- FraudProtectionController::log(
- 'error',
- 'Failed to get Jetpack authorization URL.',
- $authorization_data['errors']
- );
- return null;
- }
-
- return $authorization_data['url'];
- }
-}
diff --git a/plugins/woocommerce/tests/php/includes/class-wc-payment-gateways-test.php b/plugins/woocommerce/tests/php/includes/class-wc-payment-gateways-test.php
index 73e3ce43bc..16200b1cc3 100644
--- a/plugins/woocommerce/tests/php/includes/class-wc-payment-gateways-test.php
+++ b/plugins/woocommerce/tests/php/includes/class-wc-payment-gateways-test.php
@@ -21,6 +21,11 @@ class WC_Payment_Gateways_Test extends WC_Unit_Test_Case {
public function setUp(): void {
parent::setUp();
$this->reset_legacy_proxy_mocks();
+
+ // Set jetpack_activation_source option to prevent "Cannot use bool as array" error
+ // in Jetpack Connection Manager's apply_activation_source_to_args method.
+ update_option( 'jetpack_activation_source', array( '', '' ) );
+
$container = wc_get_container();
$container->reset_all_resolved();
$this->sut = new WC_Payment_Gateways();
@@ -33,6 +38,7 @@ class WC_Payment_Gateways_Test extends WC_Unit_Test_Case {
public function tearDown(): void {
parent::tearDown();
delete_option( 'woocommerce_feature_fraud_protection_enabled' );
+ delete_option( 'jetpack_activation_source' );
wc_get_container()->get( SessionClearanceManager::class )->reset_session();
}
diff --git a/plugins/woocommerce/tests/php/src/Blocks/StoreApi/Routes/Checkout.php b/plugins/woocommerce/tests/php/src/Blocks/StoreApi/Routes/Checkout.php
index 9aa32670d8..1c9e9757a0 100644
--- a/plugins/woocommerce/tests/php/src/Blocks/StoreApi/Routes/Checkout.php
+++ b/plugins/woocommerce/tests/php/src/Blocks/StoreApi/Routes/Checkout.php
@@ -35,6 +35,10 @@ class Checkout extends MockeryTestCase {
protected function setUp(): void {
parent::setUp();
+ // Set jetpack_activation_source option to prevent "Cannot use bool as array" error
+ // in Jetpack Connection Manager's apply_activation_source_to_args method.
+ update_option( 'jetpack_activation_source', array( '', '' ) );
+
add_filter( 'woocommerce_set_cookie_enabled', array( $this, 'filter_woocommerce_set_cookie_enabled' ), 10, 4 );
update_option( 'woocommerce_enable_guest_checkout', 'yes' );
@@ -128,6 +132,7 @@ class Checkout extends MockeryTestCase {
remove_all_actions( 'woocommerce_valid_order_statuses_for_payment' );
delete_option( 'woocommerce_feature_fraud_protection_enabled' );
+ delete_option( 'jetpack_activation_source' );
wc_get_container()->get( SessionClearanceManager::class )->reset_session();
update_option( 'woocommerce_ship_to_countries', 'all' );
diff --git a/plugins/woocommerce/tests/php/src/Internal/FraudProtection/AdminSettingsHandlerTest.php b/plugins/woocommerce/tests/php/src/Internal/FraudProtection/AdminSettingsHandlerTest.php
deleted file mode 100644
index f7256a7fc6..0000000000
--- a/plugins/woocommerce/tests/php/src/Internal/FraudProtection/AdminSettingsHandlerTest.php
+++ /dev/null
@@ -1,283 +0,0 @@
-<?php
-
-declare( strict_types=1 );
-
-namespace Automattic\WooCommerce\Tests\Internal\FraudProtection;
-
-use Automattic\WooCommerce\Internal\FraudProtection\AdminSettingsHandler;
-use Automattic\WooCommerce\Internal\FraudProtection\JetpackConnectionManager;
-
-/**
- * Tests for the AdminSettingsHandler class.
- */
-class AdminSettingsHandlerTest extends \WC_Unit_Test_Case {
-
- /**
- * System under test.
- *
- * @var AdminSettingsHandler
- */
- private $sut;
-
- /**
- * Mock Jetpack connection manager.
- *
- * @var JetpackConnectionManager|\PHPUnit\Framework\MockObject\MockObject
- */
- private $connection_manager_mock;
-
- /**
- * Setup test.
- */
- public function setUp(): void {
- parent::setUp();
-
- // Create mock connection manager.
- $this->connection_manager_mock = $this->getMockBuilder( JetpackConnectionManager::class )
- ->disableOriginalConstructor()
- ->getMock();
-
- // Get fresh instance from container.
- $this->sut = wc_get_container()->get( AdminSettingsHandler::class );
- $this->sut->init( $this->connection_manager_mock );
- }
-
- /**
- * Test that register method registers the expected hooks.
- */
- public function test_register_registers_hooks(): void {
- $this->sut->register();
-
- // Check if the settings filter is registered.
- $priority = has_filter( 'woocommerce_get_settings_advanced', array( $this->sut, 'add_jetpack_connection_field' ) );
- $this->assertSame( 100, $priority, 'Settings filter should be registered with priority 100' );
-
- // Check if the admin field action is registered.
- $priority = has_action( 'woocommerce_admin_field_jetpack_connection', array( $this->sut, 'handle_output_jetpack_connection_field' ) );
- $this->assertSame( 10, $priority, 'Admin field action should be registered with priority 10' );
- }
-
- /**
- * Test that add_jetpack_connection_field returns settings unchanged on non-features section.
- */
- public function test_add_jetpack_connection_field_returns_unchanged_on_non_features_section(): void {
- $this->sut->register();
-
- $settings = array(
- array(
- 'id' => 'some_setting',
- 'type' => 'text',
- ),
- );
- $current_section = 'general';
- $result = $this->sut->add_jetpack_connection_field( $settings, $current_section );
-
- $this->assertSame( $settings, $result, 'Settings should be unchanged on non-features section' );
- }
-
- /**
- * Test that add_jetpack_connection_field adds field after fraud_protection on features section.
- */
- public function test_add_jetpack_connection_field_adds_field_after_fraud_protection(): void {
- $this->sut->register();
-
- $settings = array(
- array(
- 'id' => 'some_other_feature',
- 'type' => 'checkbox',
- ),
- array(
- 'id' => 'woocommerce_feature_fraud_protection_enabled',
- 'type' => 'checkbox',
- ),
- array(
- 'id' => 'another_feature',
- 'type' => 'checkbox',
- ),
- );
-
- $result = $this->sut->add_jetpack_connection_field( $settings, 'features' );
-
- // Should have one more setting.
- $this->assertCount( 4, $result );
-
- // The new field should be added after fraud_protection.
- $this->assertSame( 'woocommerce_feature_fraud_protection_enabled', $result[1]['id'] );
- $this->assertSame( 'woocommerce_fraud_protection_jetpack_connection', $result[2]['id'] );
- $this->assertSame( 'jetpack_connection', $result[2]['type'] );
- $this->assertSame( 'another_feature', $result[3]['id'] );
- }
-
- /**
- * Test that add_jetpack_connection_field doesn't add duplicate field.
- */
- public function test_add_jetpack_connection_field_doesnt_duplicate(): void {
- $this->sut->register();
-
- $settings = array(
- array(
- 'id' => 'woocommerce_feature_fraud_protection_enabled',
- 'type' => 'checkbox',
- ),
- );
-
- // Call twice to check it doesn't duplicate.
- $result1 = $this->sut->add_jetpack_connection_field( $settings, 'features' );
- $result2 = $this->sut->add_jetpack_connection_field( $result1, 'features' );
-
- // Should still only have 2 settings (fraud_protection + 1 jetpack_connection).
- $this->assertCount( 2, $result2 );
- }
-
- /**
- * Test that handle_output_jetpack_connection_field does nothing when fraud protection disabled.
- */
- public function test_handle_output_jetpack_connection_field_returns_early_when_disabled(): void {
- // Disable fraud protection.
- update_option( 'woocommerce_feature_fraud_protection_enabled', 'no' );
-
- $this->sut->register();
-
- // Mock connection manager should not be called.
- $this->connection_manager_mock->expects( $this->never() )
- ->method( 'get_connection_status' );
-
- // Capture output.
- ob_start();
- $this->sut->handle_output_jetpack_connection_field( array() );
- $output = ob_get_clean();
-
- // Should produce no output.
- $this->assertEmpty( $output );
- }
-
- /**
- * Test that handle_output_jetpack_connection_field shows button when not connected.
- */
- public function test_handle_output_jetpack_connection_field_shows_button_when_not_connected(): void {
- // Enable fraud protection.
- update_option( 'woocommerce_feature_fraud_protection_enabled', 'yes' );
-
- $this->sut->register();
-
- // Mock connection status - not connected.
- $this->connection_manager_mock->expects( $this->once() )
- ->method( 'get_connection_status' )
- ->willReturn(
- array(
- 'connected' => false,
- 'error' => 'Not connected',
- 'error_code' => 'not_connected',
- 'blog_id' => null,
- )
- );
-
- // Mock authorization URL.
- $this->connection_manager_mock->expects( $this->once() )
- ->method( 'get_authorization_url' )
- ->willReturn( 'https://example.com/connect' );
-
- // Capture output.
- ob_start();
- $this->sut->handle_output_jetpack_connection_field( array() );
- $output = ob_get_clean();
-
- // Should contain Connect button.
- $this->assertStringContainsString( 'Connect to Jetpack', $output );
- $this->assertStringContainsString( 'jetpack_connection_button', $output );
- $this->assertStringContainsString( 'https://example.com/connect', $output );
- }
-
- /**
- * Test that handle_output_jetpack_connection_field shows connected status when connected.
- */
- public function test_handle_output_jetpack_connection_field_shows_connected_status(): void {
- // Enable fraud protection.
- update_option( 'woocommerce_feature_fraud_protection_enabled', 'yes' );
-
- $this->sut->register();
-
- // Mock connection status - connected.
- $this->connection_manager_mock->expects( $this->once() )
- ->method( 'get_connection_status' )
- ->willReturn(
- array(
- 'connected' => true,
- 'error' => '',
- 'error_code' => '',
- 'blog_id' => 12345,
- )
- );
-
- // Should not call get_authorization_url when connected.
- $this->connection_manager_mock->expects( $this->never() )
- ->method( 'get_authorization_url' );
-
- // Capture output.
- ob_start();
- $this->sut->handle_output_jetpack_connection_field( array() );
- $output = ob_get_clean();
-
- // Should show connected status.
- $this->assertStringContainsString( 'Connected to Jetpack', $output );
- $this->assertStringContainsString( 'Site ID: 12345', $output );
- $this->assertStringContainsString( 'dashicons-yes-alt', $output );
- }
-
- /**
- * Test that handle_output_jetpack_connection_field shows error when authorization URL fails.
- */
- public function test_handle_output_jetpack_connection_field_shows_error_when_url_fails(): void {
- // Enable fraud protection.
- update_option( 'woocommerce_feature_fraud_protection_enabled', 'yes' );
-
- $this->sut->register();
-
- // Mock connection status - not connected.
- $this->connection_manager_mock->expects( $this->once() )
- ->method( 'get_connection_status' )
- ->willReturn(
- array(
- 'connected' => false,
- 'error' => 'Jetpack not available',
- 'error_code' => 'jetpack_not_available',
- 'blog_id' => null,
- )
- );
-
- // Mock authorization URL - returns null (failure).
- $this->connection_manager_mock->expects( $this->once() )
- ->method( 'get_authorization_url' )
- ->willReturn( null );
-
- // Capture output.
- ob_start();
- $this->sut->handle_output_jetpack_connection_field( array() );
- $output = ob_get_clean();
-
- // Should show error message.
- $this->assertStringContainsString( 'Jetpack not available', $output );
- $this->assertStringNotContainsString( 'Connect to Jetpack', $output );
- }
-
- /**
- * Cleanup after test.
- */
- public function tearDown(): void {
- parent::tearDown();
-
- // Clean up options.
- delete_option( 'woocommerce_feature_fraud_protection_enabled' );
-
- // Remove hooks.
- remove_all_filters( 'woocommerce_get_settings_advanced' );
- remove_all_actions( 'woocommerce_admin_field_jetpack_connection' );
- remove_all_actions( 'admin_enqueue_scripts' );
-
- // Reset container.
- wc_get_container()->reset_all_resolved();
-
- // Clean up $_GET.
- unset( $_GET['section'] );
- }
-}
diff --git a/plugins/woocommerce/tests/php/src/Internal/FraudProtection/FraudProtectionControllerTest.php b/plugins/woocommerce/tests/php/src/Internal/FraudProtection/FraudProtectionControllerTest.php
index 1efd7c8b58..0a7cefda03 100644
--- a/plugins/woocommerce/tests/php/src/Internal/FraudProtection/FraudProtectionControllerTest.php
+++ b/plugins/woocommerce/tests/php/src/Internal/FraudProtection/FraudProtectionControllerTest.php
@@ -12,6 +12,17 @@ use Automattic\WooCommerce\Internal\FraudProtection\FraudProtectionController;
*/
class FraudProtectionControllerTest extends \WC_Unit_Test_Case {
+ /**
+ * Set up test fixtures.
+ */
+ public function setUp(): void {
+ parent::setUp();
+
+ // Set jetpack_activation_source option to prevent "Cannot use bool as array" error
+ // in Jetpack Connection Manager's apply_activation_source_to_args method.
+ update_option( 'jetpack_activation_source', array( '', '' ) );
+ }
+
/**
* Get a fresh controller instance with reset container.
*
@@ -165,6 +176,7 @@ class FraudProtectionControllerTest extends \WC_Unit_Test_Case {
// Clean up any filters or options.
remove_all_filters( 'woocommerce_logging_class' );
delete_option( 'woocommerce_feature_fraud_protection_enabled' );
+ delete_option( 'jetpack_activation_source' );
// Remove any init hooks registered by the controller.
remove_all_actions( 'init' );
diff --git a/plugins/woocommerce/tests/php/src/Internal/FraudProtection/PaymentMethodEventTrackerTest.php b/plugins/woocommerce/tests/php/src/Internal/FraudProtection/PaymentMethodEventTrackerTest.php
index 5f7e787f36..eb32ea0450 100644
--- a/plugins/woocommerce/tests/php/src/Internal/FraudProtection/PaymentMethodEventTrackerTest.php
+++ b/plugins/woocommerce/tests/php/src/Internal/FraudProtection/PaymentMethodEventTrackerTest.php
@@ -39,6 +39,10 @@ class PaymentMethodEventTrackerTest extends \WC_Unit_Test_Case {
public function setUp(): void {
parent::setUp();
+ // Set jetpack_activation_source option to prevent "Cannot use bool as array" error
+ // in Jetpack Connection Manager's apply_activation_source_to_args method.
+ update_option( 'jetpack_activation_source', array( '', '' ) );
+
// Enable the fraud protection feature.
update_option( 'woocommerce_feature_fraud_protection_enabled', 'yes' );
@@ -121,6 +125,7 @@ class PaymentMethodEventTrackerTest extends \WC_Unit_Test_Case {
// Clean up options.
delete_option( 'woocommerce_feature_fraud_protection_enabled' );
+ delete_option( 'jetpack_activation_source' );
// Reset container.
wc_get_container()->reset_all_resolved();