From d2d3bf86c85aaeb6c90536ca77517db478772577 Mon Sep 17 00:00:00 2001 From: Anthoula Wojczak Date: Fri, 30 Sep 2022 16:44:57 -0500 Subject: [PATCH 1/3] =?UTF-8?q?PWA-2985:=20[bug]:=20Payment=20method=20alw?= =?UTF-8?q?ays=20reverts=20to=20=E2=80=9CCheck=20/=20Money=20order?= =?UTF-8?q?=E2=80=9D=20when=20there=20is=20an=20error=20with=20the=20trans?= =?UTF-8?q?action?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Set selected payment method mutation upon onChange event - Set initialSelectedMethod to selected_payment_method data - Update test coverage & snapshots --- .../usePaymentMethods.spec.js.snap | 3 +- .../__tests__/usePaymentMethods.spec.js | 24 +++++++++++-- .../PaymentInformation/paymentMethods.gql.js | 25 +++++++++++++- .../PaymentInformation/usePaymentMethods.js | 34 ++++++++++++++++--- .../PaymentInformation/paymentMethods.js | 2 ++ 5 files changed, 79 insertions(+), 9 deletions(-) diff --git a/packages/peregrine/lib/talons/CheckoutPage/PaymentInformation/__tests__/__snapshots__/usePaymentMethods.spec.js.snap b/packages/peregrine/lib/talons/CheckoutPage/PaymentInformation/__tests__/__snapshots__/usePaymentMethods.spec.js.snap index f4ddf7ee4a..485d48def7 100644 --- a/packages/peregrine/lib/talons/CheckoutPage/PaymentInformation/__tests__/__snapshots__/usePaymentMethods.spec.js.snap +++ b/packages/peregrine/lib/talons/CheckoutPage/PaymentInformation/__tests__/__snapshots__/usePaymentMethods.spec.js.snap @@ -8,7 +8,8 @@ Object { }, ], "currentSelectedPaymentMethod": "currentSelectedPaymentMethod", - "initialSelectedMethod": "availablePaymentMethod", + "handlePaymentMethodSelection": [Function], + "initialSelectedMethod": "braintree", "isLoading": false, } `; diff --git a/packages/peregrine/lib/talons/CheckoutPage/PaymentInformation/__tests__/usePaymentMethods.spec.js b/packages/peregrine/lib/talons/CheckoutPage/PaymentInformation/__tests__/usePaymentMethods.spec.js index 743ce9e071..239b28121c 100644 --- a/packages/peregrine/lib/talons/CheckoutPage/PaymentInformation/__tests__/usePaymentMethods.spec.js +++ b/packages/peregrine/lib/talons/CheckoutPage/PaymentInformation/__tests__/usePaymentMethods.spec.js @@ -18,14 +18,21 @@ jest.mock( } ); +const mockSetPaymentMethodOnCartMutation = jest.fn(); + jest.mock('@apollo/client', () => { return { + useMutation: jest.fn(() => [ + mockSetPaymentMethodOnCartMutation, + { loading: true } + ]), useQuery: jest.fn().mockReturnValue({ data: { cart: { available_payment_methods: [ { code: 'availablePaymentMethod' } - ] + ], + selected_payment_method: { code: 'braintree' } } }, loading: false @@ -34,9 +41,18 @@ jest.mock('@apollo/client', () => { }); jest.mock('../paymentMethods.gql', () => ({ - getPaymentMethodsQuery: 'paymentMethodsQuery' + getPaymentMethodsQuery: 'paymentMethodsQuery', + setPaymentMethodOnCartMutation: 'setPaymentMethod' })); +const getPaymentMethodsQuery = 'getPaymentMethodsQuery'; +const setPaymentMethodOnCartMutation = 'setPaymentMethodOnCartMutation'; + +const operations = { + getPaymentMethodsQuery, + setPaymentMethodOnCartMutation +}; + const Component = props => { const talonProps = usePaymentMethods(props); @@ -58,7 +74,9 @@ const getTalonProps = props => { }; it('returns the correct shape', () => { - const { talonProps } = getTalonProps(); + const { talonProps } = getTalonProps({ + operations + }); expect(talonProps).toMatchSnapshot(); }); diff --git a/packages/peregrine/lib/talons/CheckoutPage/PaymentInformation/paymentMethods.gql.js b/packages/peregrine/lib/talons/CheckoutPage/PaymentInformation/paymentMethods.gql.js index b003f0b945..b3583f957f 100644 --- a/packages/peregrine/lib/talons/CheckoutPage/PaymentInformation/paymentMethods.gql.js +++ b/packages/peregrine/lib/talons/CheckoutPage/PaymentInformation/paymentMethods.gql.js @@ -8,10 +8,33 @@ export const GET_PAYMENT_METHODS = gql` code title } + selected_payment_method { + code + } + } + } +`; + +export const SET_PAYMENT_METHOD_ON_CART = gql` + mutation setPaymentMethodOnCart( + $cartId: String! + $paymentMethod: PaymentMethodInput! + ) { + setPaymentMethodOnCart( + input: { cart_id: $cartId, payment_method: $paymentMethod } + ) { + cart { + id + selected_payment_method { + code + title + } + } } } `; export default { - getPaymentMethodsQuery: GET_PAYMENT_METHODS + getPaymentMethodsQuery: GET_PAYMENT_METHODS, + setPaymentMethodOnCartMutation: SET_PAYMENT_METHOD_ON_CART }; diff --git a/packages/peregrine/lib/talons/CheckoutPage/PaymentInformation/usePaymentMethods.js b/packages/peregrine/lib/talons/CheckoutPage/PaymentInformation/usePaymentMethods.js index c8810abd8f..d960cb0a58 100644 --- a/packages/peregrine/lib/talons/CheckoutPage/PaymentInformation/usePaymentMethods.js +++ b/packages/peregrine/lib/talons/CheckoutPage/PaymentInformation/usePaymentMethods.js @@ -1,4 +1,5 @@ -import { useQuery } from '@apollo/client'; +import { useCallback } from 'react'; +import { useMutation, useQuery } from '@apollo/client'; import useFieldState from '@magento/peregrine/lib/hooks/hook-wrappers/useInformedFieldStateWrapper'; import DEFAULT_OPERATIONS from './paymentMethods.gql'; import mergeOperations from '@magento/peregrine/lib/util/shallowMerge'; @@ -7,7 +8,12 @@ import { useCartContext } from '../../../context/cart'; export const usePaymentMethods = props => { const operations = mergeOperations(DEFAULT_OPERATIONS, props.operations); - const { getPaymentMethodsQuery } = operations; + const { + getPaymentMethodsQuery, + setPaymentMethodOnCartMutation + } = operations; + + const [setPaymentMethod] = useMutation(setPaymentMethodOnCartMutation); const [{ cartId }] = useCartContext(); @@ -24,12 +30,32 @@ export const usePaymentMethods = props => { (data && data.cart.available_payment_methods) || []; const initialSelectedMethod = - (availablePaymentMethods.length && availablePaymentMethods[0].code) || - null; + (data && data.cart.selected_payment_method.code) || null; + + const handlePaymentMethodSelection = useCallback( + element => { + const value = element.target.value; + + setPaymentMethod({ + variables: { + cartId, + paymentMethod: { + code: value, + braintree: { + payment_method_nonce: value, + is_active_payment_token_enabler: false + } + } + } + }); + }, + [cartId, setPaymentMethod] + ); return { availablePaymentMethods, currentSelectedPaymentMethod, + handlePaymentMethodSelection, initialSelectedMethod, isLoading: loading }; diff --git a/packages/venia-ui/lib/components/CheckoutPage/PaymentInformation/paymentMethods.js b/packages/venia-ui/lib/components/CheckoutPage/PaymentInformation/paymentMethods.js index 286f08e59a..175743844c 100644 --- a/packages/venia-ui/lib/components/CheckoutPage/PaymentInformation/paymentMethods.js +++ b/packages/venia-ui/lib/components/CheckoutPage/PaymentInformation/paymentMethods.js @@ -28,6 +28,7 @@ const PaymentMethods = props => { const { availablePaymentMethods, currentSelectedPaymentMethod, + handlePaymentMethodSelection, initialSelectedMethod, isLoading } = talonProps; @@ -65,6 +66,7 @@ const PaymentMethods = props => { label: classes.radio_label }} checked={isSelected} + onChange={handlePaymentMethodSelection} /> {renderedComponent} From e9a56e4a7d768f553e253e900da52e065a087491 Mon Sep 17 00:00:00 2001 From: Anthoula Wojczak Date: Mon, 3 Oct 2022 12:46:31 -0500 Subject: [PATCH 2/3] =?UTF-8?q?PWA-2985:=20[bug]:=20Payment=20method=20alw?= =?UTF-8?q?ays=20reverts=20to=20=E2=80=9CCheck=20/=20Money=20order?= =?UTF-8?q?=E2=80=9D=20when=20there=20is=20an=20error=20with=20the=20trans?= =?UTF-8?q?action?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Set default/initial payment method - Add tests - Update padding --- .../__tests__/useCustomerWishlistSkus.spec.js | 1 - .../usePaymentMethods.spec.js.snap | 2 +- .../__tests__/usePaymentMethods.spec.js | 35 +++++++++++++++++++ .../PaymentInformation/usePaymentMethods.js | 12 ++++++- .../paymentMethods.module.css | 4 +-- 5 files changed, 48 insertions(+), 6 deletions(-) diff --git a/packages/peregrine/lib/hooks/useCustomerWishlistSkus/__tests__/useCustomerWishlistSkus.spec.js b/packages/peregrine/lib/hooks/useCustomerWishlistSkus/__tests__/useCustomerWishlistSkus.spec.js index 5b08e766d1..9afb2c60bb 100644 --- a/packages/peregrine/lib/hooks/useCustomerWishlistSkus/__tests__/useCustomerWishlistSkus.spec.js +++ b/packages/peregrine/lib/hooks/useCustomerWishlistSkus/__tests__/useCustomerWishlistSkus.spec.js @@ -49,7 +49,6 @@ test('pre-caches wishlist items', async () => { Object { "customerWishlistProducts": Array [ "Dress", - "Shirt", ], } `); diff --git a/packages/peregrine/lib/talons/CheckoutPage/PaymentInformation/__tests__/__snapshots__/usePaymentMethods.spec.js.snap b/packages/peregrine/lib/talons/CheckoutPage/PaymentInformation/__tests__/__snapshots__/usePaymentMethods.spec.js.snap index 485d48def7..8427e95511 100644 --- a/packages/peregrine/lib/talons/CheckoutPage/PaymentInformation/__tests__/__snapshots__/usePaymentMethods.spec.js.snap +++ b/packages/peregrine/lib/talons/CheckoutPage/PaymentInformation/__tests__/__snapshots__/usePaymentMethods.spec.js.snap @@ -9,7 +9,7 @@ Object { ], "currentSelectedPaymentMethod": "currentSelectedPaymentMethod", "handlePaymentMethodSelection": [Function], - "initialSelectedMethod": "braintree", + "initialSelectedMethod": "availablePaymentMethod", "isLoading": false, } `; diff --git a/packages/peregrine/lib/talons/CheckoutPage/PaymentInformation/__tests__/usePaymentMethods.spec.js b/packages/peregrine/lib/talons/CheckoutPage/PaymentInformation/__tests__/usePaymentMethods.spec.js index 239b28121c..04cca81fd3 100644 --- a/packages/peregrine/lib/talons/CheckoutPage/PaymentInformation/__tests__/usePaymentMethods.spec.js +++ b/packages/peregrine/lib/talons/CheckoutPage/PaymentInformation/__tests__/usePaymentMethods.spec.js @@ -89,3 +89,38 @@ it('returns an empty array for availablePaymentMethods when there is no data', ( expect(talonProps.availablePaymentMethods).toEqual([]); expect(talonProps.initialSelectedMethod).toBeNull(); }); + +it('default payment is selected when there is one available payment method', () => { + useQuery.mockReturnValueOnce({ + data: { + cart: { + available_payment_methods: [{ code: 'availablePaymentMethod' }], + selected_payment_method: { code: null } + } + } + }); + + const { talonProps } = getTalonProps(); + + expect(talonProps.availablePaymentMethods.length).toEqual(1); + expect(talonProps.initialSelectedMethod).toEqual('availablePaymentMethod'); +}); + +it('default payment is not selected when there is more than one available payment method', () => { + useQuery.mockReturnValueOnce({ + data: { + cart: { + available_payment_methods: [ + { code: 'availablePaymentMethod1' }, + { code: 'availablePaymentMethod2' } + ], + selected_payment_method: { code: null } + } + } + }); + + const { talonProps } = getTalonProps(); + + expect(talonProps.availablePaymentMethods.length).toEqual(2); + expect(talonProps.initialSelectedMethod).toBeNull(); +}); diff --git a/packages/peregrine/lib/talons/CheckoutPage/PaymentInformation/usePaymentMethods.js b/packages/peregrine/lib/talons/CheckoutPage/PaymentInformation/usePaymentMethods.js index d960cb0a58..49b4c69c57 100644 --- a/packages/peregrine/lib/talons/CheckoutPage/PaymentInformation/usePaymentMethods.js +++ b/packages/peregrine/lib/talons/CheckoutPage/PaymentInformation/usePaymentMethods.js @@ -29,9 +29,19 @@ export const usePaymentMethods = props => { const availablePaymentMethods = (data && data.cart.available_payment_methods) || []; - const initialSelectedMethod = + // If there is one payment method, select it by default. + // If more than one, none should be selected by default. + const defaultPaymentCode = + (availablePaymentMethods.length && availablePaymentMethods[0].code) || + null; + const selectedPaymentCode = (data && data.cart.selected_payment_method.code) || null; + const initialSelectedMethod = + availablePaymentMethods.length > 1 + ? selectedPaymentCode + : defaultPaymentCode; + const handlePaymentMethodSelection = useCallback( element => { const value = element.target.value; diff --git a/packages/venia-ui/lib/components/CheckoutPage/PaymentInformation/paymentMethods.module.css b/packages/venia-ui/lib/components/CheckoutPage/PaymentInformation/paymentMethods.module.css index 871733791f..97021147a1 100644 --- a/packages/venia-ui/lib/components/CheckoutPage/PaymentInformation/paymentMethods.module.css +++ b/packages/venia-ui/lib/components/CheckoutPage/PaymentInformation/paymentMethods.module.css @@ -1,7 +1,7 @@ .root { composes: grid from global; composes: p-md from global; - composes: pb-xs from global; + composes: pb-s from global; } .radio_group { @@ -14,8 +14,6 @@ composes: border-subtle from global; composes: pb-xs from global; composes: pt-xs from global; - - composes: last_pt-0 from global; } /* TODO @TW: cannot compose */ From a59b2f8ad1de44d95ce60d7c792d2aeb2b59691c Mon Sep 17 00:00:00 2001 From: Anthoula Wojczak Date: Mon, 3 Oct 2022 13:01:32 -0500 Subject: [PATCH 3/3] =?UTF-8?q?PWA-2985:=20[bug]:=20Payment=20method=20alw?= =?UTF-8?q?ays=20reverts=20to=20=E2=80=9CCheck=20/=20Money=20order?= =?UTF-8?q?=E2=80=9D=20when=20there=20is=20an=20error=20with=20the=20trans?= =?UTF-8?q?action?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Revert suggested snap update --- .../__tests__/useCustomerWishlistSkus.spec.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/peregrine/lib/hooks/useCustomerWishlistSkus/__tests__/useCustomerWishlistSkus.spec.js b/packages/peregrine/lib/hooks/useCustomerWishlistSkus/__tests__/useCustomerWishlistSkus.spec.js index 9afb2c60bb..5b08e766d1 100644 --- a/packages/peregrine/lib/hooks/useCustomerWishlistSkus/__tests__/useCustomerWishlistSkus.spec.js +++ b/packages/peregrine/lib/hooks/useCustomerWishlistSkus/__tests__/useCustomerWishlistSkus.spec.js @@ -49,6 +49,7 @@ test('pre-caches wishlist items', async () => { Object { "customerWishlistProducts": Array [ "Dress", + "Shirt", ], } `);