Commit ac84d33f0fe for woocommerce
commit ac84d33f0fed50c5f494ed7d5ba68159a708828b
Author: Vlad Olaru <vlad.olaru@automattic.com>
Date: Mon Nov 9 19:56:52 2026 +0200
[tests] Restore the customer, $_SERVER, Constants overrides and block types in the base test case teardown (#69738)
* test: Put the setUp() customer back after each WC_Unit_Test_Case test
WC()->customer outlives a test, so a test that changes it leaks the
change into every later one. #69117 handles the leaks it found with
the same copied code in five classes: snapshot get_shipping( 'edit' )
in setUp() and set each field back in tearDown(). That still misses
tests that swap in another customer (WC_Abstract_Order_Test does, for
an admin with a billing address in MV), billing and tax exemption
changes, and the change set the setters write to.
WC_Unit_Test_Case already resets the WC() singleton state the database
rollback misses. Keep the customer it saw at setUp() and that
customer's internal state (id, data, changes, is_vat_exempt and
calculated_shipping, read through a closure bound to WC_Customer), and
in clear_wc_singleton_state() put that instance back on WC() and write
the state back directly, so no setter touches the change set. Drop the
five per-class copies and the two tearDown() overrides left with
nothing to do. OrderControllerTests keeps setting its own shipping
location, which its invalid-address tests need.
UnitTestCaseTearDownTest swaps in another customer and changes billing,
shipping and tax exemption, then asserts the same instance, data,
change set and exemption come back. Removing the swap-back makes it
fail.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test: Restore all of $_SERVER after each WC_Unit_Test_Case test
WP_UnitTestCase::go_to() sets $_SERVER['REQUEST_URI'], and WordPress
resets $_SERVER only for its own core tests (WP_RUN_CORE_TESTS), so a
plugin suite keeps whatever a test leaves behind. 16 of the 17
WooCommerce test classes that call go_to() never put REQUEST_URI back,
and RateLimitsTests changes the client IP and user agent.
#69117 fixes the one leak with a victim in the class that causes it:
ProductPageIntegrationTest restores REQUEST_URI, because after it
visits /?product=variable-product, WC_Cart_Test's form handler test
sees every plain-permalink product URL as the page it is on.
Snapshot the whole superglobal at the end of setUp() and put it back in
tearDown(), in its own finally block so a failing singleton reset
cannot skip it. Drop the per-class restore in ProductPageIntegrationTest.
UnitTestCaseTearDownTest covers go_to(), a changed user agent and a
removed REMOTE_ADDR; removing the restore makes it and the
ProductPageIntegrationTest and WC_Cart_Test pair fail again.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test: Restore Constants overrides after each WC_Unit_Test_Case test
Constants::set_constant() keeps overrides in a static store that
neither the per-test rollback nor the hook restore resets, so every
test that sets one has to clear it again, and one that forgets leaks
the override into every later test. #69117 found two such leaks
(PHP_OS, WCPAY_VERSION_NUMBER), and about 30 tests carry their own
clear today.
Snapshot Constants::$set_constants at the end of setUp() and put it
back at teardown. Restoring the snapshot, rather than clearing every
override, keeps any override set before the test (in
setUpBeforeClass(), for example). The restore runs in the same finally
block as the $_SERVER restore, so a failure while clearing the WC()
singletons does not skip it.
Refs #69117
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test: Drop Constants cleanup the base test case now covers
WC_Unit_Test_Case now restores Constants overrides after every test,
so the per-test clears in its descendants only repeat that work.
Remove them: tearDown() clears, clears in end-of-test finally blocks,
the save-and-restore of WCPAY_VERSION_NUMBER in the two payments REST
integration tests, RemoteLoggerTest's copy of the whole store, and
the end-of-test clears in the logging SettingsTest, which were not in a
finally block and leaked on a failed assertion. Three tearDown()
methods, and two try/finally blocks in WooPaymentsTest, were left with
nothing else to do and go too.
Clears that set up a later step of the same test stay
(wc-update-functions-test.php and the logging SettingsTest).
Refs #69117
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test: Restore the block type registry after each WC_Unit_Test_Case test
WP_Block_Type_Registry is a singleton that outlives every test, and
neither the rollback nor the hook restore touches it. Tests that
register a mock, replace a real block type, or unregister one have to
undo it by hand with a list of names that must match the test body,
and a missed name leaks into later tests (#69117 fixed five such
leaks, each with its own list).
Snapshot the registered block types at the end of setUp(). At
teardown, unregister any name that is new or now points to another
WP_Block_Type, and register again any setUp() entry that is missing.
Block types registered before the test, in setUpBeforeClass() or at
bootstrap, stay as they were.
Refs #69117
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(blocks): Drop block type cleanup the base test case now covers
WC_Unit_Test_Case now puts the block type registry back after every
test, so move the block tests that kept their own cleanup onto it and
remove that cleanup: the hand-written name lists in BlockTypesController
and Blocks\Checkout, the save-and-register-again of the original block
in MiniCart, MiniCartFooterBlock and CouponCodeTest, and the test block
in BlockHooksTests.
AddToCartWithOptions' wishlist test unregistered the real
add-to-wishlist-button block and never registered it again; the base
restore now does. Its mock blocks are still registered in setUp(),
which now happens for every test, since teardown removes them.
Checkout, MiniCart, MiniCartFooterBlock, CouponCodeTest, BlockHooksTests
and AddToCartWithOptions move from WP_UnitTestCase to
WC_Unit_Test_Case, which also clears the cart, notices and the other
WC() state after each of their tests.
Refs #69117
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test: Assert the block registry test has two block types to work with
test_restore_block_type_registry_undoes_registry_changes() replaces
the first block type registered at setUp() and removes the second. With
fewer than two it would stop on an undefined offset instead of a clear
failure. Core registers many block types, so this never happens today;
the assertion states the precondition.
Raised by CodeRabbit on PR #69738.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test: Run the base teardown restores before the singleton cleanup
WC_Unit_Test_Case::tearDown() nested two try/finally blocks so a throw
from clear_wc_singleton_state() could not skip the $_SERVER, Constants
and block registry restores, and a throw from those could not skip
parent::tearDown().
The restores only assign saved values or call registry methods that
report problems through _doing_it_wrong(), so they do not throw. Run
them first and keep the single try/finally from trunk around the
singleton cleanup, which can throw. Every step still runs, with one
level of nesting.
The singleton cleanup now sees the $_SERVER and Constants from setUp()
rather than the test's values.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test: Drop the unused shipping address copy in a cart test
The show_shipping() test trunk added in #69648 saved the customer's
shipping address into $this->original_shipping_address, a property
the class never declares and nothing reads back. The address was
never restored from it.
The base test case now puts the setUp() customer back after every
test, so the copy is not needed for cleanup either. Remove it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test: Remove redundant cleanup from newly landed tests
Tests added on trunk still restore state that WC_Unit_Test_Case now
restores centrally. Remove those duplicate server and customer resets
while preserving scenario changes and unrelated cleanup.
Move the ProductCollection query builder and ProductFilters block tests
to the WooCommerce base so they inherit the same restoration. Match the
base lifecycle visibility and drop their URI and block registry cleanup.
* test(blocks): Leave block type cleanup to the base test case
BlockTypeRegistryTrait (#69611) recorded what each name held before a
test and put it back in an @after hook. WC_Unit_Test_Case now restores
the whole block type registry in tearDown(), and every class using the
trait extends it, so the trait's restore repeated that work.
Worse, @after runs after tearDown(), so the trait's restore had the last
word. Its record is taken later than the base snapshot, so a test that
replaced a name it had already unregistered would have the trait remove
the original the base had just put back.
Drop the per-name record and restore_block_types(). The trait keeps
replace_block_type(): unregister the name first, since constructing a
block class registers it and the registry rejects a taken name, then
check that the callback registered that exact name. Its tests keep the
swap, batch and wrong-name cases; restoring is covered by
UnitTestCaseTearDownTest.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test: Run the parent teardown even if a state restore throws
WC_Unit_Test_Case::tearDown() put back $_SERVER, Constants overrides
and the block type registry before its try/finally, on the grounds
that those restores cannot throw. Under the default WordPress test
setup that holds: WP_Block_Type_Registry::register() returns false
on bad input, and the test base records _doing_it_wrong() instead of
raising it.
It still depends on the test behaving. A test that renames a block
type it unregistered and leaves a throwing doing_it_wrong_run listener
makes the registry restore throw, which skipped parent::tearDown(), so
the database rollback and hook restore never ran and the next test
inherited the leftover hooks.
Move the three restores inside the try, so the parent teardown always
runs. Order is unchanged.
Refs #69738
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test: Restore the setUp() customer's meta after each test
WC_Unit_Test_Case puts the setUp() customer back with its id, data,
change set, tax exemption and shipping flag, but not its meta. Meta a
test added to WC()->customer, or changed with update_meta_data(), stayed
on the restored object and reached later tests: a throwaway pair of
tests showed the second one reading the first one's meta.
Save meta_data with the rest of the customer state. update_meta_data()
edits WC_Meta_Data objects in place, so the saved state clones them when
it is taken and again when it is written back. A null value means the
meta was never read, and writing it back makes the next read reload it
from the rolled-back database.
An instrumented run of 19,217 tests found none that leave meta changes
on the setUp() customer, so this changes no current test's starting
state. The new test covers both an added key and a value changed in
place, and fails if either the clone or the meta entry is removed.
Refs #69738
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test: Skip the teardown restores when setUp() saved nothing
PHPUnit runs tearDown() even when a subclass skips the test in setUp()
before calling parent::setUp(), as WC_Admin_List_Table_Orders_Test does
under HPOS. The $_SERVER, Constants and block type snapshots then still
held their array() defaults, and teardown "restored" them: $_SERVER
became empty, every Constants override was cleared, and every block type
was unregistered for the rest of the run. A skip-first class followed by
a checker test reproduced it.
Default the three snapshots to null and return early from each restore
when its snapshot is null, as the customer restore already does. The new
test runs the restores on a case whose setUp() never ran and checks
nothing changes; it fails if any one of the three guards is removed.
Refs #69738
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
diff --git a/.ai/skills/woocommerce-backend-dev/unit-tests.md b/.ai/skills/woocommerce-backend-dev/unit-tests.md
index 6ead6c9aedc..a5c7b970ffd 100644
--- a/.ai/skills/woocommerce-backend-dev/unit-tests.md
+++ b/.ai/skills/woocommerce-backend-dev/unit-tests.md
@@ -102,7 +102,7 @@ Choose cleanup from the test's base class; PHPUnit alone provides no database is
| Base class | Automatic isolation when parent setup/teardown runs |
| --- | --- |
| `WP_UnitTestCase` descendants, including `WP_HTTP_TestCase` and `WP_Test_REST_TestCase` | `$wpdb` transaction rollback, reset of the WordPress globals managed by the base, and hook snapshot restoration; the next setup flushes the object cache |
-| `WC_Unit_Test_Case` descendants, including `WC_REST_Unit_Test_Case` | All `WP_UnitTestCase` behavior plus WooCommerce cart/context, notices, country-locale and loaded shipping methods singleton cleanup, and, at each setup, unregistration of every `pa_*` taxonomy without an attribute row |
+| `WC_Unit_Test_Case` descendants, including `WC_REST_Unit_Test_Case` | All `WP_UnitTestCase` behavior plus WooCommerce cart/context, notices, country-locale and loaded shipping methods singleton cleanup; `WC()->customer`, `$_SERVER`, `Constants` overrides, and registered block types are put back as they were at setup; and, at each setup, unregistration of every `pa_*` taxonomy without an attribute row |
| `PHPUnit\Framework\TestCase` | No WordPress transaction, hook restoration, or global cleanup |
| Other custom base | Inspect its implementation; do not infer cleanup from PHPUnit or its name |
diff --git a/plugins/woocommerce/changelog/test-base-case-restores-constants-and-block-types b/plugins/woocommerce/changelog/test-base-case-restores-constants-and-block-types
new file mode 100644
index 00000000000..8897a0e5043
--- /dev/null
+++ b/plugins/woocommerce/changelog/test-base-case-restores-constants-and-block-types
@@ -0,0 +1,3 @@
+Significance: patch
+Type: dev
+Comment: Restore the customer, $_SERVER, Constants overrides and block types in the PHPUnit base test case; no production change.
diff --git a/plugins/woocommerce/tests/legacy/framework/class-wc-unit-test-case.php b/plugins/woocommerce/tests/legacy/framework/class-wc-unit-test-case.php
index 23af2964158..638ab3336b2 100644
--- a/plugins/woocommerce/tests/legacy/framework/class-wc-unit-test-case.php
+++ b/plugins/woocommerce/tests/legacy/framework/class-wc-unit-test-case.php
@@ -5,6 +5,7 @@
* @package WooCommerce\Tests
*/
+use Automattic\Jetpack\Constants;
use Automattic\WooCommerce\Proxies\LegacyProxy;
use Automattic\WooCommerce\Testing\Tools\CodeHacking\CodeHacker;
use Automattic\WooCommerce\Utilities\OrderUtil;
@@ -48,6 +49,41 @@ class WC_Unit_Test_Case extends WP_HTTP_TestCase {
*/
private static $direct_product_attribute_lookup_updates_depth = 0;
+ /**
+ * The WC()->customer instance at setUp(), which teardown puts back with its state.
+ *
+ * @var WC_Customer|null
+ */
+ private $customer_at_setup;
+
+ /**
+ * The internal state of $customer_at_setup when the test started.
+ *
+ * @var array<string, mixed>
+ */
+ private $customer_state_at_setup = array();
+
+ /**
+ * $_SERVER at setUp(), or null until setUp() saves it.
+ *
+ * @var array<string, mixed>|null
+ */
+ private $server_at_setup = null;
+
+ /**
+ * Constants::$set_constants at setUp(), or null until setUp() saves it.
+ *
+ * @var array<string, mixed>|null
+ */
+ private $constant_overrides_at_setup = null;
+
+ /**
+ * The registered block types at setUp(), by name, or null until setUp() saves them.
+ *
+ * @var array<string, WP_Block_Type>|null
+ */
+ private $block_types_at_setup = null;
+
/**
* Enable synchronous product attribute lookup updates for test fixtures.
*
@@ -146,6 +182,13 @@ class WC_Unit_Test_Case extends WP_HTTP_TestCase {
// Reset the instance of MockableLegacyProxy that was registered during bootstrap,
// in order to start the test in a clean state (without anything mocked).
wc_get_container()->get( LegacyProxy::class )->reset();
+
+ $this->customer_at_setup = WC()->customer instanceof WC_Customer ? WC()->customer : null;
+ $this->customer_state_at_setup = $this->customer_at_setup ? self::customer_state( $this->customer_at_setup ) : array();
+
+ $this->server_at_setup = $_SERVER;
+ $this->constant_overrides_at_setup = Constants::$set_constants;
+ $this->block_types_at_setup = WP_Block_Type_Registry::get_instance()->get_all_registered();
}
/**
@@ -176,15 +219,21 @@ class WC_Unit_Test_Case extends WP_HTTP_TestCase {
/**
* Tear down test case.
*
- * The cart contents, the cart context, the queued notices, the cached country
- * locale, and the loaded shipping methods all live on the WC() singletons, which
- * neither the per-test database rollback nor the hook restore resets, so clear them
- * here or they leak into every later test in the process.
+ * The cart, notices, country locale, loaded shipping methods, and customer live on
+ * WC() singletons that survive database rollback and hook restoration. Reset them
+ * along with $_SERVER, Constants overrides, and the block type registry so their
+ * state does not leak into later tests.
*
* @since 11.1.0
*/
public function tearDown(): void {
try {
+ // PHPUnit runs tearDown() even when a subclass skips the test before calling parent::setUp().
+ // Each restore then finds no saved state and leaves the current one alone.
+ $this->restore_server_superglobal();
+ $this->restore_constant_overrides();
+ $this->restore_block_type_registry();
+
// Function and static-method mocks are process-wide. Reset them here so the test
// that installs one is the last to see it, including when the next test extends a
// WordPress base class that never runs setUp() on this hierarchy.
@@ -244,6 +293,92 @@ class WC_Unit_Test_Case extends WP_HTTP_TestCase {
// WC_Shipping caches the loaded methods, including any a test's filters or zones added.
WC()->shipping()->unregister_shipping_methods();
+
+ if ( $this->customer_at_setup ) {
+ // Tests swap in a customer for another user, or change addresses, tax exemption, meta
+ // and other props through setters, which also leave entries in the change set. Put back
+ // the setUp() instance with its exact state, so later tests start from the same one.
+ WC()->customer = $this->customer_at_setup;
+ self::customer_state( $this->customer_at_setup, $this->customer_state_at_setup );
+ }
+ }
+
+ /**
+ * Read a customer's internal state, or write it back when $state is given.
+ *
+ * @param WC_Customer $customer The customer.
+ * @param array<string, mixed>|null $state State from an earlier read, to write back.
+ * @return array<string, mixed> The state as it was before any write.
+ */
+ private static function customer_state( WC_Customer $customer, ?array $state = null ): array {
+ // update_meta_data() changes WC_Meta_Data objects in place, so the saved state keeps its own copies.
+ // Null means the meta was never read, and writing it back makes the next read reload it.
+ $copy_meta = static fn ( $meta ) => is_array( $meta ) ? array_map( static fn ( WC_Meta_Data $item ) => clone $item, $meta ) : $meta;
+
+ $access = function ( ?array $state ) use ( $copy_meta ): array {
+ $current = array(
+ 'id' => $this->id,
+ 'data' => $this->data,
+ 'changes' => $this->changes,
+ 'meta_data' => $copy_meta( $this->meta_data ),
+ 'is_vat_exempt' => $this->is_vat_exempt,
+ 'calculated_shipping' => $this->calculated_shipping,
+ );
+ foreach ( (array) $state as $prop => $value ) {
+ $this->$prop = 'meta_data' === $prop ? $copy_meta( $value ) : $value;
+ }
+ return $current;
+ };
+
+ return Closure::bind( $access, $customer, WC_Customer::class )( $state );
+ }
+
+ /**
+ * Put back $_SERVER from setUp(). Tests change it directly and through go_to(), and code that
+ * reads the request URI, client IP or user agent would otherwise see the previous test's values.
+ */
+ protected function restore_server_superglobal(): void {
+ if ( null === $this->server_at_setup ) {
+ return;
+ }
+
+ $_SERVER = $this->server_at_setup;
+ }
+
+ /**
+ * Put back the Constants overrides from setUp(). Constants::set_constant() keeps them in a static
+ * store, so one a test forgets to clear would otherwise apply to every later test.
+ */
+ protected function restore_constant_overrides(): void {
+ if ( null === $this->constant_overrides_at_setup ) {
+ return;
+ }
+
+ Constants::$set_constants = $this->constant_overrides_at_setup;
+ }
+
+ /**
+ * Put back the block types from setUp(): unregister the ones a test added or replaced, and
+ * register again the ones it removed. The registry is a singleton that outlives the test.
+ */
+ protected function restore_block_type_registry(): void {
+ if ( null === $this->block_types_at_setup ) {
+ return;
+ }
+
+ $registry = WP_Block_Type_Registry::get_instance();
+
+ foreach ( $registry->get_all_registered() as $name => $block_type ) {
+ if ( ( $this->block_types_at_setup[ $name ] ?? null ) !== $block_type ) {
+ $registry->unregister( $name );
+ }
+ }
+
+ foreach ( $this->block_types_at_setup as $name => $block_type ) {
+ if ( ! $registry->is_registered( $name ) ) {
+ $registry->register( $block_type );
+ }
+ }
}
/**
diff --git a/plugins/woocommerce/tests/legacy/unit-tests/coupon/coupon.php b/plugins/woocommerce/tests/legacy/unit-tests/coupon/coupon.php
index a668f27cf86..870f5a6e420 100644
--- a/plugins/woocommerce/tests/legacy/unit-tests/coupon/coupon.php
+++ b/plugins/woocommerce/tests/legacy/unit-tests/coupon/coupon.php
@@ -12,40 +12,18 @@
*/
class WC_Tests_Coupon extends WC_Unit_Test_Case {
- /**
- * Customer shipping address before the test, restored at teardown.
- *
- * @var array<string, string>
- */
- private $previous_shipping_address = array();
-
/**
* Sets up the test class.
*/
public function setUp(): void {
parent::setUp();
- // WC()->customer outlives a test, so keep its location to restore at teardown.
- $this->previous_shipping_address = WC()->customer->get_shipping( 'edit' );
-
// Set a valid address for the customer so shipping rates will calculate.
WC()->customer->set_shipping_country( 'US' );
WC()->customer->set_shipping_state( 'NY' );
WC()->customer->set_shipping_postcode( '12345' );
}
- /**
- * Cleans up after the test class.
- */
- public function tearDown(): void {
- \Automattic\Jetpack\Constants::clear_single_constant( 'WOOCOMMERCE_CHECKOUT' );
- foreach ( $this->previous_shipping_address as $key => $value ) {
- WC()->customer->{"set_shipping_{$key}"}( $value );
- }
-
- parent::tearDown();
- }
-
/**
* Test the code/id differentiation of the coupon constructor.
*
diff --git a/plugins/woocommerce/tests/legacy/unit-tests/payment-gateways/cod.php b/plugins/woocommerce/tests/legacy/unit-tests/payment-gateways/cod.php
index 4041ad03f15..16c5806f578 100644
--- a/plugins/woocommerce/tests/legacy/unit-tests/payment-gateways/cod.php
+++ b/plugins/woocommerce/tests/legacy/unit-tests/payment-gateways/cod.php
@@ -12,14 +12,6 @@ use Automattic\Jetpack\Constants;
*/
class WC_Tests_Payment_Gateway_COD extends WC_Unit_Test_Case {
- /**
- * Clean up after each test.
- */
- public function tearDown(): void {
- parent::tearDown();
-
- Constants::clear_constants();
- }
/**
* Make sure that the options for the "enable_for_methods" setting are not loaded by default.
*/
diff --git a/plugins/woocommerce/tests/php/includes/admin/helper/class-wc-helper-test.php b/plugins/woocommerce/tests/php/includes/admin/helper/class-wc-helper-test.php
index 19238b11faf..5f1e95a5113 100644
--- a/plugins/woocommerce/tests/php/includes/admin/helper/class-wc-helper-test.php
+++ b/plugins/woocommerce/tests/php/includes/admin/helper/class-wc-helper-test.php
@@ -223,19 +223,17 @@ class WC_Helper_Test extends \WC_Unit_Test_Case {
* @testdox get_subscriptions should filter malformed API entries before caching them.
*/
public function test_get_subscriptions_filters_malformed_api_entries(): void {
- $response_data = $this->get_mixed_subscription_data();
- $previous_auth = WC_Helper_Options::get( 'auth', array() );
- $previous_log = WC_Helper::$log;
- $had_wp_debug_override = array_key_exists( 'WP_DEBUG', Constants::$set_constants );
- $previous_wp_debug = Constants::$set_constants['WP_DEBUG'] ?? null;
- $filtered_count = count( $response_data ) - count( $this->get_valid_subscription_data() );
- $http_mock = static function () use ( $response_data ) {
+ $response_data = $this->get_mixed_subscription_data();
+ $previous_auth = WC_Helper_Options::get( 'auth', array() );
+ $previous_log = WC_Helper::$log;
+ $filtered_count = count( $response_data ) - count( $this->get_valid_subscription_data() );
+ $http_mock = static function () use ( $response_data ) {
return array(
'response' => array( 'code' => 200 ),
'body' => wp_json_encode( $response_data ),
);
};
- $logger = $this->createMock( WC_Logger_Interface::class );
+ $logger = $this->createMock( WC_Logger_Interface::class );
$logger->expects( $this->once() )
->method( 'log' )
->with(
@@ -263,11 +261,6 @@ class WC_Helper_Test extends \WC_Unit_Test_Case {
remove_filter( 'pre_http_request', $http_mock );
WC_Helper_Options::update( 'auth', $previous_auth );
WC_Helper::$log = $previous_log;
- if ( $had_wp_debug_override ) {
- Constants::set_constant( 'WP_DEBUG', $previous_wp_debug );
- } else {
- Constants::clear_single_constant( 'WP_DEBUG' );
- }
}
$this->assertSame( $this->get_valid_subscription_data(), $result, 'Only valid API subscriptions should be returned unchanged' );
@@ -381,7 +374,6 @@ class WC_Helper_Test extends \WC_Unit_Test_Case {
* @param string $expected The source label the request should carry.
*/
public function test_get_subscriptions_labels_the_request_source( string $request_uri, string $action, string $expected ): void {
- $previous_uri = isset( $_SERVER['REQUEST_URI'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : null;
$_SERVER['REQUEST_URI'] = $request_uri;
if ( '' !== $action ) {
$_REQUEST['action'] = $action;
@@ -403,11 +395,6 @@ class WC_Helper_Test extends \WC_Unit_Test_Case {
} finally {
remove_filter( 'pre_http_request', $capture, 9 );
unset( $_REQUEST['action'] );
- if ( null === $previous_uri ) {
- unset( $_SERVER['REQUEST_URI'] );
- } else {
- $_SERVER['REQUEST_URI'] = $previous_uri;
- }
}
parse_str( (string) wp_parse_url( $requested_url, PHP_URL_QUERY ), $query );
diff --git a/plugins/woocommerce/tests/php/includes/class-wc-cart-default-shipping-method-test.php b/plugins/woocommerce/tests/php/includes/class-wc-cart-default-shipping-method-test.php
index 56d33cf9060..f2a85305d57 100644
--- a/plugins/woocommerce/tests/php/includes/class-wc-cart-default-shipping-method-test.php
+++ b/plugins/woocommerce/tests/php/includes/class-wc-cart-default-shipping-method-test.php
@@ -12,13 +12,6 @@ declare( strict_types = 1 );
*/
class WC_Cart_Default_Shipping_Method_Test extends WC_Unit_Test_Case {
- /**
- * Customer shipping address before the test, restored at teardown.
- *
- * @var array<string, string>
- */
- private $previous_shipping_address = array();
-
/**
* Set up test fixtures.
*/
@@ -37,19 +30,6 @@ class WC_Cart_Default_Shipping_Method_Test extends WC_Unit_Test_Case {
// Set block checkout context (not shortcode).
WC()->cart->cart_context = 'store-api';
-
- // Tests clear or set the shipping address on WC()->customer, which outlives a test.
- $this->previous_shipping_address = WC()->customer->get_shipping( 'edit' );
- }
-
- /**
- * Tear down test fixtures.
- */
- public function tearDown(): void {
- foreach ( $this->previous_shipping_address as $key => $value ) {
- WC()->customer->{"set_shipping_{$key}"}( $value );
- }
- parent::tearDown();
}
/**
diff --git a/plugins/woocommerce/tests/php/includes/class-wc-cart-test.php b/plugins/woocommerce/tests/php/includes/class-wc-cart-test.php
index d54e41d9218..3879cd5f148 100644
--- a/plugins/woocommerce/tests/php/includes/class-wc-cart-test.php
+++ b/plugins/woocommerce/tests/php/includes/class-wc-cart-test.php
@@ -22,13 +22,6 @@ class WC_Cart_Test extends \WC_Unit_Test_Case {
*/
protected $add_to_cart_quantity_filter_args = array();
- /**
- * Customer shipping address before the test, restored at teardown.
- *
- * @var array<string, string>
- */
- private $previous_shipping_address = array();
-
/**
* Called before every test.
*/
@@ -36,9 +29,6 @@ class WC_Cart_Test extends \WC_Unit_Test_Case {
parent::setUp();
$fixtures = new FixtureData();
$fixtures->shipping_add_flat_rate();
-
- // Several tests change the shipping address on WC()->customer, which outlives a test.
- $this->previous_shipping_address = WC()->customer->get_shipping( 'edit' );
}
/**
@@ -48,9 +38,6 @@ class WC_Cart_Test extends \WC_Unit_Test_Case {
parent::tearDown();
WC()->customer->set_is_vat_exempt( false );
- foreach ( $this->previous_shipping_address as $key => $value ) {
- WC()->customer->{"set_shipping_{$key}"}( $value );
- }
WC()->session->set( 'wc_notices', null );
// The checkout fields may have been built while a test's filters were attached.
@@ -1151,7 +1138,6 @@ class WC_Cart_Test extends \WC_Unit_Test_Case {
$this->assertFalse( WC()->cart->show_shipping(), 'A removed postcode must not stop the state from being required.' );
} finally {
remove_filter( 'woocommerce_checkout_fields', $remove_billing_address );
- WC()->customer->set_shipping_location( '', '', '', '' );
}
}
@@ -1555,13 +1541,7 @@ class WC_Cart_Test extends \WC_Unit_Test_Case {
$product = WC_Helper_Product::create_simple_product();
WC()->cart->add_to_cart( $product->get_id(), 1 );
- $customer = WC()->cart->get_customer();
- $this->original_shipping_address = array(
- 'shipping_country' => $customer->get_shipping_country(),
- 'shipping_state' => $customer->get_shipping_state(),
- 'shipping_city' => $customer->get_shipping_city(),
- 'shipping_postcode' => $customer->get_shipping_postcode(),
- );
+ $customer = WC()->cart->get_customer();
$customer->set_shipping_country( 'GB' );
$customer->set_shipping_state( '' );
$customer->set_shipping_city( '' );
diff --git a/plugins/woocommerce/tests/php/includes/class-wc-form-handler-test.php b/plugins/woocommerce/tests/php/includes/class-wc-form-handler-test.php
index f9049b9c48c..1be65b1cf39 100644
--- a/plugins/woocommerce/tests/php/includes/class-wc-form-handler-test.php
+++ b/plugins/woocommerce/tests/php/includes/class-wc-form-handler-test.php
@@ -704,8 +704,6 @@ class WC_Form_Handler_Test extends WC_Unit_Test_Case {
$this->fail( 'Expected copy_address() to stop a prefetch request.' );
} catch ( WPDieException $e ) {
$this->assertSame( '', ( new WC_Customer( $customer->get_id() ) )->get_shipping_address_1(), 'A prefetch request should not copy the address.' );
- } finally {
- unset( $_SERVER[ $header ] );
}
}
diff --git a/plugins/woocommerce/tests/php/includes/class-wc-product-downloads-test.php b/plugins/woocommerce/tests/php/includes/class-wc-product-downloads-test.php
index 601266010c2..2c3727508b1 100644
--- a/plugins/woocommerce/tests/php/includes/class-wc-product-downloads-test.php
+++ b/plugins/woocommerce/tests/php/includes/class-wc-product-downloads-test.php
@@ -39,7 +39,6 @@ class WC_Product_Download_Test extends WC_Unit_Test_Case {
$download->set_file( $file_path_with_period_at_end );
$this->assertEquals( false, $download->is_allowed_filetype() );
} finally {
- \Automattic\Jetpack\Constants::clear_single_constant( 'PHP_OS' );
$filesystem->delete( $file_path_with_period_at_end );
}
}
diff --git a/plugins/woocommerce/tests/php/includes/class-wc-session-concurrency-test.php b/plugins/woocommerce/tests/php/includes/class-wc-session-concurrency-test.php
index c33182b0dc7..999942388a0 100644
--- a/plugins/woocommerce/tests/php/includes/class-wc-session-concurrency-test.php
+++ b/plugins/woocommerce/tests/php/includes/class-wc-session-concurrency-test.php
@@ -21,7 +21,6 @@ class WC_Session_Concurrency_Test extends WC_Unit_Test_Case {
* Tear down test fixtures.
*/
public function tearDown(): void {
- unset( $_SERVER['HTTP_CART_TOKEN'] );
wp_set_current_user( 0 );
parent::tearDown();
}
diff --git a/plugins/woocommerce/tests/php/includes/rest-api/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller-test.php b/plugins/woocommerce/tests/php/includes/rest-api/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller-test.php
index bd2e1fa5f80..87e493407b9 100644
--- a/plugins/woocommerce/tests/php/includes/rest-api/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller-test.php
+++ b/plugins/woocommerce/tests/php/includes/rest-api/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller-test.php
@@ -239,7 +239,6 @@ class WC_REST_System_Status_Tools_V2_Controller_Test extends WC_REST_Unit_Test_C
$tool = $this->endpoint->get_tools()['regenerate_product_lookup_tables'];
$this->assertStringContainsString( 'View queued updates', $tool['status_text'] );
} finally {
- \Automattic\Jetpack\Constants::clear_single_constant( 'DISABLE_WP_CRON' );
as_unschedule_all_actions( '', array(), 'wc_update_product_lookup_tables' );
}
}
diff --git a/plugins/woocommerce/tests/php/includes/wc-order-step-logger-functions-test.php b/plugins/woocommerce/tests/php/includes/wc-order-step-logger-functions-test.php
index c29ea565dcf..5f6dba261b4 100644
--- a/plugins/woocommerce/tests/php/includes/wc-order-step-logger-functions-test.php
+++ b/plugins/woocommerce/tests/php/includes/wc-order-step-logger-functions-test.php
@@ -57,9 +57,6 @@ class WC_Order_Step_Logger_Functions_Test extends \WC_Unit_Test_Case {
// Clean up log files.
$this->clean_up_log_files();
- // Clear the WC_LOG_THRESHOLD constant if set.
- Constants::clear_single_constant( 'WC_LOG_THRESHOLD' );
-
// Reset logging settings.
delete_option( 'woocommerce_logs_level_threshold' );
diff --git a/plugins/woocommerce/tests/php/includes/wc-update-functions-test.php b/plugins/woocommerce/tests/php/includes/wc-update-functions-test.php
index acd6653482a..70ef3be6906 100644
--- a/plugins/woocommerce/tests/php/includes/wc-update-functions-test.php
+++ b/plugins/woocommerce/tests/php/includes/wc-update-functions-test.php
@@ -29,7 +29,6 @@ class WC_Update_Functions_Test extends \WC_Unit_Test_Case {
* Tear down test fixtures.
*/
public function tearDown(): void {
- Constants::clear_single_constant( 'WOOCOMMERCE_BIS_ALPHA_ENABLED' );
delete_option( 'woocommerce_feature_customer_stock_notifications_enabled' );
parent::tearDown();
}
diff --git a/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/AddToCartWithOptions.php b/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/AddToCartWithOptions.php
index d328bdc792b..8d52599c4fc 100644
--- a/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/AddToCartWithOptions.php
+++ b/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/AddToCartWithOptions.php
@@ -15,13 +15,13 @@ use Automattic\WooCommerce\Internal\Features\FeaturesController;
/**
* Tests for the AddToCartWithOptions block type
*/
-class AddToCartWithOptions extends \WP_UnitTestCase {
+class AddToCartWithOptions extends \WC_Unit_Test_Case {
use BlockTypeRegistryTrait;
/**
* Initiate the mock object.
*/
- protected function setUp(): void {
+ public function setUp(): void {
parent::setUp();
// The blocks are not registered on `init`, because `init` runs with a classic theme.
@@ -730,7 +730,6 @@ class AddToCartWithOptions extends \WP_UnitTestCase {
$markup = do_blocks( $block );
$this->assertStringNotContainsString( $marker, $markup, 'The Add to Wishlist Button is not injected when the wishlist feature is disabled.' );
} finally {
- $registry->unregister( 'woocommerce/add-to-wishlist-button' );
$features->change_feature_enable( 'product_wishlist', $original );
}
}
diff --git a/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/BlockHooksTests.php b/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/BlockHooksTests.php
index 61dd8a0245e..19bc9dcd0b6 100644
--- a/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/BlockHooksTests.php
+++ b/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/BlockHooksTests.php
@@ -6,12 +6,12 @@ namespace Automattic\WooCommerce\Tests\Blocks\BlockTypes;
use Automattic\WooCommerce\Tests\Blocks\Mocks\BlockHooksTestBlock;
use Automattic\WooCommerce\Tests\Blocks\Mocks\BlockHooksLowerVersionTestBlock;
use Automattic\WooCommerce\Tests\Blocks\Mocks\BlockHooksNoVersionTestBlock;
-use WP_UnitTestCase;
+use WC_Unit_Test_Case;
/**
* Tests Block Hooks logic.
*/
-class BlockHooksTests extends WP_UnitTestCase {
+class BlockHooksTests extends WC_Unit_Test_Case {
/**
* Option name for storing the block hooks version.
*
@@ -19,18 +19,6 @@ class BlockHooksTests extends WP_UnitTestCase {
*/
protected static $option_name = 'woocommerce_hooked_blocks_version';
- /**
- * Clean up the mock block registration.
- */
- public function tearDown(): void {
- $registry = \WP_Block_Type_Registry::get_instance();
- if ( $registry->is_registered( 'woocommerce/test-block' ) ) {
- unregister_block_type( 'woocommerce/test-block' );
- }
-
- parent::tearDown();
- }
-
/**
* @testdox Should hook the mock block when the configured version meets the placement requirement.
*/
diff --git a/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/Checkout.php b/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/Checkout.php
index af3c94628ed..63059f8eaf8 100644
--- a/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/Checkout.php
+++ b/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/Checkout.php
@@ -64,11 +64,6 @@ class Checkout extends \WC_Unit_Test_Case {
public function tearDown(): void {
parent::tearDown();
- // A test registers a CheckoutMock block type, and the block type registry outlives a test.
- if ( \WP_Block_Type_Registry::get_instance()->is_registered( 'woocommerce/checkout-mock' ) ) {
- \WP_Block_Type_Registry::get_instance()->unregister( 'woocommerce/checkout-mock' );
- }
-
// A test sets an admin screen so is_admin() is true.
unset( $GLOBALS['current_screen'] );
}
diff --git a/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/CouponCodeTest.php b/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/CouponCodeTest.php
index 5668d8bf723..9222c862928 100644
--- a/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/CouponCodeTest.php
+++ b/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/CouponCodeTest.php
@@ -12,7 +12,7 @@ use Automattic\WooCommerce\EmailEditor\Engine\Renderer\ContentRenderer\Rendering
/**
* Tests for the CouponCode block type.
*/
-class CouponCodeTest extends \WP_UnitTestCase {
+class CouponCodeTest extends \WC_Unit_Test_Case {
use BlockTypeRegistryTrait;
/**
diff --git a/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/MiniCart.php b/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/MiniCart.php
index 22c35d1e4d7..a8918df5b7c 100644
--- a/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/MiniCart.php
+++ b/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/MiniCart.php
@@ -15,7 +15,7 @@ use Automattic\WooCommerce\Tests\Blocks\Mocks\MiniCartMock;
*
* @since $VID:$
*/
-class MiniCart extends \WP_UnitTestCase {
+class MiniCart extends \WC_Unit_Test_Case {
use BlockTypeRegistryTrait;
/**
@@ -133,16 +133,6 @@ class MiniCart extends \WP_UnitTestCase {
add_filter( 'woocommerce_is_rest_api_request', '__return_false', 1 );
}
- /**
- * Tear down test. Called after every test.
- * @return void
- */
- public function tearDown(): void {
- parent::tearDown();
- WC()->cart->empty_cart();
- remove_filter( 'woocommerce_is_rest_api_request', '__return_false', 1 );
- }
-
/**
* Checks the output of the MiniCart block is correct based on the productCountVisibility attribute when cart is empty.
* @return void
diff --git a/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/MiniCartFooterBlock.php b/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/MiniCartFooterBlock.php
index 7e9f94ef280..74d97ada13b 100644
--- a/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/MiniCartFooterBlock.php
+++ b/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/MiniCartFooterBlock.php
@@ -14,7 +14,7 @@ use Automattic\WooCommerce\Tests\Blocks\Helpers\BlockTypeRegistryTrait;
*
* @since 10.4.0
*/
-class MiniCartFooterBlock extends \WP_UnitTestCase {
+class MiniCartFooterBlock extends \WC_Unit_Test_Case {
use BlockTypeRegistryTrait;
/**
@@ -40,14 +40,6 @@ class MiniCartFooterBlock extends \WP_UnitTestCase {
);
}
- /**
- * Tear down test.
- */
- public function tearDown(): void {
- unset( $this->block );
- parent::tearDown();
- }
-
/**
* Data provider for testing get_total_items_description().
*
diff --git a/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/ProductCollection/QueryBuilder.php b/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/ProductCollection/QueryBuilder.php
index d8afcb2808c..e76e390e82a 100644
--- a/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/ProductCollection/QueryBuilder.php
+++ b/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/ProductCollection/QueryBuilder.php
@@ -19,7 +19,7 @@ use WP_Query;
*
* @group query-building
*/
-class QueryBuilder extends \WP_UnitTestCase {
+class QueryBuilder extends \WC_Unit_Test_Case {
/**
* This variable holds our Product Query object.
*
@@ -35,9 +35,7 @@ class QueryBuilder extends \WP_UnitTestCase {
* @param bool $legacy_filterable Previously saved filterable value.
*/
public function test_local_filter_products( int $query_id, bool $legacy_filterable ): void {
- // phpcs:ignore WordPress.Security.ValidatedSanitizedInput -- Restore the original request verbatim after the test.
- $original_uri = $_SERVER['REQUEST_URI'] ?? null;
- $products = array();
+ $products = array();
foreach ( array( '10.25', '15.28', '5' ) as $price ) {
$product = WC_Helper_Product::create_simple_product();
$product->set_regular_price( $price );
@@ -64,18 +62,13 @@ class QueryBuilder extends \WP_UnitTestCase {
$this->assertEqualsCanonicalizing( array_slice( $products, 0, 2 ), wp_list_pluck( ( new WP_Query( $query ) )->posts, 'ID' ) );
} finally {
set_query_var( 'min_price', '' );
- if ( null === $original_uri ) {
- unset( $_SERVER['REQUEST_URI'] );
- } else {
- $_SERVER['REQUEST_URI'] = $original_uri;
- }
}
}
/**
* Initiate the mock object.
*/
- protected function setUp(): void {
+ public function setUp(): void {
parent::setUp();
$this->block_instance = new ProductCollectionMock();
}
diff --git a/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/ProductFilters.php b/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/ProductFilters.php
index 28c9fbf7cfd..fe01e97a756 100644
--- a/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/ProductFilters.php
+++ b/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/ProductFilters.php
@@ -13,7 +13,7 @@ use Automattic\WooCommerce\Tests\Blocks\Mocks\AssetDataRegistryMock;
/**
* Tests for the ProductFilters block type.
*/
-class ProductFilters extends \WP_UnitTestCase {
+class ProductFilters extends \WC_Unit_Test_Case {
/**
* Test-only filter block name.
@@ -89,28 +89,19 @@ class ProductFilters extends \WP_UnitTestCase {
. '</div><!-- /wp:woocommerce/product-filter-taxonomy --></div><!-- /wp:woocommerce/product-filters -->'
. '<!-- wp:woocommerce/product-template --><!-- wp:post-title /--><!-- /wp:woocommerce/product-template -->'
. '</div><!-- /wp:woocommerce/product-collection -->';
- // phpcs:ignore WordPress.Security.ValidatedSanitizedInput -- Restore the original request verbatim after the test.
- $original_uri = $_SERVER['REQUEST_URI'] ?? null;
- try {
- $_SERVER['REQUEST_URI'] = '/?wcp-0-categories=local-blue&wcp-0-min_price=20&min_price=999';
- $html = do_blocks( $markup );
- $this->assertStringContainsString( 'wp-block-woocommerce-product-collection', $html );
- $this->assertStringNotContainsString( 'wp-block-post-title', $html );
- $this->assertStringContainsString( 'aria-label="Local red"', $html );
- $this->assertStringNotContainsString( 'aria-label="Local blue"', $html );
- $this->assertStringContainsString( 'data-wp-text="context.item.count">1</span>', $html );
-
- $_SERVER['REQUEST_URI'] = '/?wcp-0-categories=local-red&min_price=999';
- $html = do_blocks( $markup );
- $this->assertStringContainsString( 'wp-block-post-title', $html );
- $this->assertStringContainsString( 'data-wp-text="context.item.count">2</span>', $html );
- } finally {
- if ( null === $original_uri ) {
- unset( $_SERVER['REQUEST_URI'] );
- } else {
- $_SERVER['REQUEST_URI'] = $original_uri;
- }
- }
+
+ $_SERVER['REQUEST_URI'] = '/?wcp-0-categories=local-blue&wcp-0-min_price=20&min_price=999';
+ $html = do_blocks( $markup );
+ $this->assertStringContainsString( 'wp-block-woocommerce-product-collection', $html );
+ $this->assertStringNotContainsString( 'wp-block-post-title', $html );
+ $this->assertStringContainsString( 'aria-label="Local red"', $html );
+ $this->assertStringNotContainsString( 'aria-label="Local blue"', $html );
+ $this->assertStringContainsString( 'data-wp-text="context.item.count">1</span>', $html );
+
+ $_SERVER['REQUEST_URI'] = '/?wcp-0-categories=local-red&min_price=999';
+ $html = do_blocks( $markup );
+ $this->assertStringContainsString( 'wp-block-post-title', $html );
+ $this->assertStringContainsString( 'data-wp-text="context.item.count">2</span>', $html );
}
/**
@@ -118,7 +109,7 @@ class ProductFilters extends \WP_UnitTestCase {
*
* @return void
*/
- protected function setUp(): void {
+ public function setUp(): void {
parent::setUp();
$asset_api = Package::container()->get( Api::class );
@@ -169,17 +160,13 @@ class ProductFilters extends \WP_UnitTestCase {
*
* @return void
*/
- protected function tearDown(): void {
+ public function tearDown(): void {
foreach ( array_reverse( $this->registered_filters ) as $filter ) {
remove_filter( $filter['hook'], $filter['callback'], $filter['priority'] );
}
$this->registered_filters = [];
- if ( \WP_Block_Type_Registry::get_instance()->is_registered( self::TEST_FILTER_BLOCK ) ) {
- unregister_block_type( self::TEST_FILTER_BLOCK );
- }
-
parent::tearDown();
}
diff --git a/plugins/woocommerce/tests/php/src/Blocks/BlockTypesController.php b/plugins/woocommerce/tests/php/src/Blocks/BlockTypesController.php
index ce644be78e1..ec31187db0d 100644
--- a/plugins/woocommerce/tests/php/src/Blocks/BlockTypesController.php
+++ b/plugins/woocommerce/tests/php/src/Blocks/BlockTypesController.php
@@ -36,23 +36,6 @@ class BlockTypesController extends WC_Unit_Test_Case {
);
}
- /**
- * Remove the block types test_block_should_have_data_attributes() registers, since the
- * block type registry outlives a test.
- */
- public function tearDown(): void {
- try {
- $registry = \WP_Block_Type_Registry::get_instance();
- foreach ( array( 'unrelated-namespace/unrelated-block-name', 'namespace/allowed-block-name', 'allowed-namespace/block-name', 'child-of-woo/block-name' ) as $block_name ) {
- if ( $registry->is_registered( $block_name ) ) {
- $registry->unregister( $block_name );
- }
- }
- } finally {
- parent::tearDown();
- }
- }
-
/**
* @testdox Should identify blocks that should have data attributes.
*/
diff --git a/plugins/woocommerce/tests/php/src/Blocks/Helpers/BlockTypeRegistryTrait.php b/plugins/woocommerce/tests/php/src/Blocks/Helpers/BlockTypeRegistryTrait.php
index 5274e1f384d..c7408325ccb 100644
--- a/plugins/woocommerce/tests/php/src/Blocks/Helpers/BlockTypeRegistryTrait.php
+++ b/plugins/woocommerce/tests/php/src/Blocks/Helpers/BlockTypeRegistryTrait.php
@@ -4,21 +4,13 @@ declare( strict_types = 1 );
namespace Automattic\WooCommerce\Tests\Blocks\Helpers;
/**
- * Registers block types for a test and puts the block type registry back as the test found it.
+ * Registers block types for a test in place of whatever is registered under their names.
*
- * Constructing a block class registers its block type, and WP_Block_Type_Registry outlives a
- * test, so a type registered without cleanup changes what every later test sees.
- * PHPUnit restores the replaced types automatically after each test.
+ * It does not clean up: WC_Unit_Test_Case puts the block type registry back after each test,
+ * so use this only in classes that extend it.
*/
trait BlockTypeRegistryTrait {
- /**
- * What each replaced name had registered before the test, or null when it had nothing.
- *
- * @var array<string, \WP_Block_Type|null>
- */
- private $block_types_before_test = array();
-
/**
* Register a block type for this test in place of whatever is registered under its name.
*
@@ -30,10 +22,7 @@ trait BlockTypeRegistryTrait {
protected function replace_block_type( string $block_name, callable $register ) {
$registry = \WP_Block_Type_Registry::get_instance();
- if ( ! array_key_exists( $block_name, $this->block_types_before_test ) ) {
- $this->block_types_before_test[ $block_name ] = $registry->get_registered( $block_name );
- }
-
+ // Constructing a block class registers it, and the registry rejects a name that is taken.
if ( $registry->is_registered( $block_name ) ) {
$registry->unregister( $block_name );
}
@@ -57,24 +46,4 @@ trait BlockTypeRegistryTrait {
$this->replace_block_type( $block_name, static fn () => new $block_class() );
}
}
-
- /**
- * Put back the block types replaced during the test, and remove the ones that were new.
- *
- * @after
- */
- protected function restore_block_types(): void {
- $registry = \WP_Block_Type_Registry::get_instance();
-
- foreach ( $this->block_types_before_test as $block_name => $block_type ) {
- if ( $registry->is_registered( $block_name ) ) {
- $registry->unregister( $block_name );
- }
- if ( $block_type ) {
- $registry->register( $block_type );
- }
- }
-
- $this->block_types_before_test = array();
- }
}
diff --git a/plugins/woocommerce/tests/php/src/Blocks/Helpers/BlockTypeRegistryTraitTest.php b/plugins/woocommerce/tests/php/src/Blocks/Helpers/BlockTypeRegistryTraitTest.php
index 4d4a738e5bc..2edb66c313a 100644
--- a/plugins/woocommerce/tests/php/src/Blocks/Helpers/BlockTypeRegistryTraitTest.php
+++ b/plugins/woocommerce/tests/php/src/Blocks/Helpers/BlockTypeRegistryTraitTest.php
@@ -13,69 +13,16 @@ class BlockTypeRegistryTraitTest extends WC_Unit_Test_Case {
use BlockTypeRegistryTrait;
/**
- * Names that outlive restore_block_types(): the original a test puts back, and the name
- * a callback registers without the trait tracking it.
+ * @testdox Replacing a registered block type registers the replacement under its name.
*/
- private const TEST_BLOCK_NAMES = array( 'woocommerce-test/swapped', 'woocommerce-test/other' );
-
- /**
- * Remove anything a test left registered.
- */
- public function tearDown(): void {
- try {
- // Restore before removing the synthetic originals, since @after runs after tearDown().
- $this->restore_block_types();
- $registry = \WP_Block_Type_Registry::get_instance();
- foreach ( self::TEST_BLOCK_NAMES as $block_name ) {
- if ( $registry->is_registered( $block_name ) ) {
- $registry->unregister( $block_name );
- }
- }
- } finally {
- parent::tearDown();
- }
- }
-
- /**
- * @testdox Replacing a registered block type puts the original back on restore.
- */
- public function test_replacing_a_registered_block_type_puts_the_original_back(): void {
+ public function test_replacing_a_registered_block_type_registers_the_replacement(): void {
$original = register_block_type( 'woocommerce-test/swapped', array( 'title' => 'Original' ) );
$replacement = $this->replace_block_type( 'woocommerce-test/swapped', static fn () => register_block_type( 'woocommerce-test/swapped', array( 'title' => 'Replacement' ) ) );
- $registry = \WP_Block_Type_Registry::get_instance();
- $this->assertSame( $replacement, $registry->get_registered( 'woocommerce-test/swapped' ), 'The replacement should be registered during the test.' );
-
- $this->restore_block_types();
-
- $this->assertSame( $original, $registry->get_registered( 'woocommerce-test/swapped' ), 'The original block type should be registered again.' );
- }
-
- /**
- * @testdox A block type that was not registered before the test is removed on restore.
- */
- public function test_a_block_type_that_was_not_registered_is_removed(): void {
- $this->replace_block_type( 'woocommerce-test/swapped', static fn () => register_block_type( 'woocommerce-test/swapped' ) );
-
- $this->restore_block_types();
-
- $this->assertFalse( \WP_Block_Type_Registry::get_instance()->is_registered( 'woocommerce-test/swapped' ), 'A block type the test added should not stay registered.' );
- }
-
- /**
- * @testdox Replacing the same name twice in a test still restores the block type from before the test.
- */
- public function test_replacing_twice_restores_the_block_type_from_before_the_test(): void {
- $original = register_block_type( 'woocommerce-test/swapped', array( 'title' => 'Original' ) );
-
- foreach ( array( 'First', 'Second' ) as $title ) {
- $this->replace_block_type( 'woocommerce-test/swapped', static fn () => register_block_type( 'woocommerce-test/swapped', array( 'title' => $title ) ) );
- }
-
- $this->restore_block_types();
-
- $this->assertSame( $original, \WP_Block_Type_Registry::get_instance()->get_registered( 'woocommerce-test/swapped' ), 'The block type from before the first replacement should come back.' );
+ $this->assertInstanceOf( \WP_Block_Type::class, $replacement, 'The replacement should register without a conflict.' );
+ $this->assertNotSame( $original, $replacement, 'The replacement should be a new block type.' );
+ $this->assertSame( $replacement, \WP_Block_Type_Registry::get_instance()->get_registered( 'woocommerce-test/swapped' ), 'The replacement should be registered during the test.' );
}
/**
@@ -97,35 +44,10 @@ class BlockTypeRegistryTraitTest extends WC_Unit_Test_Case {
* @testdox A callback that registers a different name than the one replaced is rejected.
*/
public function test_a_callback_that_registers_another_name_is_rejected(): void {
- $original = register_block_type( 'woocommerce-test/swapped', array( 'title' => 'Original' ) );
- $this->expectException( \LogicException::class );
+ register_block_type( 'woocommerce-test/swapped', array( 'title' => 'Original' ) );
- try {
- $this->replace_block_type( 'woocommerce-test/swapped', static fn () => register_block_type( 'woocommerce-test/other' ) );
- } finally {
- $this->restore_block_types();
- $this->assertSame( $original, \WP_Block_Type_Registry::get_instance()->get_registered( 'woocommerce-test/swapped' ), 'The original block type should be restored after a rejected callback.' );
- }
- }
-
- /**
- * @testdox PHPUnit restores the original block type without an explicit teardown call.
- */
- public function test_phpunit_restores_block_types_automatically(): void {
- $original = register_block_type( 'woocommerce-test/swapped', array( 'title' => 'Original' ) );
- $test = new class( 'test_replace_block_type' ) extends \PHPUnit\Framework\TestCase {
- use BlockTypeRegistryTrait;
-
- /**
- * @testdox A block type can be replaced during a test.
- */
- public function test_replace_block_type(): void {
- $this->replace_block_type( 'woocommerce-test/swapped', static fn () => register_block_type( 'woocommerce-test/swapped' ) );
- }
- };
-
- $test->runBare();
+ $this->expectException( \LogicException::class );
- $this->assertSame( $original, \WP_Block_Type_Registry::get_instance()->get_registered( 'woocommerce-test/swapped' ), 'PHPUnit should restore the original block type after the test.' );
+ $this->replace_block_type( 'woocommerce-test/swapped', static fn () => register_block_type( 'woocommerce-test/other' ) );
}
}
diff --git a/plugins/woocommerce/tests/php/src/Blocks/Shipping/ShippingControllerTest.php b/plugins/woocommerce/tests/php/src/Blocks/Shipping/ShippingControllerTest.php
index 80bfea5a4d9..7a4ab2dc517 100644
--- a/plugins/woocommerce/tests/php/src/Blocks/Shipping/ShippingControllerTest.php
+++ b/plugins/woocommerce/tests/php/src/Blocks/Shipping/ShippingControllerTest.php
@@ -32,13 +32,6 @@ class ShippingControllerTest extends \WC_Unit_Test_Case {
*/
private $backup_wc;
- /**
- * Customer shipping address before the test, restored at teardown.
- *
- * @var array<string, string>
- */
- private $previous_shipping_address = array();
-
/**
* Initialize the registry instance.
*
@@ -75,8 +68,6 @@ class ShippingControllerTest extends \WC_Unit_Test_Case {
Package::container()->get( Api::class ),
Package::container()->get( AssetDataRegistry::class )
);
- // WC()->customer outlives the test, so keep its location to restore at teardown.
- $this->previous_shipping_address = WC()->customer->get_shipping( 'edit' );
WC()->customer->set_shipping_postcode( '' );
WC()->customer->set_shipping_city( '' );
WC()->customer->set_shipping_state( '' );
@@ -94,9 +85,6 @@ class ShippingControllerTest extends \WC_Unit_Test_Case {
try {
$woocommerce = $this->backup_wc;
WC()->session->set( 'chosen_shipping_methods', null );
- foreach ( $this->previous_shipping_address as $key => $value ) {
- WC()->customer->{"set_shipping_{$key}"}( $value );
- }
// A test may null WC()->shipping, which leaves a dynamic property on the WC singleton.
unset( WC()->shipping );
} finally {
diff --git a/plugins/woocommerce/tests/php/src/Blocks/StoreApi/Routes/UnexpectedErrorHandlingTest.php b/plugins/woocommerce/tests/php/src/Blocks/StoreApi/Routes/UnexpectedErrorHandlingTest.php
index 7c30d575bfe..c1349bd4867 100644
--- a/plugins/woocommerce/tests/php/src/Blocks/StoreApi/Routes/UnexpectedErrorHandlingTest.php
+++ b/plugins/woocommerce/tests/php/src/Blocks/StoreApi/Routes/UnexpectedErrorHandlingTest.php
@@ -32,7 +32,6 @@ class UnexpectedErrorHandlingTest extends WC_Unit_Test_Case {
*/
public function tearDown(): void {
wp_set_current_user( 0 );
- Constants::clear_single_constant( 'WP_DEBUG' );
parent::tearDown();
}
diff --git a/plugins/woocommerce/tests/php/src/Blocks/StoreApi/Utilities/OrderControllerTests.php b/plugins/woocommerce/tests/php/src/Blocks/StoreApi/Utilities/OrderControllerTests.php
index 39517b552c6..484bfb6166d 100644
--- a/plugins/woocommerce/tests/php/src/Blocks/StoreApi/Utilities/OrderControllerTests.php
+++ b/plugins/woocommerce/tests/php/src/Blocks/StoreApi/Utilities/OrderControllerTests.php
@@ -21,13 +21,6 @@ class OrderControllerTests extends \WC_Unit_Test_Case {
*/
private $sut;
- /**
- * Customer shipping address before the test, restored at teardown.
- *
- * @var array<string, string>
- */
- private $previous_shipping_address = array();
-
/**
* Set up before test.
*
@@ -43,9 +36,7 @@ class OrderControllerTests extends \WC_Unit_Test_Case {
update_option( 'woocommerce_checkout_phone_field', 'optional' );
// The invalid-address tests need a shipping rate, and the flat rate only offers one for a
- // country the store ships to. The cart ships to WC()->customer, which outlives a test, so
- // give it a US/CA location here rather than depend on the address it arrives with.
- $this->previous_shipping_address = WC()->customer->get_shipping( 'edit' );
+ // country the store ships to. The cart ships to WC()->customer, so give it a US/CA location.
WC()->customer->set_shipping_location( 'US', 'CA' );
$this->sut = new class() extends OrderController {
@@ -62,19 +53,6 @@ class OrderControllerTests extends \WC_Unit_Test_Case {
};
}
- /**
- * Put back the customer shipping location that setUp() replaced.
- */
- public function tearDown(): void {
- try {
- foreach ( $this->previous_shipping_address as $key => $value ) {
- WC()->customer->{"set_shipping_{$key}"}( $value );
- }
- } finally {
- parent::tearDown();
- }
- }
-
/**
* test_validate_existing_order_before_payment_valid_data.
*/
diff --git a/plugins/woocommerce/tests/php/src/Blocks/StoreApi/Utilities/UnexpectedErrorResponseTest.php b/plugins/woocommerce/tests/php/src/Blocks/StoreApi/Utilities/UnexpectedErrorResponseTest.php
index 8469371c01b..49b0a42cd0c 100644
--- a/plugins/woocommerce/tests/php/src/Blocks/StoreApi/Utilities/UnexpectedErrorResponseTest.php
+++ b/plugins/woocommerce/tests/php/src/Blocks/StoreApi/Utilities/UnexpectedErrorResponseTest.php
@@ -31,7 +31,6 @@ class UnexpectedErrorResponseTest extends WC_Unit_Test_Case {
*/
public function tearDown(): void {
wp_set_current_user( 0 );
- Constants::clear_single_constant( 'WP_DEBUG' );
parent::tearDown();
}
diff --git a/plugins/woocommerce/tests/php/src/Gateways/ShippingMethodRestrictionsTraitTest.php b/plugins/woocommerce/tests/php/src/Gateways/ShippingMethodRestrictionsTraitTest.php
index 3e086eb9c78..6e2d12774ed 100644
--- a/plugins/woocommerce/tests/php/src/Gateways/ShippingMethodRestrictionsTraitTest.php
+++ b/plugins/woocommerce/tests/php/src/Gateways/ShippingMethodRestrictionsTraitTest.php
@@ -76,7 +76,6 @@ class ShippingMethodRestrictionsTraitTest extends WC_Unit_Test_Case {
$this->set_order_pay_query_var( null );
set_query_var( 'wc-ajax', '' );
remove_all_actions( 'wc_ajax_shipping_restrictions_test' );
- Constants::clear_single_constant( 'WC_DOING_AJAX' );
WC()->session->set( 'chosen_shipping_methods', null );
WC_Cache_Helper::get_transient_version( 'shipping', true );
WC()->shipping()->enabled = $this->shipping_was_enabled;
diff --git a/plugins/woocommerce/tests/php/src/Internal/Abilities/AbilitiesTrackingTest.php b/plugins/woocommerce/tests/php/src/Internal/Abilities/AbilitiesTrackingTest.php
index ed8ee673402..c4b4f423e9d 100644
--- a/plugins/woocommerce/tests/php/src/Internal/Abilities/AbilitiesTrackingTest.php
+++ b/plugins/woocommerce/tests/php/src/Internal/Abilities/AbilitiesTrackingTest.php
@@ -28,8 +28,6 @@ class AbilitiesTrackingTest extends WC_Unit_Test_Case {
*/
private const ADAPTER_DISCOVERY_IDS = array( 'mcp-adapter/get-ability-info', 'mcp-adapter/discover-abilities' );
- private const SERVER_KEYS = array( 'REQUEST_SCHEME', 'HTTP_HOST', 'REQUEST_URI', 'HTTP_REFERER', 'HTTP_MCP_PROTOCOL_VERSION', 'HTTP_MCP_SESSION_ID', 'A8C_PROXIED_REQUEST' );
-
/**
* Hooks that exist only on WordPress 7.1. Removed from this instance to exercise the 7.0 path.
*
@@ -87,13 +85,6 @@ class AbilitiesTrackingTest extends WC_Unit_Test_Case {
*/
private array $original_action_counts = array();
- /**
- * Original $_SERVER values, restored on tear down.
- *
- * @var array<string, mixed>
- */
- private array $original_server = array();
-
/**
* Adapter discovery stand-ins this test registered, so real MCP Adapter abilities are left alone.
*
@@ -124,10 +115,6 @@ class AbilitiesTrackingTest extends WC_Unit_Test_Case {
// The Abilities API registry requires init to have fired.
$wp_actions['init'] = max( 1, (int) ( $wp_actions['init'] ?? 0 ) ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
- foreach ( self::SERVER_KEYS as $key ) {
- $this->original_server[ $key ] = $_SERVER[ $key ] ?? null; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
- }
-
wp_set_current_user( self::$administrator_id );
$this->register_test_abilities();
@@ -162,14 +149,6 @@ class AbilitiesTrackingTest extends WC_Unit_Test_Case {
$wp_actions[ $action ] = $original_count; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
}
}
-
- foreach ( $this->original_server as $key => $value ) {
- if ( null === $value ) {
- unset( $_SERVER[ $key ] );
- } else {
- $_SERVER[ $key ] = $value;
- }
- }
} finally {
parent::tearDown();
}
diff --git a/plugins/woocommerce/tests/php/src/Internal/Admin/Logging/SettingsTest.php b/plugins/woocommerce/tests/php/src/Internal/Admin/Logging/SettingsTest.php
index e6af7a35a1a..72ccbec918f 100644
--- a/plugins/woocommerce/tests/php/src/Internal/Admin/Logging/SettingsTest.php
+++ b/plugins/woocommerce/tests/php/src/Internal/Admin/Logging/SettingsTest.php
@@ -204,8 +204,6 @@ class SettingsTest extends WC_Unit_Test_Case {
Constants::set_constant( 'WC_LOG_HANDLER', 'Fluffernutter' );
$handler = $this->sut->get_default_handler();
$this->assertEquals( LogHandlerFileV2::class, $handler );
-
- Constants::clear_single_constant( 'WC_LOG_HANDLER' );
}
/**
@@ -300,8 +298,6 @@ class SettingsTest extends WC_Unit_Test_Case {
Constants::set_constant( 'WC_LOG_THRESHOLD', 'mascarpone' );
$level = $this->sut->get_level_threshold();
$this->assertEquals( 'none', $level );
-
- Constants::clear_single_constant( 'WC_LOG_THRESHOLD' );
}
/**
@@ -362,8 +358,6 @@ class SettingsTest extends WC_Unit_Test_Case {
'This setting cannot be changed here because it is defined in the <code>WC_LOG_HANDLER</code> constant',
$content
);
-
- Constants::clear_single_constant( 'WC_LOG_HANDLER' );
}
/**
@@ -407,8 +401,6 @@ class SettingsTest extends WC_Unit_Test_Case {
'This setting cannot be changed here because it is defined in the <code>WC_LOG_THRESHOLD</code> constant',
$content
);
-
- Constants::clear_single_constant( 'WC_LOG_THRESHOLD' );
}
/**
diff --git a/plugins/woocommerce/tests/php/src/Internal/Admin/Settings/PaymentsProviders/WooPayments/WooPaymentsRestControllerIntegrationTest.php b/plugins/woocommerce/tests/php/src/Internal/Admin/Settings/PaymentsProviders/WooPayments/WooPaymentsRestControllerIntegrationTest.php
index 65e7cc78cf7..cc3a75589e0 100644
--- a/plugins/woocommerce/tests/php/src/Internal/Admin/Settings/PaymentsProviders/WooPayments/WooPaymentsRestControllerIntegrationTest.php
+++ b/plugins/woocommerce/tests/php/src/Internal/Admin/Settings/PaymentsProviders/WooPayments/WooPaymentsRestControllerIntegrationTest.php
@@ -103,12 +103,6 @@ class WooPaymentsRestControllerIntegrationTest extends WC_Unit_Test_Case {
*/
private static array $initial_option_states = array();
- /** @var bool Whether the WooPayments version override existed before the test. */
- private bool $initial_wcpay_version_override_exists = false;
-
- /** @var mixed WooPayments version override value before the test. */
- private $initial_wcpay_version_override;
-
/**
* Saves values of initial country and currency before running test suite.
*/
@@ -144,8 +138,6 @@ class WooPaymentsRestControllerIntegrationTest extends WC_Unit_Test_Case {
*/
public function setUp(): void {
parent::setUp();
- $this->initial_wcpay_version_override_exists = array_key_exists( 'WCPAY_VERSION_NUMBER', Constants::$set_constants );
- $this->initial_wcpay_version_override = Constants::$set_constants['WCPAY_VERSION_NUMBER'] ?? null;
$gateways = \WC_Payment_Gateways::instance();
$gateways->payment_gateways = array();
@@ -334,7 +326,6 @@ class WooPaymentsRestControllerIntegrationTest extends WC_Unit_Test_Case {
);
$this->run_cleanup_step( fn() => wc_get_container()->reset_all_resolved(), $cleanup_errors );
$this->run_cleanup_step( fn() => $this->clear_rest_server(), $cleanup_errors );
- $this->run_cleanup_step( fn() => $this->restore_wcpay_version_override(), $cleanup_errors );
$this->run_cleanup_step( fn() => parent::tearDown(), $cleanup_errors );
$this->run_cleanup_step( fn() => self::invalidate_test_option_caches(), $cleanup_errors );
@@ -357,17 +348,6 @@ class WooPaymentsRestControllerIntegrationTest extends WC_Unit_Test_Case {
}
}
- /**
- * Restore only the Jetpack constant override owned by this fixture.
- */
- private function restore_wcpay_version_override(): void {
- if ( $this->initial_wcpay_version_override_exists ) {
- Constants::set_constant( 'WCPAY_VERSION_NUMBER', $this->initial_wcpay_version_override );
- } else {
- Constants::clear_single_constant( 'WCPAY_VERSION_NUMBER' );
- }
- }
-
/**
* Get option rows that must survive the class exactly.
*
diff --git a/plugins/woocommerce/tests/php/src/Internal/Admin/Settings/PaymentsProviders/WooPayments/WooPaymentsServiceTest.php b/plugins/woocommerce/tests/php/src/Internal/Admin/Settings/PaymentsProviders/WooPayments/WooPaymentsServiceTest.php
index 67f5cf98735..e7d2d11c7e1 100644
--- a/plugins/woocommerce/tests/php/src/Internal/Admin/Settings/PaymentsProviders/WooPayments/WooPaymentsServiceTest.php
+++ b/plugins/woocommerce/tests/php/src/Internal/Admin/Settings/PaymentsProviders/WooPayments/WooPaymentsServiceTest.php
@@ -206,17 +206,6 @@ class WooPaymentsServiceTest extends WC_Unit_Test_Case {
$this->sut->init( $this->mock_providers, $this->mockable_proxy );
}
- /**
- * Clear the version constant setUp() sets, which would otherwise outlive the class.
- */
- public function tearDown(): void {
- try {
- Constants::clear_single_constant( 'WCPAY_VERSION_NUMBER' );
- } finally {
- parent::tearDown();
- }
- }
-
/**
* Test get onboarding details when the extension is NOT active.
*/
diff --git a/plugins/woocommerce/tests/php/src/Internal/Admin/Settings/PaymentsProviders/WooPaymentsTest.php b/plugins/woocommerce/tests/php/src/Internal/Admin/Settings/PaymentsProviders/WooPaymentsTest.php
index e661d032cf5..6af03bfce9f 100644
--- a/plugins/woocommerce/tests/php/src/Internal/Admin/Settings/PaymentsProviders/WooPaymentsTest.php
+++ b/plugins/woocommerce/tests/php/src/Internal/Admin/Settings/PaymentsProviders/WooPaymentsTest.php
@@ -286,8 +286,6 @@ class WooPaymentsTest extends WC_Unit_Test_Case {
$this->assertTrue( $recommended_pms[3]['enabled'] );
$this->assertSame( PaymentGateway::PAYMENT_METHOD_CATEGORY_SECONDARY, $recommended_pms[3]['category'] );
} finally {
- // Clean up.
- Constants::clear_constants();
$container->reset_replacement( WooPaymentsRestController::class );
}
}
@@ -384,8 +382,6 @@ class WooPaymentsTest extends WC_Unit_Test_Case {
$this->assertArrayHasKey( 'messages', $gateway_details['onboarding'] );
$this->assertArrayHasKey( 'not_supported', $gateway_details['onboarding']['messages'] );
} finally {
- // Clean up.
- Constants::clear_constants();
$container->reset_replacement( WooPaymentsRestController::class );
$container->reset_replacement( WooPaymentsService::class );
}
@@ -449,8 +445,6 @@ class WooPaymentsTest extends WC_Unit_Test_Case {
$this->assertArrayHasKey( 'state', $gateway_details['onboarding'] );
$this->assertTrue( $gateway_details['onboarding']['state']['supported'] );
} finally {
- // Clean up.
- Constants::clear_constants();
$container->reset_replacement( WooPaymentsRestController::class );
$container->reset_replacement( WooPaymentsService::class );
}
@@ -590,19 +584,14 @@ class WooPaymentsTest extends WC_Unit_Test_Case {
// Arrange the version constant.
Constants::set_constant( 'WCPAY_VERSION_NUMBER', WooPaymentsService::EXTENSION_MINIMUM_VERSION );
- try {
- // Act.
- $gateway_details = $this->sut->get_details( $fake_gateway, 0 );
+ // Act.
+ $gateway_details = $this->sut->get_details( $fake_gateway, 0 );
- // Assert - when no country code is provided, supported state should be true by default.
- $this->assertArrayHasKey( 'onboarding', $gateway_details );
- $this->assertArrayHasKey( 'state', $gateway_details['onboarding'] );
- $this->assertArrayHasKey( 'supported', $gateway_details['onboarding']['state'] );
- $this->assertTrue( $gateway_details['onboarding']['state']['supported'] );
- } finally {
- // Clean up.
- Constants::clear_constants();
- }
+ // Assert - when no country code is provided, supported state should be true by default.
+ $this->assertArrayHasKey( 'onboarding', $gateway_details );
+ $this->assertArrayHasKey( 'state', $gateway_details['onboarding'] );
+ $this->assertArrayHasKey( 'supported', $gateway_details['onboarding']['state'] );
+ $this->assertTrue( $gateway_details['onboarding']['state']['supported'] );
}
/**
@@ -650,23 +639,18 @@ class WooPaymentsTest extends WC_Unit_Test_Case {
// Arrange the version constant.
Constants::set_constant( 'WCPAY_VERSION_NUMBER', WooPaymentsService::EXTENSION_MINIMUM_VERSION );
- try {
- // Act.
- $gateway_details = $this->sut->get_details( $fake_gateway, 0, 'XX' );
+ // Act.
+ $gateway_details = $this->sut->get_details( $fake_gateway, 0, 'XX' );
- // Assert - should include the unsupported state and message.
- $this->assertArrayHasKey( 'onboarding', $gateway_details );
- $this->assertArrayHasKey( 'state', $gateway_details['onboarding'] );
- $this->assertArrayHasKey( 'supported', $gateway_details['onboarding']['state'] );
- $this->assertFalse( $gateway_details['onboarding']['state']['supported'] );
+ // Assert - should include the unsupported state and message.
+ $this->assertArrayHasKey( 'onboarding', $gateway_details );
+ $this->assertArrayHasKey( 'state', $gateway_details['onboarding'] );
+ $this->assertArrayHasKey( 'supported', $gateway_details['onboarding']['state'] );
+ $this->assertFalse( $gateway_details['onboarding']['state']['supported'] );
- $this->assertArrayHasKey( 'messages', $gateway_details['onboarding'] );
- $this->assertArrayHasKey( 'not_supported', $gateway_details['onboarding']['messages'] );
- $this->assertEquals( 'WooPayments is not available in your country.', $gateway_details['onboarding']['messages']['not_supported'] );
- } finally {
- // Clean up.
- Constants::clear_constants();
- }
+ $this->assertArrayHasKey( 'messages', $gateway_details['onboarding'] );
+ $this->assertArrayHasKey( 'not_supported', $gateway_details['onboarding']['messages'] );
+ $this->assertEquals( 'WooPayments is not available in your country.', $gateway_details['onboarding']['messages']['not_supported'] );
}
/**
diff --git a/plugins/woocommerce/tests/php/src/Internal/Admin/Settings/PaymentsRestControllerIntegrationTest.php b/plugins/woocommerce/tests/php/src/Internal/Admin/Settings/PaymentsRestControllerIntegrationTest.php
index 7f3525d6e9f..a2c914661a3 100644
--- a/plugins/woocommerce/tests/php/src/Internal/Admin/Settings/PaymentsRestControllerIntegrationTest.php
+++ b/plugins/woocommerce/tests/php/src/Internal/Admin/Settings/PaymentsRestControllerIntegrationTest.php
@@ -126,12 +126,6 @@ class PaymentsRestControllerIntegrationTest extends WC_Unit_Test_Case {
*/
private static array $initial_option_states = array();
- /** @var bool Whether the WooPayments version override existed before the test. */
- private bool $initial_wcpay_version_override_exists = false;
-
- /** @var mixed WooPayments version override value before the test. */
- private $initial_wcpay_version_override;
-
/**
* Saves values of initial country and currency before running test suite.
*/
@@ -167,8 +161,6 @@ class PaymentsRestControllerIntegrationTest extends WC_Unit_Test_Case {
*/
public function setUp(): void {
parent::setUp();
- $this->initial_wcpay_version_override_exists = array_key_exists( 'WCPAY_VERSION_NUMBER', Constants::$set_constants );
- $this->initial_wcpay_version_override = Constants::$set_constants['WCPAY_VERSION_NUMBER'] ?? null;
$gateways = \WC_Payment_Gateways::instance();
$gateways->payment_gateways = array();
@@ -205,7 +197,6 @@ class PaymentsRestControllerIntegrationTest extends WC_Unit_Test_Case {
);
$this->run_cleanup_step( fn() => wc_get_container()->reset_all_resolved(), $cleanup_errors );
$this->run_cleanup_step( fn() => $this->clear_rest_server(), $cleanup_errors );
- $this->run_cleanup_step( fn() => $this->restore_wcpay_version_override(), $cleanup_errors );
$this->run_cleanup_step( fn() => parent::tearDown(), $cleanup_errors );
$this->run_cleanup_step( fn() => self::invalidate_test_option_caches(), $cleanup_errors );
@@ -228,17 +219,6 @@ class PaymentsRestControllerIntegrationTest extends WC_Unit_Test_Case {
}
}
- /**
- * Restore only the Jetpack constant override owned by this fixture.
- */
- private function restore_wcpay_version_override(): void {
- if ( $this->initial_wcpay_version_override_exists ) {
- Constants::set_constant( 'WCPAY_VERSION_NUMBER', $this->initial_wcpay_version_override );
- } else {
- Constants::clear_single_constant( 'WCPAY_VERSION_NUMBER' );
- }
- }
-
/**
* Get option rows that must survive the class exactly.
*
diff --git a/plugins/woocommerce/tests/php/src/Internal/Logging/RemoteLoggerTest.php b/plugins/woocommerce/tests/php/src/Internal/Logging/RemoteLoggerTest.php
index 0bdf2c672f6..880b2c3634e 100644
--- a/plugins/woocommerce/tests/php/src/Internal/Logging/RemoteLoggerTest.php
+++ b/plugins/woocommerce/tests/php/src/Internal/Logging/RemoteLoggerTest.php
@@ -22,9 +22,6 @@ namespace Automattic\WooCommerce\Tests\Internal\Logging {
*/
private $sut;
- /** @var array<string, mixed> Jetpack constant overrides before the test. */
- private array $initial_constant_overrides = array();
-
/** @var array<string, array{exists: bool, value: mixed}> Namespace mock globals before the test. */
private array $initial_mock_globals = array();
@@ -35,7 +32,6 @@ namespace Automattic\WooCommerce\Tests\Internal\Logging {
*/
public function setUp(): void {
parent::setUp();
- $this->initial_constant_overrides = Constants::$set_constants;
foreach ( array( 'mock_filter_input', 'mock_return' ) as $global_name ) {
$this->initial_mock_globals[ $global_name ] = array(
'exists' => array_key_exists( $global_name, $GLOBALS ),
@@ -52,7 +48,6 @@ namespace Automattic\WooCommerce\Tests\Internal\Logging {
*/
public function tearDown(): void {
try {
- Constants::$set_constants = $this->initial_constant_overrides;
foreach ( $this->initial_mock_globals as $global_name => $state ) {
if ( $state['exists'] ) {
$GLOBALS[ $global_name ] = $state['value'];
diff --git a/plugins/woocommerce/tests/php/src/Internal/ProductFilters/ParamsTest.php b/plugins/woocommerce/tests/php/src/Internal/ProductFilters/ParamsTest.php
index 4e2656d7ca1..2fc94551df3 100644
--- a/plugins/woocommerce/tests/php/src/Internal/ProductFilters/ParamsTest.php
+++ b/plugins/woocommerce/tests/php/src/Internal/ProductFilters/ParamsTest.php
@@ -42,27 +42,17 @@ class ParamsTest extends AbstractProductFiltersTest {
};
add_filter( 'woocommerce_product_filter_params', $this->taxonomy_params_filter );
- // phpcs:ignore WordPress.Security.ValidatedSanitizedInput -- Restore the original request verbatim after the test.
- $original_uri = $_SERVER['REQUEST_URI'] ?? null;
- try {
- $_SERVER['REQUEST_URI'] = '/?min_price=5&wcp-0-min_price=10.28&wcp-17-min_price=20&wcp-0-rating_filter[]=4&wcp-0-max_price=invalid&wcp-0-unknown=value&wcp-0-filter_color=blue,red&wcp-0-query_type_color=and&wcp-00-min_price=999&wcp-0-makers=%25e6%2597%25a5';
- $local = $this->sut->get_filter_params( 0 );
- $this->assertSame( '%e6%97%a5', $local['makers'] );
- $this->assertSame( '10.28', $local['min_price'] );
- $this->assertSame( 'blue,red', $local['filter_color'] );
- $this->assertSame( 'and', $local['query_type_color'] );
- $this->assertArrayNotHasKey( 'rating_filter', $local );
- $this->assertArrayNotHasKey( 'max_price', $local );
- $this->assertArrayNotHasKey( 'unknown', $local );
- $this->assertSame( '20', $this->sut->get_filter_params( 17 )['min_price'] );
- $this->assertSame( '5', $this->sut->get_filter_params()['min_price'] );
- } finally {
- if ( null === $original_uri ) {
- unset( $_SERVER['REQUEST_URI'] );
- } else {
- $_SERVER['REQUEST_URI'] = $original_uri;
- }
- }
+ $_SERVER['REQUEST_URI'] = '/?min_price=5&wcp-0-min_price=10.28&wcp-17-min_price=20&wcp-0-rating_filter[]=4&wcp-0-max_price=invalid&wcp-0-unknown=value&wcp-0-filter_color=blue,red&wcp-0-query_type_color=and&wcp-00-min_price=999&wcp-0-makers=%25e6%2597%25a5';
+ $local = $this->sut->get_filter_params( 0 );
+ $this->assertSame( '%e6%97%a5', $local['makers'] );
+ $this->assertSame( '10.28', $local['min_price'] );
+ $this->assertSame( 'blue,red', $local['filter_color'] );
+ $this->assertSame( 'and', $local['query_type_color'] );
+ $this->assertArrayNotHasKey( 'rating_filter', $local );
+ $this->assertArrayNotHasKey( 'max_price', $local );
+ $this->assertArrayNotHasKey( 'unknown', $local );
+ $this->assertSame( '20', $this->sut->get_filter_params( 17 )['min_price'] );
+ $this->assertSame( '5', $this->sut->get_filter_params()['min_price'] );
}
/**
diff --git a/plugins/woocommerce/tests/php/src/Internal/PushNotifications/DataStores/StepLogFileReaderTest.php b/plugins/woocommerce/tests/php/src/Internal/PushNotifications/DataStores/StepLogFileReaderTest.php
index a45617f26dd..05d2d748154 100644
--- a/plugins/woocommerce/tests/php/src/Internal/PushNotifications/DataStores/StepLogFileReaderTest.php
+++ b/plugins/woocommerce/tests/php/src/Internal/PushNotifications/DataStores/StepLogFileReaderTest.php
@@ -56,8 +56,6 @@ class StepLogFileReaderTest extends WC_Unit_Test_Case {
*/
public function tearDown(): void {
try {
- Constants::clear_single_constant( 'WC_LOG_DIR_CUSTOM' );
- Constants::clear_single_constant( 'WC_LOG_DIR' );
FilesystemUtil::get_wp_filesystem_direct()->rmdir( $this->log_directory, true );
} finally {
parent::tearDown();
diff --git a/plugins/woocommerce/tests/php/src/Internal/StockNotifications/Frontend/ProductPageIntegrationTest.php b/plugins/woocommerce/tests/php/src/Internal/StockNotifications/Frontend/ProductPageIntegrationTest.php
index 10a448588f0..c8ef997283e 100644
--- a/plugins/woocommerce/tests/php/src/Internal/StockNotifications/Frontend/ProductPageIntegrationTest.php
+++ b/plugins/woocommerce/tests/php/src/Internal/StockNotifications/Frontend/ProductPageIntegrationTest.php
@@ -26,22 +26,12 @@ class ProductPageIntegrationTest extends WC_Unit_Test_Case {
*/
private $sut;
- /**
- * REQUEST_URI before the test, restored at teardown.
- *
- * @var string|null
- */
- private $request_uri_at_setup;
-
/**
* Set up test fixtures.
*/
public function setUp(): void {
parent::setUp();
- // go_to() sets REQUEST_URI and no base test case puts it back.
- $this->request_uri_at_setup = $_SERVER['REQUEST_URI'] ?? null; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
-
// The blocks are not registered on `init`, because `init` runs with a classic theme.
$this->replace_block_types(
AddToCartWithOptionsMocks::get_mock_classes(
@@ -68,11 +58,6 @@ class ProductPageIntegrationTest extends WC_Unit_Test_Case {
*/
public function tearDown(): void {
try {
- if ( null === $this->request_uri_at_setup ) {
- unset( $_SERVER['REQUEST_URI'] );
- } else {
- $_SERVER['REQUEST_URI'] = $this->request_uri_at_setup;
- }
$this->restore_stock_notifications_feature_option();
} finally {
parent::tearDown();
diff --git a/plugins/woocommerce/tests/php/src/Internal/StockNotifications/StockNotificationsTests.php b/plugins/woocommerce/tests/php/src/Internal/StockNotifications/StockNotificationsTests.php
index fa0623680f1..bf2c564fec4 100644
--- a/plugins/woocommerce/tests/php/src/Internal/StockNotifications/StockNotificationsTests.php
+++ b/plugins/woocommerce/tests/php/src/Internal/StockNotifications/StockNotificationsTests.php
@@ -36,7 +36,6 @@ class StockNotificationsTests extends \WC_Unit_Test_Case {
* Clean up after tests.
*/
public function tearDown(): void {
- Constants::clear_single_constant( 'WOOCOMMERCE_BIS_ALPHA_ENABLED' );
if ( null !== $this->original_db_version ) {
update_option( 'woocommerce_db_version', $this->original_db_version );
$this->original_db_version = null;
diff --git a/plugins/woocommerce/tests/php/src/Internal/StructuredData/OpenGraphTest.php b/plugins/woocommerce/tests/php/src/Internal/StructuredData/OpenGraphTest.php
index 6eac90e111e..e1165a7b27e 100644
--- a/plugins/woocommerce/tests/php/src/Internal/StructuredData/OpenGraphTest.php
+++ b/plugins/woocommerce/tests/php/src/Internal/StructuredData/OpenGraphTest.php
@@ -30,20 +30,12 @@ class OpenGraphTest extends WC_Unit_Test_Case {
*/
private $product;
- /**
- * Request URI before navigating to the product.
- *
- * @var string|null
- */
- private $request_uri;
-
/**
* Set up a published product with a featured image.
*/
public function setUp(): void {
parent::setUp();
- $this->sut = new OpenGraph();
- $this->request_uri = $_SERVER['REQUEST_URI'] ?? null; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput -- Preserve request state changed by go_to().
+ $this->sut = new OpenGraph();
update_option( 'woocommerce_coming_soon', 'no' );
update_option( 'blogname', 'Test store' );
@@ -79,21 +71,6 @@ class OpenGraphTest extends WC_Unit_Test_Case {
$this->go_to( $this->product->get_permalink() );
}
- /**
- * Restore request state that WordPress does not reset.
- */
- public function tearDown(): void {
- try {
- if ( null === $this->request_uri ) {
- unset( $_SERVER['REQUEST_URI'] );
- } else {
- $_SERVER['REQUEST_URI'] = $this->request_uri;
- }
- } finally {
- parent::tearDown();
- }
- }
-
/**
* @testdox Should add missing product metadata and fill empty tags without duplicates.
*/
diff --git a/plugins/woocommerce/tests/php/src/Internal/Utilities/FilesystemUtilTest.php b/plugins/woocommerce/tests/php/src/Internal/Utilities/FilesystemUtilTest.php
index 79fee616ce9..91cf596c9ba 100644
--- a/plugins/woocommerce/tests/php/src/Internal/Utilities/FilesystemUtilTest.php
+++ b/plugins/woocommerce/tests/php/src/Internal/Utilities/FilesystemUtilTest.php
@@ -63,7 +63,6 @@ class FilesystemUtilTest extends WC_Unit_Test_Case {
unset( $GLOBALS['wp_filesystem'] );
$this->reset_legacy_proxy_mocks();
- Constants::clear_constants();
$this->reset_direct_filesystem_cache();
parent::tearDown();
diff --git a/plugins/woocommerce/tests/php/src/UnitTestCaseTearDownTest.php b/plugins/woocommerce/tests/php/src/UnitTestCaseTearDownTest.php
index be60c83ead7..3a6be9b253a 100644
--- a/plugins/woocommerce/tests/php/src/UnitTestCaseTearDownTest.php
+++ b/plugins/woocommerce/tests/php/src/UnitTestCaseTearDownTest.php
@@ -3,9 +3,12 @@ declare( strict_types = 1 );
namespace Automattic\WooCommerce\Tests;
+use Automattic\Jetpack\Constants;
+
/**
- * Tests the state cleanup in WC_Unit_Test_Case: the WC() singleton state that survives the
- * parent teardown, and the attribute taxonomies the rollback leaves registered.
+ * Tests the state cleanup in WC_Unit_Test_Case: the WC() singleton, $_SERVER, Constants and
+ * block type state that survives the parent teardown, and the attribute taxonomies the
+ * rollback leaves registered.
*
* This drives the cleanup methods directly rather than dirtying state in one test and
* asserting it is gone in the next. A pair like that only holds under declaration order: run
@@ -80,6 +83,9 @@ class UnitTestCaseTearDownTest extends \WC_Unit_Test_Case {
wc_add_notice( 'Teardown coverage notice.' );
$this->assertSame( 1, wc_notice_count(), 'The notice should be queued.' );
+ $shipping_at_setup = WC()->customer->get_shipping( 'edit' );
+ WC()->customer->set_shipping_location( 'GB', '', 'LEAK 1', 'Leaked city' );
+
$clear_persistent_cart = null;
$cart_emptied_callback = function ( $should_clear_persistent_cart ) use ( &$clear_persistent_cart ) {
$clear_persistent_cart = $should_clear_persistent_cart;
@@ -102,6 +108,7 @@ class UnitTestCaseTearDownTest extends \WC_Unit_Test_Case {
$this->assertSame( 0, wc_notice_count(), 'The notice queue should have been cleared.' );
$this->assertNull( WC()->shipping()->shipping_methods, 'The loaded shipping methods should have been dropped.' );
$this->assertFalse( $clear_persistent_cart, 'Teardown should leave persistent cart cleanup to the database rollback.' );
+ $this->assertSame( $shipping_at_setup, WC()->customer->get_shipping( 'edit' ), 'The customer shipping address should be back to what it was at setUp().' );
$this->assertNotSame(
self::LEAKED_LOCALE_LABEL,
WC()->countries->get_country_locale()['GB']['postcode']['label'] ?? null,
@@ -109,6 +116,141 @@ class UnitTestCaseTearDownTest extends \WC_Unit_Test_Case {
);
}
+ /**
+ * @testdox A test that swaps in another customer or changes its props leaves the setUp() customer behind, unchanged.
+ */
+ public function test_clear_wc_singleton_state_restores_the_customer(): void {
+ $customer_at_setup = WC()->customer;
+ $data_at_setup = $customer_at_setup->get_data();
+ $changes_at_setup = $customer_at_setup->get_changes();
+ $vat_at_setup = $customer_at_setup->get_is_vat_exempt();
+
+ $customer_at_setup->set_billing_country( 'MV' );
+ $customer_at_setup->set_shipping_country( 'NZ' );
+ $customer_at_setup->set_is_vat_exempt( ! $vat_at_setup );
+ WC()->customer = new \WC_Customer( 0, true );
+
+ $this->clear_wc_singleton_state();
+
+ $this->assertSame( $customer_at_setup, WC()->customer, 'The setUp() customer should be back on WC().' );
+ $this->assertSame( $data_at_setup, WC()->customer->get_data(), 'The customer data should be back to what it was at setUp().' );
+ $this->assertSame( $changes_at_setup, WC()->customer->get_changes(), 'Restoring should not add entries to the change set.' );
+ $this->assertSame( $vat_at_setup, WC()->customer->get_is_vat_exempt(), 'The tax exemption should be back to what it was at setUp().' );
+ }
+
+ /**
+ * @testdox Meta a test adds to or changes on the setUp() customer does not outlive the test.
+ */
+ public function test_clear_wc_singleton_state_restores_the_customer_meta(): void {
+ $customer = WC()->customer;
+ $saved_state = new \ReflectionProperty( \WC_Unit_Test_Case::class, 'customer_state_at_setup' );
+ $saved_state->setAccessible( true );
+ $read_state = new \ReflectionMethod( \WC_Unit_Test_Case::class, 'customer_state' );
+ $read_state->setAccessible( true );
+ $state_at_setup = $saved_state->getValue( $this );
+
+ try {
+ // Save a state that already holds meta, so the change below edits a meta object in place.
+ $customer->update_meta_data( '_restored_key', 'original' );
+ $saved_state->setValue( $this, $read_state->invoke( null, $customer ) );
+
+ $customer->update_meta_data( '_restored_key', 'changed' );
+ $customer->add_meta_data( '_added_key', 'added' );
+
+ $this->clear_wc_singleton_state();
+
+ $this->assertSame( 'original', $customer->get_meta( '_restored_key' ), 'Meta changed in place should be back to its saved value.' );
+ $this->assertSame( '', $customer->get_meta( '_added_key' ), 'Meta the test added should be gone.' );
+ } finally {
+ $saved_state->setValue( $this, $state_at_setup );
+ }
+ }
+
+ /**
+ * @testdox $_SERVER changes, including the REQUEST_URI that go_to() sets, do not outlive the test.
+ */
+ public function test_restore_server_superglobal_undoes_server_changes(): void {
+ // phpcs:disable WordPress.Security.ValidatedSanitizedInput
+ $server_at_setup = $_SERVER;
+
+ $this->go_to( home_url( '/?product=leaked-product' ) );
+ $this->assertSame( '/?product=leaked-product', $_SERVER['REQUEST_URI'], 'go_to() should set REQUEST_URI.' );
+ $_SERVER['HTTP_USER_AGENT'] = 'Leaked agent';
+ unset( $_SERVER['REMOTE_ADDR'] );
+
+ $this->restore_server_superglobal();
+
+ $this->assertSame( $server_at_setup, $_SERVER, '$_SERVER should be back to what it was at setUp().' );
+ // phpcs:enable WordPress.Security.ValidatedSanitizedInput
+ }
+
+ /**
+ * @testdox Constants overrides a test sets or clears do not outlive the test.
+ */
+ public function test_restore_constant_overrides_undoes_overrides(): void {
+ $overrides_at_setup = Constants::$set_constants;
+
+ Constants::set_constant( 'WC_TEARDOWN_LEAKED_CONSTANT', 'leaked' );
+ Constants::clear_constants();
+ Constants::set_constant( 'WC_TEARDOWN_LEAKED_CONSTANT', 'leaked' );
+
+ $this->restore_constant_overrides();
+
+ $this->assertSame( $overrides_at_setup, Constants::$set_constants, 'The overrides should be back to what they were at setUp().' );
+ }
+
+ /**
+ * @testdox Block types a test registers, replaces or removes are put back as they were at setUp().
+ */
+ public function test_restore_block_type_registry_undoes_registry_changes(): void {
+ $registry = \WP_Block_Type_Registry::get_instance();
+ $types_at_setup = $registry->get_all_registered();
+ $this->assertGreaterThanOrEqual( 2, count( $types_at_setup ), 'The test replaces one block type registered at setUp() and removes another.' );
+ $replaced_name = array_key_first( $types_at_setup );
+ $removed_name = array_keys( $types_at_setup )[1];
+ $replaced_type = $types_at_setup[ $replaced_name ];
+ $registered_name = 'woocommerce-tests/leaked-block';
+
+ register_block_type( $registered_name );
+ $registry->unregister( $replaced_name );
+ register_block_type( $replaced_name );
+ $registry->unregister( $removed_name );
+
+ $this->restore_block_type_registry();
+
+ $this->assertFalse( $registry->is_registered( $registered_name ), 'A block type the test registered should be gone.' );
+ $this->assertSame( $replaced_type, $registry->get_registered( $replaced_name ), 'A block type the test replaced should be the original again.' );
+ $this->assertSame( $types_at_setup[ $removed_name ], $registry->get_registered( $removed_name ), 'A block type the test removed should be back.' );
+ $this->assertEqualsCanonicalizing( array_keys( $types_at_setup ), array_keys( $registry->get_all_registered() ), 'The registered names should match setUp().' );
+ }
+
+ /**
+ * @testdox The restores leave state alone for a test whose setUp() never reached the base class.
+ */
+ public function test_restores_leave_state_alone_when_setup_did_not_run(): void {
+ // Like a test that skips in setUp() before calling parent::setUp(): PHPUnit still runs its tearDown().
+ $case = new class( 'placeholder' ) extends \WC_Unit_Test_Case {
+ /**
+ * Run the three restores on a case that saved no state.
+ */
+ public function restore_without_setup(): void {
+ $this->restore_server_superglobal();
+ $this->restore_constant_overrides();
+ $this->restore_block_type_registry();
+ }
+ };
+ Constants::set_constant( 'WC_TEARDOWN_TEST_KEPT', 'kept' );
+ $server = $_SERVER;
+ $overrides = Constants::$set_constants;
+ $block_types = \WP_Block_Type_Registry::get_instance()->get_all_registered();
+
+ $case->restore_without_setup();
+
+ $this->assertSame( $server, $_SERVER, '$_SERVER should be left as it was.' );
+ $this->assertSame( $overrides, Constants::$set_constants, 'Constants overrides should be left as they were.' );
+ $this->assertSame( $block_types, \WP_Block_Type_Registry::get_instance()->get_all_registered(), 'The block type registry should be left as it was.' );
+ }
+
/**
* @testdox Setup unregisters a pa_* taxonomy an earlier test left without an attribute row.
*/