import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import BigNumber from 'bignumber.js'; import { AddressField, TransferFee, TransferForm } from './transfer-form'; import { AccountType } from '@vegaprotocol/types'; import { formatNumber, removeDecimal } from '@vegaprotocol/utils'; describe('TransferForm', () => { const submit = () => fireEvent.submit(screen.getByTestId('transfer-form')); const amount = '100'; const pubKey = '70d14a321e02e71992fd115563df765000ccc4775cbe71a0e2f9ff5a3b9dc680'; const asset = { id: 'asset-0', symbol: 'ASSET 0', name: 'Asset 0', decimals: 2, balance: '1000', }; const props = { pubKey, pubKeys: [ pubKey, 'a4b6e3de5d7ef4e31ae1b090be49d1a2ef7bcefff60cccf7658a0d4922651cce', ], assets: [asset], feeFactor: '0.001', submitTransfer: jest.fn(), }; it('validates fields and submits', async () => { render(); // check current pubkey not shown const keySelect: HTMLSelectElement = screen.getByLabelText('Vega key'); expect(keySelect.children).toHaveLength(2); expect(Array.from(keySelect.options).map((o) => o.value)).toEqual([ '', props.pubKeys[1], ]); submit(); expect(await screen.findAllByText('Required')).toHaveLength(3); // Select a pubkey fireEvent.change(screen.getByLabelText('Vega key'), { target: { value: props.pubKeys[1] }, }); // Select asset fireEvent.change( // Bypass RichSelect and target hidden native select // eslint-disable-next-line document.querySelector('select[name="asset"]')!, { target: { value: asset.id } } ); // assert rich select as updated expect(await screen.findByTestId('select-asset')).toHaveTextContent( asset.name ); expect(screen.getByTestId('asset-balance')).toHaveTextContent( formatNumber(asset.balance, asset.decimals) ); // Test amount validation fireEvent.change(screen.getByLabelText('Amount'), { target: { value: '0.00000001' }, }); expect( await screen.findByText('Value is below minimum') ).toBeInTheDocument(); fireEvent.change(screen.getByLabelText('Amount'), { target: { value: '9999999' }, }); expect( await screen.findByText(/cannot transfer more/i) ).toBeInTheDocument(); // set valid amount fireEvent.change(screen.getByLabelText('Amount'), { target: { value: amount }, }); expect(screen.getByTestId('transfer-fee')).toHaveTextContent( new BigNumber(props.feeFactor).times(amount).toFixed() ); submit(); await waitFor(() => { expect(props.submitTransfer).toHaveBeenCalledTimes(1); expect(props.submitTransfer).toHaveBeenCalledWith({ fromAccountType: AccountType.ACCOUNT_TYPE_GENERAL, toAccountType: AccountType.ACCOUNT_TYPE_GENERAL, to: props.pubKeys[1], asset: asset.id, amount: removeDecimal(amount, asset.decimals), oneOff: {}, }); }); }); it('validates a manually entered address', async () => { render(); submit(); expect(await screen.findAllByText('Required')).toHaveLength(3); const toggle = screen.getByText('Enter manually'); fireEvent.click(toggle); // has switched to input expect(toggle).toHaveTextContent('Select from wallet'); expect(screen.getByLabelText('Vega key')).toHaveAttribute('type', 'text'); fireEvent.change(screen.getByLabelText('Vega key'), { target: { value: 'invalid-address' }, }); await waitFor(() => { const errors = screen.getAllByTestId('input-error-text'); expect(errors[0]).toHaveTextContent('Invalid Vega key'); }); // same pubkey fireEvent.change(screen.getByLabelText('Vega key'), { target: { value: pubKey }, }); await waitFor(() => { const errors = screen.getAllByTestId('input-error-text'); expect(errors[0]).toHaveTextContent('Vega key is the same'); }); }); }); describe('AddressField', () => { const props = { pubKeys: ['pubkey-1', 'pubkey-2'], select:
select
, input:
input
, onChange: jest.fn(), }; it('toggles content and calls onChange', async () => { const mockOnChange = jest.fn(); render(); // select should be shown as multiple pubkeys provided expect(screen.getByText('select')).toBeInTheDocument(); expect(screen.queryByText('input')).not.toBeInTheDocument(); fireEvent.click(screen.getByText('Enter manually')); expect(screen.queryByText('select')).not.toBeInTheDocument(); expect(screen.getByText('input')).toBeInTheDocument(); expect(mockOnChange).toHaveBeenCalledTimes(1); fireEvent.click(screen.getByText('Select from wallet')); expect(screen.getByText('select')).toBeInTheDocument(); expect(screen.queryByText('input')).not.toBeInTheDocument(); expect(mockOnChange).toHaveBeenCalledTimes(2); }); it('Does not provide select option if there is only a single key', () => { render(); expect(screen.getByText('input')).toBeInTheDocument(); expect(screen.queryByText('Select from wallet')).not.toBeInTheDocument(); }); }); describe('TransferFee', () => { const props = { amount: '200', feeFactor: '0.001', }; it('calculates and renders the transfer fee', () => { render(); const expected = new BigNumber(props.amount) .times(props.feeFactor) .toFixed(); expect(screen.getByTestId('transfer-fee')).toHaveTextContent(expected); }); });