diff --git a/static/js/formatters-internal.js b/static/js/formatters-internal.js index d8f121ad0..fbdc7fb5f 100644 --- a/static/js/formatters-internal.js +++ b/static/js/formatters-internal.js @@ -10,6 +10,7 @@ import { generateCTAFieldTypeLink } from './formatters/generate-cta-field-type-l import { isChrome } from './useragent.js'; import LocaleCurrency from 'locale-currency' import getSymbolFromCurrency from 'currency-symbol-map' +import { parseLocale } from './utils.js'; export function address(profile) { if (!profile.address) { @@ -525,24 +526,31 @@ export function price(fieldValue = {}, locale) { } /** - * Returns a localized price range string for the given price range ($-$$$$) and country code (ISO format) + * Returns a localized price range string for the given price range ($-$$$$) and country code (ISO format). + * If country code is invalid or undefined, use locale of the site to determine the currency symbol. + * If all else fails, use the default priceRange with dollar sign. * @param {string} defaultPriceRange The price range from LiveAPI entity * @param {string} countrycode The country code from LiveAPI entity (e.g. profile.address.countryCode) * @return {string} The price range with correct currency symbol formatting according to country code */ export function priceRange(defaultPriceRange, countryCode) { - if (!defaultPriceRange || !countryCode) { - console.warn(`No price range or country code given.`); + if (!defaultPriceRange) { + console.warn(`Price range is not provided.`); return ''; } - const currencyCode = LocaleCurrency.getCurrency(countryCode); - if (currencyCode) { - const currencySymbol = getSymbolFromCurrency(currencyCode); + if (countryCode) { + const currencySymbol = getSymbolFromCurrency(LocaleCurrency.getCurrency(countryCode)); if (currencySymbol) { return defaultPriceRange.replace(/\$/g, currencySymbol); } } - console.warn(`Unable to determine currency symbol from ISO country code ${countryCode}.`); + const { region, language } = parseLocale(_getDocumentLocale()); + const currencySymbol = getSymbolFromCurrency(LocaleCurrency.getCurrency(region || language)); + if (currencySymbol) { + return defaultPriceRange.replace(/\$/g, currencySymbol); + } + console.warn('Unable to determine currency symbol from ' + + `ISO country code "${countryCode}" or locale "${_getDocumentLocale()}".`); return defaultPriceRange; } diff --git a/tests/static/js/formatters.js b/tests/static/js/formatters.js index def3d361d..da57bbc16 100644 --- a/tests/static/js/formatters.js +++ b/tests/static/js/formatters.js @@ -135,7 +135,23 @@ describe('Formatters', () => { expect(price).toEqual('£'); }); - it('Formats a price range in invalid input', () => { + it('Formats a price range in invalid country code, use page\'s locale', () => { + document.documentElement.lang = 'jp' + const price = Formatters.priceRange('$$$', 'IDK'); + expect(price).toEqual('¥¥¥'); + }); + + it('Formats a price range in undefined country code, use page\'s locale', () => { + document.documentElement.lang = 'zh-CN' + let price = Formatters.priceRange('$$$', undefined); + expect(price).toEqual('¥¥¥'); + document.documentElement.lang = 'zh-Hant_TW' + price = Formatters.priceRange('$$$', undefined); + expect(price).toEqual('NT$NT$NT$'); + }); + + it('Formats a price range in invalid country code and invalid page\'s locale', () => { + document.documentElement.lang = 'IDKK' const price = Formatters.priceRange('$', 'IDK'); expect(price).toEqual('$'); });