Hide "collection from" text when a location has an incomplete address. (https://github.com/woocommerce/woocommerce-blocks/pull/9808)

* Hide "collection from" text when a location has an incomplete address.

* Fix display on confirmation page

* has_valid_pickup_location helper

* Missing isset

* Update test

* Fix pickup text assertion

---------

Co-authored-by: Niels Lange <info@nielslange.de>
This commit is contained in:
Mike Jolley 2023-07-03 10:10:18 +01:00 committed by GitHub
parent c1f2949a5d
commit a6b8e0e542
4 changed files with 69 additions and 17 deletions

View File

@ -10,7 +10,7 @@ import { isPackageRateCollectable } from '@woocommerce/base-utils';
* Shows a formatted pickup location. * Shows a formatted pickup location.
*/ */
const PickupLocation = (): JSX.Element | null => { const PickupLocation = (): JSX.Element | null => {
const { pickupAddress, pickupMethod } = useSelect( ( select ) => { const { pickupAddress } = useSelect( ( select ) => {
const cartShippingRates = select( 'wc/store/cart' ).getShippingRates(); const cartShippingRates = select( 'wc/store/cart' ).getShippingRates();
const flattenedRates = cartShippingRates.flatMap( const flattenedRates = cartShippingRates.flatMap(
@ -36,7 +36,6 @@ const PickupLocation = (): JSX.Element | null => {
const selectedRatePickupAddress = selectedRateMetaData.value; const selectedRatePickupAddress = selectedRateMetaData.value;
return { return {
pickupAddress: selectedRatePickupAddress, pickupAddress: selectedRatePickupAddress,
pickupMethod: selectedCollectableRate.name,
}; };
} }
} }
@ -44,20 +43,15 @@ const PickupLocation = (): JSX.Element | null => {
if ( isObject( selectedCollectableRate ) ) { if ( isObject( selectedCollectableRate ) ) {
return { return {
pickupAddress: undefined, pickupAddress: undefined,
pickupMethod: selectedCollectableRate.name,
}; };
} }
return { return {
pickupAddress: undefined, pickupAddress: undefined,
pickupMethod: undefined,
}; };
} ); } );
// If the method does not contain an address, or the method supporting collection was not found, return early. // If the method does not contain an address, or the method supporting collection was not found, return early.
if ( if ( typeof pickupAddress === 'undefined' ) {
typeof pickupAddress === 'undefined' &&
typeof pickupMethod === 'undefined'
) {
return null; return null;
} }
@ -67,9 +61,7 @@ const PickupLocation = (): JSX.Element | null => {
{ sprintf( { sprintf(
/* translators: %s: shipping method name, e.g. "Amazon Locker" */ /* translators: %s: shipping method name, e.g. "Amazon Locker" */
__( 'Collection from %s', 'woo-gutenberg-products-block' ), __( 'Collection from %s', 'woo-gutenberg-products-block' ),
typeof pickupAddress === 'undefined' pickupAddress
? pickupMethod
: pickupAddress
) + ' ' } ) + ' ' }
</span> </span>
); );

View File

@ -26,7 +26,7 @@ jest.mock( '@woocommerce/settings', () => {
}; };
} ); } );
describe( 'PickupLocation', () => { describe( 'PickupLocation', () => {
it( `renders an address if one is set in the method's metadata`, async () => { it( `renders an address if one is set in the methods metadata`, async () => {
dispatch( CHECKOUT_STORE_KEY ).setPrefersCollection( true ); dispatch( CHECKOUT_STORE_KEY ).setPrefersCollection( true );
// Deselect the default selected rate and select pickup_location:1 rate. // Deselect the default selected rate and select pickup_location:1 rate.
@ -54,7 +54,7 @@ describe( 'PickupLocation', () => {
) )
).toBeInTheDocument(); ).toBeInTheDocument();
} ); } );
it( 'renders the method name if address is not in metadata', async () => { it( 'renders no address if one is not set in the methods metadata', async () => {
dispatch( CHECKOUT_STORE_KEY ).setPrefersCollection( true ); dispatch( CHECKOUT_STORE_KEY ).setPrefersCollection( true );
// Deselect the default selected rate and select pickup_location:1 rate. // Deselect the default selected rate and select pickup_location:1 rate.
@ -87,7 +87,7 @@ describe( 'PickupLocation', () => {
render( <PickupLocation /> ); render( <PickupLocation /> );
expect( expect(
screen.getByText( /Collection from Local pickup/ ) screen.queryByText( /Collection from / )
).toBeInTheDocument(); ).not.toBeInTheDocument();
} ); } );
} ); } );

View File

@ -8,6 +8,20 @@ use WC_Shipping_Method;
*/ */
class PickupLocation extends WC_Shipping_Method { class PickupLocation extends WC_Shipping_Method {
/**
* Pickup locations.
*
* @var array
*/
protected $pickup_locations = [];
/**
* Cost
*
* @var string
*/
protected $cost = '';
/** /**
* Constructor. * Constructor.
*/ */
@ -31,6 +45,48 @@ class PickupLocation extends WC_Shipping_Method {
add_filter( 'woocommerce_attribute_label', array( $this, 'translate_meta_data' ), 10, 3 ); add_filter( 'woocommerce_attribute_label', array( $this, 'translate_meta_data' ), 10, 3 );
} }
/**
* Checks if a given address is complete.
*
* @param array $address Address.
* @return bool
*/
protected function has_valid_pickup_location( $address ) {
// Normalize address.
$address_fields = wp_parse_args(
(array) $address,
array(
'city' => '',
'postcode' => '',
'state' => '',
'country' => '',
)
);
// Country is always required.
if ( empty( $address_fields['country'] ) ) {
return false;
}
// If all fields are provided, we can skip further checks.
if ( ! empty( $address_fields['city'] ) && ! empty( $address_fields['postcode'] ) && ! empty( $address_fields['state'] ) ) {
return true;
}
// Check validity based on requirements for the country.
$country_address_fields = wc()->countries->get_address_fields( $address_fields['country'], 'shipping_' );
foreach ( $country_address_fields as $field_name => $field ) {
$key = str_replace( 'shipping_', '', $field_name );
if ( isset( $address_fields[ $key ] ) && true === $field['required'] && empty( $address_fields[ $key ] ) ) {
return false;
}
}
return true;
}
/** /**
* Calculate shipping. * Calculate shipping.
* *
@ -51,7 +107,7 @@ class PickupLocation extends WC_Shipping_Method {
'cost' => $this->cost, 'cost' => $this->cost,
'meta_data' => array( 'meta_data' => array(
'pickup_location' => wp_kses_post( $location['name'] ), 'pickup_location' => wp_kses_post( $location['name'] ),
'pickup_address' => wc()->countries->get_formatted_address( $location['address'], ', ' ), 'pickup_address' => $this->has_valid_pickup_location( $location['address'] ) ? wc()->countries->get_formatted_address( $location['address'], ', ' ) : '',
'pickup_details' => wp_kses_post( $location['details'] ), 'pickup_details' => wp_kses_post( $location['details'] ),
), ),
) )

View File

@ -135,9 +135,13 @@ class ShippingController {
$location = $shipping_method->get_meta( 'pickup_location' ); $location = $shipping_method->get_meta( 'pickup_location' );
$address = $shipping_method->get_meta( 'pickup_address' ); $address = $shipping_method->get_meta( 'pickup_address' );
if ( ! $address ) {
return $return;
}
return sprintf( return sprintf(
// Translators: %s location name. // Translators: %s location name.
__( 'Pickup from <strong>%s</strong>:', 'woo-gutenberg-products-block' ), __( 'Collection from <strong>%s</strong>:', 'woo-gutenberg-products-block' ),
$location $location
) . '<br/><address>' . str_replace( ',', ',<br/>', $address ) . '</address><br/>' . $details; ) . '<br/><address>' . str_replace( ',', ',<br/>', $address ) . '</address><br/>' . $details;
} }