feat(deposits): if wrong network dont show the form and prompt switching to the correct network (#5571)
Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
This commit is contained in:
parent
a2bffa1dfd
commit
a8e6963521
@ -1,10 +1,4 @@
|
|||||||
import {
|
import { waitFor, fireEvent, render, screen } from '@testing-library/react';
|
||||||
waitFor,
|
|
||||||
fireEvent,
|
|
||||||
render,
|
|
||||||
screen,
|
|
||||||
act,
|
|
||||||
} from '@testing-library/react';
|
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
import BigNumber from 'bignumber.js';
|
import BigNumber from 'bignumber.js';
|
||||||
import type { DepositFormProps } from './deposit-form';
|
import type { DepositFormProps } from './deposit-form';
|
||||||
@ -89,7 +83,10 @@ describe('Deposit form', () => {
|
|||||||
render(<DepositForm {...props} />);
|
render(<DepositForm {...props} />);
|
||||||
|
|
||||||
// Assert default values (including) from/to provided by useVegaWallet and useWeb3React
|
// Assert default values (including) from/to provided by useVegaWallet and useWeb3React
|
||||||
expect(screen.getByText('From (Ethereum address)')).toBeInTheDocument();
|
// Wait for first value to show as form is rendered conditionally based on chainId
|
||||||
|
expect(
|
||||||
|
await screen.findByText('From (Ethereum address)')
|
||||||
|
).toBeInTheDocument();
|
||||||
expect(screen.getByTestId('ethereum-address')).toHaveTextContent(
|
expect(screen.getByTestId('ethereum-address')).toHaveTextContent(
|
||||||
truncateMiddle(MOCK_ETH_ADDRESS)
|
truncateMiddle(MOCK_ETH_ADDRESS)
|
||||||
);
|
);
|
||||||
@ -319,34 +316,40 @@ describe('Deposit form', () => {
|
|||||||
|
|
||||||
it('shows "View asset details" button when an asset is selected', async () => {
|
it('shows "View asset details" button when an asset is selected', async () => {
|
||||||
render(<DepositForm {...props} selectedAsset={asset} />);
|
render(<DepositForm {...props} selectedAsset={asset} />);
|
||||||
expect(await screen.getByTestId('view-asset-details')).toBeInTheDocument();
|
expect(await screen.findByTestId('view-asset-details')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not shows "View asset details" button when no asset is selected', async () => {
|
it('does not shows "View asset details" button when no asset is selected', async () => {
|
||||||
render(<DepositForm {...props} />);
|
render(<DepositForm {...props} />);
|
||||||
expect(await screen.queryAllByTestId('view-asset-details')).toHaveLength(0);
|
await waitFor(() => {
|
||||||
|
expect(screen.queryAllByTestId('view-asset-details')).toHaveLength(0);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders a connect button if Ethereum wallet is not connected', () => {
|
it('renders a connect button if Ethereum wallet is not connected', async () => {
|
||||||
(useWeb3React as jest.Mock).mockReturnValue({
|
(useWeb3React as jest.Mock).mockReturnValue({
|
||||||
isActive: false,
|
isActive: false,
|
||||||
account: '',
|
account: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
render(<DepositForm {...props} />);
|
render(<DepositForm {...props} />);
|
||||||
|
|
||||||
expect(screen.getByRole('button', { name: 'Connect' })).toBeInTheDocument();
|
expect(
|
||||||
|
await screen.findByRole('button', { name: 'Connect' })
|
||||||
|
).toBeInTheDocument();
|
||||||
expect(
|
expect(
|
||||||
screen.queryByLabelText('From (Ethereum address)')
|
screen.queryByLabelText('From (Ethereum address)')
|
||||||
).not.toBeInTheDocument();
|
).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders a disabled input if Ethereum wallet is connected', () => {
|
it('renders a disabled input if Ethereum wallet is connected', async () => {
|
||||||
(useWeb3React as jest.Mock).mockReturnValue({
|
(useWeb3React as jest.Mock).mockReturnValue({
|
||||||
isActive: true,
|
isActive: true,
|
||||||
account: MOCK_ETH_ADDRESS,
|
account: MOCK_ETH_ADDRESS,
|
||||||
});
|
});
|
||||||
render(<DepositForm {...props} />);
|
render(<DepositForm {...props} />);
|
||||||
|
|
||||||
|
expect(await screen.findByTestId('deposit-form')).toBeInTheDocument();
|
||||||
expect(
|
expect(
|
||||||
screen.queryByRole('button', { name: 'Connect' })
|
screen.queryByRole('button', { name: 'Connect' })
|
||||||
).not.toBeInTheDocument();
|
).not.toBeInTheDocument();
|
||||||
@ -356,53 +359,56 @@ describe('Deposit form', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('prevents submission if you are on the wrong chain', () => {
|
it('prevents submission if you are on the wrong chain', async () => {
|
||||||
|
// Make mocks return a chain id mismatch
|
||||||
(useWeb3React as jest.Mock).mockReturnValue({
|
(useWeb3React as jest.Mock).mockReturnValue({
|
||||||
isActive: true,
|
isActive: true,
|
||||||
account: MOCK_ETH_ADDRESS,
|
account: MOCK_ETH_ADDRESS,
|
||||||
chainId: 1,
|
chainId: 1,
|
||||||
});
|
});
|
||||||
(useWeb3ConnectStore as unknown as jest.Mock).mockImplementation(
|
(useWeb3ConnectStore as unknown as jest.Mock).mockImplementationOnce(
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
(selector: (result: ReturnType<typeof useWeb3ConnectStore>) => any) => {
|
(selector: (result: ReturnType<typeof useWeb3ConnectStore>) => any) => {
|
||||||
return selector({
|
return selector({
|
||||||
desiredChainId: 11155111,
|
desiredChainId: 11155111,
|
||||||
open: jest.fn(),
|
open: jest.fn(),
|
||||||
foo: 'asdf',
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
render(<DepositForm {...props} />);
|
render(<DepositForm {...props} />);
|
||||||
expect(screen.getByTestId('chain-error')).toHaveTextContent(
|
|
||||||
|
expect(await screen.findByTestId('chain-error')).toHaveTextContent(
|
||||||
/this app only works on/i
|
/this app only works on/i
|
||||||
);
|
);
|
||||||
|
|
||||||
|
expect(screen.queryByTestId('deposit-form')).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Remaining deposit allowance tooltip should be rendered', async () => {
|
it('Remaining deposit allowance tooltip should be rendered', async () => {
|
||||||
render(<DepositForm {...props} selectedAsset={asset} />);
|
render(<DepositForm {...props} selectedAsset={asset} />);
|
||||||
await act(async () => {
|
|
||||||
|
expect(await screen.findByTestId('deposit-form')).toBeInTheDocument();
|
||||||
|
|
||||||
await userEvent.hover(screen.getByText('Remaining deposit allowance'));
|
await userEvent.hover(screen.getByText('Remaining deposit allowance'));
|
||||||
});
|
|
||||||
await waitFor(async () => {
|
expect(
|
||||||
await expect(
|
await screen.findByRole('tooltip', {
|
||||||
screen.getByRole('tooltip', {
|
|
||||||
name: /VEGA has a lifetime deposit limit of 20 asset-symbol per address/,
|
name: /VEGA has a lifetime deposit limit of 20 asset-symbol per address/,
|
||||||
})
|
})
|
||||||
).toBeInTheDocument();
|
).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
it('Ethereum deposit cap tooltip should be rendered', async () => {
|
it('Ethereum deposit cap tooltip should be rendered', async () => {
|
||||||
render(<DepositForm {...props} selectedAsset={asset} />);
|
render(<DepositForm {...props} selectedAsset={asset} />);
|
||||||
await act(async () => {
|
|
||||||
|
expect(await screen.findByTestId('deposit-form')).toBeInTheDocument();
|
||||||
|
|
||||||
await userEvent.hover(screen.getByText('Ethereum deposit cap'));
|
await userEvent.hover(screen.getByText('Ethereum deposit cap'));
|
||||||
});
|
|
||||||
await waitFor(async () => {
|
expect(
|
||||||
await expect(
|
await screen.findByRole('tooltip', {
|
||||||
screen.getByRole('tooltip', {
|
|
||||||
name: /The deposit cap is set when you approve an asset for use with this app/,
|
name: /The deposit cap is set when you approve an asset for use with this app/,
|
||||||
})
|
})
|
||||||
).toBeInTheDocument();
|
).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
@ -92,7 +92,9 @@ export const DepositForm = ({
|
|||||||
const maxSafe = useMaxSafe();
|
const maxSafe = useMaxSafe();
|
||||||
const { open: openAssetDetailsDialog } = useAssetDetailsDialogStore();
|
const { open: openAssetDetailsDialog } = useAssetDetailsDialogStore();
|
||||||
const openDialog = useWeb3ConnectStore((store) => store.open);
|
const openDialog = useWeb3ConnectStore((store) => store.open);
|
||||||
const { isActive, account } = useWeb3React();
|
const { isActive, account, chainId } = useWeb3React();
|
||||||
|
const desiredChainId = useWeb3ConnectStore((store) => store.desiredChainId);
|
||||||
|
const invalidChain = isActive && chainId !== desiredChainId;
|
||||||
const { pubKey, pubKeys: _pubKeys } = useVegaWallet();
|
const { pubKey, pubKeys: _pubKeys } = useVegaWallet();
|
||||||
const [approveNotificationIntent, setApproveNotificationIntent] =
|
const [approveNotificationIntent, setApproveNotificationIntent] =
|
||||||
useState<Intent>(Intent.Warning);
|
useState<Intent>(Intent.Warning);
|
||||||
@ -152,7 +154,20 @@ export const DepositForm = ({
|
|||||||
const approved =
|
const approved =
|
||||||
balances && balances.allowance.isGreaterThan(0) ? true : false;
|
balances && balances.allowance.isGreaterThan(0) ? true : false;
|
||||||
|
|
||||||
return (
|
return invalidChain ? (
|
||||||
|
<div className="mb-2">
|
||||||
|
<Notification
|
||||||
|
intent={Intent.Danger}
|
||||||
|
testId="chain-error"
|
||||||
|
message={t(
|
||||||
|
'This app only works on {{chainId}}. Switch your Ethereum wallet to the correct network.',
|
||||||
|
{
|
||||||
|
chainId: getChainName(desiredChainId),
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
<form
|
<form
|
||||||
onSubmit={handleSubmit(onSubmit)}
|
onSubmit={handleSubmit(onSubmit)}
|
||||||
noValidate={true}
|
noValidate={true}
|
||||||
@ -417,7 +432,11 @@ export const DepositForm = ({
|
|||||||
intent={approveNotificationIntent}
|
intent={approveNotificationIntent}
|
||||||
amount={amount}
|
amount={amount}
|
||||||
/>
|
/>
|
||||||
<FormButton approved={approved} selectedAsset={selectedAsset} />
|
<FormButton
|
||||||
|
approved={approved}
|
||||||
|
isActive={isActive}
|
||||||
|
selectedAsset={selectedAsset}
|
||||||
|
/>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -425,35 +444,21 @@ export const DepositForm = ({
|
|||||||
interface FormButtonProps {
|
interface FormButtonProps {
|
||||||
approved: boolean;
|
approved: boolean;
|
||||||
selectedAsset: AssetFieldsFragment | undefined;
|
selectedAsset: AssetFieldsFragment | undefined;
|
||||||
|
isActive: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const FormButton = ({ approved, selectedAsset }: FormButtonProps) => {
|
const FormButton = ({ approved, selectedAsset, isActive }: FormButtonProps) => {
|
||||||
const t = useT();
|
const t = useT();
|
||||||
const { isActive, chainId } = useWeb3React();
|
|
||||||
const desiredChainId = useWeb3ConnectStore((store) => store.desiredChainId);
|
|
||||||
const invalidChain = isActive && chainId !== desiredChainId;
|
|
||||||
return (
|
return (
|
||||||
<>
|
|
||||||
{invalidChain && (
|
|
||||||
<div className="mb-2">
|
|
||||||
<Notification
|
|
||||||
intent={Intent.Danger}
|
|
||||||
testId="chain-error"
|
|
||||||
message={t('This app only works on {{chainId}}.', {
|
|
||||||
chainId: getChainName(desiredChainId),
|
|
||||||
})}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<TradingButton
|
<TradingButton
|
||||||
type="submit"
|
type="submit"
|
||||||
data-testid="deposit-submit"
|
data-testid="deposit-submit"
|
||||||
fill
|
fill
|
||||||
disabled={!isActive || invalidChain}
|
disabled={!isActive}
|
||||||
>
|
>
|
||||||
{t('Deposit')}
|
{t('Deposit')}
|
||||||
</TradingButton>
|
</TradingButton>
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
"The {{symbol}} faucet is not available at this time": "The {{symbol}} faucet is not available at this time",
|
"The {{symbol}} faucet is not available at this time": "The {{symbol}} faucet is not available at this time",
|
||||||
"The deposit cap is set when you approve an asset for use with this app. To increase this cap, approve {{assetSymbol}} again and choose a higher cap. Check the documentation for your Ethereum wallet app for details.": "The deposit cap is set when you approve an asset for use with this app. To increase this cap, approve {{assetSymbol}} again and choose a higher cap. Check the documentation for your Ethereum wallet app for details.",
|
"The deposit cap is set when you approve an asset for use with this app. To increase this cap, approve {{assetSymbol}} again and choose a higher cap. Check the documentation for your Ethereum wallet app for details.": "The deposit cap is set when you approve an asset for use with this app. To increase this cap, approve {{assetSymbol}} again and choose a higher cap. Check the documentation for your Ethereum wallet app for details.",
|
||||||
"The faucet transaction was rejected by the connected Ethereum wallet": "The faucet transaction was rejected by the connected Ethereum wallet",
|
"The faucet transaction was rejected by the connected Ethereum wallet": "The faucet transaction was rejected by the connected Ethereum wallet",
|
||||||
"This app only works on {{chainId}}.": "This app only works on {{chainId}}.",
|
"This app only works on {{chainId}}. Switch your Ethereum wallet to the correct network.": "This app only works on {{chainId}}. Switch your Ethereum wallet to the correct network.",
|
||||||
"To (Vega key)": "To (Vega key)",
|
"To (Vega key)": "To (Vega key)",
|
||||||
"To date, {{currentDeposit}} {{assetSymbol}} has been deposited from this Ethereum address, so you can deposit up to {{remainingDeposit}} {{assetSymbol}} more.": "To date, {{currentDeposit}} {{assetSymbol}} has been deposited from this Ethereum address, so you can deposit up to {{remainingDeposit}} {{assetSymbol}} more.",
|
"To date, {{currentDeposit}} {{assetSymbol}} has been deposited from this Ethereum address, so you can deposit up to {{remainingDeposit}} {{assetSymbol}} more.": "To date, {{currentDeposit}} {{assetSymbol}} has been deposited from this Ethereum address, so you can deposit up to {{remainingDeposit}} {{assetSymbol}} more.",
|
||||||
"Use maximum": "Use maximum",
|
"Use maximum": "Use maximum",
|
||||||
|
Loading…
Reference in New Issue
Block a user