diff --git a/react-components/src/actions/cart/__test__/actions.test.js b/react-components/src/actions/cart/__test__/actions.test.js index 9c2cc13ffd..c1666dcb64 100644 --- a/react-components/src/actions/cart/__test__/actions.test.js +++ b/react-components/src/actions/cart/__test__/actions.test.js @@ -11,7 +11,15 @@ * governing permissions and limitations under the License. * ******************************************************************************/ -import { addItemToCart, getCartDetails, removeItemFromCart, mergeCarts, addCoupon, removeCoupon } from '../actions'; +import { + addItemToCart, + getCartDetails, + removeItemFromCart, + mergeCarts, + addCoupon, + removeCoupon, + updateCartItem +} from '../actions'; describe('Cart actions', () => { const addToCartMutation = jest.fn(); @@ -33,6 +41,8 @@ describe('Cart actions', () => { const removeCouponMutation = jest.fn(); const removeItemMutation = jest.fn(); + const updateCartItemMutation = jest.fn(); + const dispatch = jest.fn(); afterEach(() => { @@ -129,4 +139,18 @@ describe('Cart actions', () => { expect(removeCouponMutation).toHaveBeenCalledTimes(1); expect(dispatch).toHaveBeenCalledWith({ type: 'cart', cart: { id: cartId } }); }); + + it('update quantity in the cart', async () => { + const cartId = 'guest123'; + const cartItemId = '1'; + const itemQuantity = 2; + + await updateCartItem({ cartDetailsQuery, updateCartItemMutation, cartId, cartItemId, itemQuantity, dispatch }); + expect(updateCartItemMutation).toHaveBeenCalledTimes(1); + expect(updateCartItemMutation).toHaveBeenCalledWith({ + variables: { cartId, cartItemId, quantity: itemQuantity } + }); + + expect(dispatch).toHaveBeenCalledWith({ type: 'cart', cart: { id: cartId } }); + }); }); diff --git a/react-components/src/actions/cart/actions.js b/react-components/src/actions/cart/actions.js index f1084ab14a..b6b961da6c 100644 --- a/react-components/src/actions/cart/actions.js +++ b/react-components/src/actions/cart/actions.js @@ -174,3 +174,15 @@ export const mergeCarts = async payload => { dispatch({ type: 'error', error: parseError(error) }); } }; + +export const updateCartItem = async payload => { + const { cartDetailsQuery, updateCartItemMutation, cartId, cartItemId, itemQuantity, dispatch } = payload; + try { + await updateCartItemMutation({ + variables: { cartId, cartItemId, quantity: itemQuantity } + }); + await getCartDetails({ cartDetailsQuery, dispatch, cartId }); + } catch (error) { + dispatch({ type: 'error', error: parseError(error) }); + } +}; diff --git a/react-components/src/components/Minicart/cartInitializer.js b/react-components/src/components/Minicart/cartInitializer.js index 8549dd73a0..84a136c3b1 100644 --- a/react-components/src/components/Minicart/cartInitializer.js +++ b/react-components/src/components/Minicart/cartInitializer.js @@ -66,21 +66,18 @@ const CartInitializer = props => { useEffect(() => { if (cartId && cartId.length > 0 && !stateCartId) { - console.log(`Put the cart id ${cartId} in the state.`); dispatch({ type: 'cartId', cartId, methods: createCartHandlers(cartId, dispatch) }); } }, [cartId]); useEffect(() => { if (stateCartId && (!cartId || cartId.length === 0)) { - console.log(`Put the cart id in the cookie`); setCartCookie(stateCartId); } }, [stateCartId]); useEffect(() => { if (registeredCartId) { - console.log(`Running the effect with the registered cart id ${registeredCartId}`); setCartCookie(registeredCartId); dispatch({ type: 'cartId', diff --git a/react-components/src/components/Minicart/cartOptions.js b/react-components/src/components/Minicart/cartOptions.js index d869a4f40c..c0572a44a7 100644 --- a/react-components/src/components/Minicart/cartOptions.js +++ b/react-components/src/components/Minicart/cartOptions.js @@ -13,8 +13,10 @@ ******************************************************************************/ import React, { useState } from 'react'; -import { useMutation } from '@apollo/react-hooks'; import { useTranslation } from 'react-i18next'; +import { useMutation } from '@apollo/react-hooks'; + +import { useAwaitQuery } from '../../utils/hooks'; import Price from '../Price'; import Button from '../Button'; @@ -23,13 +25,18 @@ import classes from './cartOptions.css'; import CART_DETAILS_QUERY from '../../queries/query_cart_details.graphql'; import MUTATION_UPDATE_CART_ITEM from '../../queries/mutation_update_cart_item.graphql'; - -import { useCartState } from './cartContext'; +import useCartOptions from './useCartOptions'; const CartOptions = () => { - const [{ editItem, cartId }, dispatch] = useCartState(); + const [updateCartItemMutation] = useMutation(MUTATION_UPDATE_CART_ITEM); + const cartDetailsQuery = useAwaitQuery(CART_DETAILS_QUERY); const [t] = useTranslation(['cart', 'common']); + const [{ editItem }, { dispatch, updateCartItem }] = useCartOptions({ + updateCartItemMutation, + cartDetailsQuery + }); + const { product, quantity: initialQuantity, prices } = editItem; const { name } = product; const { value, currency } = prices.price; @@ -51,20 +58,8 @@ const CartOptions = () => { } ]; - const [updateCart] = useMutation(MUTATION_UPDATE_CART_ITEM, { - refetchQueries: [{ query: CART_DETAILS_QUERY, variables: { cartId } }], - awaitRefetchQueries: true - }); - - const handleUpdateClick = () => { - updateCart({ variables: { cartId, cartItemId: editItem.id, quantity } }) - .catch(error => { - dispatch({ type: 'error', error: error.toString() }); - }) - .finally(() => { - dispatch({ type: 'endLoading' }); - }); - dispatch({ type: 'beginLoading' }); + const handleUpdateClick = async () => { + await updateCartItem(quantity); dispatch({ type: 'endEditing' }); }; diff --git a/react-components/src/components/Minicart/useCartOptions.js b/react-components/src/components/Minicart/useCartOptions.js new file mode 100644 index 0000000000..bf3b3a575b --- /dev/null +++ b/react-components/src/components/Minicart/useCartOptions.js @@ -0,0 +1,38 @@ +/******************************************************************************* + * + * Copyright 2019 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + * + ******************************************************************************/ +import { useCartState } from './cartContext'; +import { updateCartItem } from '../../actions/cart'; + +const useCartOptions = ({ updateCartItemMutation, cartDetailsQuery }) => { + const [{ editItem, cartId }, dispatch] = useCartState(); + + const updateCart = async newQuantity => { + dispatch({ type: 'beginLoading' }); + await updateCartItem({ + cartDetailsQuery, + updateCartItemMutation, + cartId, + cartItemId: editItem.id, + itemQuantity: newQuantity, + dispatch + }); + dispatch({ type: 'endLoading' }); + }; + + const data = { editItem, cartId }; + const api = { dispatch, updateCartItem: updateCart }; + return [data, api]; +}; + +export default useCartOptions; diff --git a/react-components/src/components/SignIn/useSignin.js b/react-components/src/components/SignIn/useSignin.js index c8d2722712..fd5df95fb6 100644 --- a/react-components/src/components/SignIn/useSignin.js +++ b/react-components/src/components/SignIn/useSignin.js @@ -60,7 +60,6 @@ export const useSignin = () => { let mergedCartId; if (cartId) { - console.log(`We have a cart id already ${cartId}, let's merge...`); mergedCartId = await mergeCarts({ mergeCartsMutation, cartDetailsQuery, @@ -69,10 +68,8 @@ export const useSignin = () => { dispatch: cartDispatch }); } else { - console.log(`No cart id present, no need to merge anything.`); mergedCartId = customerCartId; } - console.log(`Carts are merged, id is ${mergedCartId}`); //4. set the cart id in the cookie setCartCookie(mergedCartId); setCustomerCart(mergedCartId);