Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 1 addition & 43 deletions packages/peregrine/lib/context/cart.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,5 @@
import React, {
createContext,
useContext,
useEffect,
useMemo,
useCallback
} from 'react';
import React, { createContext, useContext, useMemo, useCallback } from 'react';
import { connect } from 'react-redux';
import { useMutation } from '@apollo/client';
import gql from 'graphql-tag';

import { useAwaitQuery } from '@magento/peregrine/lib/hooks/useAwaitQuery';
import actions from '../store/actions/cart/actions';
import * as asyncActions from '../store/actions/cart/asyncActions';
import bindActionCreators from '../util/bindActionCreators';
Expand Down Expand Up @@ -62,9 +52,6 @@ const CartContextProvider = props => {
return [derivedCartState, cartApi];
}, [cartApi, cartState, derivedDetails]);

const [fetchCartId] = useMutation(CREATE_CART_MUTATION);
const fetchCartDetails = useAwaitQuery(CART_DETAILS_QUERY);

// Storage listener to force a state update if cartId changes from another browser tab.
const storageListener = useCallback(() => {
const storage = new BrowserPersistence();
Expand All @@ -77,14 +64,6 @@ const CartContextProvider = props => {

useEventListener(globalThis, 'storage', storageListener);

useEffect(() => {
// cartApi.getCartDetails initializes the cart if there isn't one.
cartApi.getCartDetails({
fetchCartId,
fetchCartDetails
});
}, [cartApi, fetchCartDetails, fetchCartId]);

return (
<CartContext.Provider value={contextValue}>
{children}
Expand All @@ -105,24 +84,3 @@ export default connect(
)(CartContextProvider);

export const useCartContext = () => useContext(CartContext);

/**
* We normally do not keep GQL queries in Peregrine. All components should pass
* queries to talons/hooks. This is an exception to the rule because it would
* be unecessarily complex to pass these queries to the context provider.
*/
const CREATE_CART_MUTATION = gql`
mutation createCart {
cartId: createEmptyCart
}
`;

const CART_DETAILS_QUERY = gql`
query checkUserIsAuthed($cartId: String!) {
cart(cart_id: $cartId) {
# The purpose of this query is to check that the user is authorized
# to query on the current cart. Just fetch "id" to keep it small.
id
}
}
`;
Original file line number Diff line number Diff line change
Expand Up @@ -530,16 +530,13 @@ test('addToCart succeeds and closes dialog', async () => {
await new Promise(resolve => setTimeout(resolve, 0));
});

expect(initialProps.onClose).not.toHaveBeenCalled();
expect(result.current.imageProps).toBeTruthy();
expect(result.current.priceProps).toBeTruthy();

act(() => {
result.current.buttonProps.onClick();
});

await act(async () => {
await new Promise(resolve => setTimeout(resolve, 0));
await new Promise(resolve => setTimeout(resolve, 0));
});

expect(initialProps.onClose).toHaveBeenCalled();
Expand All @@ -558,7 +555,9 @@ test('addToCart failures returns error', async () => {
}
}
},
error: new Error('Oh noes! Something went wrong :(')
result: {
errors: [new Error('Oh noes! Something went wrong :(')]
}
};

const { result } = renderHookWithProviders({
Expand Down Expand Up @@ -589,6 +588,7 @@ test('addToCart failures returns error', async () => {

await act(async () => {
await new Promise(resolve => setTimeout(resolve, 0));
await new Promise(resolve => setTimeout(resolve, 0));
});

expect(initialProps.onClose).not.toHaveBeenCalled();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { useCallback, useEffect, useMemo, useState } from 'react';
import { useMutation, useQuery } from '@apollo/client';
import { useMutation, useQuery, gql } from '@apollo/client';

import mergeOperations from '../../util/shallowMerge';
import { useCartContext } from '../../context/cart';
import defaultOperations from './addToCartDialog.gql';
import { useEventingContext } from '../../context/eventing';
import { isProductConfigurable } from '@magento/peregrine/lib/util/isProductConfigurable';
import { getOutOfStockVariants } from '@magento/peregrine/lib/util/getOutOfStockVariants';
import { useAwaitQuery } from '@magento/peregrine/lib/hooks/useAwaitQuery';
import BrowserPersistence from '../../util/simplePersistence';

export const useAddToCartDialog = props => {
const { item, onClose } = props;
Expand All @@ -25,7 +27,51 @@ export const useAddToCartDialog = props => {
new Map()
);

const [{ cartId }] = useCartContext();
//const [{ cartId }] = useCartContext();

const [cartState, cartApi] = useCartContext();

const { cartId } = cartState;

// cart creation logic

const CREATE_CART_MUTATION = gql`
mutation createCart {
cartId: createEmptyCart
}
`;

const CART_DETAILS_QUERY = gql`
query checkUserIsAuthed($cartId: String!) {
cart(cart_id: $cartId) {
id
}
}
`;

const [fetchCartId] = useMutation(CREATE_CART_MUTATION);

const fetchCartDetails = useAwaitQuery(CART_DETAILS_QUERY);

const ensureCartId = useCallback(async () => {
let newCartId = cartId;

if (!newCartId) {
await cartApi.getCartDetails({
fetchCartId,

fetchCartDetails
});

newCartId = new BrowserPersistence().getItem('cartId');

if (!newCartId) {
throw new Error('Failed to create a new cart');
}
}

return newCartId;
}, [cartId, cartApi, fetchCartId, fetchCartDetails]);

const optionCodes = useMemo(() => {
const optionCodeMap = new Map();
Expand Down Expand Up @@ -112,7 +158,9 @@ export const useAddToCartDialog = props => {
fetchPolicy: 'cache-and-network',
nextFetchPolicy: 'cache-first',
variables: {
configurableOptionValues: selectedOptionsArray,
configurableOptionValues: selectedOptionsArray.length
? selectedOptionsArray
: null,
sku
},
skip: !sku
Expand All @@ -127,6 +175,7 @@ export const useAddToCartDialog = props => {
useEffect(() => {
if (data) {
const product = data.products.items[0];
console.log('useAddToCartDialog.js - data', data);
const {
media_gallery: selectedProductMediaGallery,
variant: selectedVariant
Expand Down Expand Up @@ -181,12 +230,14 @@ export const useAddToCartDialog = props => {
);

const handleAddToCart = useCallback(async () => {
//console.log("useAddToCartDialog.js handleAddToCart is called for ",cartId);
try {
const ensuredCartId = await ensureCartId();
const quantity = 1;

await addProductToCart({
variables: {
cartId,
cartId: ensuredCartId,
cartItem: {
quantity,
selected_options: selectedOptionsArray,
Expand All @@ -207,7 +258,7 @@ export const useAddToCartDialog = props => {
dispatch({
type: 'CART_ADD_ITEM',
payload: {
cartId,
cartId: ensuredCartId,
sku: item.product.sku,
name: item.product.name,
pricing: item.product.price,
Expand All @@ -225,7 +276,7 @@ export const useAddToCartDialog = props => {
}
}, [
addProductToCart,
cartId,
ensureCartId,
currentDiscount,
currentPrice,
dispatch,
Expand Down
Loading