Prevent email address being removed when changing shipping method/entering shipping address (https://github.com/woocommerce/woocommerce-blocks/pull/9328)

* Preserve email when rendering shipping address form for the first time

* Ensure billing email does not reset when changing form values

* Add test to ensure email does not get overwritten
This commit is contained in:
Thomas Roberts 2023-05-03 16:45:57 +03:00 committed by GitHub
parent b813a98691
commit fdfb445a58
2 changed files with 76 additions and 15 deletions

View File

@ -45,6 +45,7 @@ const Block = ( {
setShippingAddress,
setBillingAddress,
shippingAddress,
billingAddress,
setShippingPhone,
useShippingAsBilling,
setUseShippingAsBilling,
@ -52,6 +53,7 @@ const Block = ( {
const { dispatchCheckoutEvent } = useStoreEvents();
const { isEditor } = useEditorContext();
const { email } = billingAddress;
// This is used to track whether the "Use shipping as billing" checkbox was checked on first load and if we synced
// the shipping address to the billing address if it was. This is not used on further toggles of the checkbox.
const [ addressesSynced, setAddressesSynced ] = useState( false );
@ -65,20 +67,25 @@ const Block = ( {
// Run this on first render to ensure addresses sync if needed, there is no need to re-run this when toggling the
// checkbox.
useEffect( () => {
if ( addressesSynced ) {
return;
}
if ( useShippingAsBilling ) {
setBillingAddress( shippingAddress );
}
setAddressesSynced( true );
}, [
addressesSynced,
setBillingAddress,
shippingAddress,
useShippingAsBilling,
] );
useEffect(
() => {
if ( addressesSynced ) {
return;
}
if ( useShippingAsBilling ) {
setBillingAddress( { ...shippingAddress, email } );
}
setAddressesSynced( true );
},
// Skip the `email` dependency since we don't want to re-run if that changes, but we do want to sync it on first render.
// eslint-disable-next-line react-hooks/exhaustive-deps
[
addressesSynced,
setBillingAddress,
shippingAddress,
useShippingAsBilling,
]
);
const addressFieldsConfig = useMemo( () => {
return {
@ -111,7 +118,7 @@ const Block = ( {
onChange={ ( values: Partial< ShippingAddress > ) => {
setShippingAddress( values );
if ( useShippingAsBilling ) {
setBillingAddress( values );
setBillingAddress( { ...values, email } );
}
dispatchCheckoutEvent( 'set-shipping-address' );
} }

View File

@ -46,6 +46,8 @@ describe( 'Shopper → Checkout', () => {
} );
describe( 'Local pickup', () => {
const NORMAL_SHIPPING_NAME = 'Normal Shipping';
beforeAll( async () => {
// Enable local pickup.
await visitAdminPage(
@ -122,6 +124,58 @@ describe( 'Shopper → Checkout', () => {
'.woocommerce-customer-details address'
);
} );
it( 'Switching between local pickup and shipping does not affect the address', async () => {
await shopper.block.emptyCart();
await shopper.block.goToShop();
await shopper.addToCartFromShopPage( SIMPLE_PHYSICAL_PRODUCT_NAME );
await shopper.block.goToCheckout();
await expect( page ).toClick(
'.wc-block-checkout__shipping-method-option-title',
{
text: 'Local Pickup',
}
);
expect( page ).toMatch( 'Woo Collection' );
await shopper.block.fillBillingDetails( BILLING_DETAILS );
await expect( page ).toFill(
'input#email',
'thisShouldRemainHere@mail.com'
);
await expect( page ).toClick(
'.wc-block-checkout__shipping-method-option-title',
{
text: 'Shipping',
}
);
await page.waitForXPath(
`//div[contains(@class, "wc-block-components-totals-item__description")][contains(text(), "${ NORMAL_SHIPPING_NAME }")]`
);
const enteredEmail = await page.evaluate( () => {
return document.getElementById( 'email' ).value;
} );
expect( enteredEmail ).toEqual( 'thisShouldRemainHere@mail.com' );
await expect( page ).toFill(
'input#email',
'thisShouldRemainHereToo@mail.com'
);
await expect( page ).toFill( 'input#shipping-first_name', 'Test' );
const secondEnteredEmail = await page.evaluate( () => {
return document.getElementById( 'email' ).value;
} );
expect( secondEnteredEmail ).toEqual(
'thisShouldRemainHereToo@mail.com'
);
} );
} );
describe( 'Payment Methods', () => {