This repository has been archived by the owner on Feb 23, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 219
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add "Collection from..." in Checkout sidebar when selecting local pic…
…kup (#8305) * Add get_collectible_method_ids function * Add collectibleMethodIds to asset data registry * Remove unnecessary pluck and add pickup_location to returned array * Add hasSelectedLocalPickup to shipping types * show shipping address even if collecting * Make checkout store set prefersCollection based on IDs from settings * Move areRatesCollectible outside of hook * Add pickup location component * Show pickup location if user prefers collection * Move prefersCollection check into ShippingAddress component * Remove spread for collectibleMethodIds Not needed now since pickup_location is included in the setting by default * Check address metadata has a value before displaying it * Add tests for ShippingAddress component * Move PickupLocation specific tests to new file * Ensure TotalsShipping shows only one package rate if local pickup chosen * Update prefersCollection selector to use typeof check * Use isPackageRateCollectible rather than checking against settings * Do not show calculator button if local pickup rate is selected * Update test to mock correct setting * Remove unused method from ShippingController * Check isPackageRateCollectable rather than checking settings array * Update test to mock correct setting * Change spelling of collectible to collectable * Improve mocked useSelect function Old one returned incorrect data shape for prefersCollection * Remove duplicate import
- Loading branch information
Showing
10 changed files
with
326 additions
and
34 deletions.
There are no files selected for viewing
78 changes: 78 additions & 0 deletions
78
assets/js/base/components/cart-checkout/pickup-location/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { __, sprintf } from '@wordpress/i18n'; | ||
import { useSelect } from '@wordpress/data'; | ||
import { isObject, objectHasProp } from '@woocommerce/types'; | ||
import { isPackageRateCollectable } from '@woocommerce/base-utils'; | ||
|
||
/** | ||
* Shows a formatted pickup location. | ||
*/ | ||
const PickupLocation = (): JSX.Element | null => { | ||
const { pickupAddress, pickupMethod } = useSelect( ( select ) => { | ||
const cartShippingRates = select( 'wc/store/cart' ).getShippingRates(); | ||
|
||
const flattenedRates = cartShippingRates.flatMap( | ||
( cartShippingRate ) => cartShippingRate.shipping_rates | ||
); | ||
const selectedCollectableRate = flattenedRates.find( | ||
( rate ) => rate.selected && isPackageRateCollectable( rate ) | ||
); | ||
|
||
// If the rate has an address specified in its metadata. | ||
if ( | ||
isObject( selectedCollectableRate ) && | ||
objectHasProp( selectedCollectableRate, 'meta_data' ) | ||
) { | ||
const selectedRateMetaData = selectedCollectableRate.meta_data.find( | ||
( meta ) => meta.key === 'pickup_address' | ||
); | ||
if ( | ||
isObject( selectedRateMetaData ) && | ||
objectHasProp( selectedRateMetaData, 'value' ) && | ||
selectedRateMetaData.value | ||
) { | ||
const selectedRatePickupAddress = selectedRateMetaData.value; | ||
return { | ||
pickupAddress: selectedRatePickupAddress, | ||
pickupMethod: selectedCollectableRate.name, | ||
}; | ||
} | ||
} | ||
|
||
if ( isObject( selectedCollectableRate ) ) { | ||
return { | ||
pickupAddress: undefined, | ||
pickupMethod: selectedCollectableRate.name, | ||
}; | ||
} | ||
return { | ||
pickupAddress: undefined, | ||
pickupMethod: undefined, | ||
}; | ||
} ); | ||
|
||
// If the method does not contain an address, or the method supporting collection was not found, return early. | ||
if ( | ||
typeof pickupAddress === 'undefined' && | ||
typeof pickupMethod === 'undefined' | ||
) { | ||
return null; | ||
} | ||
|
||
// Show the pickup method's name if we don't have an address to show. | ||
return ( | ||
<span className="wc-block-components-shipping-address"> | ||
{ sprintf( | ||
/* translators: %s: shipping method name, e.g. "Amazon Locker" */ | ||
__( 'Collection from %s', 'woo-gutenberg-products-block' ), | ||
typeof pickupAddress === 'undefined' | ||
? pickupMethod | ||
: pickupAddress | ||
) + ' ' } | ||
</span> | ||
); | ||
}; | ||
|
||
export default PickupLocation; |
93 changes: 93 additions & 0 deletions
93
assets/js/base/components/cart-checkout/pickup-location/test/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { render, screen } from '@testing-library/react'; | ||
import { CART_STORE_KEY, CHECKOUT_STORE_KEY } from '@woocommerce/block-data'; | ||
import { dispatch } from '@wordpress/data'; | ||
import { previewCart } from '@woocommerce/resource-previews'; | ||
import PickupLocation from '@woocommerce/base-components/cart-checkout/pickup-location'; | ||
|
||
jest.mock( '@woocommerce/settings', () => { | ||
const originalModule = jest.requireActual( '@woocommerce/settings' ); | ||
|
||
return { | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore We know @woocommerce/settings is an object. | ||
...originalModule, | ||
getSetting: ( setting: string, ...rest: unknown[] ) => { | ||
if ( setting === 'localPickupEnabled' ) { | ||
return true; | ||
} | ||
if ( setting === 'collectableMethodIds' ) { | ||
return [ 'pickup_location' ]; | ||
} | ||
return originalModule.getSetting( setting, ...rest ); | ||
}, | ||
}; | ||
} ); | ||
describe( 'PickupLocation', () => { | ||
it( `renders an address if one is set in the method's metadata`, async () => { | ||
dispatch( CHECKOUT_STORE_KEY ).setPrefersCollection( true ); | ||
|
||
// Deselect the default selected rate and select pickup_location:1 rate. | ||
const currentlySelectedIndex = | ||
previewCart.shipping_rates[ 0 ].shipping_rates.findIndex( | ||
( rate ) => rate.selected | ||
); | ||
previewCart.shipping_rates[ 0 ].shipping_rates[ | ||
currentlySelectedIndex | ||
].selected = false; | ||
const pickupRateIndex = | ||
previewCart.shipping_rates[ 0 ].shipping_rates.findIndex( | ||
( rate ) => rate.method_id === 'pickup_location' | ||
); | ||
previewCart.shipping_rates[ 0 ].shipping_rates[ | ||
pickupRateIndex | ||
].selected = true; | ||
|
||
dispatch( CART_STORE_KEY ).receiveCart( previewCart ); | ||
|
||
render( <PickupLocation /> ); | ||
expect( | ||
screen.getByText( | ||
/Collection from 123 Easy Street, New York, 12345/ | ||
) | ||
).toBeInTheDocument(); | ||
} ); | ||
it( 'renders the method name if address is not in metadata', async () => { | ||
dispatch( CHECKOUT_STORE_KEY ).setPrefersCollection( true ); | ||
|
||
// Deselect the default selected rate and select pickup_location:1 rate. | ||
const currentlySelectedIndex = | ||
previewCart.shipping_rates[ 0 ].shipping_rates.findIndex( | ||
( rate ) => rate.selected | ||
); | ||
previewCart.shipping_rates[ 0 ].shipping_rates[ | ||
currentlySelectedIndex | ||
].selected = false; | ||
const pickupRateIndex = | ||
previewCart.shipping_rates[ 0 ].shipping_rates.findIndex( | ||
( rate ) => rate.rate_id === 'pickup_location:2' | ||
); | ||
previewCart.shipping_rates[ 0 ].shipping_rates[ | ||
pickupRateIndex | ||
].selected = true; | ||
|
||
// Set the pickup_location metadata value to an empty string in the selected pickup rate. | ||
const addressKeyIndex = previewCart.shipping_rates[ 0 ].shipping_rates[ | ||
pickupRateIndex | ||
].meta_data.findIndex( | ||
( metaData ) => metaData.key === 'pickup_address' | ||
); | ||
previewCart.shipping_rates[ 0 ].shipping_rates[ | ||
pickupRateIndex | ||
].meta_data[ addressKeyIndex ].value = ''; | ||
|
||
dispatch( CART_STORE_KEY ).receiveCart( previewCart ); | ||
|
||
render( <PickupLocation /> ); | ||
expect( | ||
screen.getByText( /Collection from Local pickup/ ) | ||
).toBeInTheDocument(); | ||
} ); | ||
} ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.