diff --git a/assets/js/blocks/mini-cart/utils/data.ts b/assets/js/blocks/mini-cart/utils/data.ts index 7cb5c78c316..a4d1ea62611 100644 --- a/assets/js/blocks/mini-cart/utils/data.ts +++ b/assets/js/blocks/mini-cart/utils/data.ts @@ -6,7 +6,16 @@ import { getCurrencyFromPriceResponse, formatPrice, } from '@woocommerce/price-format'; -import { CartResponse } from '@woocommerce/types'; +import { CartResponse, isBoolean } from '@woocommerce/types'; +import { getSettingWithCoercion } from '@woocommerce/settings'; + +const getPrice = ( cartResponse: CartResponse, showIncludingTax: boolean ) => { + const currency = getCurrencyFromPriceResponse( cartResponse.totals ); + + return showIncludingTax + ? formatPrice( cartResponse.totals.total_price, currency ) + : formatPrice( cartResponse.totals.total_items, currency ); +}; export const updateTotals = ( totals: [ string, number ] | undefined ) => { if ( ! totals ) { @@ -86,11 +95,12 @@ export const getMiniCartTotalsFromLocalStorage = (): return undefined; } const miniCartTotals = JSON.parse( rawMiniCartTotals ); - const currency = getCurrencyFromPriceResponse( miniCartTotals.totals ); - const formattedPrice = formatPrice( - miniCartTotals.totals.total_price, - currency + const showIncludingTax = getSettingWithCoercion( + 'displayCartPricesIncludingTax', + false, + isBoolean ); + const formattedPrice = getPrice( miniCartTotals, showIncludingTax ); return [ formattedPrice, miniCartTotals.itemsCount ] as [ string, number ]; }; @@ -107,11 +117,12 @@ export const getMiniCartTotalsFromServer = async (): Promise< return response.json(); } ) .then( ( data: CartResponse ) => { - const currency = getCurrencyFromPriceResponse( data.totals ); - const formattedPrice = formatPrice( - data.totals.total_price, - currency + const showIncludingTax = getSettingWithCoercion( + 'displayCartPricesIncludingTax', + false, + isBoolean ); + const formattedPrice = getPrice( data, showIncludingTax ); // Save server data to local storage, so we can re-fetch it faster // on the next page load. localStorage.setItem( diff --git a/assets/js/blocks/mini-cart/utils/test/data.ts b/assets/js/blocks/mini-cart/utils/test/data.ts index 73e72b73f8e..7c02da72053 100644 --- a/assets/js/blocks/mini-cart/utils/test/data.ts +++ b/assets/js/blocks/mini-cart/utils/test/data.ts @@ -3,6 +3,7 @@ * External dependencies */ import { getByTestId, waitFor } from '@testing-library/dom'; +import { getSettingWithCoercion } from '@woocommerce/settings'; /** * Internal dependencies @@ -19,6 +20,7 @@ const responseMock = { json: async () => ( { totals: { total_price: '1600', + total_items: '1400', currency_code: 'USD', currency_symbol: '$', currency_minor_unit: 2, @@ -33,6 +35,7 @@ const responseMock = { const localStorageMock = { totals: { total_price: '1600', + total_items: '1400', currency_code: 'USD', currency_symbol: '$', currency_minor_unit: 2, @@ -67,7 +70,21 @@ const getMiniCartDOM = () => { return div; }; -describe( 'Mini-Cart frontend script', () => { +jest.mock( '@woocommerce/settings', () => { + return { + ...jest.requireActual( '@woocommerce/settings' ), + getSettingWithCoercion: jest.fn(), + }; +} ); + +describe( 'Mini-Cart frontend script when "the display prices during cart and checkout" option is set to "Including Tax"', () => { + beforeAll( () => { + ( getSettingWithCoercion as jest.Mock ).mockReturnValue( true ); + } ); + + afterAll( () => { + jest.resetModules(); + } ); it( 'updates the cart contents based on the localStorage values', async () => { initializeLocalStorage(); const container = getMiniCartDOM(); @@ -125,3 +142,65 @@ describe( 'Mini-Cart frontend script', () => { jest.restoreAllMocks(); } ); } ); + +describe( 'Mini-Cart frontend script when "the display prices during cart and checkout" option is set to "Excluding Tax"', () => { + beforeAll( () => { + ( getSettingWithCoercion as jest.Mock ).mockReturnValue( false ); + } ); + it( 'updates the cart contents based on the localStorage values', async () => { + initializeLocalStorage(); + const container = getMiniCartDOM(); + document.body.appendChild( container ); + + updateTotals( getMiniCartTotalsFromLocalStorage() ); + + // Assert that we are rendering the amount. + await waitFor( () => + expect( getByTestId( container, 'amount' ).textContent ).toBe( + '$14.00' + ) + ); + // Assert that we are rendering the quantity. + await waitFor( () => + expect( getByTestId( container, 'quantity' ).textContent ).toBe( + '2' + ) + ); + } ); + + it( 'updates the cart contents based on the API response', async () => { + jest.spyOn( window, 'fetch' ).mockResolvedValue( responseMock ); + const container = getMiniCartDOM(); + document.body.appendChild( container ); + + getMiniCartTotalsFromServer().then( updateTotals ); + + // Assert we called the correct endpoint. + await waitFor( () => + expect( window.fetch ).toHaveBeenCalledWith( + '/wp-json/wc/store/v1/cart/' + ) + ); + + // Assert we saved the values returned to the localStorage. + await waitFor( () => + expect( window.localStorage.setItem.mock.calls[ 0 ][ 1 ] ).toEqual( + JSON.stringify( localStorageMock ) + ) + ); + + // Assert that we are rendering the amount. + await waitFor( () => + expect( getByTestId( container, 'amount' ).textContent ).toBe( + '$14.00' + ) + ); + // Assert that we are rendering the quantity. + await waitFor( () => + expect( getByTestId( container, 'quantity' ).textContent ).toBe( + '2' + ) + ); + jest.restoreAllMocks(); + } ); +} );