Commit 180a5e867d5 for woocommerce
commit 180a5e867d54fff2e03f19a9b1c981fb0d98095b
Author: Vlad Olaru <vlad.olaru@automattic.com>
Date: Fri Sep 18 21:14:36 2026 +0300
[tests] Add payment gateway state and ordering coverage to the REST API tests (#68284)
* test(rest-api): Fix system status route and add gateway state coverage
The V3 system status tests dispatched against the wc/v2 route, so they never
exercised the controller they are named for, and their tools tests keyed on
regenerate_thumbnails, which the controller removes when Jetpack Photon is
active. The payment gateway tests asserted a POST echo of enabled but never
proved the stored gateway settings changed.
Point the system status tests at wc/v3, assert the full set of top-level
keys and the logging block, and key the tool tests on tools that are always
registered. Add gateway coverage for BACS and COD setting types and for the
enabled state surviving a rebuild of the gateway registry from options.
Additive; the Playwright specs are untouched.
Extracted from the reference branch behind #68046.
Refs #68046
* test(rest-api): Cover gateway state persistence and ordering
Follow-up to review feedback on the gateway coverage added in this
branch.
Nothing in this test class asserted that a gateway update reaches
storage. Every existing assertion reads the POST response, which the
controller builds from the in-memory gateway the write just mutated,
so a failure to persist goes unnoticed: dropping the update_option
call from update_item leaves the whole class green.
Replace the enabled-only test with one that posts top level fields and
a settings value in separate requests, since update_item routes them
differently, and reads both back. Add a second test for order, which
lives in its own option and decides where a gateway sits in the
collection. Both rebuild the registry so the read goes through gateway
construction, as the next request would.
Use assertArraySubset for the COD settings type check so both gateway
assertions in test_get_payment_gateways read the same way.
* test(rest-api): Clear the gateway registry before rebuilding it
The gateway tests called WC_Payment_Gateways::init() to re-read gateways
from storage, but init() only writes into slots keyed by each gateway's
order. It never clears what is already there, so any gateway whose slot
changed left its old instance behind at the previous key.
The order test reordered cheque and bacs, which pushed cod and paypal
into lower slots and stranded their first-init instances at the slots
above. The registry grew from four entries to six, and because
payment_gateways() re-keys by id with last-wins, cod and paypal resolved
back to the stale objects the rebuild was meant to replace.
Clear the registry before init(), the same way WC_REST_Unit_Test_Case
does in setUp(), and move it behind a helper so all three call sites
stay consistent.
Also shorten the changelog entry, which described the earlier shape of
these tests and no longer matched what they cover.
Refs #68284
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* test(rest-api): Move the system status tests to their own branch
They change a separate file from the gateway tests and need a review
from the people who own that endpoint, so keeping them here would hold
the gateway work behind an unrelated review.
Rename the changelog entry to match what is left.
Refs #68284
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
diff --git a/plugins/woocommerce/changelog/test-rest-api-payment-gateways b/plugins/woocommerce/changelog/test-rest-api-payment-gateways
new file mode 100644
index 00000000000..1f722ed9dcd
--- /dev/null
+++ b/plugins/woocommerce/changelog/test-rest-api-payment-gateways
@@ -0,0 +1,3 @@
+Significance: patch
+Type: dev
+Comment: Improve the payment gateway REST API tests.
diff --git a/plugins/woocommerce/tests/legacy/unit-tests/rest-api/Tests/Version3/payment-gateways.php b/plugins/woocommerce/tests/legacy/unit-tests/rest-api/Tests/Version3/payment-gateways.php
index 003de832293..e88aea63f9e 100644
--- a/plugins/woocommerce/tests/legacy/unit-tests/rest-api/Tests/Version3/payment-gateways.php
+++ b/plugins/woocommerce/tests/legacy/unit-tests/rest-api/Tests/Version3/payment-gateways.php
@@ -27,6 +27,18 @@ class Payment_Gateways extends WC_REST_Unit_Test_Case {
);
}
+ /**
+ * Rebuild the gateway registry so a read goes through gateway construction, as the next request would.
+ *
+ * Clearing first matters: init() writes each gateway into a slot keyed by its order, so on its own it
+ * leaves stale gateways behind in the slots the new order no longer uses.
+ */
+ private function rebuild_payment_gateways() {
+ $gateways = WC_Payment_Gateways::instance();
+ $gateways->payment_gateways = array();
+ $gateways->init();
+ }
+
/**
* Test route registration.
*
@@ -51,6 +63,21 @@ class Payment_Gateways extends WC_REST_Unit_Test_Case {
$this->assertEquals( 200, $response->get_status() );
+ // COD covers several distinct form field types, so use it to check how each one is surfaced.
+ $gateways_by_id = array_column( $gateways, null, 'id' );
+ $this->assertArrayHasKey( WC_Gateway_COD::ID, $gateways_by_id );
+ $this->assertArraySubset(
+ array(
+ 'settings' => array(
+ 'title' => array( 'type' => 'safe_text' ),
+ 'instructions' => array( 'type' => 'textarea' ),
+ 'enable_for_methods' => array( 'type' => 'multiselect' ),
+ 'enable_for_virtual' => array( 'type' => 'checkbox' ),
+ ),
+ ),
+ $gateways_by_id[ WC_Gateway_COD::ID ]
+ );
+
$matching_gateway_data = current(
array_filter(
$gateways,
@@ -272,6 +299,77 @@ class Payment_Gateways extends WC_REST_Unit_Test_Case {
$this->assertEquals( 'authorization', $paypal['settings']['paymentaction']['value'] );
}
+ /**
+ * @testdox A gateway update reaches storage, so a later request reads the new state.
+ */
+ public function test_update_payment_gateway_persists_to_storage() {
+ wp_set_current_user( $this->user );
+
+ // No settings payload here, so the write has to happen for the top level fields on their own.
+ $request = new WP_REST_Request( 'POST', '/wc/v3/payment_gateways/cheque' );
+ $request->set_body_params(
+ array(
+ 'enabled' => true,
+ 'title' => 'Pay by check',
+ )
+ );
+ $this->assertSame( 200, $this->server->dispatch( $request )->get_status() );
+
+ $this->rebuild_payment_gateways();
+
+ $data = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/payment_gateways/cheque' ) )->get_data();
+ $this->assertTrue( $data['enabled'] );
+ $this->assertSame( 'Pay by check', $data['title'] );
+
+ // Settings values take a different route through update_item, so post one on its own too.
+ $request = new WP_REST_Request( 'POST', '/wc/v3/payment_gateways/cheque' );
+ $request->set_body_params(
+ array(
+ 'settings' => array(
+ 'instructions' => 'Post the check to our office.',
+ ),
+ )
+ );
+ $this->assertSame( 200, $this->server->dispatch( $request )->get_status() );
+
+ $this->rebuild_payment_gateways();
+
+ $data = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/payment_gateways/cheque' ) )->get_data();
+ $this->assertSame( 'Post the check to our office.', $data['settings']['instructions']['value'] );
+ $this->assertTrue( $data['enabled'] );
+ }
+
+ /**
+ * @testdox Gateway order persists and decides where a gateway sits in the collection.
+ */
+ public function test_update_payment_gateway_order_persists_to_storage() {
+ wp_set_current_user( $this->user );
+
+ // BACS loads before cheque, so putting cheque first means the registry has to reorder them.
+ foreach ( array(
+ WC_Gateway_Cheque::ID => 0,
+ WC_Gateway_BACS::ID => 1,
+ ) as $gateway_id => $order ) {
+ $request = new WP_REST_Request( 'POST', '/wc/v3/payment_gateways/' . $gateway_id );
+ $request->set_body_params( array( 'order' => $order ) );
+ $this->assertSame( 200, $this->server->dispatch( $request )->get_status() );
+ }
+
+ // Order lives in its own option, and the registry reads it to sort gateways.
+ $this->rebuild_payment_gateways();
+
+ $gateways = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/payment_gateways' ) )->get_data();
+ $by_id = array_column( $gateways, null, 'id' );
+ $this->assertSame( 0, $by_id[ WC_Gateway_Cheque::ID ]['order'] );
+ $this->assertSame( 1, $by_id[ WC_Gateway_BACS::ID ]['order'] );
+
+ $ids = array_column( $gateways, 'id' );
+ $this->assertLessThan(
+ array_search( WC_Gateway_BACS::ID, $ids, true ),
+ array_search( WC_Gateway_Cheque::ID, $ids, true )
+ );
+ }
+
/**
* Test updating a payment gateway without valid permissions.
*