Prevent checkout blocks breakage for stores using similar number separators (#46241)
* Add a safety check for the numbers with the same value for the separators This case breaks the library we are using for number formatting. This is not documented on their end and can't be fixed by passing a different configuration. We are fixing it on our end by overwriting the thousand separator. This change will only surface in the checkout blocks, at they are the only blocks doing formatting via React (the products blocks use php). This will not apply to the order confirmation. This change is preventing a fatal error thrown by the library and allowing users to see the content of the cart. It's an edge case, because it happens only why people have the same values for the separators, which is an non-standard way to format. * Add unit tests and changelog * Add a safety check for the numbers with the same value for the separators This case breaks the library we are using for number formatting. This is not documented on their end and can't be fixed by passing a different configuration. We are fixing it on our end by overwriting the thousand separator. This change will only surface in the checkout blocks, at they are the only blocks doing formatting via React (the products blocks use php). This will not apply to the order confirmation. This change is preventing a fatal error thrown by the library and allowing users to see the content of the cart. It's an edge case, because it happens only why people have the same values for the separators, which is an non-standard way to format. * Add unit tests and changelog * Improve tests * "Improve tests"
This commit is contained in:
parent
4797d72c60
commit
f165667632
|
@ -34,8 +34,18 @@ export interface FormattedMonetaryAmountProps
|
||||||
const currencyToNumberFormat = (
|
const currencyToNumberFormat = (
|
||||||
currency: FormattedMonetaryAmountProps[ 'currency' ]
|
currency: FormattedMonetaryAmountProps[ 'currency' ]
|
||||||
) => {
|
) => {
|
||||||
|
const hasSimiliarSeparators =
|
||||||
|
currency?.thousandSeparator === currency?.decimalSeparator;
|
||||||
|
if ( hasSimiliarSeparators ) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.warn(
|
||||||
|
'Thousand separator and decimal separator are the same. This may cause formatting issues.'
|
||||||
|
);
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
thousandSeparator: currency?.thousandSeparator,
|
thousandSeparator: hasSimiliarSeparators
|
||||||
|
? ''
|
||||||
|
: currency?.thousandSeparator,
|
||||||
decimalSeparator: currency?.decimalSeparator,
|
decimalSeparator: currency?.decimalSeparator,
|
||||||
fixedDecimalScale: true,
|
fixedDecimalScale: true,
|
||||||
prefix: currency?.prefix,
|
prefix: currency?.prefix,
|
||||||
|
|
|
@ -0,0 +1,139 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import { render, screen } from '@testing-library/react';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import FormattedMonetaryAmount from '../index';
|
||||||
|
|
||||||
|
describe( 'FormattedMonetaryAmount', () => {
|
||||||
|
describe( 'separators', () => {
|
||||||
|
test( 'should add the thousand separator', () => {
|
||||||
|
render(
|
||||||
|
<FormattedMonetaryAmount
|
||||||
|
value="156345"
|
||||||
|
currency={ {
|
||||||
|
code: 'EUR',
|
||||||
|
symbol: '€',
|
||||||
|
thousandSeparator: '.',
|
||||||
|
decimalSeparator: ',',
|
||||||
|
minorUnit: 2,
|
||||||
|
prefix: '',
|
||||||
|
suffix: ' €',
|
||||||
|
} }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
expect( screen.getByText( '1.563,45 €' ) ).toBeInTheDocument();
|
||||||
|
} );
|
||||||
|
|
||||||
|
test( 'should not add thousand separator', () => {
|
||||||
|
render(
|
||||||
|
<FormattedMonetaryAmount
|
||||||
|
value="156345"
|
||||||
|
currency={ {
|
||||||
|
code: 'EUR',
|
||||||
|
symbol: '€',
|
||||||
|
decimalSeparator: ',',
|
||||||
|
minorUnit: 2,
|
||||||
|
prefix: '',
|
||||||
|
suffix: ' €',
|
||||||
|
} }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
expect( screen.getByText( '1563,45 €' ) ).toBeInTheDocument();
|
||||||
|
} );
|
||||||
|
|
||||||
|
test( 'should remove the thousand separator when identical to the decimal one', () => {
|
||||||
|
render(
|
||||||
|
<FormattedMonetaryAmount
|
||||||
|
value="156345"
|
||||||
|
currency={ {
|
||||||
|
code: 'EUR',
|
||||||
|
symbol: '€',
|
||||||
|
thousandSeparator: ',',
|
||||||
|
decimalSeparator: ',',
|
||||||
|
minorUnit: 2,
|
||||||
|
prefix: '',
|
||||||
|
suffix: ' €',
|
||||||
|
} }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
expect( console ).toHaveWarned();
|
||||||
|
expect( screen.getByText( '1563,45 €' ) ).toBeInTheDocument();
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
describe( 'suffix/prefix', () => {
|
||||||
|
test( 'should add the currency suffix', () => {
|
||||||
|
render(
|
||||||
|
<FormattedMonetaryAmount
|
||||||
|
value="15"
|
||||||
|
currency={ {
|
||||||
|
code: 'EUR',
|
||||||
|
symbol: '€',
|
||||||
|
thousandSeparator: '.',
|
||||||
|
decimalSeparator: ',',
|
||||||
|
minorUnit: 2,
|
||||||
|
suffix: ' €',
|
||||||
|
} }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
expect( screen.getByText( '0,15 €' ) ).toBeInTheDocument();
|
||||||
|
} );
|
||||||
|
|
||||||
|
test( 'should add the currency prefix', () => {
|
||||||
|
render(
|
||||||
|
<FormattedMonetaryAmount
|
||||||
|
value="15"
|
||||||
|
currency={ {
|
||||||
|
code: 'EUR',
|
||||||
|
symbol: '€',
|
||||||
|
thousandSeparator: '.',
|
||||||
|
decimalSeparator: ',',
|
||||||
|
minorUnit: 2,
|
||||||
|
prefix: '€ ',
|
||||||
|
} }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
expect( screen.getByText( '€ 0,15' ) ).toBeInTheDocument();
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
|
||||||
|
describe( 'supports different value types', () => {
|
||||||
|
test( 'should support numbers', () => {
|
||||||
|
render(
|
||||||
|
<FormattedMonetaryAmount
|
||||||
|
value={ 15.0 }
|
||||||
|
currency={ {
|
||||||
|
code: 'EUR',
|
||||||
|
symbol: '€',
|
||||||
|
thousandSeparator: '.',
|
||||||
|
decimalSeparator: ',',
|
||||||
|
minorUnit: 0,
|
||||||
|
suffix: ' €',
|
||||||
|
} }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
expect( screen.getByText( '15 €' ) ).toBeInTheDocument();
|
||||||
|
} );
|
||||||
|
|
||||||
|
test( 'should support strings', () => {
|
||||||
|
render(
|
||||||
|
<FormattedMonetaryAmount
|
||||||
|
value="15.0"
|
||||||
|
currency={ {
|
||||||
|
code: 'EUR',
|
||||||
|
symbol: '€',
|
||||||
|
thousandSeparator: '.',
|
||||||
|
decimalSeparator: ',',
|
||||||
|
minorUnit: 0,
|
||||||
|
prefix: '€ ',
|
||||||
|
} }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
expect( screen.getByText( '€ 15' ) ).toBeInTheDocument();
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
} );
|
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: patch
|
||||||
|
Type: fix
|
||||||
|
|
||||||
|
Add a safety check for the numbers with the same value for the separators
|
Loading…
Reference in New Issue