From b2617910b029ec9b3995f31b061c2663614baeb4 Mon Sep 17 00:00:00 2001 From: sirugh Date: Tue, 23 Feb 2021 14:37:13 -0600 Subject: [PATCH] Fix zero total checkout use case. Add tests --- .../talons/CheckoutPage/useCheckoutPage.js | 8 +- .../__snapshots__/checkoutPage.spec.js.snap | 169 ++++++++++++++++++ .../__tests__/checkoutPage.spec.js | 28 ++- .../components/CheckoutPage/checkoutPage.js | 11 +- 4 files changed, 205 insertions(+), 11 deletions(-) diff --git a/packages/peregrine/lib/talons/CheckoutPage/useCheckoutPage.js b/packages/peregrine/lib/talons/CheckoutPage/useCheckoutPage.js index c15ed675f5..50f137ff52 100644 --- a/packages/peregrine/lib/talons/CheckoutPage/useCheckoutPage.js +++ b/packages/peregrine/lib/talons/CheckoutPage/useCheckoutPage.js @@ -216,6 +216,9 @@ export const useCheckoutPage = (props = {}) => { return { activeContent, + availablePaymentMethods: checkoutData + ? checkoutData.cart.available_payment_methods + : null, cartItems, checkoutStep, customer, @@ -241,9 +244,6 @@ export const useCheckoutPage = (props = {}) => { handleReviewOrder, reviewOrderButtonClicked, toggleAddressBookContent, - toggleSignInContent, - availablePaymentMethods: checkoutData - ? checkoutData.cart.available_payment_methods - : null + toggleSignInContent }; }; diff --git a/packages/venia-ui/lib/components/CheckoutPage/__tests__/__snapshots__/checkoutPage.spec.js.snap b/packages/venia-ui/lib/components/CheckoutPage/__tests__/__snapshots__/checkoutPage.spec.js.snap index c9c6dfd0c5..56a4197255 100644 --- a/packages/venia-ui/lib/components/CheckoutPage/__tests__/__snapshots__/checkoutPage.spec.js.snap +++ b/packages/venia-ui/lib/components/CheckoutPage/__tests__/__snapshots__/checkoutPage.spec.js.snap @@ -8,6 +8,14 @@ exports[`CheckoutPage renders address book for customer 1`] = `
+
@@ -84,6 +92,143 @@ exports[`CheckoutPage renders address book for customer 1`] = `
`; +exports[`CheckoutPage renders an error and disables review order button if there is no payment method 1`] = ` +
+ Title +
+ +
+ + + + + + + } + /> +

+ Guest Checkout +

+
+
+ + + + +
+
+ +
+
+ +
+
+ +
+
+ +
+ +
+ +
+
+ +
+`; + exports[`CheckoutPage renders checkout content for customer - default address 1`] = `
+
@@ -176,6 +329,14 @@ exports[`CheckoutPage renders checkout content for customer - no default address
+
@@ -260,6 +421,14 @@ exports[`CheckoutPage renders checkout content for guest 1`] = `
+
diff --git a/packages/venia-ui/lib/components/CheckoutPage/__tests__/checkoutPage.spec.js b/packages/venia-ui/lib/components/CheckoutPage/__tests__/checkoutPage.spec.js index 0d72e44739..fc0b7c8f0b 100644 --- a/packages/venia-ui/lib/components/CheckoutPage/__tests__/checkoutPage.spec.js +++ b/packages/venia-ui/lib/components/CheckoutPage/__tests__/checkoutPage.spec.js @@ -7,6 +7,7 @@ import { } from '@magento/peregrine/lib/talons/CheckoutPage/useCheckoutPage'; import CheckoutPage from '../checkoutPage'; import OrderConfirmationPage from '../OrderConfirmationPage'; +import FormError from '../../FormError'; jest.mock('@magento/peregrine', () => { const actual = jest.requireActual('@magento/peregrine'); @@ -36,6 +37,7 @@ jest.mock('@magento/peregrine/lib/talons/CheckoutPage/useCheckoutPage', () => { jest.mock('../../../classify'); jest.mock('../../../components/Head', () => ({ Title: () => 'Title' })); +jest.mock('../../FormError', () => 'FormError'); jest.mock('../../StockStatusMessage', () => 'StockStatusMessage'); jest.mock('../ItemsReview', () => 'ItemsReview'); jest.mock('../GuestSignIn', () => 'GuestSignIn'); @@ -52,6 +54,7 @@ jest.mock('../AddressBook', () => 'AddressBook'); const defaultTalonProps = { activeContent: 'checkout', + availablePaymentMethods: [{ code: 'braintree' }], cartItems: [], checkoutStep: 1, customer: null, @@ -74,9 +77,9 @@ const defaultTalonProps = { setShippingMethodDone: jest.fn().mockName('setShippingMethodDone'), setPaymentInformationDone: jest.fn().mockName('setPaymentInformationDone'), toggleAddressBookContent: jest.fn().mockName('toggleAddressBookContent'), - toggleSignInContent: jest.fn().mockName('toggleSignInContent'), - availablePaymentMethods: [{ code: 'braintree' }] + toggleSignInContent: jest.fn().mockName('toggleSignInContent') }; + describe('CheckoutPage', () => { test('throws a toast if there is an error', () => { useCheckoutPage.mockReturnValueOnce({ @@ -215,4 +218,25 @@ describe('CheckoutPage', () => { expect(priceAdjustmentsComponent.props).toMatchSnapshot(); expect(reviewOrderButtonComponent.props).toMatchSnapshot(); }); + + test('renders an error and disables review order button if there is no payment method', () => { + useCheckoutPage.mockReturnValueOnce({ + ...defaultTalonProps, + checkoutStep: CHECKOUT_STEP.PAYMENT, + isUpdating: true, + availablePaymentMethods: [] + }); + + const tree = createTestInstance(); + const formErrorComponent = tree.root.findByType(FormError); + const reviewOrderButtonComponent = tree.root.findByProps({ + className: 'review_order_button' + }); + + expect(tree).toMatchSnapshot(); + expect(formErrorComponent.props.errors[0]).toEqual( + new Error('Payment is currently unavailable.') + ); + expect(reviewOrderButtonComponent.props.disabled).toBe(true); + }); }); diff --git a/packages/venia-ui/lib/components/CheckoutPage/checkoutPage.js b/packages/venia-ui/lib/components/CheckoutPage/checkoutPage.js index 2306b83d3a..c417e4ce8a 100644 --- a/packages/venia-ui/lib/components/CheckoutPage/checkoutPage.js +++ b/packages/venia-ui/lib/components/CheckoutPage/checkoutPage.js @@ -42,6 +42,7 @@ const CheckoutPage = props => { * SHIPPING_ADDRESS, SHIPPING_METHOD, PAYMENT, REVIEW */ activeContent, + availablePaymentMethods, cartItems, checkoutStep, customer, @@ -65,8 +66,7 @@ const CheckoutPage = props => { handleReviewOrder, reviewOrderButtonClicked, toggleAddressBookContent, - toggleSignInContent, - availablePaymentMethods + toggleSignInContent } = talonProps; const [, { addToast }] = useToasts(); @@ -176,9 +176,10 @@ const CheckoutPage = props => { const formErrors = []; const paymentMethods = Object.keys(payments); - // If we don't have an implementation for a method type, ignore it. - const isPaymentAvailable = !!availablePaymentMethods.find(({ code }) => - paymentMethods.includes(code) + // If we have an implementation, or if this is a "zero" checkout, + // we can allow checkout to proceed. + const isPaymentAvailable = !!availablePaymentMethods.find( + ({ code }) => code === 'free' || paymentMethods.includes(code) ); if (!isPaymentAvailable) {