diff --git a/packages/peregrine/lib/talons/CartPage/__tests__/useCartPage.spec.js b/packages/peregrine/lib/talons/CartPage/__tests__/useCartPage.spec.js
index bc04700152..52dd175881 100644
--- a/packages/peregrine/lib/talons/CartPage/__tests__/useCartPage.spec.js
+++ b/packages/peregrine/lib/talons/CartPage/__tests__/useCartPage.spec.js
@@ -1,18 +1,28 @@
-import React, { useEffect } from 'react';
+import React, { useEffect, useState } from 'react';
import { createTestInstance } from '@magento/peregrine';
+import { useQuery } from '@apollo/react-hooks';
import { useCartPage } from '../useCartPage';
+jest.mock('react', () => {
+ const React = jest.requireActual('react');
+ const spy = jest.spyOn(React, 'useState');
+
+ return {
+ ...React,
+ useState: spy
+ };
+});
+
jest.mock('@apollo/react-hooks', () => {
- const runQuery = jest.fn();
const queryResult = {
+ called: false,
data: null,
- error: null,
loading: false
};
- const useLazyQuery = jest.fn(() => [runQuery, queryResult]);
+ const useQuery = jest.fn(() => queryResult);
- return { useLazyQuery };
+ return { useQuery };
});
jest.mock('@magento/peregrine/lib/context/app', () => {
@@ -67,6 +77,43 @@ test('it returns the proper shape', () => {
handleSignIn: expect.any(Function),
isCartUpdating: expect.any(Boolean),
isSignedIn: expect.any(Boolean),
- setIsCartUpdating: expect.any(Function)
+ setIsCartUpdating: expect.any(Function),
+ shouldShowLoadingIndicator: expect.any(Boolean)
});
});
+
+test('it calls setIsCartUpdating true when loading is true', () => {
+ // Arrange.
+ useQuery.mockReturnValueOnce({
+ called: true,
+ data: { cart: { total_quantity: 0 } },
+ loading: true
+ });
+ // isCartUpdating
+ useState.mockReturnValueOnce([false, jest.fn()]);
+
+ // Act.
+ createTestInstance();
+
+ // Assert.
+ const { setIsCartUpdating } = log.mock.calls[0][0];
+ expect(setIsCartUpdating).toBeCalledWith(true);
+});
+
+test('it calls setIsCartUpdating false when loading is false', () => {
+ // Arrange.
+ useQuery.mockReturnValueOnce({
+ called: true,
+ data: { cart: { total_quantity: 0 } },
+ loading: false
+ });
+ // isCartUpdating
+ useState.mockReturnValueOnce([false, jest.fn()]);
+
+ // Act.
+ createTestInstance();
+
+ // Assert.
+ const { setIsCartUpdating } = log.mock.calls[0][0];
+ expect(setIsCartUpdating).toBeCalledWith(false);
+});
diff --git a/packages/peregrine/lib/talons/CartPage/useCartPage.js b/packages/peregrine/lib/talons/CartPage/useCartPage.js
index e026777cca..2ce2d33f9f 100644
--- a/packages/peregrine/lib/talons/CartPage/useCartPage.js
+++ b/packages/peregrine/lib/talons/CartPage/useCartPage.js
@@ -1,5 +1,5 @@
import { useCallback, useEffect, useState } from 'react';
-import { useLazyQuery } from '@apollo/react-hooks';
+import { useQuery } from '@apollo/react-hooks';
import { useAppContext } from '@magento/peregrine/lib/context/app';
import { useUserContext } from '@magento/peregrine/lib/context/user';
@@ -16,10 +16,11 @@ export const useCartPage = props => {
const [isCartUpdating, setIsCartUpdating] = useState(false);
- const [fetchCartData, { data }] = useLazyQuery(getCartDetails, {
- // TODO: Purposely overfetch and hit the network until all components
- // are correctly updating the cache. Will be fixed by PWA-321.
- fetchPolicy: 'cache-and-network'
+ const { called, data, loading } = useQuery(getCartDetails, {
+ fetchPolicy: 'cache-and-network',
+ // Don't make this call if we don't have a cartId
+ skip: !cartId,
+ variables: { cartId }
});
const handleSignIn = useCallback(() => {
@@ -28,20 +29,19 @@ export const useCartPage = props => {
}, [toggleDrawer]);
useEffect(() => {
- if (cartId) {
- fetchCartData({
- variables: {
- cartId
- }
- });
- }
- }, [cartId, fetchCartData]);
+ // Let the cart page know it is updating while we're waiting on network data.
+ setIsCartUpdating(loading);
+ }, [loading]);
+
+ const hasItems = !!(data && data.cart.total_quantity);
+ const shouldShowLoadingIndicator = called && loading && !hasItems;
return {
- hasItems: !!(data && data.cart.total_quantity),
+ hasItems,
handleSignIn,
isSignedIn,
isCartUpdating,
- setIsCartUpdating
+ setIsCartUpdating,
+ shouldShowLoadingIndicator
};
};
diff --git a/packages/venia-ui/lib/components/CartPage/__tests__/__snapshots__/cartPage.spec.js.snap b/packages/venia-ui/lib/components/CartPage/__tests__/__snapshots__/cartPage.spec.js.snap
index 8d20aa53a3..983c165bb7 100644
--- a/packages/venia-ui/lib/components/CartPage/__tests__/__snapshots__/cartPage.spec.js.snap
+++ b/packages/venia-ui/lib/components/CartPage/__tests__/__snapshots__/cartPage.spec.js.snap
@@ -1,5 +1,75 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
+exports[`renders a loading indicator when talon indicates 1`] = `
+
+
+
+
+
+ Fetching Data...
+
+
+`;
+
exports[`renders components if cart has items 1`] = `
@@ -7,7 +77,7 @@ exports[`renders components if cart has items 1`] = `
Cart