mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-15 14:43:46 +01:00
[web] Use localized number formatting for currencies (#17622)
* Add a unit test on `SubscriptionFormatters.formatPrice` * Add JSDoc to `formatPrice` Also: Name the functions before exporting: This fixes my IDE (WebStorm) navigation * Make `'USD'` the default param instead of reassigning * Create `formatCurrency` function * Use `formatCurrency` in SubscriptionFormatters * Use an `isNoCentsCurrency` logic for `CLP` `JPY` `KRW` `VND` And remove custom `CLP` logic and locale * Add `locale` param to `formatPrice` * Generate `groups.json` and `localizedPlanPricing.json` ``` bin/exec web node ./scripts/recurly/recurly_prices.js --download -o prices.json bin/exec web node ./scripts/plan-prices/plans.js -f ../../prices.json -o dir ``` * Update scripts/plan-prices/plans.js to generate numbers instead of localized amounts * Generate `groups.json` and `localizedPlanPricing.json` ``` bin/exec web node ./scripts/recurly/recurly_prices.js --download -o prices.json bin/exec web node ./scripts/plan-prices/plans.js -f ../../prices.json -o dir ``` * Remove generation of `plans.json` As /services/web/frontend/js/main/plans.js was removed in https://github.com/overleaf/internal/pull/12593 * Sort currencies in alphabetical order in scripts/plan-prices/plans.js * Generate `groups.json` and `localizedPlanPricing.json` ``` bin/exec web node ./scripts/recurly/recurly_prices.js --download -o prices.json bin/exec web node ./scripts/plan-prices/plans.js -f ../../prices.json -o dir ``` * Use `formatCurrency` in price-summary.tsx * Use `formatCurrency` in Subscription Pug files * Fix unit tests SubscriptionHelperTests.js * Remove unused `currencySymbol` * Change to `formatCurrency` in other React components * Add `CurrencyCode` JSDoc types * Duplicate `formatCurrency` into services/web/app/src/util * Wrap tests in a top-level describe block * Use `narrowSymbol` * Fix tests with `narrowSymbol` expects * Revert deletion of old `formatPrice` in SubscriptionFormatters.js * Rename `formatCurrency` -> `formatCurrencyLocalized` * Revert deletion of `CurrencySymbol` * Add split-test in SubscriptionController.js * Add split-test in SubscriptionViewModelBuilder.js * Add split-test in plans * Add split-test in subscription-dashboard-context.tsx * Add split-test in 4 more components * Update tests * Show currency and payment methods in interstitial page * Fix `–` being printed. Use `–` instead * Fix test with NOK * Storybook: Fix missing `SplitTestProvider` * Storybook: Revert "Remove unused `currencySymbol`" This reverts commit e55387d4753f97bbf8e39e0fdc3ad17312122aaa. * Replace `getSplitTestVariant` by `useSplitTestContext` * Use parameterize currencyFormat in `generateInitialLocalizedGroupPrice` * Fixup import paths of `formatCurrencyLocalized` * Replace `% 1 === 0` by `Number.isInteger` * Add comment explaining that any combinations of languages/currencies could happen * Fixup after rebase: import `useSplitTestContext` * Revert "Remove SplitTestProvider from subscription root" This reverts commit be9f378fda715b86589ab0759737581c72321d87. * Revert "Remove split test provider from some tests" This reverts commit 985522932b550cfd38fa6a4f4c3d2ebaee6ff7df. GitOrigin-RevId: 59a83cbbe0f7cc7e45f189c654e23fcf9bfa37af
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { expect } from 'chai'
|
||||
import { formatPriceForDisplayData } from '../../../../../frontend/js/features/subscription/util/recurly-pricing'
|
||||
import { formatCurrencyLocalized } from '@/shared/utils/currency'
|
||||
|
||||
describe('formatPriceForDisplayData', function () {
|
||||
beforeEach(function () {
|
||||
@@ -9,11 +10,17 @@ describe('formatPriceForDisplayData', function () {
|
||||
window.metaAttributesCache = new Map()
|
||||
})
|
||||
it('should handle no tax rate', function () {
|
||||
const data = formatPriceForDisplayData('1000', 0, 'USD')
|
||||
const data = formatPriceForDisplayData(
|
||||
'1000',
|
||||
0,
|
||||
'USD',
|
||||
'en',
|
||||
formatCurrencyLocalized
|
||||
)
|
||||
expect(data).to.deep.equal({
|
||||
totalForDisplay: '$1000',
|
||||
totalForDisplay: '$1,000',
|
||||
totalAsNumber: 1000,
|
||||
subtotal: '$1000.00',
|
||||
subtotal: '$1,000.00',
|
||||
tax: '$0.00',
|
||||
includesTax: false,
|
||||
})
|
||||
@@ -21,7 +28,13 @@ describe('formatPriceForDisplayData', function () {
|
||||
})
|
||||
|
||||
it('should handle a tax rate', function () {
|
||||
const data = formatPriceForDisplayData('380', 0.2, 'EUR')
|
||||
const data = formatPriceForDisplayData(
|
||||
'380',
|
||||
0.2,
|
||||
'EUR',
|
||||
'en',
|
||||
formatCurrencyLocalized
|
||||
)
|
||||
expect(data).to.deep.equal({
|
||||
totalForDisplay: '€456',
|
||||
totalAsNumber: 456,
|
||||
@@ -32,7 +45,13 @@ describe('formatPriceForDisplayData', function () {
|
||||
})
|
||||
|
||||
it('should handle total with cents', function () {
|
||||
const data = formatPriceForDisplayData('8', 0.2, 'EUR')
|
||||
const data = formatPriceForDisplayData(
|
||||
'8',
|
||||
0.2,
|
||||
'EUR',
|
||||
'en',
|
||||
formatCurrencyLocalized
|
||||
)
|
||||
expect(data).to.deep.equal({
|
||||
totalForDisplay: '€9.60',
|
||||
totalAsNumber: 9.6,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { expect } from 'chai'
|
||||
import { createLocalizedGroupPlanPrice } from '../../../../frontend/js/features/plans/utils/group-plan-pricing'
|
||||
import { formatCurrencyLocalized } from '@/shared/utils/currency'
|
||||
|
||||
describe('group-plan-pricing', function () {
|
||||
beforeEach(function () {
|
||||
@@ -44,11 +45,12 @@ describe('group-plan-pricing', function () {
|
||||
currency: 'CHF',
|
||||
licenseSize: '2',
|
||||
usage: 'enterprise',
|
||||
formatCurrency: formatCurrencyLocalized,
|
||||
})
|
||||
|
||||
expect(localizedGroupPlanPrice).to.deep.equal({
|
||||
localizedPrice: 'Fr 100',
|
||||
localizedPerUserPrice: 'Fr 50',
|
||||
localizedPrice: 'CHF 100',
|
||||
localizedPerUserPrice: 'CHF 50',
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -59,11 +61,12 @@ describe('group-plan-pricing', function () {
|
||||
currency: 'DKK',
|
||||
licenseSize: '2',
|
||||
usage: 'enterprise',
|
||||
formatCurrency: formatCurrencyLocalized,
|
||||
})
|
||||
|
||||
expect(localizedGroupPlanPrice).to.deep.equal({
|
||||
localizedPrice: '200 kr',
|
||||
localizedPerUserPrice: '100 kr',
|
||||
localizedPrice: 'kr 200',
|
||||
localizedPerUserPrice: 'kr 100',
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -74,6 +77,7 @@ describe('group-plan-pricing', function () {
|
||||
currency: 'USD',
|
||||
licenseSize: '2',
|
||||
usage: 'enterprise',
|
||||
formatCurrency: formatCurrencyLocalized,
|
||||
})
|
||||
|
||||
expect(localizedGroupPlanPrice).to.deep.equal({
|
||||
|
||||
@@ -14,6 +14,35 @@ function clearSettingsCache() {
|
||||
settingsDeps.forEach(dep => delete require.cache[dep])
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} value
|
||||
* @returns {string} A string representation of the structure of the value
|
||||
*/
|
||||
function serializeTypes(value) {
|
||||
if (typeof value === 'object') {
|
||||
const keys = Object.keys(value).sort()
|
||||
const types = keys.reduce((acc, key) => {
|
||||
acc[key] = serializeTypes(value[key])
|
||||
return acc
|
||||
}, {})
|
||||
return JSON.stringify(types)
|
||||
}
|
||||
if (Array.isArray(value)) {
|
||||
return JSON.stringify(value.map(serializeTypes))
|
||||
}
|
||||
return typeof value
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any[]} objects
|
||||
* @returns {boolean} Whether all objects have the same structure
|
||||
*/
|
||||
function haveSameStructure(objects) {
|
||||
if (!objects.length) return true
|
||||
const referenceStructure = serializeTypes(objects[0])
|
||||
return objects.every(obj => serializeTypes(obj) === referenceStructure)
|
||||
}
|
||||
|
||||
describe('settings.defaults', function () {
|
||||
it('additional text extensions can be added via config', function () {
|
||||
clearSettingsCache()
|
||||
@@ -23,4 +52,35 @@ describe('settings.defaults', function () {
|
||||
expect(settings.textExtensions).to.include('abc')
|
||||
expect(settings.textExtensions).to.include('xyz')
|
||||
})
|
||||
|
||||
it('generates pricings with same structures', function () {
|
||||
const settingsOverridesSaas = require('../../../../config/settings.overrides.saas.js')
|
||||
const { localizedPlanPricing } = settingsOverridesSaas
|
||||
|
||||
const pricingCurrencies = Object.keys(localizedPlanPricing)
|
||||
expect(pricingCurrencies.sort()).to.eql([
|
||||
'AUD',
|
||||
'BRL',
|
||||
'CAD',
|
||||
'CHF',
|
||||
'CLP',
|
||||
'COP',
|
||||
'DKK',
|
||||
'EUR',
|
||||
'GBP',
|
||||
'INR',
|
||||
'MXN',
|
||||
'NOK',
|
||||
'NZD',
|
||||
'PEN',
|
||||
'SEK',
|
||||
'SGD',
|
||||
'USD',
|
||||
])
|
||||
|
||||
const pricings = pricingCurrencies.map(
|
||||
currency => localizedPlanPricing[currency]
|
||||
)
|
||||
expect(haveSameStructure(pricings)).to.be.true
|
||||
})
|
||||
})
|
||||
|
||||
@@ -0,0 +1,300 @@
|
||||
const chai = require('chai')
|
||||
const SubscriptionFormatters = require('../../../../app/src/Features/Subscription/SubscriptionFormatters')
|
||||
|
||||
const { expect } = chai
|
||||
|
||||
/*
|
||||
Users can select any language we support, regardless of the country where they are located.
|
||||
Which mean that any combination of "supported language"-"supported currency" can be displayed
|
||||
on the user's screen.
|
||||
|
||||
Users located in the USA visiting https://fr.overleaf.com/user/subscription/plans
|
||||
should see amounts in USD (because of their IP address),
|
||||
but with French text, number formatting and currency formats (because of language choice).
|
||||
(e.g. 1 000,00 $)
|
||||
|
||||
Users located in the France visiting https://www.overleaf.com/user/subscription/plans
|
||||
should see amounts in EUR (because of their IP address),
|
||||
but with English text, number formatting and currency formats (because of language choice).
|
||||
(e.g. €1,000.00)
|
||||
*/
|
||||
|
||||
describe('SubscriptionFormatters.formatPrice', function () {
|
||||
describe('en', function () {
|
||||
const format = currency => priceInCents =>
|
||||
SubscriptionFormatters.formatPriceLocalized(priceInCents, currency)
|
||||
|
||||
describe('USD', function () {
|
||||
const formatUSD = format('USD')
|
||||
|
||||
it('should format basic amounts', function () {
|
||||
expect(formatUSD(0)).to.equal('$0.00')
|
||||
expect(formatUSD(1234)).to.equal('$12.34')
|
||||
})
|
||||
|
||||
it('should format thousand separators', function () {
|
||||
expect(formatUSD(100_000)).to.equal('$1,000.00')
|
||||
expect(formatUSD(9_876_543_210)).to.equal('$98,765,432.10')
|
||||
})
|
||||
|
||||
it('should format negative amounts', function () {
|
||||
expect(formatUSD(-1)).to.equal('-$0.01')
|
||||
expect(formatUSD(-1234)).to.equal('-$12.34')
|
||||
})
|
||||
})
|
||||
|
||||
describe('EUR', function () {
|
||||
const formatEUR = format('EUR')
|
||||
|
||||
it('should format basic amounts', function () {
|
||||
expect(formatEUR(0)).to.equal('€0.00')
|
||||
expect(formatEUR(1234)).to.equal('€12.34')
|
||||
})
|
||||
|
||||
it('should format thousand separators', function () {
|
||||
expect(formatEUR(100_000)).to.equal('€1,000.00')
|
||||
expect(formatEUR(9_876_543_210)).to.equal('€98,765,432.10')
|
||||
})
|
||||
|
||||
it('should format negative amounts', function () {
|
||||
expect(formatEUR(-1)).to.equal('-€0.01')
|
||||
expect(formatEUR(-1234)).to.equal('-€12.34')
|
||||
})
|
||||
})
|
||||
|
||||
describe('HUF', function () {
|
||||
const formatHUF = format('HUF')
|
||||
|
||||
it('should format basic amounts', function () {
|
||||
expect(formatHUF(0)).to.equal('Ft 0.00')
|
||||
expect(formatHUF(1234)).to.equal('Ft 12.34')
|
||||
})
|
||||
|
||||
it('should format thousand separators', function () {
|
||||
expect(formatHUF(100_000)).to.equal('Ft 1,000.00')
|
||||
expect(formatHUF(9_876_543_210)).to.equal('Ft 98,765,432.10')
|
||||
})
|
||||
|
||||
it('should format negative amounts', function () {
|
||||
expect(formatHUF(-1)).to.equal('-Ft 0.01')
|
||||
expect(formatHUF(-1234)).to.equal('-Ft 12.34')
|
||||
})
|
||||
})
|
||||
|
||||
describe('CLP', function () {
|
||||
const formatCLP = format('CLP')
|
||||
|
||||
it('should format basic amounts', function () {
|
||||
expect(formatCLP(0)).to.equal('$0')
|
||||
expect(formatCLP(1234)).to.equal('$1,234')
|
||||
})
|
||||
|
||||
it('should format thousand separators', function () {
|
||||
expect(formatCLP(100_000)).to.equal('$100,000')
|
||||
expect(formatCLP(9_876_543_210)).to.equal('$9,876,543,210')
|
||||
})
|
||||
|
||||
it('should format negative amounts', function () {
|
||||
expect(formatCLP(-1)).to.equal('-$1')
|
||||
expect(formatCLP(-1234)).to.equal('-$1,234')
|
||||
})
|
||||
})
|
||||
|
||||
describe('all currencies', function () {
|
||||
it('should format 100 "minimal atomic units"', function () {
|
||||
const amount = 100
|
||||
|
||||
// "no cents currencies"
|
||||
expect(format('CLP')(amount)).to.equal('$100')
|
||||
expect(format('JPY')(amount)).to.equal('¥100')
|
||||
expect(format('KRW')(amount)).to.equal('₩100')
|
||||
expect(format('VND')(amount)).to.equal('₫100')
|
||||
|
||||
// other currencies
|
||||
expect(format('AUD')(amount)).to.equal('$1.00')
|
||||
expect(format('BRL')(amount)).to.equal('R$1.00')
|
||||
expect(format('CAD')(amount)).to.equal('$1.00')
|
||||
expect(format('CHF')(amount)).to.equal('CHF 1.00')
|
||||
expect(format('CNY')(amount)).to.equal('¥1.00')
|
||||
expect(format('COP')(amount)).to.equal('$1.00')
|
||||
expect(format('DKK')(amount)).to.equal('kr 1.00')
|
||||
expect(format('EUR')(amount)).to.equal('€1.00')
|
||||
expect(format('GBP')(amount)).to.equal('£1.00')
|
||||
expect(format('HUF')(amount)).to.equal('Ft 1.00')
|
||||
expect(format('IDR')(amount)).to.equal('Rp 1.00')
|
||||
expect(format('INR')(amount)).to.equal('₹1.00')
|
||||
expect(format('MXN')(amount)).to.equal('$1.00')
|
||||
expect(format('MYR')(amount)).to.equal('RM 1.00')
|
||||
expect(format('NOK')(amount)).to.equal('kr 1.00')
|
||||
expect(format('NZD')(amount)).to.equal('$1.00')
|
||||
expect(format('PEN')(amount)).to.equal('PEN 1.00')
|
||||
expect(format('PHP')(amount)).to.equal('₱1.00')
|
||||
expect(format('SEK')(amount)).to.equal('kr 1.00')
|
||||
expect(format('SGD')(amount)).to.equal('$1.00')
|
||||
expect(format('THB')(amount)).to.equal('฿1.00')
|
||||
expect(format('USD')(amount)).to.equal('$1.00')
|
||||
})
|
||||
|
||||
it('should format 123_456_789.987_654 "minimal atomic units"', function () {
|
||||
const amount = 123_456_789.987_654
|
||||
|
||||
// "no cents currencies"
|
||||
expect(format('CLP')(amount)).to.equal('$123,456,790')
|
||||
expect(format('JPY')(amount)).to.equal('¥123,456,790')
|
||||
expect(format('KRW')(amount)).to.equal('₩123,456,790')
|
||||
expect(format('VND')(amount)).to.equal('₫123,456,790')
|
||||
|
||||
// other currencies
|
||||
expect(format('AUD')(amount)).to.equal('$1,234,567.90')
|
||||
expect(format('BRL')(amount)).to.equal('R$1,234,567.90')
|
||||
expect(format('CAD')(amount)).to.equal('$1,234,567.90')
|
||||
expect(format('CHF')(amount)).to.equal('CHF 1,234,567.90')
|
||||
expect(format('CNY')(amount)).to.equal('¥1,234,567.90')
|
||||
expect(format('COP')(amount)).to.equal('$1,234,567.90')
|
||||
expect(format('DKK')(amount)).to.equal('kr 1,234,567.90')
|
||||
expect(format('EUR')(amount)).to.equal('€1,234,567.90')
|
||||
expect(format('GBP')(amount)).to.equal('£1,234,567.90')
|
||||
expect(format('HUF')(amount)).to.equal('Ft 1,234,567.90')
|
||||
expect(format('IDR')(amount)).to.equal('Rp 1,234,567.90')
|
||||
expect(format('INR')(amount)).to.equal('₹1,234,567.90')
|
||||
expect(format('MXN')(amount)).to.equal('$1,234,567.90')
|
||||
expect(format('MYR')(amount)).to.equal('RM 1,234,567.90')
|
||||
expect(format('NOK')(amount)).to.equal('kr 1,234,567.90')
|
||||
expect(format('NZD')(amount)).to.equal('$1,234,567.90')
|
||||
expect(format('PEN')(amount)).to.equal('PEN 1,234,567.90')
|
||||
expect(format('PHP')(amount)).to.equal('₱1,234,567.90')
|
||||
expect(format('SEK')(amount)).to.equal('kr 1,234,567.90')
|
||||
expect(format('SGD')(amount)).to.equal('$1,234,567.90')
|
||||
expect(format('THB')(amount)).to.equal('฿1,234,567.90')
|
||||
expect(format('USD')(amount)).to.equal('$1,234,567.90')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('fr', function () {
|
||||
const format = currency => priceInCents =>
|
||||
SubscriptionFormatters.formatPriceLocalized(priceInCents, currency, 'fr')
|
||||
|
||||
describe('USD', function () {
|
||||
const formatUSD = format('USD')
|
||||
|
||||
it('should format basic amounts', function () {
|
||||
expect(formatUSD(0)).to.equal('0,00 $')
|
||||
expect(formatUSD(1234)).to.equal('12,34 $')
|
||||
})
|
||||
|
||||
it('should format thousand separators', function () {
|
||||
expect(formatUSD(100_000)).to.equal('1 000,00 $')
|
||||
expect(formatUSD(9_876_543_210)).to.equal('98 765 432,10 $')
|
||||
})
|
||||
|
||||
it('should format negative amounts', function () {
|
||||
expect(formatUSD(-1)).to.equal('-0,01 $')
|
||||
expect(formatUSD(-1234)).to.equal('-12,34 $')
|
||||
})
|
||||
})
|
||||
|
||||
describe('EUR', function () {
|
||||
const formatEUR = format('EUR')
|
||||
|
||||
it('should format basic amounts', function () {
|
||||
expect(formatEUR(0)).to.equal('0,00 €')
|
||||
expect(formatEUR(1234)).to.equal('12,34 €')
|
||||
})
|
||||
|
||||
it('should format thousand separators', function () {
|
||||
expect(formatEUR(100_000)).to.equal('1 000,00 €')
|
||||
expect(formatEUR(9_876_543_210)).to.equal('98 765 432,10 €')
|
||||
})
|
||||
|
||||
it('should format negative amounts', function () {
|
||||
expect(formatEUR(-1)).to.equal('-0,01 €')
|
||||
expect(formatEUR(-1234)).to.equal('-12,34 €')
|
||||
})
|
||||
})
|
||||
|
||||
describe('HUF', function () {
|
||||
const formatHUF = format('HUF')
|
||||
|
||||
it('should format basic amounts', function () {
|
||||
expect(formatHUF(0)).to.equal('0,00 Ft')
|
||||
expect(formatHUF(1234)).to.equal('12,34 Ft')
|
||||
})
|
||||
|
||||
it('should format thousand separators', function () {
|
||||
expect(formatHUF(100_000)).to.equal('1 000,00 Ft')
|
||||
expect(formatHUF(9_876_543_210)).to.equal('98 765 432,10 Ft')
|
||||
})
|
||||
|
||||
it('should format negative amounts', function () {
|
||||
expect(formatHUF(-1)).to.equal('-0,01 Ft')
|
||||
expect(formatHUF(-1234)).to.equal('-12,34 Ft')
|
||||
})
|
||||
})
|
||||
|
||||
describe('CLP', function () {
|
||||
const formatCLP = format('CLP')
|
||||
|
||||
it('should format basic amounts', function () {
|
||||
expect(formatCLP(0)).to.equal('0 $')
|
||||
expect(formatCLP(1234)).to.equal('1 234 $')
|
||||
})
|
||||
|
||||
it('should format thousand separators', function () {
|
||||
expect(formatCLP(100_000)).to.equal('100 000 $')
|
||||
expect(formatCLP(9_876_543_210)).to.equal('9 876 543 210 $')
|
||||
})
|
||||
|
||||
it('should format negative amounts', function () {
|
||||
expect(formatCLP(-1)).to.equal('-1 $')
|
||||
expect(formatCLP(-1234)).to.equal('-1 234 $')
|
||||
})
|
||||
})
|
||||
|
||||
describe('all currencies', function () {
|
||||
it('should format 100 "minimal atomic units"', function () {
|
||||
const amount = 100
|
||||
|
||||
// "no cents currencies"
|
||||
expect(format('CLP')(amount)).to.equal('100 $')
|
||||
expect(format('JPY')(amount)).to.equal('100 ¥')
|
||||
expect(format('KRW')(amount)).to.equal('100 ₩')
|
||||
expect(format('VND')(amount)).to.equal('100 ₫')
|
||||
|
||||
// other currencies
|
||||
expect(format('AUD')(amount)).to.equal('1,00 $')
|
||||
expect(format('BRL')(amount)).to.equal('1,00 R$')
|
||||
expect(format('CAD')(amount)).to.equal('1,00 $')
|
||||
expect(format('CHF')(amount)).to.equal('1,00 CHF')
|
||||
expect(format('CNY')(amount)).to.equal('1,00 ¥')
|
||||
expect(format('COP')(amount)).to.equal('1,00 $')
|
||||
|
||||
expect(format('EUR')(amount)).to.equal('1,00 €')
|
||||
expect(format('GBP')(amount)).to.equal('1,00 £')
|
||||
expect(format('USD')(amount)).to.equal('1,00 $')
|
||||
})
|
||||
|
||||
it('should format 123_456_789.987_654 "minimal atomic units"', function () {
|
||||
const amount = 123_456_789.987_654
|
||||
|
||||
// "no cents currencies"
|
||||
expect(format('CLP')(amount)).to.equal('123 456 790 $')
|
||||
expect(format('JPY')(amount)).to.equal('123 456 790 ¥')
|
||||
expect(format('KRW')(amount)).to.equal('123 456 790 ₩')
|
||||
expect(format('VND')(amount)).to.equal('123 456 790 ₫')
|
||||
|
||||
// other currencies
|
||||
expect(format('AUD')(amount)).to.equal('1 234 567,90 $')
|
||||
expect(format('BRL')(amount)).to.equal('1 234 567,90 R$')
|
||||
expect(format('CAD')(amount)).to.equal('1 234 567,90 $')
|
||||
expect(format('CHF')(amount)).to.equal('1 234 567,90 CHF')
|
||||
expect(format('CNY')(amount)).to.equal('1 234 567,90 ¥')
|
||||
expect(format('COP')(amount)).to.equal('1 234 567,90 $')
|
||||
|
||||
expect(format('EUR')(amount)).to.equal('1 234 567,90 €')
|
||||
expect(format('GBP')(amount)).to.equal('1 234 567,90 £')
|
||||
expect(format('USD')(amount)).to.equal('1 234 567,90 $')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -1,5 +1,6 @@
|
||||
const SandboxedModule = require('sandboxed-module')
|
||||
const { expect } = require('chai')
|
||||
const { formatCurrencyLocalized } = require('../../../../app/src/util/currency')
|
||||
const modulePath =
|
||||
'../../../../app/src/Features/Subscription/SubscriptionHelper'
|
||||
|
||||
@@ -151,16 +152,20 @@ describe('SubscriptionHelper', function () {
|
||||
describe('CHF currency', function () {
|
||||
it('should return the correct localized price for every plan', function () {
|
||||
const localizedPrice =
|
||||
this.SubscriptionHelper.generateInitialLocalizedGroupPrice('CHF')
|
||||
this.SubscriptionHelper.generateInitialLocalizedGroupPrice(
|
||||
'CHF',
|
||||
'fr',
|
||||
formatCurrencyLocalized
|
||||
)
|
||||
|
||||
expect(localizedPrice).to.deep.equal({
|
||||
price: {
|
||||
collaborator: 'Fr 10',
|
||||
professional: 'Fr 100',
|
||||
collaborator: '10 CHF',
|
||||
professional: '100 CHF',
|
||||
},
|
||||
pricePerUser: {
|
||||
collaborator: 'Fr 5',
|
||||
professional: 'Fr 50',
|
||||
collaborator: '5 CHF',
|
||||
professional: '50 CHF',
|
||||
},
|
||||
})
|
||||
})
|
||||
@@ -169,16 +174,20 @@ describe('SubscriptionHelper', function () {
|
||||
describe('DKK currency', function () {
|
||||
it('should return the correct localized price for every plan', function () {
|
||||
const localizedPrice =
|
||||
this.SubscriptionHelper.generateInitialLocalizedGroupPrice('DKK')
|
||||
this.SubscriptionHelper.generateInitialLocalizedGroupPrice(
|
||||
'DKK',
|
||||
'da',
|
||||
formatCurrencyLocalized
|
||||
)
|
||||
|
||||
expect(localizedPrice).to.deep.equal({
|
||||
price: {
|
||||
collaborator: '20 kr',
|
||||
professional: '200 kr',
|
||||
collaborator: '20 kr.',
|
||||
professional: '200 kr.',
|
||||
},
|
||||
pricePerUser: {
|
||||
collaborator: '10 kr',
|
||||
professional: '100 kr',
|
||||
collaborator: '10 kr.',
|
||||
professional: '100 kr.',
|
||||
},
|
||||
})
|
||||
})
|
||||
@@ -187,16 +196,20 @@ describe('SubscriptionHelper', function () {
|
||||
describe('SEK currency', function () {
|
||||
it('should return the correct localized price for every plan', function () {
|
||||
const localizedPrice =
|
||||
this.SubscriptionHelper.generateInitialLocalizedGroupPrice('SEK')
|
||||
this.SubscriptionHelper.generateInitialLocalizedGroupPrice(
|
||||
'SEK',
|
||||
'sv',
|
||||
formatCurrencyLocalized
|
||||
)
|
||||
|
||||
expect(localizedPrice).to.deep.equal({
|
||||
price: {
|
||||
collaborator: '30 kr',
|
||||
professional: '300 kr',
|
||||
collaborator: '30 kr',
|
||||
professional: '300 kr',
|
||||
},
|
||||
pricePerUser: {
|
||||
collaborator: '15 kr',
|
||||
professional: '150 kr',
|
||||
collaborator: '15 kr',
|
||||
professional: '150 kr',
|
||||
},
|
||||
})
|
||||
})
|
||||
@@ -205,16 +218,22 @@ describe('SubscriptionHelper', function () {
|
||||
describe('NOK currency', function () {
|
||||
it('should return the correct localized price for every plan', function () {
|
||||
const localizedPrice =
|
||||
this.SubscriptionHelper.generateInitialLocalizedGroupPrice('NOK')
|
||||
this.SubscriptionHelper.generateInitialLocalizedGroupPrice(
|
||||
'NOK',
|
||||
// there seem to be possible inconsistencies with the CI
|
||||
// maybe it depends on what languages are installed on the server?
|
||||
'en',
|
||||
formatCurrencyLocalized
|
||||
)
|
||||
|
||||
expect(localizedPrice).to.deep.equal({
|
||||
price: {
|
||||
collaborator: '40 kr',
|
||||
professional: '400 kr',
|
||||
collaborator: 'kr 40',
|
||||
professional: 'kr 400',
|
||||
},
|
||||
pricePerUser: {
|
||||
collaborator: '20 kr',
|
||||
professional: '200 kr',
|
||||
collaborator: 'kr 20',
|
||||
professional: 'kr 200',
|
||||
},
|
||||
})
|
||||
})
|
||||
@@ -223,7 +242,11 @@ describe('SubscriptionHelper', function () {
|
||||
describe('other supported currencies', function () {
|
||||
it('should return the correct localized price for every plan', function () {
|
||||
const localizedPrice =
|
||||
this.SubscriptionHelper.generateInitialLocalizedGroupPrice('USD')
|
||||
this.SubscriptionHelper.generateInitialLocalizedGroupPrice(
|
||||
'USD',
|
||||
'en',
|
||||
formatCurrencyLocalized
|
||||
)
|
||||
|
||||
expect(localizedPrice).to.deep.equal({
|
||||
price: {
|
||||
|
||||
Reference in New Issue
Block a user