Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#2 - Fix user can submit 10-digit amount and gives an unexpected error #42815

Merged
Merged
2 changes: 1 addition & 1 deletion src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1580,7 +1580,7 @@ const CONST = {
APPROVE: 'approve',
TRACK: 'track',
},
AMOUNT_MAX_LENGTH: 10,
AMOUNT_MAX_LENGTH: 8,
RECEIPT_STATE: {
SCANREADY: 'SCANREADY',
OPEN: 'OPEN',
Expand Down
21 changes: 3 additions & 18 deletions src/libs/MoneyRequestUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,31 +37,16 @@ function addLeadingZero(amount: string): string {
return amount.startsWith('.') ? `0${amount}` : amount;
}

/**
* Calculate the length of the amount with leading zeroes
*/
function calculateAmountLength(amount: string, decimals: number): number {
const leadingZeroes = amount.match(/^0+/);
const leadingZeroesLength = leadingZeroes?.[0]?.length ?? 0;
const absAmount = parseFloat((Number(stripCommaFromAmount(amount)) * 10 ** decimals).toFixed(2)).toString();

if (/\D/.test(absAmount)) {
return CONST.IOU.AMOUNT_MAX_LENGTH + 1;
}

return leadingZeroesLength + (absAmount === '0' ? 2 : absAmount.length);
}

/**
* Check if amount is a decimal up to 3 digits
*/
function validateAmount(amount: string, decimals: number, amountMaxLength: number = CONST.IOU.AMOUNT_MAX_LENGTH): boolean {
const regexString =
decimals === 0
? `^\\d+(,\\d*)*$` // Don't allow decimal point if decimals === 0
: `^\\d+(,\\d*)*(\\.\\d{0,${decimals}})?$`; // Allow the decimal point and the desired number of digits after the point
? `^\\d{1,${amountMaxLength}}$` // Don't allow decimal point if decimals === 0
: `^\\d{1,${amountMaxLength}}(\\.\\d{0,${decimals}})?$`; // Allow the decimal point and the desired number of digits after the point
const decimalNumberRegex = new RegExp(regexString, 'i');
return amount === '' || (decimalNumberRegex.test(amount) && calculateAmountLength(amount, decimals) <= amountMaxLength);
return amount === '' || decimalNumberRegex.test(amount);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/pages/workspace/taxes/ValuePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ function ValuePage({
// The default currency uses 2 decimal places, so we substract it
extraDecimals={CONST.MAX_TAX_RATE_DECIMAL_PLACES - 2}
// We increase the amount max length to support the extra decimals.
amountMaxLength={CONST.MAX_TAX_RATE_DECIMAL_PLACES + CONST.MAX_TAX_RATE_INTEGER_PLACES}
amountMaxLength={CONST.MAX_TAX_RATE_INTEGER_PLACES}
extraSymbol={<Text style={styles.iouAmountText}>%</Text>}
ref={inputCallbackRef}
/>
Expand Down
2 changes: 1 addition & 1 deletion src/pages/workspace/taxes/WorkspaceCreateTaxPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ function WorkspaceCreateTaxPage({
// The default currency uses 2 decimal places, so we substract it
extraDecimals={CONST.MAX_TAX_RATE_DECIMAL_PLACES - 2}
// We increase the amount max length to support the extra decimals.
amountMaxLength={CONST.MAX_TAX_RATE_DECIMAL_PLACES + CONST.MAX_TAX_RATE_INTEGER_PLACES}
amountMaxLength={CONST.MAX_TAX_RATE_INTEGER_PLACES}
extraSymbol={<Text style={styles.iouAmountText}>%</Text>}
/>
</View>
Expand Down
22 changes: 22 additions & 0 deletions tests/unit/MoneyRequestUtilsTest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import * as MoneyRequestUtils from '@libs/MoneyRequestUtils';

describe('ReportActionsUtils', () => {
describe('validateAmount', () => {
it('should pass the validation when amount is within the max digit and decimal', () => {
expect(MoneyRequestUtils.validateAmount('12345678', 2, 8)).toBe(true);
expect(MoneyRequestUtils.validateAmount('12345678', 0, 8)).toBe(true);
expect(MoneyRequestUtils.validateAmount('12345678.12', 2, 8)).toBe(true);
expect(MoneyRequestUtils.validateAmount('1234567.1', 2, 8)).toBe(true);
expect(MoneyRequestUtils.validateAmount('12345678.123', 3, 8)).toBe(true);
expect(MoneyRequestUtils.validateAmount('1234.1234', 4, 4)).toBe(true);
});

it("shouldn't pass the validation when amount is bigger than the max digit and decimal", () => {
expect(MoneyRequestUtils.validateAmount('12345678.123', 2, 8)).toBe(false);
expect(MoneyRequestUtils.validateAmount('12345678.1', 0, 8)).toBe(false);
expect(MoneyRequestUtils.validateAmount('123456789.12', 2, 8)).toBe(false);
expect(MoneyRequestUtils.validateAmount('123456789.1234', 3, 8)).toBe(false);
expect(MoneyRequestUtils.validateAmount('1234.12345', 4, 4)).toBe(false);
});
});
});
Loading