Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 125 additions & 0 deletions tests/Unit/AbstractWPUnitTestWithSafeFiltering.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
<?php
/**
* Abstract test case for unit tests.
*/

namespace WooCommerce\Facebook\Tests\Unit;

use WP_UnitTestCase;

/**
* Abstract test case that provides filter management functionality.
*/
abstract class AbstractWPUnitTestWithSafeFiltering extends WP_UnitTestCase {
/**
* Store filter callbacks to remove them after tests
*
* @var array
*/
private $filter_callbacks = [];

/**
* Set up before each test.
*/
public function setUp(): void {
parent::setUp();
$this->filter_callbacks = [];
}

/**
* Clean up after each test.
*/
public function tearDown(): void {
// Remove specific filters that were added by this test
foreach ($this->filter_callbacks as $hook => $callbacks) {
foreach ($callbacks as $callback_data) {
remove_filter($hook, $callback_data['callback'], $callback_data['priority']);
}
}

parent::tearDown();
}

/**
* Helper method to remove all filters for a specific hook safely
*
* @param string $hook The filter hook name to remove all callbacks for
* @return void
*/
protected function teardown_callback_category_safely($hook) {
if (isset($this->filter_callbacks[$hook])) {
foreach ($this->filter_callbacks[$hook] as $callback_data) {
remove_filter($hook, $callback_data['callback'], $callback_data['priority']);
}
// Clear the tracking for this hook
unset($this->filter_callbacks[$hook]);
}
}

/**
* Helper method to add a filter and store its callback for later removal
*
* @param string $hook The filter hook name
* @param callable $callback The filter callback function
* @param int $priority The priority of the filter
* @param int $accepted_args The number of arguments the function accepts
* @return object A simple object with remove() method for easy cleanup
*/
protected function add_filter_with_safe_teardown($hook, $callback, $priority = 10, $accepted_args = 1) {
add_filter($hook, $callback, $priority, $accepted_args);

if (!isset($this->filter_callbacks[$hook])) {
$this->filter_callbacks[$hook] = [];
}

$this->filter_callbacks[$hook][] = [
'callback' => $callback,
'priority' => $priority
];

$self = $this;

// Return a simple object with a remove method
return new class($hook, $callback, $priority, $self) {
private $hook;
private $callback;
private $priority;
private $test_case;

public function __construct($hook, $callback, $priority, $test_case) {
$this->hook = $hook;
$this->callback = $callback;
$this->priority = $priority;
$this->test_case = $test_case;
}

public function teardown_safely_immediately() {
remove_filter($this->hook, $this->callback, $this->priority);
$this->test_case->removeFilterFromTracking($this->hook, $this->callback, $this->priority);
}
};
}

/**
* Remove a filter from the tracking array
*
* @param string $hook The filter hook name
* @param callable $callback The filter callback function
* @param int $priority The priority of the filter
*/
public function removeFilterFromTracking($hook, $callback, $priority) {
if (isset($this->filter_callbacks[$hook])) {
foreach ($this->filter_callbacks[$hook] as $key => $callback_data) {
if ($callback_data['callback'] === $callback && $callback_data['priority'] === $priority) {
unset($this->filter_callbacks[$hook][$key]);
break;
}
}

// Clean up empty arrays
if (empty($this->filter_callbacks[$hook])) {
unset($this->filter_callbacks[$hook]);
}
}
}
}
48 changes: 24 additions & 24 deletions tests/Unit/ApiTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
/**
* Api unit test clas.
*/
class ApiTest extends WP_UnitTestCase {
class ApiTest extends \WooCommerce\Facebook\Tests\Unit\AbstractWPUnitTestWithSafeFiltering {

/**
* Facebook Graph API endpoint.
Expand Down Expand Up @@ -54,7 +54,7 @@ public function test_perform_request_performs_successful_request() {
],
];
};
add_filter( 'pre_http_request', $response, 10, 3 );
$this->add_filter_with_safe_teardown( 'pre_http_request', $response, 10, 3 );

$response = $this->api->get_catalog( '726635365295186' );

Expand All @@ -78,7 +78,7 @@ public function test_perform_request_produces_wp_error() {
$this->assertEquals( "{$this->endpoint}{$this->version}/726635365295186?fields=name", $url );
return new WP_Error( 007, 'WP Error Message' );
};
add_filter( 'pre_http_request', $response, 10, 3 );
$this->add_filter_with_safe_teardown( 'pre_http_request', $response, 10, 3 );

$this->api->get_catalog( '726635365295186' );
}
Expand All @@ -103,7 +103,7 @@ public function test_get_installation_ids_returns_installation_ids_request() {
],
];
};
add_filter( 'pre_http_request', $response, 10, 3 );
$this->add_filter_with_safe_teardown( 'pre_http_request', $response, 10, 3 );

$response = $this->api->get_installation_ids( $external_business_id );

Expand All @@ -130,7 +130,7 @@ public function test_get_catalog_returns_catalog_id_and_name_request() {
],
];
};
add_filter( 'pre_http_request', $response, 10, 3 );
$this->add_filter_with_safe_teardown( 'pre_http_request', $response, 10, 3 );

$response = $this->api->get_catalog( $catalog_id );

Expand Down Expand Up @@ -158,7 +158,7 @@ public function test_get_user_returns_user_information_request() {
],
];
};
add_filter( 'pre_http_request', $response, 10, 3 );
$this->add_filter_with_safe_teardown( 'pre_http_request', $response, 10, 3 );

$response = $this->api->get_user( $user_id );

Expand Down Expand Up @@ -187,7 +187,7 @@ public function test_delete_mbe_connection_deletes_mbe_request() {
],
];
};
add_filter( 'pre_http_request', $response, 10, 3 );
$this->add_filter_with_safe_teardown( 'pre_http_request', $response, 10, 3 );

$response = $this->api->delete_mbe_connection( $external_business_id );

Expand All @@ -214,7 +214,7 @@ public function test_get_business_configuration_returns_business_configuration_r
],
];
};
add_filter( 'pre_http_request', $response, 10, 3 );
$this->add_filter_with_safe_teardown( 'pre_http_request', $response, 10, 3 );

$response = $this->api->get_business_configuration( $external_business_id );

Expand Down Expand Up @@ -267,7 +267,7 @@ public function test_send_item_updates_sends_item_updates_request() {
],
];
};
add_filter( 'pre_http_request', $response, 10, 3 );
$this->add_filter_with_safe_teardown( 'pre_http_request', $response, 10, 3 );

$response = $this->api->send_item_updates( $facebook_catalog_id, $requests );

Expand Down Expand Up @@ -313,7 +313,7 @@ public function test_create_product_group_performs_create_product_group_request(
],
];
};
add_filter( 'pre_http_request', $response, 10, 3 );
$this->add_filter_with_safe_teardown( 'pre_http_request', $response, 10, 3 );

$response = $this->api->create_product_group( $facebook_product_catalog_id, $data );

Expand Down Expand Up @@ -355,7 +355,7 @@ public function test_update_product_group_preforms_update_product_group_request(
],
];
};
add_filter( 'pre_http_request', $response, 10, 3 );
$this->add_filter_with_safe_teardown( 'pre_http_request', $response, 10, 3 );

$response = $this->api->update_product_group( $facebook_product_group_id, $data );

Expand All @@ -382,7 +382,7 @@ public function test_delete_product_group_deletes_product_group_request() {
],
];
};
add_filter( 'pre_http_request', $response, 10, 3 );
$this->add_filter_with_safe_teardown( 'pre_http_request', $response, 10, 3 );

$response = $this->api->delete_product_group( $facebook_product_group_id );

Expand Down Expand Up @@ -410,7 +410,7 @@ public function test_get_product_group_products_returns_group_products_request()
],
];
};
add_filter( 'pre_http_request', $response, 10, 3 );
$this->add_filter_with_safe_teardown( 'pre_http_request', $response, 10, 3 );

$response = $this->api->get_product_group_products( $facebook_product_group_id, $limit );

Expand Down Expand Up @@ -473,7 +473,7 @@ public function test_create_product_item_creates_product_item_request() {
],
];
};
add_filter( 'pre_http_request', $response, 10, 3 );
$this->add_filter_with_safe_teardown( 'pre_http_request', $response, 10, 3 );

$response = $this->api->create_product_item( $facebook_product_group_id, $data );

Expand Down Expand Up @@ -520,7 +520,7 @@ public function test_update_product_item_updated_product_item_request() {
],
];
};
add_filter( 'pre_http_request', $response, 10, 3 );
$this->add_filter_with_safe_teardown( 'pre_http_request', $response, 10, 3 );

$response = $this->api->update_product_item( $facebook_product_id, $data );

Expand Down Expand Up @@ -552,7 +552,7 @@ public function test_get_product_facebook_ids_creates_get_ids_request() {
],
];
};
add_filter( 'pre_http_request', $response, 10, 3 );
$this->add_filter_with_safe_teardown( 'pre_http_request', $response, 10, 3 );

$response = $this->api->get_product_facebook_ids( $facebook_product_catalog_id, $facebook_product_retailer_id );

Expand Down Expand Up @@ -580,7 +580,7 @@ public function test_delete_product_item_deletes_product_item_request() {
],
];
};
add_filter( 'pre_http_request', $response, 10, 3 );
$this->add_filter_with_safe_teardown( 'pre_http_request', $response, 10, 3 );

$response = $this->api->delete_product_item( $facebook_product_id );

Expand Down Expand Up @@ -613,7 +613,7 @@ public function test_create_product_set_item_creates_set_request() {
],
];
};
add_filter( 'pre_http_request', $response, 10, 3 );
$this->add_filter_with_safe_teardown( 'pre_http_request', $response, 10, 3 );

$response = $this->api->create_product_set_item( $facebook_product_catalog_id, $data );

Expand Down Expand Up @@ -646,7 +646,7 @@ public function test_update_product_set_item_updates_set_request() {
],
];
};
add_filter( 'pre_http_request', $response, 10, 3 );
$this->add_filter_with_safe_teardown( 'pre_http_request', $response, 10, 3 );

$response = $this->api->update_product_set_item( $facebook_product_set_id, $data );

Expand All @@ -673,7 +673,7 @@ public function test_delete_product_set_item_deletes_set_request() {
],
];
};
add_filter( 'pre_http_request', $response, 10, 3 );
$this->add_filter_with_safe_teardown( 'pre_http_request', $response, 10, 3 );

$response = $this->api->delete_product_set_item( $facebook_product_set_id, true );

Expand All @@ -700,7 +700,7 @@ public function test_read_feeds_creates_read_feeds_request() {
],
];
};
add_filter( 'pre_http_request', $response, 10, 3 );
$this->add_filter_with_safe_teardown( 'pre_http_request', $response, 10, 3 );

$response = $this->api->read_feeds( $facebook_product_catalog_id );

Expand Down Expand Up @@ -740,7 +740,7 @@ public function test_create_feed_request() {
],
];
};
add_filter( 'pre_http_request', $response, 10, 3 );
$this->add_filter_with_safe_teardown( 'pre_http_request', $response, 10, 3 );

$response_feed = $this->api->create_feed( $facebook_product_catalog_id, $data );

Expand Down Expand Up @@ -770,7 +770,7 @@ public function test_create_upload_request() {
],
];
};
add_filter( 'pre_http_request', $response, 10, 3 );
$this->add_filter_with_safe_teardown( 'pre_http_request', $response, 10, 3 );

$response = $this->api->create_product_feed_upload( $product_feed_id, $data );
$this->assertFalse( $response->has_api_error() );
Expand Down Expand Up @@ -801,7 +801,7 @@ public function test_create_common_upload_request() {
],
];
};
add_filter( 'pre_http_request', $response, 10, 3 );
$this->add_filter_with_safe_teardown( 'pre_http_request', $response, 10, 3 );

$response = $this->api->create_common_data_feed_upload( $cpi, $data );
$this->assertFalse( $response->has_api_error() );
Expand Down
20 changes: 9 additions & 11 deletions tests/Unit/Feed/FeedUploadUtilsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
*
* Sets up environment to test various logic in FeedUploadUtils
*/
class FeedUploadUtilsTest extends WP_UnitTestCase {
class FeedUploadUtilsTest extends \WooCommerce\Facebook\Tests\Unit\AbstractWPUnitTestWithSafeFiltering {

/** @var int Shop page ID */
protected static $shop_page_id;
Expand All @@ -27,9 +27,10 @@ public function setUp(): void {
parent::setUp();

// Force a pretty permalink structure.
add_filter( 'pre_option_permalink_structure', function () {
$this->add_filter_with_safe_teardown('pre_option_permalink_structure', function () {
return '/%postname%/';
} );
});

update_option( 'permalink_structure', '/%postname%/' );
global $wp_rewrite;
if ( ! ( $wp_rewrite instanceof WP_Rewrite ) ) {
Expand All @@ -56,21 +57,18 @@ public function setUp(): void {
flush_rewrite_rules();

// Add high–priority filters to force URLs.
add_filter( 'woocommerce_get_page_permalink', [ $this, 'forceShopPermalink' ], 9999, 2 );
add_filter( 'get_permalink', [ $this, 'forceGetPermalink' ], 9999, 2 );
add_filter( 'post_type_link', [ $this, 'forcePostTypeLink' ], 9999, 3 );
add_filter( 'woocommerce_product_get_permalink', [ $this, 'forceProductPermalink' ], 9999, 2 );
$this->add_filter_with_safe_teardown('woocommerce_get_page_permalink', [ $this, 'forceShopPermalink' ], 9999, 2);
$this->add_filter_with_safe_teardown('get_permalink', [ $this, 'forceGetPermalink' ], 9999, 2);
$this->add_filter_with_safe_teardown('post_type_link', [ $this, 'forcePostTypeLink' ], 9999, 3);
$this->add_filter_with_safe_teardown('woocommerce_product_get_permalink', [ $this, 'forceProductPermalink' ], 9999, 2);
}

/**
* Clean up filters and rewrite rules.
*/
public function tearDown(): void {
remove_filter( 'woocommerce_get_page_permalink', [ $this, 'forceShopPermalink' ], 9999 );
remove_filter( 'get_permalink', [ $this, 'forceGetPermalink' ], 9999 );
remove_filter( 'post_type_link', [ $this, 'forcePostTypeLink' ], 9999 );
remove_filter( 'woocommerce_product_get_permalink', [ $this, 'forceProductPermalink' ], 9999 );
flush_rewrite_rules();
// No need to manually remove filters, parent tearDown will handle it
parent::tearDown();
}

Expand Down
Loading