Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Mini Cart Block: show the total price, including tax, according to the option #9878

Merged
merged 4 commits into from
Jun 19, 2023
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
29 changes: 20 additions & 9 deletions assets/js/blocks/mini-cart/utils/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 ) {
Expand Down Expand Up @@ -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 ];
};

Expand All @@ -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(
Expand Down
81 changes: 80 additions & 1 deletion assets/js/blocks/mini-cart/utils/test/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* External dependencies
*/
import { getByTestId, waitFor } from '@testing-library/dom';
import { getSettingWithCoercion } from '@woocommerce/settings';

/**
* Internal dependencies
Expand All @@ -19,6 +20,7 @@ const responseMock = {
json: async () => ( {
totals: {
total_price: '1600',
total_items: '1400',
currency_code: 'USD',
currency_symbol: '$',
currency_minor_unit: 2,
Expand All @@ -33,6 +35,7 @@ const responseMock = {
const localStorageMock = {
totals: {
total_price: '1600',
total_items: '1400',
currency_code: 'USD',
currency_symbol: '$',
currency_minor_unit: 2,
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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();
} );
} );