Skip to content

Commit

Permalink
chore: withdrawal crypto disclaimer and receipt unit tests (deriv-com…
Browse files Browse the repository at this point in the history
  • Loading branch information
lubega-deriv authored Mar 13, 2024
1 parent 91d8afb commit 2fc317b
Show file tree
Hide file tree
Showing 8 changed files with 278 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import './WalletClipboard.scss';

type TProps = {
infoMessage?: string;
popoverAlignment: 'bottom' | 'left' | 'right' | 'top';
successMessage: string;
popoverAlignment?: 'bottom' | 'left' | 'right' | 'top';
successMessage?: string;
textCopy: string;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ const WithdrawalDisclaimer = () => (
the initial coin offering (ICO) tokens will not be credited into your account.
</li>
<li>
Please note that your maximum and minimum withdrawal limits arent fixed. They change due to the
high volatility of cryptocurrency.
Please note that your maximum and minimum withdrawal limits aren&apos;t fixed. They change due to
the high volatility of cryptocurrency.
</li>
</ul>
</InlineMessage>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import WithdrawalCryptoDisclaimer from '../WithdrawalCryptoDisclaimer';

describe('WithdrawalCryptoDisclaimer', () => {
it('should render content of withdrawal crypto disclaimer', () => {
render(<WithdrawalCryptoDisclaimer />);

expect(screen.getByText(/Do not enter an address linked to an initial coin offering/)).toBeInTheDocument();
expect(
screen.getByText(/Please note that your maximum and minimum withdrawal limits aren't fixed./)
).toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ const WithdrawalCryptoAmountConverter: React.FC = () => {
{({ field }: FieldProps<string>) => (
<WalletTextField
{...field}
data-testid='dt_withdrawal_crypto_amount_input'
errorMessage={errors.cryptoAmount}
isInvalid={Boolean(errors.cryptoAmount)}
label={`Amount (${activeWallet?.currency})`}
Expand All @@ -81,13 +82,15 @@ const WithdrawalCryptoAmountConverter: React.FC = () => {
className={classNames('wallets-withdrawal-crypto-amount-converter__arrow', {
'wallets-withdrawal-crypto-amount-converter__arrow--rtl': !isCryptoInputActive,
})}
data-testid='dt_withdrawal_crypto_amount_converter_arrow'
>
<ArrowBold />
</div>
<Field name='fiatAmount' validate={(value: string) => validateFiatInput(fractionalDigits, value)}>
{({ field }: FieldProps<string>) => (
<WalletTextField
{...field}
data-testid='dt_withdrawal_fiat_amount_input'
errorMessage={errors.fiatAmount}
isInvalid={Boolean(errors.fiatAmount)}
label='Amount (USD)'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
import React from 'react';
import { Formik } from 'formik';
import { act, fireEvent, render, screen } from '@testing-library/react';
import { useWithdrawalCryptoContext } from '../../../../../provider';
import { validateCryptoInput, validateFiatInput } from '../../../../../utils';
import WithdrawalCryptoAmountConverter from '../WithdrawalCryptoAmountConverter';

jest.mock('../../../../../utils', () => ({
...jest.requireActual('../../../../../utils'),
validateCryptoInput: jest.fn(),
validateFiatInput: jest.fn(),
}));

jest.mock('../../../../../provider', () => ({
...jest.requireActual('../../../../../provider'),
useWithdrawalCryptoContext: jest.fn(),
}));

const mockUseWithdrawalCryptoContext = useWithdrawalCryptoContext as jest.MockedFunction<
typeof useWithdrawalCryptoContext
>;
const mockValidateCryptoInput = validateCryptoInput as jest.Mock;
const mockValidateFiatInput = validateFiatInput as jest.Mock;

const wrapper: React.FC<React.PropsWithChildren> = ({ children }) => {
return (
<Formik
initialErrors={{}}
initialValues={{
cryptoAddress: '',
cryptoAmount: '',
fiatAmount: '',
}}
onSubmit={jest.fn()}
>
{children}
</Formik>
);
};

describe('WithdrawalCryptoAmountConverter', () => {
beforeEach(() => {
mockUseWithdrawalCryptoContext.mockReturnValue({
accountLimits: {
remainder: undefined,
},
// @ts-expect-error - since this is a mock, we only need partial properties of the hook
activeAccount: {
currency: 'BTC',
},
fractionalDigits: {
crypto: 8,
fiat: 2,
},
getConvertedCryptoAmount: (fiatInput: number | string) => fiatInput as string,
getConvertedFiatAmount: (cryptoInput: number | string) => cryptoInput as string,
isClientVerified: false,
});
});

afterEach(() => {
jest.clearAllMocks();
});

it('should display error below crypto input field if crypto input is invalid', async () => {
mockValidateCryptoInput.mockReturnValue('Crypto Input Error');

render(<WithdrawalCryptoAmountConverter />, { wrapper });

const cryptoInput = screen.getByTestId('dt_withdrawal_crypto_amount_input');

await act(async () => {
await fireEvent.change(cryptoInput, { target: { value: '10' } });
});
expect(screen.getByText('Crypto Input Error')).toBeInTheDocument();
});

it('should change value of fiat input field when value of crypto input changes', async () => {
mockValidateCryptoInput.mockReturnValue('');

render(<WithdrawalCryptoAmountConverter />, { wrapper });

const cryptoInput = screen.getByTestId('dt_withdrawal_crypto_amount_input');
const fiatInput = screen.getByTestId('dt_withdrawal_fiat_amount_input');
await act(async () => {
await fireEvent.change(cryptoInput, { target: { value: '10' } });
});
expect(fiatInput).toHaveValue('10');
});

it('should empty fiat input field if crypto input field has errors', async () => {
mockValidateCryptoInput.mockReturnValue('Crypto Input Error');

render(<WithdrawalCryptoAmountConverter />, { wrapper });

const cryptoInput = screen.getByTestId('dt_withdrawal_crypto_amount_input');
const fiatInput = screen.getByTestId('dt_withdrawal_fiat_amount_input');
await act(async () => {
await fireEvent.change(cryptoInput, { target: { value: '10' } });
});
expect(fiatInput).toHaveValue('');
});

it('should display error below fiat input field if fiat input is invalid', async () => {
mockValidateFiatInput.mockReturnValue('Fiat Input Error');

render(<WithdrawalCryptoAmountConverter />, { wrapper });

const fiatInput = screen.getByTestId('dt_withdrawal_fiat_amount_input');

await act(async () => {
await fireEvent.change(fiatInput, { target: { value: '10' } });
});
expect(screen.getByText('Fiat Input Error')).toBeInTheDocument();
});

it('should change value of crypto input field when value of fiat input changes', async () => {
mockValidateFiatInput.mockReturnValue('');

render(<WithdrawalCryptoAmountConverter />, { wrapper });

const cryptoInput = screen.getByTestId('dt_withdrawal_crypto_amount_input');
const fiatInput = screen.getByTestId('dt_withdrawal_fiat_amount_input');
await act(async () => {
await fireEvent.change(fiatInput, { target: { value: '10' } });
});
expect(cryptoInput).toHaveValue('10');
});

it('should empty crypto input field if fiat input field has errors', async () => {
mockValidateFiatInput.mockReturnValue('Fiat Input Error');

render(<WithdrawalCryptoAmountConverter />, { wrapper });

const cryptoInput = screen.getByTestId('dt_withdrawal_crypto_amount_input');
const fiatInput = screen.getByTestId('dt_withdrawal_fiat_amount_input');
await act(async () => {
await fireEvent.change(fiatInput, { target: { value: '10' } });
});
expect(cryptoInput).toHaveValue('');
});

it('should handle onFocus for crypto input field', async () => {
render(<WithdrawalCryptoAmountConverter />, { wrapper });

const cryptoInput = screen.getByTestId('dt_withdrawal_crypto_amount_input');
await act(async () => {
await fireEvent.focus(cryptoInput);
});

expect(screen.queryByTestId('dt_withdrawal_crypto_amount_converter_arrow')).not.toHaveClass(
'wallets-withdrawal-crypto-amount-converter__arrow--rtl'
);
});

it('should handle onFocus for fiat input field', async () => {
render(<WithdrawalCryptoAmountConverter />, { wrapper });

const fiatInput = screen.getByTestId('dt_withdrawal_fiat_amount_input');
await act(async () => {
await fireEvent.focus(fiatInput);
});

expect(screen.getByTestId('dt_withdrawal_crypto_amount_converter_arrow')).toHaveClass(
'wallets-withdrawal-crypto-amount-converter__arrow--rtl'
);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import React, { PropsWithChildren } from 'react';
import { APIProvider, AuthProvider } from '@deriv/api-v2';
import { fireEvent, render, screen } from '@testing-library/react';
import WithdrawalCryptoReceipt from '../WithdrawalCryptoReceipt';

const mockPush = jest.fn();
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useHistory: jest.fn(() => ({
push: mockPush,
})),
}));

const mockWithdrawalReceipt = {
address: 'test_crypto_address',
};

const wrapper = ({ children }: PropsWithChildren) => (
<APIProvider>
<AuthProvider>{children}</AuthProvider>
</APIProvider>
);

describe('WithdrawalCryptoReceipt', () => {
it('should render the component with withdrawal information', () => {
const mockBTCWithdrawalReceipt = {
address: 'test_crypto_address',
amount: '100',
currency: 'BTC',
};
render(<WithdrawalCryptoReceipt onClose={() => jest.fn()} withdrawalReceipt={mockBTCWithdrawalReceipt} />, {
wrapper,
});

const amountElement = screen.getByText('100 BTC');
expect(amountElement).toBeInTheDocument();

const addressElement = screen.getByText('test_crypto_address');
expect(addressElement).toBeInTheDocument();

const reviewTextElement = screen.getByText(
'Your withdrawal is currently in review. It will be processed within 24 hours. We’ll send you an email once your transaction has been processed.'
);
expect(reviewTextElement).toBeInTheDocument();
});

it('should trigger the close function when the "Close" button is clicked', () => {
const onCloseMock = jest.fn();

render(<WithdrawalCryptoReceipt onClose={onCloseMock} withdrawalReceipt={mockWithdrawalReceipt} />, {
wrapper,
});

fireEvent.click(screen.getByText('Close'));

expect(onCloseMock).toHaveBeenCalled();
});

it('should navigate to the transactions page when the "View transactions" button is clicked', () => {
render(<WithdrawalCryptoReceipt onClose={() => jest.fn()} withdrawalReceipt={mockWithdrawalReceipt} />, {
wrapper,
});

fireEvent.click(screen.getByText('View transactions'));

expect(mockPush).toHaveBeenCalledWith('/wallets/cashier/transactions');
});
});
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import React from 'react';
import { WalletClipboard, WalletText } from '../../../../../../../../components';
import useDevice from '../../../../../../../../hooks/useDevice';
import './WithdrawalCryptoDestinationAddress.scss';

const WithdrawalCryptoDestinationAddress: React.FC<{ address?: string }> = ({ address }) => {
const { isMobile } = useDevice();
return (
<div className='wallets-withdrawal-crypto-destination-address'>
<div className='wallets-withdrawal-crypto-destination-address__title'>
Expand All @@ -16,12 +14,7 @@ const WithdrawalCryptoDestinationAddress: React.FC<{ address?: string }> = ({ ad
<WalletText size='sm' weight='bold'>
{address}
</WalletText>
<WalletClipboard
infoMessage={isMobile ? undefined : 'copy'}
popoverAlignment={isMobile ? 'left' : 'bottom'}
successMessage='copied'
textCopy={address ?? ''}
/>
<WalletClipboard textCopy={address ?? ''} />
</div>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import WithdrawalCryptoDestinationAddress from '../WithdrawalCryptoDestinationAddress';

describe('WithdrawalCryptoDestinationAddress', () => {
it('should render the component with the provided address', () => {
const address = 'your_crypto_address';
render(<WithdrawalCryptoDestinationAddress address={address} />);

const addressElement = screen.getByText(address);
expect(addressElement).toBeInTheDocument();
});

it('should render the component without an address', () => {
render(<WithdrawalCryptoDestinationAddress />);

const noAddressElement = screen.getByText('Destination address');
expect(noAddressElement).toBeInTheDocument();
});
});

0 comments on commit 2fc317b

Please sign in to comment.