Skip to content

Commit

Permalink
CIF-1415 - [Cart] Editing the quantity doesn't update the cart (#282)
Browse files Browse the repository at this point in the history
Move the logic of the `CartOption` component in a separate module. Move the actual cart update mutation in the `actions` module and refresh the cart details after the cart update.

Clean-up some leftover `console.log` statements.

Co-authored-by: Daniel Platon <[email protected]>
Co-authored-by: Mark J. Becker <[email protected]>
  • Loading branch information
3 people authored Jun 18, 2020
1 parent 551de8d commit f374f88
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 25 deletions.
26 changes: 25 additions & 1 deletion react-components/src/actions/cart/__test__/actions.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -33,6 +41,8 @@ describe('Cart actions', () => {
const removeCouponMutation = jest.fn();
const removeItemMutation = jest.fn();

const updateCartItemMutation = jest.fn();

const dispatch = jest.fn();

afterEach(() => {
Expand Down Expand Up @@ -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 } });
});
});
12 changes: 12 additions & 0 deletions react-components/src/actions/cart/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) });
}
};
3 changes: 0 additions & 3 deletions react-components/src/components/Minicart/cartInitializer.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
31 changes: 13 additions & 18 deletions react-components/src/components/Minicart/cartOptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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;
Expand All @@ -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' });
};

Expand Down
38 changes: 38 additions & 0 deletions react-components/src/components/Minicart/useCartOptions.js
Original file line number Diff line number Diff line change
@@ -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;
3 changes: 0 additions & 3 deletions react-components/src/components/SignIn/useSignin.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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);
Expand Down

0 comments on commit f374f88

Please sign in to comment.