From 948db1880e5ad0b05e43cbaa7f100bbff37d5f76 Mon Sep 17 00:00:00 2001 From: Matthew Russell Date: Tue, 21 Feb 2023 20:49:23 -0800 Subject: [PATCH] feat: split validation for amount so we can render conditionally based on type --- .../trading-e2e/src/integration/deposit.cy.ts | 26 +++++--- libs/deposits/src/lib/deposit-form.tsx | 64 +++++++++++++------ 2 files changed, 63 insertions(+), 27 deletions(-) diff --git a/apps/trading-e2e/src/integration/deposit.cy.ts b/apps/trading-e2e/src/integration/deposit.cy.ts index 44f472e2e..48b3ebc74 100644 --- a/apps/trading-e2e/src/integration/deposit.cy.ts +++ b/apps/trading-e2e/src/integration/deposit.cy.ts @@ -11,7 +11,7 @@ const formFieldError = 'input-error-text'; const ASSET_EURO = 1; describe('deposit form validation', { tags: '@smoke' }, () => { - before(() => { + function openDepositForm() { cy.mockWeb3Provider(); cy.mockSubscription(); cy.mockTradingPage(); @@ -22,10 +22,14 @@ describe('deposit form validation', { tags: '@smoke' }, () => { cy.getByTestId('deposit-button').click(); cy.wait('@Assets'); connectEthereumWallet('MetaMask'); - cy.getByTestId('deposit-submit').click(); + } + + before(() => { + openDepositForm(); }); it('handles empty fields', () => { + cy.getByTestId('deposit-submit').click(); cy.getByTestId(formFieldError).should('contain.text', 'Required'); cy.getByTestId(formFieldError).should('have.length', 2); }); @@ -48,7 +52,7 @@ describe('deposit form validation', { tags: '@smoke' }, () => { it('invalid amount', () => { mockWeb3DepositCalls({ allowance: '1000', - depositLifetimeLimit: '600', + depositLifetimeLimit: '1000', balance: '800', deposited: '0', dps: 5, @@ -67,7 +71,7 @@ describe('deposit form validation', { tags: '@smoke' }, () => { it('insufficient funds', () => { mockWeb3DepositCalls({ allowance: '1000', - depositLifetimeLimit: '600', + depositLifetimeLimit: '1000', balance: '800', deposited: '0', dps: 5, @@ -80,6 +84,8 @@ describe('deposit form validation', { tags: '@smoke' }, () => { }); it('above deposit limit', () => { + // reload form with new web3 mocks + openDepositForm(); mockWeb3DepositCalls({ allowance: '1000', depositLifetimeLimit: '600', @@ -87,11 +93,13 @@ describe('deposit form validation', { tags: '@smoke' }, () => { deposited: '0', dps: 5, }); - cy.get(amountField) - .clear() - .type('650') - .next(`[data-testid="${formFieldError}"]`) - .should('have.text', 'Amount is above deposit limit'); + selectAsset(ASSET_EURO); + cy.get(amountField).clear().type('650'); + cy.getByTestId('deposit-submit').click(); + cy.get(`[data-testid="${formFieldError}"]`).should( + 'have.text', + 'Amount is above deposit limit' + ); }); }); diff --git a/libs/deposits/src/lib/deposit-form.tsx b/libs/deposits/src/lib/deposit-form.tsx index d78500a23..2df087e12 100644 --- a/libs/deposits/src/lib/deposit-form.tsx +++ b/libs/deposits/src/lib/deposit-form.tsx @@ -25,7 +25,8 @@ import { useWeb3React } from '@web3-react/core'; import BigNumber from 'bignumber.js'; import type { ButtonHTMLAttributes } from 'react'; import { useMemo } from 'react'; -import { Controller, useForm, useWatch } from 'react-hook-form'; +import type { FieldError } from 'react-hook-form'; +import { Controller, useForm } from 'react-hook-form'; import { DepositLimits } from './deposit-limits'; import { useAssetDetailsDialogStore } from '@vegaprotocol/assets'; import { @@ -106,8 +107,6 @@ export const DepositForm = ({ } }; - const amount = useWatch({ name: 'amount', control }); - const maxAmount = useMemo(() => { const maxApproved = allowance ? allowance : new BigNumber(0); const maxAvailable = balance ? balance : new BigNumber(0); @@ -138,13 +137,7 @@ export const DepositForm = ({ return minViableAmount; }, [selectedAsset]); - const approved = - allowance && - allowance.isGreaterThan(0) && - new BigNumber(amount || 0).isLessThan(allowance) - ? true - : false; - + const approved = allowance && allowance.isGreaterThan(0) ? true : false; const formState = getFormState(selectedAsset, isActive, approved); return ( @@ -304,24 +297,35 @@ export const DepositForm = ({ validate: { required, minSafe: (value) => minSafe(new BigNumber(min))(value), - maxSafe: (v) => { + approved: (v) => { + const value = new BigNumber(v); + if (value.isGreaterThan(maxAmount.approved)) { + return t('Amount is above approved amount'); + } + return true; + }, + limit: (v) => { + const value = new BigNumber(v); + if (value.isGreaterThan(maxAmount.limit)) { + return t('Amount is above deposit limit'); + } + return true; + }, + balance: (v) => { const value = new BigNumber(v); if (value.isGreaterThan(maxAmount.available)) { return t('Insufficient amount in Ethereum wallet'); - } else if (value.isGreaterThan(maxAmount.limit)) { - return t('Amount is above deposit limit'); - } else if (value.isGreaterThan(maxAmount.approved)) { - return t('Amount is above approved amount'); } + return true; + }, + maxSafe: (v) => { return maxSafe(maxAmount.amount)(v); }, }, })} /> {errors.amount?.message && ( - - {errors.amount.message} - + )} {selectedAsset && balance && ( void; +}) => { + if (error.type === 'approved') { + return ( + + {error.message}. + + + ); + } + return ( + + {error.message} + + ); +}; + interface FormButtonProps { selectedAsset?: Asset; formState: ReturnType;