Commit 77d725ae012 for woocommerce
commit 77d725ae01255aa1b20d07e432be64ce60f9ce7f
Author: Néstor Soriano <konamiman@konamiman.com>
Date: Thu Aug 6 05:21:38 2026 +0900
Fix emptied customer address fields being restored from saved values (#65703)
* Fix emptied customer address fields being restored from saved values
* Remove redundant test and changelog file
* Add changelog entry for the customer session data store tests
---------
Co-authored-by: Brandon Kraft <public@brandonkraft.com>
diff --git a/plugins/woocommerce/changelog/65703-add-customer-session-empty-value-tests b/plugins/woocommerce/changelog/65703-add-customer-session-empty-value-tests
new file mode 100644
index 00000000000..bbe4d310865
--- /dev/null
+++ b/plugins/woocommerce/changelog/65703-add-customer-session-empty-value-tests
@@ -0,0 +1,4 @@
+Significance: patch
+Type: dev
+
+Add unit tests covering empty customer session values overriding persisted customer data.
diff --git a/plugins/woocommerce/includes/data-stores/class-wc-customer-data-store-session.php b/plugins/woocommerce/includes/data-stores/class-wc-customer-data-store-session.php
index e6ab8928453..f6fd37974d7 100644
--- a/plugins/woocommerce/includes/data-stores/class-wc-customer-data-store-session.php
+++ b/plugins/woocommerce/includes/data-stores/class-wc-customer-data-store-session.php
@@ -111,6 +111,9 @@ class WC_Customer_Data_Store_Session extends WC_Data_Store_WP implements WC_Cust
* There is a valid session if $data is not empty, and the ID matches the logged in user ID.
*
* If the user object has been updated since the session was created (based on date_modified) we should not load the session - data should be reloaded.
+ *
+ * Empty session values must be applied too (hence isset and not empty below): the session snapshot always contains all the keys,
+ * so an empty value means the field was explicitly cleared and must override the value loaded from the database.
*/
if ( isset( $data['id'], $data['date_modified'] ) && $data['id'] === (string) $customer->get_id() && $data['date_modified'] === (string) $customer->get_date_modified( 'edit' ) ) {
foreach ( $this->session_keys as $session_key ) {
diff --git a/plugins/woocommerce/tests/php/includes/data-stores/class-wc-customer-data-store-session-test.php b/plugins/woocommerce/tests/php/includes/data-stores/class-wc-customer-data-store-session-test.php
index 7f0b0eec713..f16298dd7b9 100644
--- a/plugins/woocommerce/tests/php/includes/data-stores/class-wc-customer-data-store-session-test.php
+++ b/plugins/woocommerce/tests/php/includes/data-stores/class-wc-customer-data-store-session-test.php
@@ -4,6 +4,24 @@
* Tests relating to the WC_Customer_Data_Store_Session class.
*/
class WC_Customer_Data_Store_Session_Test extends WC_Unit_Test_Case {
+
+ /**
+ * Set up test fixtures.
+ */
+ public function setUp(): void {
+ parent::setUp();
+ WC()->session->set( 'customer', null );
+ }
+
+ /**
+ * Tear down test fixtures.
+ */
+ public function tearDown(): void {
+ WC()->session->set( 'customer', null );
+ wp_set_current_user( 0 );
+ parent::tearDown();
+ }
+
/**
* Ensure that the country and state shipping address fields only inherit
* the corresponding billing address values if a shipping address is not set.
@@ -65,6 +83,97 @@ class WC_Customer_Data_Store_Session_Test extends WC_Unit_Test_Case {
$this->assertArrayNotHasKey( 'customer', $session_data );
}
+ /**
+ * @testdox Should override a persisted billing field with an empty value stored in the session.
+ */
+ public function test_empty_session_value_overrides_persisted_billing_field(): void {
+ $customer_id = WC_Helper_Customer::create_customer( 'session_empty_billing', 'password', 'session-empty-billing@example.com' )->get_id();
+
+ $session_customer = new WC_Customer( $customer_id, true );
+ $session_customer->set_billing_address_2( '' );
+ $session_customer->save();
+
+ $reloaded_customer = new WC_Customer( $customer_id, true );
+
+ $this->assertSame( '', $reloaded_customer->get_billing_address_2(), 'A billing field emptied in the session should not be restored from the persisted customer data' );
+ }
+
+ /**
+ * @testdox Should leave persisted values untouched for keys that are absent from the session data.
+ */
+ public function test_keys_absent_from_session_data_keep_persisted_values(): void {
+ $customer_id = WC_Helper_Customer::create_customer( 'session_absent_keys', 'password', 'session-absent-keys@example.com' )->get_id();
+ $date_modified = (string) ( new WC_Customer( $customer_id ) )->get_date_modified( 'edit' );
+
+ WC()->session->set(
+ 'customer',
+ array(
+ 'id' => (string) $customer_id,
+ 'date_modified' => $date_modified,
+ 'first_name' => 'Session-Name',
+ )
+ );
+
+ $customer = new WC_Customer( $customer_id, true );
+
+ $this->assertSame( 'Session-Name', $customer->get_billing_first_name(), 'Keys present in the session data should be applied' );
+ $this->assertSame( 'Apt 1', $customer->get_shipping_address_2(), 'Keys absent from the session data should keep the persisted values' );
+ }
+
+ /**
+ * @testdox Should ignore the session data entirely when the date modified does not match the persisted customer.
+ */
+ public function test_stale_session_data_is_ignored(): void {
+ $customer_id = WC_Helper_Customer::create_customer( 'session_stale_data', 'password', 'session-stale-data@example.com' )->get_id();
+
+ WC()->session->set(
+ 'customer',
+ array(
+ 'id' => (string) $customer_id,
+ 'date_modified' => 'stale-date',
+ 'address_2' => '',
+ 'shipping_address_2' => '',
+ )
+ );
+
+ $customer = new WC_Customer( $customer_id, true );
+
+ $this->assertSame( 'Apt 1', $customer->get_billing_address_2(), 'Stale session data should not override the persisted billing values' );
+ $this->assertSame( 'Apt 1', $customer->get_shipping_address_2(), 'Stale session data should not override the persisted shipping values' );
+ }
+
+ /**
+ * @testdox Should fall back to the default location when the billing country is emptied in the session.
+ */
+ public function test_emptied_billing_country_falls_back_to_default_location(): void {
+ $customer_id = WC_Helper_Customer::create_customer( 'session_empty_country', 'password', 'session-empty-country@example.com' )->get_id();
+
+ $session_customer = new WC_Customer( $customer_id, true );
+ $session_customer->set_billing_country( '' );
+ $session_customer->save();
+
+ $reloaded_customer = new WC_Customer( $customer_id, true );
+ $default_location = wc_get_customer_default_location();
+
+ $this->assertSame( $default_location['country'], $reloaded_customer->get_billing_country(), 'An emptied billing country should be replaced with the default location country' );
+ }
+
+ /**
+ * @testdox Should fall back to the account email when the billing email is emptied in the session for a logged in user.
+ */
+ public function test_emptied_billing_email_falls_back_to_account_email_for_logged_in_user(): void {
+ $customer_id = WC_Helper_Customer::create_customer( 'session_empty_email', 'password', 'session-empty-email@example.com' )->get_id();
+ wp_set_current_user( $customer_id );
+
+ $session_customer = new WC_Customer( $customer_id, true );
+ $session_customer->set_billing_email( '' );
+ $session_customer->save();
+
+ $reloaded_customer = new WC_Customer( $customer_id, true );
+
+ $this->assertSame( 'session-empty-email@example.com', $reloaded_customer->get_billing_email(), 'An emptied billing email should be replaced with the account email for logged in users' );
+ }
+
/**
* Customer objects with a mixture of billing and shipping addresses.
*