166 lines
4.7 KiB
TypeScript
166 lines
4.7 KiB
TypeScript
// Copyright 2025 Signal Messenger, LLC
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
import { assert } from 'chai';
|
|
|
|
import {
|
|
brandHumanDonationAmount,
|
|
brandStripeDonationAmount,
|
|
parseCurrencyString,
|
|
toHumanDonationAmount,
|
|
toHumanCurrencyString,
|
|
toStripeDonationAmount,
|
|
} from '../../util/currency';
|
|
|
|
describe('parseCurrencyString', () => {
|
|
function testFn(
|
|
{ currency, value }: { currency: string; value: string },
|
|
expectedOutput: number | undefined
|
|
): void {
|
|
const brandedOutput =
|
|
expectedOutput == null
|
|
? undefined
|
|
: brandHumanDonationAmount(expectedOutput);
|
|
assert.equal(parseCurrencyString({ currency, value }), brandedOutput);
|
|
}
|
|
|
|
it('handles USD', () => {
|
|
testFn({ currency: 'usd', value: '10' }, 10);
|
|
testFn({ currency: 'usd', value: '10.0' }, 10);
|
|
testFn({ currency: 'usd', value: '10.00' }, 10);
|
|
testFn({ currency: 'usd', value: '10.000' }, 10);
|
|
testFn({ currency: 'usd', value: '10.50' }, 10.5);
|
|
testFn({ currency: 'usd', value: '10.6969' }, 10.69);
|
|
testFn({ currency: 'usd', value: '.69' }, 0.69);
|
|
testFn({ currency: 'usd', value: '0.69' }, 0.69);
|
|
});
|
|
|
|
it('handles JPY', () => {
|
|
testFn({ currency: 'jpy', value: '1000' }, 1000);
|
|
testFn({ currency: 'jpy', value: '1000.0' }, 1000);
|
|
testFn({ currency: 'jpy', value: '1000.5' }, 1000);
|
|
testFn({ currency: 'jpy', value: '1000.5555' }, 1000);
|
|
});
|
|
|
|
it('handles malformed input', () => {
|
|
testFn({ currency: 'usd', value: '' }, undefined);
|
|
testFn({ currency: 'usd', value: '??' }, undefined);
|
|
testFn({ currency: 'usd', value: '-50' }, undefined);
|
|
testFn({ currency: 'usd', value: 'abc' }, undefined);
|
|
});
|
|
});
|
|
|
|
describe('toHumanDonationAmount', () => {
|
|
function testFn(
|
|
{ amount, currency }: { amount: number; currency: string },
|
|
expectedOutput: number
|
|
): void {
|
|
const stripeAmount = brandStripeDonationAmount(amount);
|
|
const brandedOutput = brandHumanDonationAmount(expectedOutput);
|
|
assert.equal(
|
|
toHumanDonationAmount({ amount: stripeAmount, currency }),
|
|
brandedOutput
|
|
);
|
|
}
|
|
|
|
it('handles USD', () => {
|
|
testFn({ amount: 1000, currency: 'usd' }, 10);
|
|
testFn({ amount: 1000, currency: 'USD' }, 10);
|
|
});
|
|
|
|
it('handles JPY', () => {
|
|
testFn({ amount: 1000, currency: 'jpy' }, 1000);
|
|
testFn({ amount: 1000, currency: 'JPY' }, 1000);
|
|
});
|
|
|
|
it('handles KRW', () => {
|
|
testFn({ amount: 10000, currency: 'krw' }, 10000);
|
|
testFn({ amount: 10000, currency: 'KRW' }, 10000);
|
|
});
|
|
});
|
|
|
|
describe('toStripeDonationAmount', () => {
|
|
function testFn(
|
|
{ amount, currency }: { amount: number; currency: string },
|
|
expectedOutput: number
|
|
): void {
|
|
const humanAmount = brandHumanDonationAmount(amount);
|
|
const brandedOutput = brandStripeDonationAmount(expectedOutput);
|
|
assert.equal(
|
|
toStripeDonationAmount({ amount: humanAmount, currency }),
|
|
brandedOutput
|
|
);
|
|
}
|
|
|
|
it('handles USD', () => {
|
|
testFn({ amount: 10, currency: 'usd' }, 1000);
|
|
testFn({ amount: 10, currency: 'USD' }, 1000);
|
|
});
|
|
|
|
it('handles JPY', () => {
|
|
testFn({ amount: 1000, currency: 'jpy' }, 1000);
|
|
testFn({ amount: 1000, currency: 'JPY' }, 1000);
|
|
});
|
|
|
|
it('handles KRW', () => {
|
|
testFn({ amount: 10000, currency: 'krw' }, 10000);
|
|
testFn({ amount: 10000, currency: 'KRW' }, 10000);
|
|
});
|
|
});
|
|
|
|
describe('toHumanCurrencyString', () => {
|
|
function testFn(
|
|
{
|
|
amount,
|
|
currency,
|
|
showInsignificantFractionDigits = false,
|
|
}: {
|
|
amount: number;
|
|
currency: string;
|
|
showInsignificantFractionDigits?: boolean;
|
|
},
|
|
expectedOutput: string | undefined
|
|
): void {
|
|
const humanAmount = brandHumanDonationAmount(amount);
|
|
assert.equal(
|
|
toHumanCurrencyString({
|
|
amount: humanAmount,
|
|
currency,
|
|
showInsignificantFractionDigits,
|
|
}),
|
|
expectedOutput
|
|
);
|
|
}
|
|
|
|
it('handles USD', () => {
|
|
testFn(
|
|
{ amount: 10, currency: 'usd', showInsignificantFractionDigits: true },
|
|
'$10.00'
|
|
);
|
|
testFn({ amount: 10, currency: 'USD' }, '$10');
|
|
testFn({ amount: 10.5, currency: 'USD' }, '$10.50');
|
|
testFn({ amount: 10.5, currency: 'USD' }, '$10.50');
|
|
testFn({ amount: 10.69, currency: 'USD' }, '$10.69');
|
|
});
|
|
|
|
it('handles EUR', () => {
|
|
testFn(
|
|
{ amount: 10, currency: 'eur', showInsignificantFractionDigits: true },
|
|
'€10.00'
|
|
);
|
|
testFn({ amount: 10, currency: 'eur' }, '€10');
|
|
});
|
|
|
|
it('handles JPY', () => {
|
|
testFn({ amount: 1000, currency: 'jpy' }, '¥1,000');
|
|
testFn(
|
|
{ amount: 1000, currency: 'JPY', showInsignificantFractionDigits: true },
|
|
'¥1,000'
|
|
);
|
|
});
|
|
|
|
it('returns empty string for bad inputs', () => {
|
|
testFn({ amount: 10, currency: '420' }, '');
|
|
testFn({ amount: 10, currency: '' }, '');
|
|
});
|
|
});
|